search-rotation 0.4.9

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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +124 -0
  3. package/dist/abort.js +14 -0
  4. package/dist/config.js +109 -0
  5. package/dist/engines/base.js +72 -0
  6. package/dist/engines/duckduckgo.js +98 -0
  7. package/dist/engines/exa.js +113 -0
  8. package/dist/engines/firecrawl.js +78 -0
  9. package/dist/engines/googlecse.js +41 -0
  10. package/dist/engines/hosted-mcp.js +24 -0
  11. package/dist/engines/index.js +13 -0
  12. package/dist/engines/jina.js +28 -0
  13. package/dist/engines/parallel.js +74 -0
  14. package/dist/engines/tavily.js +74 -0
  15. package/dist/history.js +59 -0
  16. package/dist/index.js +182 -0
  17. package/dist/mcp/engine-status.js +58 -0
  18. package/dist/mcp/http.js +35 -0
  19. package/dist/mcp/server.js +105 -0
  20. package/dist/persistence.js +80 -0
  21. package/dist/quota.js +37 -0
  22. package/dist/router.js +183 -0
  23. package/dist/search-time.js +31 -0
  24. package/dist/status.js +141 -0
  25. package/dist/types.js +1 -0
  26. package/dist/usage.js +95 -0
  27. package/dist/version.js +5 -0
  28. package/dist/web/app.js +155 -0
  29. package/dist/web/security.js +116 -0
  30. package/docs/assets/brand/FONT-LICENSE.txt +93 -0
  31. package/docs/assets/brand/README.md +18 -0
  32. package/docs/assets/brand/icon-128.png +0 -0
  33. package/docs/assets/brand/icon-32.png +0 -0
  34. package/docs/assets/brand/icon-512.png +0 -0
  35. package/docs/assets/brand/icon-dark-128.png +0 -0
  36. package/docs/assets/brand/icon-dark-512.png +0 -0
  37. package/docs/assets/brand/icon-dark.svg +1 -0
  38. package/docs/assets/brand/icon-light-128.png +0 -0
  39. package/docs/assets/brand/icon-light-512.png +0 -0
  40. package/docs/assets/brand/icon-light.svg +1 -0
  41. package/docs/assets/brand/icon-mono.svg +1 -0
  42. package/docs/assets/brand/icon.svg +1 -0
  43. package/docs/assets/brand/preview.png +0 -0
  44. package/docs/assets/brand/preview.svg +1 -0
  45. package/docs/assets/brand/wordmark-dark.svg +1 -0
  46. package/docs/assets/brand/wordmark-light.svg +1 -0
  47. package/docs/assets/dashboard-dark.png +0 -0
  48. package/docs/assets/dashboard-light.png +0 -0
  49. package/docs/assets/dashboard.png +0 -0
  50. package/docs/assets/mcp-tools-dark.png +0 -0
  51. package/docs/assets/mcp-tools-light.png +0 -0
  52. package/docs/assets/mcp-tools.png +0 -0
  53. package/docs/assets/search-rotation.svg +52 -0
  54. package/docs/clients.md +93 -0
  55. package/docs/operations.md +66 -0
  56. package/docs/provider-access.md +38 -0
  57. package/docs/release-notes.md +52 -0
  58. package/package.json +65 -0
  59. package/static/app.js +1126 -0
  60. package/static/engine-logos/README.md +11 -0
  61. package/static/engine-logos/duckduckgo.png +0 -0
  62. package/static/engine-logos/exa.png +0 -0
  63. package/static/engine-logos/firecrawl.png +0 -0
  64. package/static/engine-logos/google-cse.png +0 -0
  65. package/static/engine-logos/jina.png +0 -0
  66. package/static/engine-logos/parallel.png +0 -0
  67. package/static/engine-logos/tavily.png +0 -0
  68. package/static/i18n.js +709 -0
  69. package/static/index.html +95 -0
  70. package/static/style.css +1258 -0
@@ -0,0 +1,1258 @@
1
+ /* ============================================================
2
+ search-rotation — Design-System
3
+ Dark-first, Light-Theme via [data-theme="light"]
4
+ ============================================================ */
5
+
6
+ .tools-intro { color: var(--muted); max-width: 78ch; margin: 0 0 24px; }
7
+ .tools-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
8
+ .tool-card { min-width: 0; display: flex; flex-direction: column; }
9
+ .tool-card .panel-head svg { color: var(--accent); flex-shrink: 0; }
10
+ .tool-body { padding: 20px; display: flex; flex-direction: column; flex: 1; }
11
+ .tool-body > p { margin: 0 0 20px; color: var(--muted); }
12
+ .tool-body h3 { margin: 0 0 10px; font-size: 13px; }
13
+ .tool-params { margin: 0 0 24px; display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 10px 16px; font-size: 13px; }
14
+ .tool-params dd { margin: 0; color: var(--muted); overflow-wrap: anywhere; }
15
+ .tool-example { margin-top: auto; }
16
+ .tool-example pre { padding: 16px; background: var(--input-bg); border: 1px solid var(--border); border-radius: var(--radius-s); white-space: pre-wrap; overflow-wrap: anywhere; font-size: 12px; }
17
+ @media (max-width: 720px) { .tools-grid { grid-template-columns: minmax(0, 1fr); } }
18
+
19
+ :root {
20
+ --accent: #8b7cf7;
21
+ --accent-2: #4dd8e6;
22
+ --ok: #3ecf8e;
23
+ --warn: #f5b642;
24
+ --crit: #f26d6d;
25
+ --radius: 14px;
26
+ --radius-s: 10px;
27
+ --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
28
+ --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
29
+ --shadow: 0 8px 30px rgba(0, 0, 0, 0.35);
30
+ --shadow-s: 0 2px 10px rgba(0, 0, 0, 0.25);
31
+ --speed: 0.18s;
32
+ }
33
+
34
+ [data-theme="dark"] {
35
+ color-scheme: dark;
36
+ --bg: #0a0c12;
37
+ --bg-glow-1: rgba(139, 124, 247, 0.09);
38
+ --bg-glow-2: rgba(77, 216, 230, 0.06);
39
+ --surface: #12151d;
40
+ --surface-2: #181c26;
41
+ --surface-3: #1f2431;
42
+ --border: rgba(255, 255, 255, 0.09);
43
+ --border-strong: rgba(255, 255, 255, 0.16);
44
+ --text: #e9ecf4;
45
+ --muted: #98a0b3;
46
+ --faint: #6b7386;
47
+ --input-bg: #0d1017;
48
+ --chip-bg: rgba(255, 255, 255, 0.05);
49
+ --topbar-bg: rgba(10, 12, 18, 0.78);
50
+ --fill-track: rgba(255, 255, 255, 0.08);
51
+ --shadow: 0 8px 30px rgba(0, 0, 0, 0.35);
52
+ --shadow-s: 0 2px 10px rgba(0, 0, 0, 0.25);
53
+ }
54
+
55
+ [data-theme="light"] {
56
+ color-scheme: light;
57
+ --bg: #f4f5fa;
58
+ --bg-glow-1: rgba(109, 90, 232, 0.07);
59
+ --bg-glow-2: rgba(14, 165, 196, 0.06);
60
+ --surface: #ffffff;
61
+ --surface-2: #f2f3f9;
62
+ --surface-3: #e9ebf4;
63
+ --border: rgba(18, 24, 48, 0.11);
64
+ --border-strong: rgba(18, 24, 48, 0.22);
65
+ --text: #191d28;
66
+ --muted: #5c6579;
67
+ --faint: #8b93a6;
68
+ --input-bg: #ffffff;
69
+ --chip-bg: rgba(18, 24, 48, 0.05);
70
+ --topbar-bg: rgba(255, 255, 255, 0.82);
71
+ --fill-track: rgba(18, 24, 48, 0.08);
72
+ --accent: #6d5ae8;
73
+ --accent-2: #0e95b3;
74
+ --ok: #0f9d6a;
75
+ --warn: #bb7d0e;
76
+ --crit: #d64545;
77
+ --shadow: 0 8px 30px rgba(24, 32, 64, 0.10);
78
+ --shadow-s: 0 2px 10px rgba(24, 32, 64, 0.07);
79
+ }
80
+
81
+ * { box-sizing: border-box; }
82
+
83
+ html { scroll-behavior: smooth; }
84
+
85
+ body {
86
+ margin: 0;
87
+ background: var(--bg);
88
+ color: var(--text);
89
+ font: 14.5px/1.55 var(--font);
90
+ min-height: 100vh;
91
+ background-image:
92
+ radial-gradient(900px 420px at 15% -5%, var(--bg-glow-1), transparent 60%),
93
+ radial-gradient(800px 380px at 85% -8%, var(--bg-glow-2), transparent 60%);
94
+ background-attachment: fixed;
95
+ -webkit-font-smoothing: antialiased;
96
+ }
97
+
98
+ ::selection { background: color-mix(in srgb, var(--accent) 35%, transparent); }
99
+
100
+ :focus-visible {
101
+ outline: 2px solid var(--accent);
102
+ outline-offset: 2px;
103
+ border-radius: 6px;
104
+ }
105
+
106
+ .hidden { display: none !important; }
107
+ .muted { color: var(--muted); }
108
+ .error-text { color: var(--crit); }
109
+
110
+ /* ================= Topbar ================= */
111
+
112
+ .topbar {
113
+ position: sticky;
114
+ top: 0;
115
+ z-index: 50;
116
+ background: var(--topbar-bg);
117
+ backdrop-filter: blur(14px);
118
+ -webkit-backdrop-filter: blur(14px);
119
+ border-bottom: 1px solid var(--border);
120
+ }
121
+
122
+ .topbar-inner {
123
+ max-width: 1060px;
124
+ margin: 0 auto;
125
+ padding: 10px 20px;
126
+ display: flex;
127
+ align-items: center;
128
+ gap: 18px;
129
+ }
130
+
131
+ .brand {
132
+ display: flex;
133
+ align-items: center;
134
+ gap: 10px;
135
+ text-decoration: none;
136
+ color: var(--text);
137
+ flex: none;
138
+ }
139
+
140
+ .brand-mark { display: block; }
141
+ body[data-booted] .brand-mark { animation: spin 14s linear infinite; }
142
+ @keyframes spin { to { transform: rotate(360deg); } }
143
+
144
+ .brand-name {
145
+ font-weight: 700;
146
+ font-size: 15.5px;
147
+ letter-spacing: 0.01em;
148
+ white-space: nowrap;
149
+ }
150
+
151
+ .brand-accent { color: var(--accent); }
152
+
153
+ .brand-ver {
154
+ font: 10.5px var(--mono);
155
+ color: var(--faint);
156
+ background: var(--chip-bg);
157
+ border: 1px solid var(--border);
158
+ border-radius: 999px;
159
+ padding: 1px 7px;
160
+ margin-left: 2px;
161
+ }
162
+
163
+ /* --- Segmentierte Navigation mit gleitendem Indikator --- */
164
+
165
+ .nav {
166
+ position: relative;
167
+ display: flex;
168
+ background: var(--surface-2);
169
+ border: 1px solid var(--border);
170
+ border-radius: 999px;
171
+ padding: 3px;
172
+ margin: 0 auto;
173
+ }
174
+
175
+ .nav-ind {
176
+ position: absolute;
177
+ top: 3px;
178
+ left: 0;
179
+ height: calc(100% - 6px);
180
+ background: var(--surface);
181
+ border: 1px solid var(--border-strong);
182
+ border-radius: 999px;
183
+ box-shadow: var(--shadow-s);
184
+ transition: transform 0.25s cubic-bezier(0.3, 0.9, 0.3, 1), width 0.25s cubic-bezier(0.3, 0.9, 0.3, 1);
185
+ pointer-events: none;
186
+ }
187
+
188
+ .nav-tab {
189
+ position: relative;
190
+ z-index: 1;
191
+ display: flex;
192
+ align-items: center;
193
+ gap: 7px;
194
+ padding: 6px 14px;
195
+ border-radius: 999px;
196
+ color: var(--muted);
197
+ text-decoration: none;
198
+ font-size: 13.5px;
199
+ font-weight: 600;
200
+ white-space: nowrap;
201
+ transition: color var(--speed);
202
+ }
203
+
204
+ .nav-tab:hover { color: var(--text); }
205
+ .nav-tab.active { color: var(--text); }
206
+ .nav-tab.active svg { color: var(--accent); }
207
+
208
+ /* --- Actions rechts --- */
209
+
210
+ .topbar-actions {
211
+ display: flex;
212
+ align-items: center;
213
+ gap: 8px;
214
+ flex: none;
215
+ margin-left: auto;
216
+ }
217
+
218
+ .icon-btn {
219
+ display: inline-flex;
220
+ align-items: center;
221
+ justify-content: center;
222
+ gap: 6px;
223
+ width: 36px;
224
+ height: 36px;
225
+ border-radius: 10px;
226
+ border: 1px solid var(--border);
227
+ background: var(--surface);
228
+ color: var(--muted);
229
+ cursor: pointer;
230
+ transition: color var(--speed), border-color var(--speed), background var(--speed), transform var(--speed);
231
+ }
232
+
233
+ .icon-btn:hover {
234
+ color: var(--text);
235
+ border-color: var(--border-strong);
236
+ background: var(--surface-2);
237
+ }
238
+
239
+ .icon-btn:active { transform: scale(0.94); }
240
+
241
+ .lang-code {
242
+ font-size: 11px;
243
+ font-weight: 700;
244
+ letter-spacing: 0.06em;
245
+ }
246
+
247
+ /* --- Dropdown-Menü (Sprache) --- */
248
+
249
+ .dropdown { position: relative; }
250
+
251
+ .menu {
252
+ position: absolute;
253
+ right: 0;
254
+ top: calc(100% + 8px);
255
+ min-width: 170px;
256
+ background: var(--surface);
257
+ border: 1px solid var(--border-strong);
258
+ border-radius: 12px;
259
+ box-shadow: var(--shadow);
260
+ padding: 5px;
261
+ display: flex;
262
+ flex-direction: column;
263
+ z-index: 60;
264
+ animation: menu-in 0.14s ease-out;
265
+ }
266
+
267
+ .menu[hidden] { display: none; }
268
+
269
+ .menu-left { left: 0; right: auto; }
270
+
271
+ #engine-dd-btn .chev { transition: transform var(--speed); }
272
+ #engine-dd .menu { min-width: 190px; max-height: 320px; overflow-y: auto; }
273
+
274
+ @keyframes menu-in {
275
+ from { opacity: 0; transform: translateY(-4px) scale(0.98); }
276
+ to { opacity: 1; transform: none; }
277
+ }
278
+
279
+ .menu button {
280
+ display: flex;
281
+ align-items: center;
282
+ justify-content: space-between;
283
+ gap: 10px;
284
+ padding: 7px 11px;
285
+ border: 0;
286
+ background: none;
287
+ color: var(--text);
288
+ font: 500 13.5px var(--font);
289
+ border-radius: 8px;
290
+ cursor: pointer;
291
+ text-align: left;
292
+ }
293
+
294
+ .menu button:hover { background: var(--surface-2); }
295
+
296
+ .menu button.active { color: var(--accent); font-weight: 700; }
297
+
298
+ .menu button .mi-check { visibility: hidden; color: var(--accent); }
299
+ .menu button.active .mi-check { visibility: visible; }
300
+
301
+ /* ================= View / Seiten ================= */
302
+
303
+ .view {
304
+ max-width: 1060px;
305
+ margin: 0 auto;
306
+ padding: 26px 20px 60px;
307
+ min-height: 60vh;
308
+ }
309
+
310
+ .page { animation: page-in 0.28s cubic-bezier(0.2, 0.8, 0.3, 1); }
311
+
312
+ @keyframes page-in {
313
+ from { opacity: 0; transform: translateY(8px); }
314
+ to { opacity: 1; transform: none; }
315
+ }
316
+
317
+ .page-head { margin-bottom: 20px; }
318
+
319
+ .page-head h1 {
320
+ margin: 0;
321
+ font-size: 24px;
322
+ font-weight: 750;
323
+ letter-spacing: -0.01em;
324
+ }
325
+
326
+ .page-head .sub { color: var(--muted); margin-top: 3px; font-size: 13.5px; }
327
+
328
+ /* ================= Skeleton ================= */
329
+
330
+ .skeleton {
331
+ border-radius: var(--radius);
332
+ background: linear-gradient(100deg, var(--surface) 40%, var(--surface-2) 50%, var(--surface) 60%);
333
+ background-size: 200% 100%;
334
+ animation: shimmer 1.4s infinite linear;
335
+ border: 1px solid var(--border);
336
+ }
337
+
338
+ @keyframes shimmer { to { background-position: -200% 0; } }
339
+
340
+ /* ================= Banner ================= */
341
+
342
+ .banner {
343
+ display: flex;
344
+ gap: 10px;
345
+ align-items: flex-start;
346
+ background: color-mix(in srgb, var(--warn) 12%, var(--surface));
347
+ border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent);
348
+ color: var(--text);
349
+ border-radius: var(--radius-s);
350
+ padding: 10px 14px;
351
+ margin: 0 0 18px;
352
+ font-size: 13.5px;
353
+ }
354
+
355
+ .banner svg { flex: none; margin-top: 2px; color: var(--warn); }
356
+
357
+ /* ================= Panels & Stat-Karten ================= */
358
+
359
+ .panel {
360
+ background: var(--surface);
361
+ border: 1px solid var(--border);
362
+ border-radius: var(--radius);
363
+ box-shadow: var(--shadow-s);
364
+ }
365
+
366
+ .panel-head {
367
+ display: flex;
368
+ align-items: baseline;
369
+ gap: 10px;
370
+ padding: 14px 18px 0;
371
+ }
372
+
373
+ .panel-head h2 { margin: 0; font-size: 15px; font-weight: 700; }
374
+ .panel-head .sub { color: var(--muted); font-size: 12.5px; }
375
+ .panel-head .spacer { margin-left: auto; }
376
+
377
+ .overview-grid {
378
+ display: grid;
379
+ grid-template-columns: repeat(4, 1fr);
380
+ gap: 14px;
381
+ margin-bottom: 18px;
382
+ }
383
+
384
+ .stat-card {
385
+ padding: 16px 18px;
386
+ display: flex;
387
+ flex-direction: column;
388
+ gap: 2px;
389
+ }
390
+
391
+ .stat-card .stat-icon {
392
+ width: 30px;
393
+ height: 30px;
394
+ border-radius: 9px;
395
+ display: grid;
396
+ place-items: center;
397
+ background: color-mix(in srgb, var(--accent) 14%, transparent);
398
+ color: var(--accent);
399
+ margin-bottom: 8px;
400
+ }
401
+
402
+ .stat-card:nth-child(2) .stat-icon { color: var(--accent-2); background: color-mix(in srgb, var(--accent-2) 14%, transparent); }
403
+ .stat-card:nth-child(3) .stat-icon { color: var(--crit); background: color-mix(in srgb, var(--crit) 13%, transparent); }
404
+ .stat-card:nth-child(4) .stat-icon { color: var(--ok); background: color-mix(in srgb, var(--ok) 13%, transparent); }
405
+
406
+ .stat-value {
407
+ font-size: 26px;
408
+ font-weight: 800;
409
+ letter-spacing: -0.02em;
410
+ font-variant-numeric: tabular-nums;
411
+ line-height: 1.1;
412
+ }
413
+
414
+ .stat-label { color: var(--muted); font-size: 12.5px; font-weight: 600; }
415
+ .stat-sub { color: var(--faint); font-size: 11.5px; }
416
+
417
+ .two-col {
418
+ display: grid;
419
+ grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
420
+ gap: 14px;
421
+ margin-bottom: 18px;
422
+ align-items: start;
423
+ }
424
+
425
+ /* --- Rotations-Vorschau --- */
426
+
427
+ .rot-list { padding: 8px 10px 10px; display: flex; flex-direction: column; }
428
+
429
+ .rot-row {
430
+ display: flex;
431
+ align-items: center;
432
+ gap: 11px;
433
+ padding: 8px 8px;
434
+ border-radius: var(--radius-s);
435
+ text-decoration: none;
436
+ color: var(--text);
437
+ transition: background var(--speed);
438
+ }
439
+
440
+ .rot-row:hover { background: var(--surface-2); }
441
+
442
+ .rot-pos {
443
+ flex: none;
444
+ width: 22px;
445
+ height: 22px;
446
+ border-radius: 7px;
447
+ display: grid;
448
+ place-items: center;
449
+ font-size: 11.5px;
450
+ font-weight: 800;
451
+ color: #fff;
452
+ background: linear-gradient(135deg, var(--accent), var(--accent-2));
453
+ }
454
+
455
+ .rot-name {
456
+ font-weight: 650;
457
+ font-size: 13.5px;
458
+ /* Feste Breite → alle Balken in der Liste sind gleich lang */
459
+ flex: none;
460
+ width: 150px;
461
+ overflow: hidden;
462
+ text-overflow: ellipsis;
463
+ white-space: nowrap;
464
+ }
465
+ .rot-row .bar { flex: 1; }
466
+ .rot-arrow { color: var(--faint); }
467
+
468
+ /* --- Engine-Gesundheit (Ringe) --- */
469
+
470
+ .health-grid {
471
+ display: grid;
472
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
473
+ gap: 12px;
474
+ padding: 14px;
475
+ }
476
+
477
+ .health-card {
478
+ display: flex;
479
+ align-items: center;
480
+ gap: 12px;
481
+ padding: 10px;
482
+ border: 1px solid var(--border);
483
+ border-radius: var(--radius-s);
484
+ background: var(--surface-2);
485
+ text-decoration: none;
486
+ color: var(--text);
487
+ transition: transform var(--speed), border-color var(--speed);
488
+ }
489
+
490
+ .health-card:hover { transform: translateY(-1px); border-color: var(--border-strong); }
491
+ .health-card.off { opacity: 0.75; }
492
+
493
+ .gauge { flex: none; position: relative; width: 52px; height: 52px; }
494
+ .gauge svg { display: block; transform: rotate(-90deg); }
495
+ .gauge .track { stroke: var(--fill-track); }
496
+ .gauge .val.ok { stroke: var(--ok); }
497
+ .gauge .val.warn { stroke: var(--warn); }
498
+ .gauge .val.crit { stroke: var(--crit); }
499
+ .gauge .val { transition: stroke-dashoffset 0.6s cubic-bezier(0.3, 0.9, 0.3, 1); }
500
+ .gauge .gauge-val {
501
+ position: absolute;
502
+ inset: 0;
503
+ display: grid;
504
+ place-items: center;
505
+ font-size: 11.5px;
506
+ font-weight: 800;
507
+ font-variant-numeric: tabular-nums;
508
+ }
509
+
510
+ .gauge .gauge-val.inf { color: var(--faint); font-size: 15px; font-weight: 600; }
511
+
512
+ .health-meta { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
513
+ .health-name { font-weight: 650; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
514
+ .health-src { color: var(--faint); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
515
+
516
+ /* --- Letzte Aufrufe --- */
517
+
518
+ .recent-list { padding: 6px 10px 12px; }
519
+
520
+ .recent-row {
521
+ display: flex;
522
+ align-items: center;
523
+ gap: 10px;
524
+ padding: 7px 8px;
525
+ border-radius: var(--radius-s);
526
+ text-decoration: none;
527
+ color: var(--text);
528
+ font-size: 13px;
529
+ }
530
+
531
+ .recent-row:hover { background: var(--surface-2); }
532
+ .recent-row .ri { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 550; }
533
+ .recent-row .rt { color: var(--faint); font-size: 11.5px; font-variant-numeric: tabular-nums; }
534
+
535
+ /* --- Sparkline --- */
536
+
537
+ .sparkline { padding: 4px 18px 14px; }
538
+ .sparkline svg { width: 100%; height: 54px; display: block; }
539
+
540
+ /* --- Setup-Snippets --- */
541
+
542
+ .setup-panel { margin-top: 18px; }
543
+ .setup-panel summary {
544
+ cursor: pointer;
545
+ list-style: none;
546
+ padding: 14px 18px;
547
+ font-weight: 700;
548
+ font-size: 15px;
549
+ display: flex;
550
+ align-items: center;
551
+ gap: 8px;
552
+ }
553
+ .setup-panel summary::-webkit-details-marker { display: none; }
554
+ .setup-panel summary .chev { margin-left: auto; transition: transform var(--speed); color: var(--muted); }
555
+ .setup-panel[open] summary .chev { transform: rotate(180deg); }
556
+
557
+ .snippets {
558
+ display: grid;
559
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
560
+ gap: 12px;
561
+ padding: 4px 18px 18px;
562
+ }
563
+
564
+ .snippet { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-s); padding: 12px; }
565
+ .snippet h3 { margin: 0 0 8px; font-size: 12.5px; color: var(--muted); font-weight: 650; }
566
+ .snippet pre {
567
+ background: var(--input-bg);
568
+ border: 1px solid var(--border);
569
+ border-radius: 8px;
570
+ padding: 10px;
571
+ font: 11.5px var(--mono);
572
+ overflow-x: auto;
573
+ white-space: pre-wrap;
574
+ margin: 0 0 8px;
575
+ color: var(--text);
576
+ }
577
+
578
+ /* ================= Buttons & Inputs ================= */
579
+
580
+ .btn {
581
+ display: inline-flex;
582
+ align-items: center;
583
+ gap: 6px;
584
+ background: var(--surface-2);
585
+ color: var(--text);
586
+ border: 1px solid var(--border);
587
+ border-radius: 9px;
588
+ padding: 6px 13px;
589
+ font: 600 12.5px var(--font);
590
+ cursor: pointer;
591
+ transition: background var(--speed), border-color var(--speed), transform var(--speed), color var(--speed);
592
+ text-decoration: none;
593
+ }
594
+
595
+ .btn:hover { background: var(--surface-3); border-color: var(--border-strong); }
596
+ .btn:active { transform: scale(0.97); }
597
+
598
+ .btn-primary {
599
+ background: linear-gradient(135deg, var(--accent), color-mix(in srgb, var(--accent-2) 60%, var(--accent)));
600
+ border-color: transparent;
601
+ color: #fff;
602
+ }
603
+ .btn-primary:hover { filter: brightness(1.08); background: linear-gradient(135deg, var(--accent), color-mix(in srgb, var(--accent-2) 60%, var(--accent))); }
604
+
605
+ .btn-danger { color: var(--crit); border-color: color-mix(in srgb, var(--crit) 35%, transparent); }
606
+ .btn-danger:hover { background: color-mix(in srgb, var(--crit) 12%, var(--surface)); border-color: var(--crit); }
607
+
608
+ .btn-ghost { background: transparent; border-color: transparent; color: var(--muted); }
609
+ .btn-ghost:hover { color: var(--text); background: var(--surface-2); border-color: transparent; }
610
+
611
+ input[type="password"], input[type="text"], select {
612
+ background: var(--input-bg);
613
+ border: 1px solid var(--border);
614
+ color: var(--text);
615
+ border-radius: 9px;
616
+ padding: 7px 11px;
617
+ font: 13px var(--font);
618
+ transition: border-color var(--speed), box-shadow var(--speed);
619
+ }
620
+
621
+ input:focus, select:focus {
622
+ outline: none;
623
+ border-color: var(--accent);
624
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
625
+ }
626
+
627
+ input::placeholder { color: var(--faint); }
628
+
629
+ /* ================= Engines-Seite ================= */
630
+
631
+ .engines-stat {
632
+ display: inline-flex;
633
+ align-items: center;
634
+ gap: 8px;
635
+ background: var(--chip-bg);
636
+ border: 1px solid var(--border);
637
+ border-radius: 999px;
638
+ padding: 4px 12px;
639
+ font-size: 12.5px;
640
+ color: var(--muted);
641
+ font-weight: 600;
642
+ }
643
+
644
+ .engines-stat .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 8px color-mix(in srgb, var(--ok) 70%, transparent); }
645
+
646
+ .engine-list { display: flex; flex-direction: column; gap: 10px; }
647
+
648
+ .engine-card {
649
+ background: var(--surface);
650
+ border: 1px solid var(--border);
651
+ border-radius: var(--radius);
652
+ box-shadow: var(--shadow-s);
653
+ transition: border-color var(--speed), opacity var(--speed), transform var(--speed), box-shadow var(--speed);
654
+ }
655
+
656
+ .engine-card.off { border-style: dashed; }
657
+
658
+ .engine-card.dragging {
659
+ opacity: 0.35;
660
+ transform: scale(0.99);
661
+ }
662
+
663
+ .engine-card.drag-over {
664
+ border-color: var(--accent);
665
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
666
+ }
667
+
668
+ .engine-head {
669
+ display: flex;
670
+ align-items: center;
671
+ gap: 12px;
672
+ padding: 12px 14px;
673
+ }
674
+
675
+ .handle {
676
+ cursor: grab;
677
+ color: var(--faint);
678
+ flex: none;
679
+ display: grid;
680
+ place-items: center;
681
+ padding: 2px;
682
+ border-radius: 6px;
683
+ }
684
+
685
+ .handle:hover { color: var(--text); background: var(--surface-2); }
686
+ .handle:active { cursor: grabbing; }
687
+
688
+ .pos-badge {
689
+ flex: none;
690
+ width: 26px;
691
+ height: 26px;
692
+ border-radius: 8px;
693
+ display: grid;
694
+ place-items: center;
695
+ font-size: 12px;
696
+ font-weight: 800;
697
+ color: #fff;
698
+ font-variant-numeric: tabular-nums;
699
+ background: linear-gradient(135deg, var(--accent), var(--accent-2));
700
+ }
701
+
702
+ .engine-card.off .pos-badge {
703
+ background: var(--surface-3);
704
+ color: var(--faint);
705
+ }
706
+
707
+ .avatar {
708
+ flex: none;
709
+ width: 34px;
710
+ height: 34px;
711
+ border-radius: 10px;
712
+ display: grid;
713
+ place-items: center;
714
+ font-weight: 800;
715
+ font-size: 15px;
716
+ color: #fff;
717
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
718
+ }
719
+
720
+ /* --- Offizielle Engine-Favicons (Fallback: Buchstaben-Avatar) --- */
721
+
722
+ .logo-wrap {
723
+ flex: none;
724
+ width: 34px;
725
+ height: 34px;
726
+ border-radius: 10px;
727
+ display: grid;
728
+ place-items: center;
729
+ background: #fff;
730
+ border: 1px solid var(--border);
731
+ overflow: hidden;
732
+ }
733
+
734
+ .logo-wrap img { width: 22px; height: 22px; object-fit: contain; display: block; }
735
+
736
+ .rot-row .logo-wrap,
737
+ .rot-row .avatar { width: 22px; height: 22px; border-radius: 6px; }
738
+ .rot-row .logo-wrap img { width: 14px; height: 14px; }
739
+ .rot-row .avatar { font-size: 11px; }
740
+
741
+ .engine-title { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
742
+
743
+ .engine-name { font-weight: 700; font-size: 14.5px; }
744
+
745
+ .engine-badges { display: flex; gap: 6px; flex-wrap: wrap; }
746
+
747
+ .badge {
748
+ font-size: 10.5px;
749
+ font-weight: 650;
750
+ border-radius: 999px;
751
+ padding: 1.5px 8px;
752
+ border: 1px solid var(--border);
753
+ color: var(--muted);
754
+ background: var(--chip-bg);
755
+ }
756
+
757
+ .badge.ip { color: var(--accent-2); border-color: color-mix(in srgb, var(--accent-2) 35%, transparent); }
758
+ .badge.quota { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
759
+
760
+ .engine-quota {
761
+ margin-left: auto;
762
+ display: flex;
763
+ align-items: center;
764
+ gap: 10px;
765
+ min-width: 0;
766
+ flex: 1 1 220px;
767
+ max-width: 340px;
768
+ }
769
+
770
+ .engine-quota .bar { flex: 1; }
771
+ .quota-label { font-size: 11.5px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
772
+ .quota-none { color: var(--faint); font-size: 11.5px; white-space: nowrap; }
773
+ .quota-err { color: var(--crit); font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
774
+
775
+ /* --- Toggle-Switch --- */
776
+
777
+ .switch { position: relative; display: inline-block; width: 40px; height: 23px; flex: none; }
778
+ .switch input { opacity: 0; width: 0; height: 0; position: absolute; }
779
+ .switch .track-el {
780
+ position: absolute; inset: 0; border-radius: 999px;
781
+ background: var(--surface-3);
782
+ border: 1px solid var(--border);
783
+ transition: background var(--speed), border-color var(--speed);
784
+ cursor: pointer;
785
+ }
786
+ .switch .track-el::before {
787
+ content: ""; position: absolute; width: 17px; height: 17px;
788
+ border-radius: 50%; background: #fff; top: 2px; left: 2px;
789
+ transition: transform 0.18s cubic-bezier(0.3, 0.9, 0.3, 1);
790
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
791
+ }
792
+ .switch input:checked + .track-el {
793
+ background: linear-gradient(135deg, var(--accent), var(--accent-2));
794
+ border-color: transparent;
795
+ }
796
+ .switch input:checked + .track-el::before { transform: translateX(17px); }
797
+ .switch input:focus-visible + .track-el { outline: 2px solid var(--accent); outline-offset: 2px; }
798
+
799
+ .drawer-toggle {
800
+ flex: none;
801
+ background: none;
802
+ border: 1px solid transparent;
803
+ color: var(--muted);
804
+ width: 30px;
805
+ height: 30px;
806
+ border-radius: 8px;
807
+ display: grid;
808
+ place-items: center;
809
+ cursor: pointer;
810
+ transition: transform var(--speed), color var(--speed), background var(--speed);
811
+ }
812
+
813
+ .drawer-toggle:hover { color: var(--text); background: var(--surface-2); }
814
+ .engine-card.open .drawer-toggle { transform: rotate(180deg); color: var(--accent); }
815
+
816
+ .drawer {
817
+ border-top: 1px solid var(--border);
818
+ padding: 14px 16px 16px 66px;
819
+ display: none;
820
+ flex-direction: column;
821
+ gap: 10px;
822
+ background: color-mix(in srgb, var(--surface-2) 45%, transparent);
823
+ border-radius: 0 0 var(--radius) var(--radius);
824
+ }
825
+
826
+ .engine-card.open .drawer { display: flex; animation: drawer-in 0.2s ease-out; }
827
+
828
+ @keyframes drawer-in {
829
+ from { opacity: 0; transform: translateY(-4px); }
830
+ to { opacity: 1; transform: none; }
831
+ }
832
+
833
+ .drawer-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
834
+ .drawer-row input.keyinput { flex: 1 1 240px; }
835
+ .drawer-row input.extrainput { flex: 1 1 200px; }
836
+
837
+ .drawer-meta { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; font-size: 12.5px; }
838
+ .caps-chips { display: flex; gap: 5px; }
839
+
840
+ a.signup { color: var(--accent-2); font-weight: 600; text-decoration: none; display: inline-flex; align-items: center; gap: 4px; }
841
+ a.signup:hover { text-decoration: underline; }
842
+
843
+ .notes { color: var(--faint); font-size: 12px; }
844
+
845
+ .testout { font-size: 13px; }
846
+ .testout .ok { color: var(--ok); font-weight: 600; }
847
+ .testout .error { color: var(--crit); font-weight: 600; }
848
+ .testout pre {
849
+ background: var(--input-bg);
850
+ border: 1px solid var(--border);
851
+ border-radius: 8px;
852
+ padding: 8px 10px;
853
+ overflow-x: auto;
854
+ font: 11.5px var(--mono);
855
+ max-height: 140px;
856
+ margin: 6px 0 0;
857
+ color: var(--text);
858
+ }
859
+
860
+ /* --- Fortschrittsbalken (wiederverwendbar) --- */
861
+
862
+ .bar {
863
+ height: 7px;
864
+ border-radius: 999px;
865
+ background: var(--fill-track);
866
+ overflow: hidden;
867
+ min-width: 60px;
868
+ }
869
+
870
+ .fill { height: 100%; border-radius: 999px; background: var(--ok); transition: width 0.5s cubic-bezier(0.3, 0.9, 0.3, 1); }
871
+ .fill.warn { background: var(--warn); }
872
+ .fill.crit { background: var(--crit); }
873
+ .fill.accent { background: linear-gradient(90deg, var(--accent), var(--accent-2)); }
874
+
875
+ /* ================= Verlauf ================= */
876
+
877
+ .hist-toolbar {
878
+ display: flex;
879
+ align-items: center;
880
+ gap: 10px;
881
+ flex-wrap: wrap;
882
+ margin-bottom: 14px;
883
+ }
884
+
885
+ .seg {
886
+ display: flex;
887
+ background: var(--surface-2);
888
+ border: 1px solid var(--border);
889
+ border-radius: 999px;
890
+ padding: 3px;
891
+ }
892
+
893
+ .seg button {
894
+ border: 0;
895
+ background: none;
896
+ color: var(--muted);
897
+ font: 600 12.5px var(--font);
898
+ padding: 5px 13px;
899
+ border-radius: 999px;
900
+ cursor: pointer;
901
+ transition: color var(--speed), background var(--speed);
902
+ }
903
+
904
+ .seg button:hover { color: var(--text); }
905
+ .seg button.active { background: var(--surface); color: var(--text); box-shadow: var(--shadow-s); }
906
+ .seg button.active.count-red::after { content: " !"; color: var(--crit); font-weight: 800; }
907
+
908
+ .hist-toolbar input[type="text"] { flex: 1 1 200px; max-width: 280px; }
909
+
910
+ .hist-toolbar .spacer { margin-left: auto; }
911
+
912
+ .live-dot { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--faint); }
913
+ .live-dot .pulse {
914
+ width: 8px; height: 8px; border-radius: 50%; background: var(--ok);
915
+ animation: pulse 2s ease-in-out infinite;
916
+ }
917
+ .live-dot.paused .pulse { animation: none; background: var(--faint); }
918
+
919
+ @keyframes pulse {
920
+ 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 45%, transparent); }
921
+ 50% { box-shadow: 0 0 0 5px transparent; }
922
+ }
923
+
924
+ .hist-summary { color: var(--faint); font-size: 12px; margin: 0 2px 10px; font-variant-numeric: tabular-nums; }
925
+
926
+ .hist-list { display: flex; flex-direction: column; gap: 7px; }
927
+
928
+ .hist {
929
+ background: var(--surface);
930
+ border: 1px solid var(--border);
931
+ border-radius: var(--radius-s);
932
+ overflow: hidden;
933
+ transition: border-color var(--speed);
934
+ }
935
+
936
+ .hist:hover { border-color: var(--border-strong); }
937
+ .hist.fail { border-left: 3px solid var(--crit); }
938
+ .hist.fail:hover { border-color: var(--border-strong); border-left-color: var(--crit); }
939
+
940
+ .hist summary {
941
+ display: flex;
942
+ align-items: center;
943
+ gap: 11px;
944
+ cursor: pointer;
945
+ list-style: none;
946
+ padding: 10px 14px;
947
+ user-select: none;
948
+ }
949
+
950
+ .hist summary::-webkit-details-marker { display: none; }
951
+
952
+ .hkind-icon {
953
+ flex: none;
954
+ width: 28px;
955
+ height: 28px;
956
+ border-radius: 8px;
957
+ display: grid;
958
+ place-items: center;
959
+ }
960
+
961
+ .hkind-icon.search { color: var(--accent); background: color-mix(in srgb, var(--accent) 13%, transparent); }
962
+ .hkind-icon.fetch { color: var(--accent-2); background: color-mix(in srgb, var(--accent-2) 13%, transparent); }
963
+
964
+ .htime { color: var(--faint); font-size: 11.5px; font-variant-numeric: tabular-nums; flex: none; width: 66px; }
965
+
966
+ .hinput {
967
+ flex: 1;
968
+ min-width: 0;
969
+ overflow: hidden;
970
+ text-overflow: ellipsis;
971
+ white-space: nowrap;
972
+ font-weight: 600;
973
+ font-size: 13.5px;
974
+ }
975
+
976
+ .chips { display: flex; gap: 5px; flex-wrap: wrap; flex: none; }
977
+
978
+ .chip {
979
+ font-size: 10.5px;
980
+ font-weight: 650;
981
+ border-radius: 999px;
982
+ padding: 2px 9px;
983
+ border: 1px solid var(--border);
984
+ background: var(--chip-bg);
985
+ color: var(--muted);
986
+ }
987
+
988
+ .chip.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, transparent); }
989
+ .chip.fail { color: var(--crit); border-color: color-mix(in srgb, var(--crit) 35%, transparent); text-decoration: line-through; }
990
+
991
+ .hmeta { flex: none; display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
992
+ .hmeta .fail-mark { color: var(--crit); font-weight: 700; }
993
+
994
+ .hist .chev { color: var(--faint); transition: transform var(--speed); }
995
+ .hist[open] .chev { transform: rotate(180deg); }
996
+
997
+ .histbody {
998
+ border-top: 1px solid var(--border);
999
+ padding: 12px 16px;
1000
+ font-size: 13px;
1001
+ background: color-mix(in srgb, var(--surface-2) 40%, transparent);
1002
+ }
1003
+
1004
+ .histbody p { margin: 6px 0; }
1005
+
1006
+ .att { margin: 4px 0; padding-left: 20px; color: var(--muted); }
1007
+ .att li { margin: 2px 0; }
1008
+
1009
+ .hitems { margin: 4px 0; padding-left: 0; list-style: none; }
1010
+ .hitems li { margin: 7px 0; padding-left: 14px; border-left: 2px solid var(--border-strong); }
1011
+ .hitems a { color: var(--accent-2); text-decoration: none; font-weight: 600; }
1012
+ .hitems a:hover { text-decoration: underline; }
1013
+ .hitems .snip { color: var(--muted); font-size: 12.5px; }
1014
+
1015
+ .histbody pre {
1016
+ background: var(--input-bg);
1017
+ border: 1px solid var(--border);
1018
+ border-radius: 8px;
1019
+ padding: 10px;
1020
+ font: 11.5px var(--mono);
1021
+ overflow-x: auto;
1022
+ max-height: 220px;
1023
+ white-space: pre-wrap;
1024
+ color: var(--text);
1025
+ }
1026
+
1027
+ /* ================= Empty State ================= */
1028
+
1029
+ .empty {
1030
+ display: flex;
1031
+ flex-direction: column;
1032
+ align-items: center;
1033
+ gap: 8px;
1034
+ text-align: center;
1035
+ padding: 48px 20px;
1036
+ color: var(--muted);
1037
+ }
1038
+
1039
+ .empty .empty-icon {
1040
+ width: 52px;
1041
+ height: 52px;
1042
+ border-radius: 16px;
1043
+ display: grid;
1044
+ place-items: center;
1045
+ background: var(--surface-2);
1046
+ border: 1px solid var(--border);
1047
+ color: var(--faint);
1048
+ margin-bottom: 4px;
1049
+ }
1050
+
1051
+ .empty .empty-title { font-weight: 700; color: var(--text); font-size: 15px; }
1052
+ .empty .empty-hint { font-size: 13px; max-width: 380px; }
1053
+
1054
+ /* ================= Toasts ================= */
1055
+
1056
+ .toasts {
1057
+ position: fixed;
1058
+ bottom: 20px;
1059
+ right: 20px;
1060
+ display: flex;
1061
+ flex-direction: column;
1062
+ gap: 8px;
1063
+ z-index: 100;
1064
+ pointer-events: none;
1065
+ }
1066
+
1067
+ .toast {
1068
+ display: flex;
1069
+ align-items: center;
1070
+ gap: 9px;
1071
+ background: var(--surface);
1072
+ border: 1px solid var(--border-strong);
1073
+ color: var(--text);
1074
+ border-radius: 11px;
1075
+ padding: 10px 14px;
1076
+ font-size: 13px;
1077
+ font-weight: 600;
1078
+ box-shadow: var(--shadow);
1079
+ animation: toast-in 0.22s cubic-bezier(0.2, 0.9, 0.3, 1.2);
1080
+ pointer-events: auto;
1081
+ max-width: 360px;
1082
+ }
1083
+
1084
+ .toast svg { flex: none; }
1085
+ .toast.ok svg { color: var(--ok); }
1086
+ .toast.error svg { color: var(--crit); }
1087
+ .toast.info svg { color: var(--accent-2); }
1088
+ .toast.leaving { animation: toast-out 0.25s ease-in forwards; }
1089
+
1090
+ @keyframes toast-in {
1091
+ from { opacity: 0; transform: translateY(10px) scale(0.96); }
1092
+ to { opacity: 1; transform: none; }
1093
+ }
1094
+
1095
+ @keyframes toast-out {
1096
+ to { opacity: 0; transform: translateY(6px) scale(0.97); }
1097
+ }
1098
+
1099
+ /* ================= Footer ================= */
1100
+
1101
+ .footer {
1102
+ max-width: 1060px;
1103
+ margin: 0 auto;
1104
+ padding: 8px 20px 36px;
1105
+ color: var(--faint);
1106
+ font-size: 12px;
1107
+ display: flex;
1108
+ gap: 12px;
1109
+ flex-wrap: wrap;
1110
+ align-items: baseline;
1111
+ }
1112
+
1113
+ .footer-meta code {
1114
+ font: 10.5px var(--mono);
1115
+ background: var(--chip-bg);
1116
+ border: 1px solid var(--border);
1117
+ padding: 1px 7px;
1118
+ border-radius: 6px;
1119
+ color: var(--muted);
1120
+ }
1121
+
1122
+ /* ================= FLIP-Animation ================= */
1123
+
1124
+ .flip-anim {
1125
+ transition: transform 0.28s cubic-bezier(0.3, 0.9, 0.3, 1);
1126
+ }
1127
+
1128
+ /* ================= Fehlerseite (401) ================= */
1129
+
1130
+ .auth-error {
1131
+ display: grid;
1132
+ place-items: center;
1133
+ min-height: 60vh;
1134
+ text-align: center;
1135
+ color: var(--muted);
1136
+ }
1137
+
1138
+ .auth-error code {
1139
+ background: var(--chip-bg);
1140
+ border: 1px solid var(--border);
1141
+ border-radius: 6px;
1142
+ padding: 1px 7px;
1143
+ color: var(--accent-2);
1144
+ }
1145
+
1146
+ /* ================= Responsive ================= */
1147
+
1148
+ @media (max-width: 900px) {
1149
+ .topbar-inner { flex-wrap: wrap; gap: 10px; }
1150
+ .nav { order: 3; width: 100%; justify-content: space-between; }
1151
+ .nav-tab { flex: 1; justify-content: center; }
1152
+ .overview-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
1153
+ .two-col { grid-template-columns: minmax(0, 1fr); }
1154
+ }
1155
+
1156
+ @media (max-width: 720px) {
1157
+ .topbar-inner { flex-wrap: wrap; gap: 10px; padding: 10px 14px; }
1158
+ .nav { order: 3; width: 100%; justify-content: space-between; }
1159
+ .nav-tab { flex: 1; justify-content: center; padding: 7px 8px; }
1160
+ .nav-tab .nav-label { display: none; }
1161
+ .brand-ver { display: none; }
1162
+ .view { padding: 18px 14px 50px; }
1163
+ .engine-quota { max-width: none; }
1164
+ .drawer { padding-left: 16px; }
1165
+ .hist summary { flex-wrap: wrap; }
1166
+ .hmeta { margin-left: 38px; }
1167
+ .hinput { flex-basis: 100%; order: 5; margin-left: 38px; }
1168
+ .footer { padding: 8px 14px 30px; }
1169
+ }
1170
+
1171
+ @media (max-width: 480px) {
1172
+ .overview-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
1173
+ .stat-value { font-size: 21px; }
1174
+ .health-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
1175
+ .rot-row .rot-arrow { display: none; }
1176
+ .rot-row .bar { min-width: 46px; }
1177
+ .rot-name { width: 96px; font-size: 12.5px; }
1178
+ }
1179
+
1180
+ /* ================= Reduced Motion ================= */
1181
+
1182
+ @media (prefers-reduced-motion: reduce) {
1183
+ *, *::before, *::after {
1184
+ animation-duration: 0.01ms !important;
1185
+ animation-iteration-count: 1 !important;
1186
+ transition-duration: 0.01ms !important;
1187
+ }
1188
+ html { scroll-behavior: auto; }
1189
+ }
1190
+
1191
+ .settings-panel { padding: 18px; margin-bottom: 18px; }
1192
+ .settings-panel h2 { margin: 0 0 14px; font-size: 16px; }
1193
+ .settings-panel p { max-width: 80ch; line-height: 1.5; }
1194
+ .settings-check { display: flex; align-items: center; gap: 8px; }
1195
+ .settings-panel input[type="number"] { width: 125px; margin: 8px; padding: 8px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg); color: var(--text); }
1196
+
1197
+ /* Quota explanations must fit cards at every viewport. */
1198
+ .rot-quota { flex: 1; min-width: 0; font-size: 11.5px; color: var(--muted); text-align: right; }
1199
+ .engine-quota { flex-direction: column; align-items: stretch; gap: 5px; }
1200
+ .engine-quota .bar { flex: none; width: 100%; }
1201
+ .quota-label, .quota-none { white-space: normal; overflow-wrap: anywhere; line-height: 1.45; }
1202
+ @media (max-width: 720px) {
1203
+ .engine-head { flex-wrap: wrap; gap: 10px; }
1204
+ .engine-quota { order: 2; flex: 1 0 100%; margin: 0; }
1205
+ .engine-title { min-width: 0; flex: 1; }
1206
+ .engine-head .drawer-toggle { margin-left: auto; }
1207
+ .drawer-row { flex-wrap: wrap; }
1208
+ .drawer-row input { min-width: 0; flex-basis: 100%; }
1209
+ .nav-tab .nav-label { display: inline; }
1210
+ .rot-name { flex: 1; min-width: 0; }
1211
+ .rot-quota { flex: none; }
1212
+ }
1213
+
1214
+ .two-col > .panel, .health-card { min-width: 0; }
1215
+ .panel-head { flex-wrap: wrap; }
1216
+ @media(max-width:480px) { .health-grid { grid-template-columns: minmax(0, 1fr); } .btn, .drawer-toggle, .nav-tab, .icon-btn { min-height: 44px; } }
1217
+
1218
+ .result-settings { margin: 18px 0; }
1219
+ .result-settings select { max-width: 100%; }
1220
+ #result-count { width: 84px; }
1221
+
1222
+ /* Calls and quota are distinct metrics, regardless of credentials. */
1223
+ .usage-summary { display: flex; flex-direction: column; gap: 2px; font-size: 12px; min-width: 0; }
1224
+ .usage-summary strong { font-weight: 650; font-variant-numeric: tabular-nums; }
1225
+ .usage-detail { color: var(--muted); font-size: 11.5px; line-height: 1.5; }
1226
+ .budget-summary { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
1227
+ .budget-summary .bar { display: block; flex: none; width: 100%; }
1228
+ .bar .fill { display: block; }
1229
+ .rot-content { flex: 1; min-width: 0; display: grid; gap: 5px; }
1230
+ .rot-name { width: auto; }
1231
+ .rot-row { align-items: flex-start; padding: 12px 8px; }
1232
+ .rot-arrow { flex: none; margin-top: 5px; }
1233
+ .rot-content .usage-summary { flex-direction: row; flex-wrap: wrap; justify-content: space-between; gap: 2px 12px; }
1234
+ .health-grid { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
1235
+ .health-card { align-items: flex-start; }
1236
+ .health-meta { gap: 6px; }
1237
+ .health-name, .health-src { white-space: normal; overflow: visible; }
1238
+ .health-src { line-height: 1.5; }
1239
+ .quota-err { white-space: normal; overflow-wrap: anywhere; }
1240
+ .engine-quota { gap: 8px; max-width: 440px; }
1241
+ .recent-engine { color: var(--muted); font-size: 11.5px; }
1242
+ .recent-row { min-height: 44px; flex-wrap: wrap; }
1243
+ .recent-row .ri { flex-basis: 50%; }
1244
+ .activity-caption, .activity-axis, .activity-note { color: var(--muted); font-size: 11.5px; line-height: 1.5; }
1245
+ .activity-bars { position: relative; display: grid; grid-template-columns: repeat(24, minmax(0, 1fr)); height: 72px; margin-top: 10px; }
1246
+ .activity-bucket { display: flex; align-items: flex-end; justify-content: center; border: 0; border-bottom: 1px solid var(--border); background: transparent; padding: 0 15%; cursor: help; min-width: 0; color: var(--text); }
1247
+ .activity-fill { display: block; width: 100%; background: var(--accent); border-radius: 3px 3px 0 0; pointer-events: none; }
1248
+ .activity-bucket:hover, .activity-bucket:focus { background: var(--surface-2); outline: 2px solid var(--accent); outline-offset: -2px; }
1249
+ .activity-tooltip { display: none; position: absolute; z-index: 5; bottom: calc(100% + 8px); left: 0; right: 0; padding: 12px; border: 1px solid var(--border-strong); border-radius: 8px; background: var(--surface); box-shadow: 0 6px 24px #0004; color: var(--text); text-align: left; white-space: pre-line; line-height: 1.6; font-size: 12px; pointer-events: none; }
1250
+ .activity-bucket:hover .activity-tooltip, .activity-bucket:focus .activity-tooltip { display: block; }
1251
+ .activity-axis { display: flex; justify-content: space-between; margin-top: 6px; }
1252
+ .activity-note { margin: 8px 0 0; }
1253
+ @media (max-width: 480px) {
1254
+ .nav-tab { padding-inline: 5px; gap: 5px; font-size: 12.5px; }
1255
+ .health-grid { grid-template-columns: minmax(0, 1fr); }
1256
+ .recent-engine { margin-left: 34px; }
1257
+ .recent-row .ri { flex-basis: calc(100% - 45px); }
1258
+ }