levix-bot 3.3.0-rc.2 → 4.0.0-beta

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 (118) hide show
  1. package/README.md +11 -7
  2. package/app.cjs +42 -45
  3. package/package.json +9 -1
  4. package/public/dashboard/assets/index-C1b7ijfu.js +391 -0
  5. package/public/dashboard/assets/index-pYaivHON.css +1 -0
  6. package/public/dashboard/index.html +19 -0
  7. package/public/dashboard.css +391 -66
  8. package/public/dashboard.js +593 -42
  9. package/scheduler.cjs +9 -14
  10. package/src/auth/use-database-auth-state.js +2 -4
  11. package/src/bootstrap/core.js +2 -5
  12. package/src/bootstrap/panel.js +10 -5
  13. package/src/cli.js +3 -5
  14. package/src/commands/autoschedule.cjs +1 -4
  15. package/src/commands/blacklist.cjs +22 -20
  16. package/src/commands/block.cjs +2 -4
  17. package/src/commands/calc.cjs +9 -16
  18. package/src/commands/digit.cjs +97 -0
  19. package/src/commands/gemini.cjs +147 -161
  20. package/src/commands/group/add.cjs +7 -16
  21. package/src/commands/group/antiSpam.cjs +5 -11
  22. package/src/commands/group/antilink.cjs +34 -28
  23. package/src/commands/group/approveall.cjs +3 -11
  24. package/src/commands/group/clearwarns.cjs +2 -5
  25. package/src/commands/group/demote.cjs +3 -8
  26. package/src/commands/group/kick.cjs +12 -15
  27. package/src/commands/group/media.cjs +17 -24
  28. package/src/commands/group/members.cjs +1 -2
  29. package/src/commands/group/promote.cjs +4 -12
  30. package/src/commands/group/removeall.cjs +2 -5
  31. package/src/commands/group/setpp.cjs +1 -1
  32. package/src/commands/group/setrules.cjs +2 -8
  33. package/src/commands/group/setwarn.cjs +4 -2
  34. package/src/commands/group/tagadmins.cjs +2 -5
  35. package/src/commands/group/warn.cjs +26 -24
  36. package/src/commands/group/warns.cjs +1 -2
  37. package/src/commands/group/welcome.cjs +13 -17
  38. package/src/commands/group.cjs +7 -10
  39. package/src/commands/help.cjs +6 -12
  40. package/src/commands/lang.cjs +104 -0
  41. package/src/commands/listschedules.cjs +2 -6
  42. package/src/commands/loop.cjs +6 -13
  43. package/src/commands/memory.cjs +19 -32
  44. package/src/commands/mod.cjs +97 -35
  45. package/src/commands/perm.cjs +18 -56
  46. package/src/commands/ping.cjs +1 -5
  47. package/src/commands/poll.cjs +1 -1
  48. package/src/commands/rand.cjs +2 -5
  49. package/src/commands/schedule.cjs +4 -8
  50. package/src/commands/score.cjs +8 -2
  51. package/src/commands/setprefix.cjs +2 -2
  52. package/src/commands/shortlink.cjs +7 -15
  53. package/src/commands/shutdown.cjs +1 -1
  54. package/src/commands/sticker.cjs +222 -0
  55. package/src/commands/stt.cjs +136 -68
  56. package/src/commands/todo.cjs +9 -15
  57. package/src/commands/tts.cjs +10 -16
  58. package/src/commands/unblock.cjs +2 -6
  59. package/src/commands/weather.cjs +5 -12
  60. package/src/config/ai-persona.md +5 -3
  61. package/src/config/available-models.json +1156 -0
  62. package/src/config/baileys.config.js +2 -1
  63. package/src/config/brand.esm.js +1 -10
  64. package/src/config/constants.js +1 -1
  65. package/src/config/defaults.cjs +66 -66
  66. package/src/config/lock.cjs +2 -2
  67. package/src/config/modelCapabilities.cjs +172 -0
  68. package/src/config/runtime-config.cjs +8 -13
  69. package/src/config/secrets.cjs +18 -10
  70. package/src/config/settings.cjs +94 -10
  71. package/src/config/vault.cjs +107 -0
  72. package/src/core/connection.js +13 -12
  73. package/src/core/events.js +41 -23
  74. package/src/core/proxy.js +7 -7
  75. package/src/core/session.js +91 -48
  76. package/src/core/socket.js +12 -15
  77. package/src/db/db.cjs +14 -6
  78. package/src/db/store.cjs +221 -87
  79. package/src/domain/caddy.js +1 -1
  80. package/src/domain/command.js +40 -19
  81. package/src/domain/detect.js +1 -1
  82. package/src/domain/system.js +2 -5
  83. package/src/handlers/command.handler.js +22 -43
  84. package/src/handlers/group.handler.js +13 -13
  85. package/src/handlers/message.handler.js +11 -21
  86. package/src/index.js +8 -4
  87. package/src/middleware/antispam.middleware.js +46 -23
  88. package/src/middleware/blacklist.middleware.js +14 -9
  89. package/src/middleware/forward-tracking.middleware.js +3 -2
  90. package/src/middleware/permissions.middleware.js +7 -10
  91. package/src/panel/login-throttle.cjs +43 -0
  92. package/src/panel/session-auth.cjs +17 -0
  93. package/src/routes/dashboard.api.esm.js +394 -72
  94. package/src/services/aiAgent.cjs +136 -49
  95. package/src/services/aiProviders.cjs +193 -47
  96. package/src/services/aiRouter.cjs +137 -0
  97. package/src/services/aiTools.cjs +305 -125
  98. package/src/services/llmDiscovery.cjs +481 -0
  99. package/src/services/modelRegistry.cjs +412 -0
  100. package/src/utils/datetime.cjs +2 -2
  101. package/src/utils/lid-helper.esm.js +7 -7
  102. package/src/utils/logger.cjs +1 -1
  103. package/src/utils/markdownParser.cjs +159 -0
  104. package/src/utils/memory.cjs +43 -13
  105. package/src/utils/messageContent.cjs +40 -0
  106. package/src/utils/normalizeJid.esm.js +7 -7
  107. package/src/utils/numerals.cjs +75 -0
  108. package/src/utils/permissions.esm.js +10 -15
  109. package/src/utils/providerUrl.cjs +281 -0
  110. package/src/utils/recurrence.cjs +7 -11
  111. package/src/utils/sendBotMessage.esm.js +4 -14
  112. package/src/utils/statusMessage.cjs +5 -13
  113. package/src/utils/storage.cjs +10 -0
  114. package/src/utils/storage.esm.js +11 -0
  115. package/src/utils/textDecode.cjs +4 -9
  116. package/src/utils/thumbnail.cjs +8 -14
  117. package/src/utils/typing.esm.js +12 -12
  118. package/views/dashboard.ejs +134 -106
@@ -10,12 +10,10 @@
10
10
  --blue-bright: #5a94ff;
11
11
  --cyan: #21cef3;
12
12
  --cyan-soft: #8be8fb;
13
- --grad: linear-gradient(
14
- 120deg,
15
- var(--blue) 0%,
16
- #087ff2 58%,
17
- var(--cyan) 115%
18
- );
13
+ --grad: linear-gradient(120deg,
14
+ var(--blue) 0%,
15
+ #087ff2 58%,
16
+ var(--cyan) 115%);
19
17
 
20
18
  --bg: #07101f;
21
19
  --bg-soft: #0a1629;
@@ -156,11 +154,9 @@ kbd {
156
154
  .dashboard-page {
157
155
  min-width: 320px;
158
156
  background:
159
- radial-gradient(
160
- circle at 78% 0%,
157
+ radial-gradient(circle at 78% 0%,
161
158
  color-mix(in srgb, var(--blue) 9%, transparent),
162
- transparent 32rem
163
- ),
159
+ transparent 32rem),
164
160
  var(--bg);
165
161
  }
166
162
 
@@ -171,11 +167,9 @@ kbd {
171
167
  pointer-events: none;
172
168
  content: "";
173
169
  opacity: 0.26;
174
- background-image: radial-gradient(
175
- circle,
176
- color-mix(in srgb, var(--faint) 24%, transparent) 0.75px,
177
- transparent 0.85px
178
- );
170
+ background-image: radial-gradient(circle,
171
+ color-mix(in srgb, var(--faint) 24%, transparent) 0.75px,
172
+ transparent 0.85px);
179
173
  background-size: 22px 22px;
180
174
  mask-image: linear-gradient(to bottom, black, transparent 72%);
181
175
  }
@@ -197,11 +191,9 @@ kbd {
197
191
  overflow-y: auto;
198
192
  border-right: 1px solid #203555;
199
193
  background:
200
- radial-gradient(
201
- circle at 15% 6%,
194
+ radial-gradient(circle at 15% 6%,
202
195
  rgba(25, 118, 255, 0.2),
203
- transparent 17rem
204
- ),
196
+ transparent 17rem),
205
197
  linear-gradient(180deg, #08152b 0%, #071226 100%);
206
198
  color: #f4f7ff;
207
199
  scrollbar-width: thin;
@@ -278,11 +270,13 @@ kbd {
278
270
  }
279
271
 
280
272
  @keyframes pulse-bars {
273
+
281
274
  0%,
282
275
  100% {
283
276
  opacity: 0.4;
284
277
  transform: scaleY(0.65);
285
278
  }
279
+
286
280
  50% {
287
281
  opacity: 1;
288
282
  transform: scaleY(1);
@@ -353,11 +347,9 @@ kbd {
353
347
 
354
348
  .nav a.active {
355
349
  border-color: rgba(83, 142, 232, 0.24);
356
- background: linear-gradient(
357
- 105deg,
358
- rgba(23, 107, 250, 0.2),
359
- rgba(33, 206, 243, 0.06)
360
- );
350
+ background: linear-gradient(105deg,
351
+ rgba(23, 107, 250, 0.2),
352
+ rgba(33, 206, 243, 0.06));
361
353
  color: #ffffff;
362
354
  box-shadow: inset 3px 0 0 var(--cyan);
363
355
  }
@@ -483,7 +475,7 @@ kbd {
483
475
  gap: 1px;
484
476
  }
485
477
 
486
- .page-heading > span {
478
+ .page-heading>span {
487
479
  color: var(--faint);
488
480
  font-size: 0.61rem;
489
481
  font-weight: 720;
@@ -500,7 +492,7 @@ kbd {
500
492
  line-height: 1.25;
501
493
  }
502
494
 
503
- .topbar > .spacer,
495
+ .topbar>.spacer,
504
496
  .card-head .spacer {
505
497
  flex: 1;
506
498
  }
@@ -544,6 +536,7 @@ kbd {
544
536
  opacity: 0;
545
537
  transform: translateY(7px);
546
538
  }
539
+
547
540
  to {
548
541
  opacity: 1;
549
542
  transform: translateY(0);
@@ -562,11 +555,9 @@ kbd {
562
555
  border: 1px solid #1e3e6c;
563
556
  border-radius: 28px 28px 28px 10px;
564
557
  background:
565
- linear-gradient(
566
- 105deg,
558
+ linear-gradient(105deg,
567
559
  rgba(4, 20, 48, 0.98) 0 52%,
568
- rgba(6, 35, 73, 0.94) 100%
569
- ),
560
+ rgba(6, 35, 73, 0.94) 100%),
570
561
  #07172f;
571
562
  box-shadow: 0 28px 80px rgba(0, 20, 57, 0.26);
572
563
  color: #f7faff;
@@ -636,7 +627,7 @@ kbd {
636
627
  font-weight: 560;
637
628
  }
638
629
 
639
- .hero-copy > p {
630
+ .hero-copy>p {
640
631
  max-width: 590px;
641
632
  margin-top: 20px;
642
633
  color: #a9bdd9;
@@ -744,6 +735,7 @@ kbd {
744
735
  from {
745
736
  transform: translate(-50%, -58%) rotate(0deg);
746
737
  }
738
+
747
739
  to {
748
740
  transform: translate(-50%, -58%) rotate(360deg);
749
741
  }
@@ -753,6 +745,7 @@ kbd {
753
745
  from {
754
746
  transform: translate(-50%, -58%) rotate(360deg);
755
747
  }
748
+
756
749
  to {
757
750
  transform: translate(-50%, -58%) rotate(0deg);
758
751
  }
@@ -775,10 +768,12 @@ kbd {
775
768
  top: 21%;
776
769
  left: 30%;
777
770
  }
771
+
778
772
  .node-two {
779
773
  top: 46%;
780
774
  right: 18%;
781
775
  }
776
+
782
777
  .node-three {
783
778
  bottom: 23%;
784
779
  left: 27%;
@@ -1035,7 +1030,7 @@ kbd {
1035
1030
  box-shadow: var(--shadow-soft);
1036
1031
  }
1037
1032
 
1038
- .card + .card,
1033
+ .card+.card,
1039
1034
  #settings-list .card:first-child {
1040
1035
  margin-top: 18px;
1041
1036
  }
@@ -1244,11 +1239,9 @@ kbd {
1244
1239
  width: 190px;
1245
1240
  height: 100%;
1246
1241
  pointer-events: none;
1247
- background: radial-gradient(
1248
- circle at 100% 0,
1249
- color-mix(in srgb, var(--blue) 10%, transparent),
1250
- transparent 70%
1251
- );
1242
+ background: radial-gradient(circle at 100% 0,
1243
+ color-mix(in srgb, var(--blue) 10%, transparent),
1244
+ transparent 70%);
1252
1245
  content: "";
1253
1246
  }
1254
1247
 
@@ -1294,7 +1287,7 @@ label.field {
1294
1287
  margin-bottom: 15px;
1295
1288
  }
1296
1289
 
1297
- label.field > span,
1290
+ label.field>span,
1298
1291
  .setting-label {
1299
1292
  display: block;
1300
1293
  margin-bottom: 6px;
@@ -1303,7 +1296,7 @@ label.field > span,
1303
1296
  font-weight: 650;
1304
1297
  }
1305
1298
 
1306
- label.field > small {
1299
+ label.field>small {
1307
1300
  display: block;
1308
1301
  margin-top: 6px;
1309
1302
  color: var(--faint);
@@ -1405,17 +1398,17 @@ select {
1405
1398
  background 180ms ease;
1406
1399
  }
1407
1400
 
1408
- .switch input:checked + .track {
1401
+ .switch input:checked+.track {
1409
1402
  border-color: var(--blue);
1410
1403
  background: var(--blue);
1411
1404
  }
1412
1405
 
1413
- .switch input:checked + .track::after {
1406
+ .switch input:checked+.track::after {
1414
1407
  background: #ffffff;
1415
1408
  transform: translateX(18px);
1416
1409
  }
1417
1410
 
1418
- .switch input:focus-visible + .track {
1411
+ .switch input:focus-visible+.track {
1419
1412
  outline: 2px solid var(--cyan);
1420
1413
  outline-offset: 3px;
1421
1414
  }
@@ -1457,7 +1450,7 @@ select {
1457
1450
  margin-bottom: 0;
1458
1451
  }
1459
1452
 
1460
- .security-card > .hint {
1453
+ .security-card>.hint {
1461
1454
  max-width: 820px;
1462
1455
  margin-top: 14px;
1463
1456
  }
@@ -1478,7 +1471,7 @@ select {
1478
1471
  margin-bottom: 16px;
1479
1472
  }
1480
1473
 
1481
- .toolbar > .spacer {
1474
+ .toolbar>.spacer {
1482
1475
  flex: 1;
1483
1476
  }
1484
1477
 
@@ -1681,7 +1674,7 @@ td.wrap {
1681
1674
  box-shadow: none;
1682
1675
  }
1683
1676
 
1684
- .group-card + .group-card {
1677
+ .group-card+.group-card {
1685
1678
  margin-top: 12px;
1686
1679
  }
1687
1680
 
@@ -1764,12 +1757,12 @@ td.wrap {
1764
1757
  margin-bottom: 0;
1765
1758
  }
1766
1759
 
1767
- .setting-item > .inline:not(.setting-label-row) {
1760
+ .setting-item>.inline:not(.setting-label-row) {
1768
1761
  max-width: 720px;
1769
1762
  }
1770
1763
 
1771
- .setting-item > .inline:not(.setting-label-row) > input,
1772
- .setting-item > .inline:not(.setting-label-row) > select {
1764
+ .setting-item>.inline:not(.setting-label-row)>input,
1765
+ .setting-item>.inline:not(.setting-label-row)>select {
1773
1766
  flex: 1 1 300px;
1774
1767
  }
1775
1768
 
@@ -1867,8 +1860,6 @@ td.wrap {
1867
1860
  color: var(--text);
1868
1861
  border: 1px solid var(--line);
1869
1862
  }
1870
- font-weight: 700;
1871
- }
1872
1863
 
1873
1864
  .steps li span {
1874
1865
  color: var(--text);
@@ -1904,6 +1895,7 @@ td.wrap {
1904
1895
  .toast.ok {
1905
1896
  border-left-color: var(--ok);
1906
1897
  }
1898
+
1907
1899
  .toast.error {
1908
1900
  border-left-color: var(--danger);
1909
1901
  }
@@ -1913,6 +1905,7 @@ td.wrap {
1913
1905
  opacity: 0;
1914
1906
  transform: translateX(16px) scale(0.98);
1915
1907
  }
1908
+
1916
1909
  to {
1917
1910
  opacity: 1;
1918
1911
  transform: translateX(0) scale(1);
@@ -1987,7 +1980,7 @@ td.wrap {
1987
1980
  filter: drop-shadow(0 10px 20px rgba(0, 102, 245, 0.3));
1988
1981
  }
1989
1982
 
1990
- .brand-lockup > span {
1983
+ .brand-lockup>span {
1991
1984
  display: grid;
1992
1985
  }
1993
1986
 
@@ -2086,7 +2079,7 @@ td.wrap {
2086
2079
  text-transform: uppercase;
2087
2080
  }
2088
2081
 
2089
- .gateway-trust > span {
2082
+ .gateway-trust>span {
2090
2083
  width: 7px;
2091
2084
  height: 7px;
2092
2085
  border-radius: 50%;
@@ -2102,11 +2095,9 @@ td.wrap {
2102
2095
  place-items: center;
2103
2096
  padding: clamp(26px, 5vw, 72px);
2104
2097
  background:
2105
- radial-gradient(
2106
- circle at 95% 4%,
2098
+ radial-gradient(circle at 95% 4%,
2107
2099
  rgba(23, 107, 250, 0.1),
2108
- transparent 24rem
2109
- ),
2100
+ transparent 24rem),
2110
2101
  #091222;
2111
2102
  }
2112
2103
 
@@ -2146,7 +2137,7 @@ td.wrap {
2146
2137
  font-size: 0.86rem;
2147
2138
  }
2148
2139
 
2149
- .auth-card label.field > span {
2140
+ .auth-card label.field>span {
2150
2141
  color: #dce6f6;
2151
2142
  }
2152
2143
 
@@ -2294,7 +2285,7 @@ td.wrap {
2294
2285
  padding: 22px 14px 34px;
2295
2286
  }
2296
2287
 
2297
- .page-heading > span {
2288
+ .page-heading>span {
2298
2289
  display: none;
2299
2290
  }
2300
2291
 
@@ -2314,7 +2305,7 @@ td.wrap {
2314
2305
  font-size: clamp(2.15rem, 10vw, 3.25rem);
2315
2306
  }
2316
2307
 
2317
- .hero-copy > p {
2308
+ .hero-copy>p {
2318
2309
  max-width: 520px;
2319
2310
  }
2320
2311
 
@@ -2399,7 +2390,7 @@ td.wrap {
2399
2390
  display: none;
2400
2391
  }
2401
2392
 
2402
- .topbar > .spacer {
2393
+ .topbar>.spacer {
2403
2394
  display: none;
2404
2395
  }
2405
2396
 
@@ -2472,7 +2463,7 @@ td.wrap {
2472
2463
  width: 100%;
2473
2464
  }
2474
2465
 
2475
- .toolbar > .spacer {
2466
+ .toolbar>.spacer {
2476
2467
  display: none;
2477
2468
  }
2478
2469
 
@@ -2491,9 +2482,9 @@ td.wrap {
2491
2482
  max-width: none;
2492
2483
  }
2493
2484
 
2494
- .role-control > input,
2495
- .role-control > select,
2496
- .role-control > button {
2485
+ .role-control>input,
2486
+ .role-control>select,
2487
+ .role-control>button {
2497
2488
  width: 100%;
2498
2489
  }
2499
2490
 
@@ -2552,7 +2543,7 @@ td.wrap {
2552
2543
  min-height: 128px;
2553
2544
  }
2554
2545
 
2555
- .prefix-control > * {
2546
+ .prefix-control>* {
2556
2547
  width: 100%;
2557
2548
  max-width: none;
2558
2549
  }
@@ -2568,7 +2559,341 @@ td.wrap {
2568
2559
  }
2569
2560
  }
2570
2561
 
2562
+ /* --- Language Switcher ---------------------------------------------------- */
2563
+ .lang-btn {
2564
+ display: inline-flex;
2565
+ align-items: center;
2566
+ gap: 5px;
2567
+ padding: 0 10px;
2568
+ width: auto !important;
2569
+ font-weight: 600;
2570
+ font-size: 13px;
2571
+ }
2572
+
2573
+ .lang-btn svg {
2574
+ width: 17px;
2575
+ height: 17px;
2576
+ }
2577
+
2578
+ .lang-tag {
2579
+ font-family: var(--display);
2580
+ letter-spacing: 0.5px;
2581
+ }
2582
+
2583
+ /* --- Settings Redesign Tabs ----------------------------------------------- */
2584
+ .settings-nav-tabs {
2585
+ display: flex;
2586
+ gap: 8px;
2587
+ overflow-x: auto;
2588
+ padding: 4px 0 16px 0;
2589
+ margin-bottom: 8px;
2590
+ border-bottom: 1px solid var(--line-soft);
2591
+ scrollbar-width: thin;
2592
+ }
2593
+
2594
+ .settings-tab {
2595
+ display: inline-flex;
2596
+ align-items: center;
2597
+ gap: 8px;
2598
+ padding: 10px 18px;
2599
+ background: var(--panel-raised);
2600
+ border: 1px solid var(--line);
2601
+ border-radius: var(--radius-sm);
2602
+ color: var(--muted);
2603
+ font-weight: 550;
2604
+ font-size: 14px;
2605
+ cursor: pointer;
2606
+ white-space: nowrap;
2607
+ transition: all 0.18s ease;
2608
+ }
2609
+
2610
+ .settings-tab:hover {
2611
+ background: var(--panel-hover);
2612
+ color: var(--text);
2613
+ border-color: var(--blue-bright);
2614
+ }
2615
+
2616
+ .settings-tab.active {
2617
+ background: var(--grad);
2618
+ color: #ffffff;
2619
+ border-color: transparent;
2620
+ box-shadow: 0 4px 16px rgba(23, 107, 250, 0.35);
2621
+ }
2622
+
2623
+ .settings-tab svg {
2624
+ width: 17px;
2625
+ height: 17px;
2626
+ stroke: currentColor;
2627
+ flex-shrink: 0;
2628
+ }
2629
+
2630
+ /* --- AI Provider Selector Grid -------------------------------------------- */
2631
+ .provider-grid {
2632
+ display: grid;
2633
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
2634
+ gap: 14px;
2635
+ margin: 16px 0;
2636
+ }
2637
+
2638
+ .provider-card {
2639
+ display: flex;
2640
+ flex-direction: column;
2641
+ padding: 16px;
2642
+ background: var(--panel-raised);
2643
+ border: 1.5px solid var(--line);
2644
+ border-radius: var(--radius);
2645
+ cursor: pointer;
2646
+ transition: all 0.22s ease;
2647
+ position: relative;
2648
+ text-align: left;
2649
+ }
2650
+
2651
+ html[dir="rtl"] .provider-card {
2652
+ text-align: right;
2653
+ }
2654
+
2655
+ .provider-card:hover {
2656
+ background: var(--panel-hover);
2657
+ border-color: var(--blue-bright);
2658
+ transform: translateY(-2px);
2659
+ }
2660
+
2661
+ .provider-card.active {
2662
+ border-color: var(--cyan);
2663
+ background: linear-gradient(135deg, rgba(23, 107, 250, 0.14) 0%, rgba(33, 206, 243, 0.08) 100%);
2664
+ box-shadow: 0 8px 24px rgba(23, 107, 250, 0.2);
2665
+ }
2666
+
2667
+ .provider-card-head {
2668
+ display: flex;
2669
+ align-items: center;
2670
+ justify-content: space-between;
2671
+ margin-bottom: 8px;
2672
+ }
2673
+
2674
+ .provider-title {
2675
+ font-weight: 700;
2676
+ font-size: 16px;
2677
+ color: var(--text);
2678
+ display: flex;
2679
+ align-items: center;
2680
+ gap: 8px;
2681
+ }
2682
+
2683
+ .provider-desc {
2684
+ font-size: 13px;
2685
+ color: var(--muted);
2686
+ line-height: 1.45;
2687
+ }
2688
+
2689
+ .provider-active-badge {
2690
+ display: none;
2691
+ font-size: 11px;
2692
+ padding: 2px 8px;
2693
+ border-radius: 999px;
2694
+ background: var(--ok);
2695
+ color: #07101f;
2696
+ font-weight: 700;
2697
+ }
2698
+
2699
+ .provider-card.active .provider-active-badge {
2700
+ display: inline-block;
2701
+ }
2702
+
2703
+ /* --- Presets & Capabilities ----------------------------------------------- */
2704
+ .preset-chips {
2705
+ display: flex;
2706
+ flex-wrap: wrap;
2707
+ gap: 8px;
2708
+ margin: 12px 0 16px 0;
2709
+ }
2710
+
2711
+ .preset-chip {
2712
+ display: inline-flex;
2713
+ align-items: center;
2714
+ gap: 6px;
2715
+ padding: 6px 12px;
2716
+ background: rgba(33, 206, 243, 0.12);
2717
+ border: 1px solid rgba(33, 206, 243, 0.35);
2718
+ border-radius: 999px;
2719
+ color: var(--cyan);
2720
+ font-size: 12px;
2721
+ font-weight: 600;
2722
+ cursor: pointer;
2723
+ transition: all 0.15s ease;
2724
+ }
2725
+
2726
+ .preset-chip:hover {
2727
+ background: rgba(33, 206, 243, 0.22);
2728
+ transform: translateY(-1px);
2729
+ }
2730
+
2731
+ .capability-badge {
2732
+ display: inline-flex;
2733
+ align-items: center;
2734
+ gap: 4px;
2735
+ font-size: 11px;
2736
+ font-weight: 700;
2737
+ padding: 3px 9px;
2738
+ border-radius: 999px;
2739
+ margin-inline-start: 8px;
2740
+ }
2741
+
2742
+ .capability-badge.supported {
2743
+ background: rgba(59, 214, 139, 0.15);
2744
+ color: var(--ok);
2745
+ border: 1px solid rgba(59, 214, 139, 0.35);
2746
+ }
2747
+
2748
+ .capability-badge.manual {
2749
+ background: rgba(242, 184, 75, 0.15);
2750
+ color: var(--warn);
2751
+ border: 1px solid rgba(242, 184, 75, 0.35);
2752
+ }
2753
+
2754
+ /* --- Modal Dialog --------------------------------------------------------- */
2755
+ .modal-backdrop {
2756
+ position: fixed;
2757
+ inset: 0;
2758
+ background: rgba(7, 16, 31, 0.78);
2759
+ backdrop-filter: blur(8px);
2760
+ -webkit-backdrop-filter: blur(8px);
2761
+ display: flex;
2762
+ align-items: center;
2763
+ justify-content: center;
2764
+ z-index: 999;
2765
+ padding: 16px;
2766
+ }
2767
+
2768
+ .modal-card {
2769
+ background: var(--panel);
2770
+ border: 1px solid var(--line);
2771
+ border-radius: var(--radius);
2772
+ box-shadow: var(--shadow);
2773
+ width: 100%;
2774
+ max-width: 620px;
2775
+ max-height: 88vh;
2776
+ display: flex;
2777
+ flex-direction: column;
2778
+ overflow: hidden;
2779
+ animation: modalIn 0.2s cubic-bezier(0.16, 1, 0.3, 1);
2780
+ }
2781
+
2782
+ @keyframes modalIn {
2783
+ from {
2784
+ opacity: 0;
2785
+ transform: scale(0.96) translateY(10px);
2786
+ }
2787
+
2788
+ to {
2789
+ opacity: 1;
2790
+ transform: scale(1) translateY(0);
2791
+ }
2792
+ }
2793
+
2794
+ .modal-head {
2795
+ display: flex;
2796
+ align-items: center;
2797
+ justify-content: space-between;
2798
+ padding: 18px 22px;
2799
+ border-bottom: 1px solid var(--line-soft);
2800
+ }
2801
+
2802
+ .modal-body {
2803
+ padding: 22px;
2804
+ overflow-y: auto;
2805
+ display: flex;
2806
+ flex-direction: column;
2807
+ gap: 16px;
2808
+ }
2809
+
2810
+ .modal-foot {
2811
+ display: flex;
2812
+ justify-content: flex-end;
2813
+ padding: 14px 22px;
2814
+ border-top: 1px solid var(--line-soft);
2815
+ background: var(--panel-raised);
2816
+ }
2817
+
2818
+ /* --- RTL Support ---------------------------------------------------------- */
2819
+ html[dir="rtl"] {
2820
+ font-family: var(--body);
2821
+ direction: rtl;
2822
+ text-align: right;
2823
+ }
2824
+
2825
+ html[dir="rtl"] .sidebar {
2826
+ border-right: none;
2827
+ border-left: 1px solid var(--line-soft);
2828
+ }
2829
+
2830
+ html[dir="rtl"] .nav a {
2831
+ padding: 10px 16px 10px 14px;
2832
+ }
2833
+
2834
+ html[dir="rtl"] .nav a svg {
2835
+ margin-right: 0;
2836
+ margin-left: 12px;
2837
+ }
2838
+
2839
+ html[dir="rtl"] .brand img {
2840
+ margin-right: 0;
2841
+ margin-left: 12px;
2842
+ }
2843
+
2844
+ html[dir="rtl"] .topbar-actions {
2845
+ margin-left: 0;
2846
+ margin-right: auto;
2847
+ }
2848
+
2849
+ html[dir="rtl"] .page-heading {
2850
+ margin-right: 0;
2851
+ margin-left: auto;
2852
+ }
2853
+
2854
+ html[dir="rtl"] .inline {
2855
+ flex-direction: row;
2856
+ }
2857
+
2858
+ html[dir="rtl"] .card-head {
2859
+ flex-direction: row;
2860
+ }
2861
+
2862
+ html[dir="rtl"] .setting-label-row {
2863
+ flex-direction: row;
2864
+ }
2865
+
2866
+ html[dir="rtl"] .modal-head {
2867
+ flex-direction: row;
2868
+ }
2869
+
2870
+ html[dir="rtl"] .modal-foot {
2871
+ justify-content: flex-start;
2872
+ }
2873
+
2874
+ html[dir="rtl"] .status-dot {
2875
+ margin-right: 0;
2876
+ margin-left: 8px;
2877
+ }
2878
+
2879
+ html[dir="rtl"] .source {
2880
+ margin-left: 0;
2881
+ margin-right: 8px;
2882
+ }
2883
+
2884
+ html[dir="rtl"] .btn svg {
2885
+ margin-right: 0;
2886
+ margin-left: 6px;
2887
+ }
2888
+
2889
+ html[dir="rtl"] .logout-btn svg {
2890
+ margin-left: 0;
2891
+ margin-right: 6px;
2892
+ transform: rotate(180deg);
2893
+ }
2894
+
2571
2895
  @media (prefers-reduced-motion: reduce) {
2896
+
2572
2897
  *,
2573
2898
  *::before,
2574
2899
  *::after {
@@ -2577,4 +2902,4 @@ td.wrap {
2577
2902
  animation-iteration-count: 1 !important;
2578
2903
  transition-duration: 0.001ms !important;
2579
2904
  }
2580
- }
2905
+ }