codex-lb 0.2.0__py3-none-any.whl → 0.3.1__py3-none-any.whl

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 (44) hide show
  1. app/core/auth/__init__.py +10 -0
  2. app/core/balancer/logic.py +33 -6
  3. app/core/config/settings.py +2 -0
  4. app/core/usage/__init__.py +2 -0
  5. app/core/usage/logs.py +12 -2
  6. app/core/usage/quota.py +10 -4
  7. app/core/usage/types.py +3 -2
  8. app/db/migrations/__init__.py +14 -3
  9. app/db/migrations/versions/add_accounts_chatgpt_account_id.py +29 -0
  10. app/db/migrations/versions/add_accounts_reset_at.py +29 -0
  11. app/db/migrations/versions/add_dashboard_settings.py +31 -0
  12. app/db/migrations/versions/add_request_logs_reasoning_effort.py +21 -0
  13. app/db/models.py +33 -0
  14. app/db/session.py +71 -11
  15. app/dependencies.py +27 -1
  16. app/main.py +11 -2
  17. app/modules/accounts/auth_manager.py +44 -3
  18. app/modules/accounts/repository.py +14 -6
  19. app/modules/accounts/service.py +4 -2
  20. app/modules/oauth/service.py +4 -3
  21. app/modules/proxy/load_balancer.py +74 -5
  22. app/modules/proxy/service.py +155 -31
  23. app/modules/proxy/sticky_repository.py +56 -0
  24. app/modules/request_logs/repository.py +6 -3
  25. app/modules/request_logs/schemas.py +2 -0
  26. app/modules/request_logs/service.py +8 -1
  27. app/modules/settings/__init__.py +1 -0
  28. app/modules/settings/api.py +37 -0
  29. app/modules/settings/repository.py +40 -0
  30. app/modules/settings/schemas.py +13 -0
  31. app/modules/settings/service.py +33 -0
  32. app/modules/shared/schemas.py +16 -2
  33. app/modules/usage/schemas.py +1 -0
  34. app/modules/usage/service.py +17 -1
  35. app/modules/usage/updater.py +36 -7
  36. app/static/index.css +1024 -319
  37. app/static/index.html +461 -377
  38. app/static/index.js +327 -49
  39. {codex_lb-0.2.0.dist-info → codex_lb-0.3.1.dist-info}/METADATA +33 -7
  40. {codex_lb-0.2.0.dist-info → codex_lb-0.3.1.dist-info}/RECORD +43 -34
  41. app/static/7.css +0 -1336
  42. {codex_lb-0.2.0.dist-info → codex_lb-0.3.1.dist-info}/WHEEL +0 -0
  43. {codex_lb-0.2.0.dist-info → codex_lb-0.3.1.dist-info}/entry_points.txt +0 -0
  44. {codex_lb-0.2.0.dist-info → codex_lb-0.3.1.dist-info}/licenses/LICENSE +0 -0
app/static/index.css CHANGED
@@ -1,156 +1,74 @@
1
- .dialog-backdrop.auth-dialog-backdrop {
2
- z-index: 1000;
3
- }
4
-
5
- .window.auth-dialog[role="dialog"] {
6
- position: absolute;
7
- top: 50%;
8
- left: 50%;
9
- width: min(560px, calc(100% - 40px));
10
- transform: translate(-50%, -50%) scale(0.98);
11
- opacity: 0;
12
- visibility: hidden;
13
- pointer-events: none;
14
- transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s linear 0.2s;
15
- box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45), 0 6px 16px rgba(0, 0, 0, 0.25);
16
- z-index: 1001;
17
- }
18
-
19
- .window.auth-dialog[role="dialog"].is-open {
20
- opacity: 1;
21
- visibility: visible;
22
- pointer-events: auto;
23
- transform: translate(-50%, -50%) scale(1);
24
- transition: opacity 0.2s ease, transform 0.2s ease;
25
- }
26
-
27
- .window.auth-dialog .auth-dialog__body {
28
- padding: 18px 22px;
29
- }
1
+ :root {
2
+ --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
30
3
 
31
- .auth-dialog__intro,
32
- .auth-dialog__panel {
33
- display: grid;
34
- gap: 12px;
35
- }
4
+ --bg-app: #09090b;
5
+ --bg-panel: #18181b;
6
+ --bg-card: #27272a;
7
+ --bg-surface: #27272a;
36
8
 
37
- .auth-dialog__lead {
38
- margin: 0;
39
- line-height: 1.4;
40
- color: #1a1a1a;
41
- }
9
+ --border-subtle: #3f3f46;
10
+ --border-strong: #52525b;
42
11
 
43
- .auth-dialog__methods {
44
- margin: 0;
45
- gap: 12px;
46
- }
12
+ --text-main: #f4f4f5;
13
+ --text-muted: #a1a1aa;
47
14
 
48
- .auth-dialog__option {
49
- display: grid;
50
- gap: 4px;
51
- align-items: start;
52
- }
15
+ --accent-primary: #3b82f6;
16
+ --accent-primary-hover: #2563eb;
17
+ --accent-primary-text: #ffffff;
53
18
 
54
- .auth-dialog__option label {
55
- font-weight: 600;
56
- }
19
+ --status-active-bg: rgba(34, 197, 94, 0.15);
20
+ --status-active-text: #4ade80;
57
21
 
58
- .auth-dialog__option-meta {
59
- margin-left: var(--w7-rd-left);
60
- }
22
+ --status-warning-bg: rgba(234, 179, 8, 0.15);
23
+ --status-warning-text: #facc15;
61
24
 
25
+ --status-error-bg: rgba(239, 68, 68, 0.15);
26
+ --status-error-text: #f87171;
62
27
 
63
- .auth-dialog__detail {
64
- display: grid;
65
- gap: 4px;
66
- }
28
+ --status-paused-bg: rgba(59, 130, 246, 0.15);
29
+ --status-paused-text: #60a5fa;
67
30
 
68
- .auth-dialog__label {
69
- font-size: 12px;
70
- color: #555;
71
- }
31
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5);
32
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.5), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
72
33
 
73
- .auth-dialog__value {
74
- font-size: 12px;
75
- color: #1a1a1a;
76
- word-break: break-all;
77
- }
34
+ --donut-empty: #3f3f46;
78
35
 
79
- .auth-dialog__link {
80
- color: #2b579a;
81
- text-decoration: underline;
82
- }
36
+ --bg-list-hover: rgba(255, 255, 255, 0.03);
37
+ --bg-list-selected: rgba(59, 130, 246, 0.15);
83
38
 
84
- .auth-dialog__device-grid {
85
- display: grid;
86
- gap: 12px;
39
+ --shell-max-width: 1400px;
87
40
  }
88
41
 
89
- .auth-dialog__device-grid > div {
90
- display: grid;
91
- gap: 4px;
92
- }
42
+ [data-theme="light"] {
43
+ --bg-app: #f4f4f5;
44
+ --bg-panel: #ffffff;
45
+ --bg-card: #ffffff;
46
+ --bg-surface: #f4f4f5;
93
47
 
94
- .auth-dialog__steps {
95
- margin: 0;
96
- padding-left: 18px;
97
- color: #333;
98
- font-size: 12px;
99
- line-height: 1.4;
100
- }
48
+ --border-subtle: #e4e4e7;
49
+ --border-strong: #d4d4d8;
101
50
 
102
- .auth-dialog__steps li {
103
- margin-bottom: 4px;
104
- }
51
+ --text-main: #18181b;
52
+ --text-muted: #71717a;
105
53
 
106
- .auth-dialog__code-value {
107
- display: inline-block;
108
- padding: 6px 10px;
109
- border: 1px solid #c2c2c2;
110
- background: #fff;
111
- border-radius: 3px;
112
- font-weight: 700;
113
- letter-spacing: 1px;
114
- font-size: 13px;
115
- }
54
+ --status-active-bg: #dcfce7;
55
+ --status-active-text: #16a34a;
116
56
 
117
- .auth-dialog__device-meta {
118
- font-size: 12px;
119
- }
57
+ --status-warning-bg: #fef3c7;
58
+ --status-warning-text: #f59e0b;
120
59
 
121
- .auth-dialog__status {
122
- display: flex;
123
- align-items: center;
124
- gap: 6px;
125
- font-size: 12px;
126
- color: #444;
127
- }
60
+ --status-error-bg: #fee2e2;
61
+ --status-error-text: #ef4444;
128
62
 
129
- .auth-dialog__actions {
130
- display: flex;
131
- justify-content: flex-end;
132
- gap: 8px;
133
- flex-wrap: wrap;
134
- }
63
+ --status-paused-bg: #dbeafe;
64
+ --status-paused-text: #2563eb;
135
65
 
136
- .auth-dialog__actions-row {
137
- display: flex;
138
- gap: 8px;
139
- flex-wrap: wrap;
140
- }
66
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
67
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
68
+ --bg-list-hover: rgba(0, 0, 0, 0.04);
69
+ --bg-list-selected: rgba(59, 130, 246, 0.1);
141
70
 
142
- :root {
143
- color-scheme: light;
144
- --shell-max-width: 1180px;
145
- --shell-gap: 16px;
146
- --panel-bg: #f6f8fc;
147
- --panel-border: #b7c0d6;
148
- --panel-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
149
- --accent-blue: #2b579a;
150
- --accent-green: #2f7d32;
151
- --accent-orange: #b86a00;
152
- --accent-red: #a32a2a;
153
- --accent-gray: #5f5f5f;
71
+ --donut-empty: #e4e4e7;
154
72
  }
155
73
 
156
74
  * {
@@ -163,124 +81,212 @@
163
81
 
164
82
  body {
165
83
  margin: 0;
84
+ padding: 0;
166
85
  min-height: 100vh;
167
- padding: 20px;
168
- background:
169
- radial-gradient(circle at 12% 18%, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0) 45%),
170
- linear-gradient(135deg, #b9cce8 0%, #cadcf2 40%, #e8f0fb 100%);
86
+ font-family: var(--font-sans);
87
+ background-color: var(--bg-app);
88
+ color: var(--text-main);
89
+ text-rendering: optimizeLegibility;
90
+ -webkit-font-smoothing: antialiased;
171
91
  }
172
92
 
173
93
  .app-shell {
94
+ display: flex;
95
+ flex-direction: column;
96
+ min-height: 100vh;
97
+ }
98
+
99
+ .main-header {
100
+ background: var(--bg-panel);
101
+ border-bottom: 1px solid var(--border-subtle);
102
+ position: sticky;
103
+ top: 0;
104
+ z-index: 10;
105
+ }
106
+
107
+ .header-content {
174
108
  max-width: var(--shell-max-width);
175
109
  margin: 0 auto;
110
+ padding: 16px 24px;
176
111
  display: flex;
177
- flex-direction: column;
178
- gap: var(--shell-gap);
112
+ justify-content: space-between;
113
+ align-items: center;
179
114
  }
180
115
 
181
- .window > .window-body {
182
- position: relative;
116
+ .app-logo {
117
+ font-size: 18px;
118
+ font-weight: 600;
119
+ margin: 0;
120
+ color: var(--text-main);
121
+ letter-spacing: -0.02em;
183
122
  }
184
123
 
185
- .loading-overlay {
186
- position: absolute;
187
- inset: 0;
124
+ .header-actions button {
125
+ background: transparent;
126
+ border: 1px solid var(--border-strong);
127
+ color: var(--text-muted);
128
+ cursor: pointer;
129
+ padding: 8px;
130
+ border-radius: 8px;
188
131
  display: flex;
189
132
  align-items: center;
190
133
  justify-content: center;
191
- background: rgba(248, 250, 255, 0.88);
192
- z-index: 10;
134
+ transition: all 0.2s;
193
135
  }
194
136
 
195
- .loading-panel {
137
+ .header-actions button:hover {
138
+ background: var(--bg-surface);
139
+ color: var(--text-main);
140
+ border-color: var(--text-muted);
141
+ }
142
+
143
+ .main-content {
144
+ flex: 1;
145
+ width: 100%;
146
+ max-width: var(--shell-max-width);
147
+ margin: 0 auto;
148
+ padding: 32px 24px 80px;
149
+ position: relative;
150
+ }
151
+
152
+ .tabs menu[role="tablist"] {
196
153
  display: flex;
197
- align-items: center;
198
- gap: 10px;
199
- padding: 10px 14px;
200
- border: 1px solid var(--panel-border);
201
- border-radius: 4px;
202
- background: #fff;
203
- box-shadow: 0 10px 24px rgba(0, 0, 0, 0.2);
204
- font-weight: 600;
205
- color: #222;
154
+ gap: 24px;
155
+ margin: 0 0 32px 0;
156
+ padding: 0;
157
+ list-style: none;
158
+ border-bottom: 1px solid var(--border-subtle);
159
+ }
160
+
161
+ .tabs menu[role="tablist"] button {
162
+ appearance: none;
163
+ background: transparent;
164
+ border: none;
165
+ border-bottom: 2px solid transparent;
166
+ color: var(--text-muted);
167
+ font-family: inherit;
168
+ font-size: 14px;
169
+ font-weight: 500;
170
+ padding: 0 0 12px 0;
171
+ cursor: pointer;
172
+ transition: all 0.2s;
206
173
  }
207
174
 
208
- .loading-panel .spinner {
209
- width: 22px;
210
- height: 22px;
175
+ .tabs menu[role="tablist"] button:hover {
176
+ color: var(--text-main);
211
177
  }
212
178
 
179
+ .tabs menu[role="tablist"] button[aria-selected="true"] {
180
+ color: var(--accent-primary);
181
+ border-bottom-color: var(--accent-primary);
182
+ }
213
183
 
214
184
  .section-grid {
215
185
  display: grid;
216
- gap: 12px;
217
- grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
186
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
187
+ gap: 24px;
188
+ margin-top: 24px;
218
189
  }
219
190
 
220
191
  .two-column {
221
192
  display: grid;
222
- gap: 16px;
223
- grid-template-columns: minmax(0, 2fr) minmax(260px, 1fr);
193
+ grid-template-columns: 1fr 380px;
194
+ gap: 24px;
195
+ margin-top: 24px;
196
+ }
197
+
198
+ @media (max-width: 900px) {
199
+ .two-column {
200
+ grid-template-columns: 1fr;
201
+ }
224
202
  }
225
203
 
226
204
  .two-column--equal {
227
- grid-template-columns: repeat(2, minmax(0, 1fr));
205
+ grid-template-columns: 1fr 1fr;
228
206
  }
229
207
 
230
- @media (max-width: 900px) {
231
- .two-column {
208
+ @media (max-width: 768px) {
209
+ .two-column--equal {
232
210
  grid-template-columns: 1fr;
233
211
  }
234
212
  }
235
213
 
236
214
  .panel {
237
- border: 1px solid var(--panel-border);
238
- background: var(--panel-bg);
239
- padding: 12px;
240
- border-radius: 4px;
241
- box-shadow: var(--panel-shadow);
215
+ background: var(--bg-card);
216
+ border: 1px solid var(--border-subtle);
217
+ border-radius: 12px;
218
+ padding: 24px;
219
+ box-shadow: var(--shadow-sm);
242
220
  }
243
221
 
244
222
  .panel h3 {
245
- margin: 0 0 6px;
223
+ margin: 0 0 16px 0;
246
224
  font-size: 14px;
225
+ font-weight: 600;
226
+ color: var(--text-muted);
227
+ text-transform: uppercase;
228
+ letter-spacing: 0.05em;
247
229
  }
248
230
 
231
+ .hero-banner {
232
+ background: linear-gradient(to right bottom, var(--bg-card), var(--bg-surface));
233
+ border: 1px solid var(--border-subtle);
234
+ border-radius: 12px;
235
+ padding: 32px;
236
+ margin-bottom: 32px;
237
+ }
249
238
 
250
- .stat-value {
251
- margin-top: 4px;
252
- font-size: 22px;
239
+ .hero-banner h2 {
240
+ font-size: 24px;
253
241
  font-weight: 600;
242
+ margin: 0 0 12px 0;
243
+ color: var(--text-main);
244
+ letter-spacing: -0.02em;
245
+ }
246
+
247
+ .hero-banner p {
248
+ color: var(--text-muted);
249
+ margin: 0 0 24px 0;
250
+ line-height: 1.6;
251
+ max-width: 600px;
252
+ }
253
+
254
+ .stat-value {
255
+ font-size: 32px;
256
+ font-weight: 700;
257
+ color: var(--text-main);
258
+ margin-bottom: 4px;
259
+ letter-spacing: -0.02em;
254
260
  }
255
261
 
256
262
  .stat-meta {
257
- color: #555;
258
- font-size: 12px;
263
+ color: var(--text-muted);
264
+ font-size: 14px;
259
265
  }
260
266
 
261
267
  .donut-wrap {
262
268
  display: flex;
263
269
  align-items: center;
264
- gap: 16px;
270
+ gap: 32px;
271
+ justify-content: center;
265
272
  flex-wrap: wrap;
266
- margin-top: 10px;
267
273
  }
268
274
 
269
275
  .donut {
270
276
  width: 140px;
271
277
  height: 140px;
272
278
  border-radius: 50%;
273
- background: var(--donut-data, #d3d3d3);
279
+ background: var(--donut-data, var(--donut-empty));
274
280
  position: relative;
281
+ flex-shrink: 0;
275
282
  }
276
283
 
277
284
  .donut::after {
278
285
  content: "";
279
286
  position: absolute;
280
- inset: 18px;
281
- background: #fdfdfd;
287
+ inset: 24px;
288
+ background: var(--bg-card);
282
289
  border-radius: 50%;
283
- box-shadow: inset 0 0 0 1px #c7c7c7;
284
290
  }
285
291
 
286
292
  .donut-center {
@@ -289,16 +295,24 @@ body {
289
295
  left: 50%;
290
296
  transform: translate(-50%, -50%);
291
297
  text-align: center;
298
+ z-index: 2;
299
+ }
300
+
301
+ .donut-center strong {
302
+ display: block;
303
+ font-size: 16px;
304
+ color: var(--text-main);
305
+ }
306
+
307
+ .donut-center div {
292
308
  font-size: 12px;
293
- color: #333;
294
- z-index: 1;
309
+ color: var(--text-muted);
295
310
  }
296
311
 
297
312
  .legend {
298
- display: grid;
299
- gap: 6px;
300
- padding: 0;
301
313
  list-style: none;
314
+ padding: 0;
315
+ margin: 0;
302
316
  flex: 1;
303
317
  min-width: 0;
304
318
  }
@@ -306,238 +320,929 @@ body {
306
320
  .legend li {
307
321
  display: flex;
308
322
  justify-content: space-between;
309
- gap: 8px;
310
- font-size: 12px;
311
- width: 100%;
312
- }
313
-
314
- .legend span {
315
- display: inline-flex;
316
323
  align-items: center;
317
- gap: 6px;
318
- }
319
-
320
-
321
- .legend i {
322
- width: 10px;
323
- height: 10px;
324
- border-radius: 2px;
325
- display: inline-block;
326
- background: var(--legend-color, #999);
327
- }
328
-
329
-
330
- .account-grid {
331
- display: grid;
324
+ padding: 8px 0;
325
+ border-bottom: 1px solid var(--border-subtle);
326
+ font-size: 13px;
332
327
  gap: 12px;
333
- grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
334
328
  }
335
329
 
336
- .account-card {
337
- border: 1px solid var(--panel-border);
338
- background: #fff;
339
- padding: 10px;
340
- border-radius: 4px;
330
+ .legend li:last-child {
331
+ border-bottom: none;
341
332
  }
342
333
 
343
- .account-card header {
334
+ .legend-label {
344
335
  display: flex;
345
- justify-content: space-between;
346
336
  align-items: center;
347
- gap: 10px;
348
- margin-bottom: 8px;
349
- }
350
-
351
- .account-card header > div {
352
- flex: 1 1 auto;
337
+ gap: 8px;
338
+ color: var(--text-main);
353
339
  min-width: 0;
340
+ flex: 1;
354
341
  }
355
342
 
356
- .account-card header > div > div {
343
+ .legend-label-text {
344
+ min-width: 0;
357
345
  overflow: hidden;
358
346
  text-overflow: ellipsis;
359
347
  white-space: nowrap;
360
348
  }
361
349
 
362
- .account-card .account-id {
363
- font-size: 12px;
364
- color: #666;
350
+ .legend i {
351
+ width: 8px;
352
+ height: 8px;
353
+ border-radius: 50%;
354
+ background: var(--legend-color, #888);
365
355
  }
366
356
 
367
- .account-card .account-actions {
357
+ .legend-detail {
368
358
  display: flex;
369
- gap: 6px;
370
- flex-wrap: wrap;
371
- margin-top: 8px;
359
+ gap: 12px;
360
+ }
361
+
362
+ .legend-detail-value {
363
+ font-family: monospace;
364
+ color: var(--text-main);
365
+ min-width: 4ch;
366
+ text-align: right;
367
+ }
368
+
369
+ .text-success,
370
+ .legend-detail-value.success {
371
+ color: var(--status-active-text);
372
+ }
373
+
374
+ .text-limited,
375
+ .legend-detail-value.limited {
376
+ color: var(--status-warning-text);
377
+ }
378
+
379
+ .text-error,
380
+ .legend-detail-value.error {
381
+ color: var(--status-error-text);
372
382
  }
373
383
 
374
384
  .status-pill {
375
385
  display: inline-flex;
376
386
  align-items: center;
377
- gap: 4px;
378
- padding: 0 9px;
379
- min-height: 18px;
380
- border-radius: 999px;
381
- border: 1px solid var(--w7-el-bd);
382
- box-shadow: var(--w7-el-sd);
383
- font-size: 11px;
384
- line-height: 16px;
387
+ padding: 4px 10px;
388
+ border-radius: 9999px;
389
+ font-size: 12px;
390
+ font-weight: 500;
391
+ background: var(--bg-surface);
392
+ color: var(--text-muted);
393
+ line-height: 1;
385
394
  white-space: nowrap;
386
- flex-shrink: 0;
387
- color: #222;
388
- background: var(--w7-el-grad);
389
- text-shadow: 0 1px 0 #fff;
390
395
  }
391
396
 
392
397
  .status-pill.active {
393
- background: linear-gradient(#f4fff6 45%, #dff3e4 45%, #c7e6d0);
394
- border-color: #7fab86;
395
- color: #1f5b2c;
398
+ background: var(--status-active-bg);
399
+ color: var(--status-active-text);
400
+ }
401
+
402
+ .status-pill.ok {
403
+ background: var(--status-active-bg);
404
+ color: var(--status-active-text);
396
405
  }
397
406
 
398
407
  .status-pill.limited {
399
- background: linear-gradient(#fff8e7 45%, #f9e3b9 45%, #e5c981);
400
- border-color: #c4973b;
401
- color: #7c4f13;
408
+ background: var(--status-warning-bg);
409
+ color: var(--status-warning-text);
402
410
  }
403
411
 
404
- .status-pill.paused {
405
- background: linear-gradient(#f0f7ff 45%, #d6e6fb 45%, #bdd7f6);
406
- border-color: #6f92c9;
407
- color: #2b4a7a;
412
+ .status-pill.rate_limit {
413
+ background: var(--status-warning-bg);
414
+ color: var(--status-warning-text);
408
415
  }
409
416
 
410
417
  .status-pill.exceeded {
411
- background: linear-gradient(#ffefed 45%, #f5d0cb 45%, #e2a59c);
412
- border-color: #b45d58;
413
- color: #7a2f2c;
418
+ background: var(--status-error-bg);
419
+ color: var(--status-error-text);
414
420
  }
415
421
 
416
- .status-pill.deactivated {
417
- background: linear-gradient(#f7f7f7 45%, #e7e7e7 45%, #d2d2d2);
418
- border-color: #9b9b9b;
419
- color: #5a5a5a;
422
+ .status-pill.quota {
423
+ background: var(--status-error-bg);
424
+ color: var(--status-error-text);
420
425
  }
421
426
 
422
- .progress-row {
427
+ .status-pill.deactivated,
428
+ .status-pill.paused {
429
+ background: var(--status-paused-bg);
430
+ color: var(--status-paused-text);
431
+ }
432
+
433
+ .badge-row {
423
434
  display: flex;
424
- align-items: center;
425
- gap: 2px;
435
+ gap: 8px;
436
+ flex-wrap: wrap;
426
437
  }
427
438
 
428
- .progress-row label {
429
- min-width: 60px;
430
- font-size: 12px;
431
- margin-right: 10px;
439
+ .account-grid {
440
+ display: grid;
441
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
442
+ gap: 16px;
443
+ margin-top: 16px;
432
444
  }
433
445
 
434
- .progress-row [role="progressbar"] {
435
- flex: 1;
446
+ .account-card {
447
+ background: var(--bg-card);
448
+ border: 1px solid var(--border-subtle);
449
+ border-radius: 12px;
450
+ padding: 20px;
451
+ display: flex;
452
+ flex-direction: column;
453
+ gap: 16px;
454
+ transition: transform 0.2s, box-shadow 0.2s;
436
455
  }
437
456
 
438
- .progress-row .text-muted {
439
- flex: 0 0 36px;
440
- text-align: right;
457
+ .account-card:hover {
458
+ transform: translateY(-2px);
459
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -2px rgba(0, 0, 0, 0.3);
460
+ border-color: var(--accent-primary);
461
+ background: var(--bg-surface);
441
462
  }
442
463
 
443
- #tab-accounts .account-list-panel {
464
+ .account-card header {
444
465
  display: flex;
445
- flex-direction: column;
466
+ justify-content: space-between;
467
+ align-items: flex-start;
468
+ gap: 12px;
446
469
  }
447
470
 
448
- #tab-accounts .account-list-panel .table-wrap {
471
+ .account-card header>div {
449
472
  flex: 1;
450
- min-height: 0;
473
+ min-width: 0;
474
+ padding-right: 8px;
451
475
  }
452
476
 
453
- #tab-accounts .account-list-panel .table-wrap--column-lines {
454
- --w7-table-cols: 6;
477
+ .account-card header .status-pill {
478
+ flex-shrink: 0;
455
479
  }
456
480
 
457
- .table-wrap--requests {
458
- --w7-table-cols: 7;
459
- height: 220px;
481
+ .account-card header>div>div:first-child {
482
+ font-weight: 500;
483
+ font-size: 15px;
484
+ color: var(--text-main);
485
+ white-space: nowrap;
486
+ overflow: hidden;
487
+ text-overflow: ellipsis;
460
488
  }
461
489
 
462
- table {
463
- width: 100%;
490
+ .account-card .account-id {
491
+ font-size: 12px;
492
+ color: var(--text-muted);
493
+ font-family: monospace;
494
+ margin-top: 4px;
464
495
  }
465
496
 
466
- .inline-actions {
497
+ .progress-row {
467
498
  display: flex;
468
- gap: 8px;
469
- flex-wrap: wrap;
499
+ flex-direction: column;
500
+ gap: 6px;
470
501
  }
471
502
 
472
- .badge-row {
473
- display: flex;
474
- gap: 8px;
475
- flex-wrap: wrap;
503
+ .progress-row+.progress-row {
504
+ margin-top: 24px;
476
505
  }
477
506
 
478
- .text-muted {
479
- color: #666;
507
+ .progress-row label {
508
+ font-size: 13px;
509
+ color: var(--text-muted);
510
+ display: flex;
511
+ justify-content: space-between;
512
+ }
513
+
514
+ [role="progressbar"] {
515
+ height: 6px;
516
+ background: var(--border-strong);
517
+ border-radius: 99px;
518
+ overflow: hidden;
519
+ position: relative;
520
+ }
521
+
522
+ [role="progressbar"] div {
523
+ height: 100%;
524
+ background: var(--accent-primary);
525
+ border-radius: 99px;
526
+ }
527
+
528
+ [role="progressbar"].limited div {
529
+ background: var(--status-warning-text);
530
+ }
531
+
532
+ [role="progressbar"].error div {
533
+ background: var(--status-error-text);
534
+ }
535
+
536
+ [role="progressbar"].success div {
537
+ background: var(--status-active-text);
538
+ }
539
+
540
+ .account-actions {
541
+ display: flex;
542
+ gap: 8px;
543
+ margin-top: auto;
544
+ padding-top: 8px;
545
+ }
546
+
547
+ .account-actions button {
480
548
  font-size: 12px;
549
+ padding: 6px 10px;
550
+ border-radius: 6px;
551
+ border: 1px solid var(--accent-primary);
552
+ background: var(--accent-primary);
553
+ color: var(--accent-primary-text);
554
+ cursor: pointer;
555
+ font-weight: 500;
556
+ transition: background 0.2s;
481
557
  }
482
558
 
483
- .split-stack {
484
- display: grid;
485
- gap: 12px;
559
+ .account-actions button:hover {
560
+ background: var(--accent-primary-hover);
561
+ border-color: var(--accent-primary-hover);
486
562
  }
487
563
 
488
- .list-actions {
564
+
565
+
566
+ .inline-actions {
489
567
  display: flex;
490
568
  gap: 8px;
569
+ }
570
+
571
+ .inline-actions button {
572
+ font-size: 13px;
573
+ padding: 8px 12px;
574
+ border-radius: 6px;
575
+ border: 1px solid var(--accent-primary);
576
+ background: var(--accent-primary);
577
+ color: var(--accent-primary-text);
578
+ cursor: pointer;
579
+ font-weight: 500;
580
+ transition: all 0.2s;
581
+ }
582
+
583
+ .inline-actions button:hover {
584
+ border-color: var(--accent-primary-hover);
585
+ background: var(--accent-primary-hover);
586
+ }
587
+
588
+ .table-wrap {
589
+ width: 100%;
590
+ overflow-x: auto;
591
+ border: 1px solid var(--border-subtle);
592
+ border-radius: 8px;
593
+ }
594
+
595
+ table {
596
+ width: 100%;
597
+ border-collapse: collapse;
598
+ font-size: 14px;
599
+ text-align: left;
600
+ table-layout: fixed;
601
+ }
602
+
603
+ .cell-truncate {
604
+ white-space: nowrap;
605
+ overflow: hidden;
606
+ text-overflow: ellipsis;
607
+ }
608
+
609
+ /* ... existing styles ... */
610
+
611
+ .list-actions .searchbox button {
612
+ background: transparent;
613
+ color: var(--text-muted);
614
+ border: none;
615
+ padding: 0;
616
+ right: 8px;
617
+ width: auto;
618
+ }
619
+
620
+ .list-actions .searchbox button:hover {
621
+ background: transparent;
622
+ }
623
+
624
+ /* ... existing styles ... */
625
+
626
+ .summary-list strong {
627
+ color: var(--text-main);
628
+ font-weight: 500;
629
+ white-space: nowrap;
630
+ overflow: hidden;
631
+ text-overflow: ellipsis;
632
+ max-width: 60%;
633
+ text-align: right;
634
+ }
635
+
636
+ th {
637
+ background: var(--bg-surface);
638
+ padding: 12px 20px;
639
+ font-weight: 600;
640
+ color: var(--text-muted);
641
+ font-size: 12px;
642
+ text-transform: uppercase;
643
+ border-bottom: 1px solid var(--border-subtle);
644
+ }
645
+
646
+ td {
647
+ padding: 14px 20px;
648
+ border-bottom: 1px solid var(--border-subtle);
649
+ color: var(--text-main);
650
+ }
651
+
652
+ tr:last-child td {
653
+ border-bottom: none;
654
+ }
655
+
656
+ tr {
657
+ transition: background-color 0.15s;
658
+ }
659
+
660
+ tr:hover td {
661
+ background: var(--bg-list-hover);
662
+ color: var(--text-main);
663
+ }
664
+
665
+ tr:hover td.text-success {
666
+ color: var(--status-active-text);
667
+ }
668
+
669
+ tr:hover td.text-limited {
670
+ color: var(--status-warning-text);
671
+ }
672
+
673
+ tr:hover td.text-error {
674
+ color: var(--status-error-text);
675
+ }
676
+
677
+ tr:hover {
678
+ outline: none;
679
+ }
680
+
681
+ tr.highlighted td {
682
+ background: var(--bg-list-selected);
683
+ border-bottom-color: var(--border-subtle);
684
+ }
685
+
686
+ tr.highlighted td:first-child {
687
+ box-shadow: inset 3px 0 0 var(--accent-primary);
688
+ }
689
+
690
+ input[type="text"],
691
+ input[type="search"],
692
+ input[type="file"] {
693
+ background: var(--bg-surface);
694
+ border: 1px solid var(--border-strong);
695
+ color: var(--text-main);
696
+ padding: 8px 12px;
697
+ border-radius: 6px;
698
+ font-family: inherit;
699
+ font-size: 14px;
700
+ outline: none;
701
+ transition: border-color 0.2s;
702
+ width: 100%;
703
+ }
704
+
705
+ input:focus {
706
+ border-color: var(--accent-primary);
707
+ }
708
+
709
+ .list-actions {
710
+ display: flex;
711
+ gap: 12px;
491
712
  align-items: center;
492
- flex-wrap: wrap;
493
- margin-bottom: 8px;
713
+ margin-bottom: 16px;
494
714
  }
495
715
 
496
- .list-actions label[role="button"] {
716
+ .searchbox {
717
+ flex: 1;
718
+ max-width: 320px;
497
719
  position: relative;
498
- overflow: hidden;
499
720
  }
500
721
 
501
- .list-actions label[role="button"].is-disabled {
502
- opacity: 0.6;
503
- pointer-events: none;
722
+ .searchbox button {
723
+ position: absolute;
724
+ right: 8px;
725
+ top: 50%;
726
+ transform: translateY(-50%);
727
+ background: transparent;
728
+ border: none;
729
+ color: var(--text-muted);
730
+ cursor: pointer;
731
+ }
732
+
733
+ button {
734
+ font-family: inherit;
504
735
  }
505
736
 
506
- .list-actions label[role="button"] > input[type="file"].file-input {
737
+ .list-actions button,
738
+ .dialog-actions button {
739
+ background: var(--accent-primary);
740
+ color: var(--accent-primary-text);
741
+ border: none;
742
+ padding: 8px 16px;
743
+ border-radius: 6px;
744
+ font-size: 14px;
745
+ font-weight: 500;
746
+ cursor: pointer;
747
+ transition: background 0.2s;
748
+ }
749
+
750
+ .list-actions button:hover {
751
+ background: var(--accent-primary-hover);
752
+ }
753
+
754
+ .list-actions label[role="button"] {
755
+ display: inline-block;
756
+ padding: 8px 16px;
757
+ border: 1px solid var(--accent-primary);
758
+ border-radius: 6px;
759
+ font-size: 14px;
760
+ font-weight: 500;
761
+ cursor: pointer;
762
+ color: var(--accent-primary-text);
763
+ position: relative;
764
+ background: var(--accent-primary);
765
+ transition: background 0.2s;
766
+ }
767
+
768
+ .list-actions label[role="button"] input {
507
769
  position: absolute;
770
+ opacity: 0;
771
+ width: 0;
772
+ }
773
+
774
+ .list-actions label[role="button"]:hover {
775
+ background: var(--accent-primary-hover);
776
+ border-color: var(--accent-primary-hover);
777
+ }
778
+
779
+ .dialog-backdrop {
780
+ position: fixed;
508
781
  inset: 0;
509
- display: block;
510
- border: 0;
511
- margin: 0;
512
- padding: 0;
513
- width: 100%;
514
- height: 100%;
782
+ background: rgba(0, 0, 0, 0.6);
783
+ backdrop-filter: blur(4px);
784
+ z-index: 50;
785
+ opacity: 0;
786
+ pointer-events: none;
787
+ transition: opacity 0.2s;
788
+ }
789
+
790
+ .dialog-backdrop.is-open {
791
+ opacity: 1;
792
+ pointer-events: auto;
793
+ }
794
+
795
+ .window.message-dialog,
796
+ .window.auth-dialog {
797
+ position: fixed;
798
+ top: 50%;
799
+ left: 50%;
800
+ transform: translate(-50%, -50%) scale(0.95);
801
+ width: 90%;
802
+ max-width: 480px;
803
+ background: var(--bg-panel);
804
+ z-index: 51;
515
805
  opacity: 0;
806
+ pointer-events: none;
807
+ transition: all 0.2s;
808
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.4);
809
+ border: 1px solid var(--border-subtle);
810
+ border-radius: 12px;
811
+ overflow: hidden;
812
+ /* Ensure children don't bleed out */
813
+ }
814
+
815
+ /* Title Bar - Common for all dialogs */
816
+ .title-bar {
817
+ display: flex;
818
+ justify-content: space-between;
819
+ align-items: center;
820
+ padding: 16px 20px;
821
+ border-bottom: 1px solid var(--border-subtle);
822
+ background: var(--bg-panel);
823
+ }
824
+
825
+ .title-bar-text {
826
+ font-weight: 600;
827
+ font-size: 16px;
828
+ color: var(--text-main);
829
+ }
830
+
831
+ .title-bar-controls button {
832
+ width: 28px;
833
+ height: 28px;
834
+ background: transparent;
835
+ border: none;
836
+ color: var(--text-muted);
516
837
  cursor: pointer;
838
+ position: relative;
839
+ border-radius: 4px;
840
+ transition: all 0.2s;
517
841
  }
518
842
 
519
- .hero-banner {
843
+ .title-bar-controls button:hover {
844
+ background: var(--bg-surface);
845
+ color: var(--text-main);
846
+ }
847
+
848
+ .title-bar-controls button::before,
849
+ .title-bar-controls button::after {
850
+ content: '';
851
+ position: absolute;
852
+ top: 50%;
853
+ left: 50%;
854
+ width: 14px;
855
+ height: 1.5px;
856
+ background: currentColor;
857
+ transform: translate(-50%, -50%) rotate(45deg);
858
+ }
859
+
860
+ .title-bar-controls button::after {
861
+ transform: translate(-50%, -50%) rotate(-45deg);
862
+ }
863
+
864
+ .window.is-open {
865
+ opacity: 1;
866
+ pointer-events: auto;
867
+ transform: translate(-50%, -50%) scale(1);
868
+ }
869
+
870
+ .window-body {
871
+ padding: 20px;
872
+ }
873
+
874
+ .text-muted {
875
+ color: var(--text-muted);
876
+ font-size: 13px;
877
+ }
878
+
879
+ .summary-list>div {
880
+ display: flex;
881
+ justify-content: space-between;
882
+ padding: 10px 0;
883
+ border-bottom: 1px solid var(--border-subtle);
884
+ font-size: 14px;
885
+ }
886
+
887
+ .summary-list span {
888
+ color: var(--text-muted);
889
+ }
890
+
891
+ .summary-list strong {
892
+ color: var(--text-main);
893
+ font-weight: 500;
894
+ }
895
+
896
+ .settings-fieldset {
897
+ margin-top: 12px;
898
+ border: 1px solid var(--border-strong);
899
+ border-radius: 8px;
900
+ padding: 16px;
901
+ }
902
+
903
+ .settings-fieldset legend {
904
+ padding: 0 8px;
905
+ color: var(--text-muted);
906
+ font-size: 13px;
907
+ font-weight: 500;
908
+ margin-left: -4px;
909
+ }
910
+
911
+ .settings-fieldset label {
912
+ font-size: 14px;
913
+ color: var(--text-main);
914
+ }
915
+
916
+ .settings-fieldset input[type="checkbox"] {
917
+ accent-color: var(--accent-primary);
918
+ margin-right: 8px;
919
+ }
920
+
921
+ .settings-fieldset .text-muted {
922
+ margin-top: 6px;
923
+ margin-left: 22px;
924
+ }
925
+
926
+ .token-fieldset {
927
+ margin-top: 24px;
928
+ border: 1px solid var(--border-strong);
929
+ border-radius: 8px;
930
+ padding: 0 16px;
931
+ }
932
+
933
+ .token-fieldset legend {
934
+ padding: 0 8px;
935
+ color: var(--text-muted);
936
+ font-size: 13px;
937
+ font-weight: 500;
938
+ margin-left: -4px;
939
+ }
940
+
941
+ .token-fieldset .summary-list>div:last-child {
942
+ border-bottom: none;
943
+ }
944
+
945
+ .auth-dialog__panel {
946
+ padding: 24px;
947
+ display: flex;
948
+ flex-direction: column;
949
+ }
950
+
951
+ .auth-dialog__lead {
952
+ margin: 0 0 20px 0;
953
+ line-height: 1.5;
954
+ color: var(--text-main);
955
+ }
956
+
957
+ .auth-dialog__detail {
958
+ margin-bottom: 24px;
959
+ }
960
+
961
+ .auth-dialog__steps {
962
+ margin: 0 0 24px 0;
963
+ padding-left: 20px;
964
+ color: var(--text-muted);
965
+ font-size: 13px;
966
+ display: flex;
967
+ flex-direction: column;
968
+ gap: 8px;
969
+ }
970
+
971
+ .auth-dialog__device-grid {
520
972
  display: grid;
973
+ grid-template-columns: 1fr;
974
+ gap: 20px;
975
+ margin-bottom: 24px;
976
+ }
977
+
978
+ .auth-dialog__methods {
979
+ margin: 20px 0 0;
980
+ border: 1px solid var(--border-subtle);
981
+ border-radius: 8px;
982
+ padding: 12px;
983
+ display: flex;
984
+ flex-direction: column;
521
985
  gap: 8px;
522
- border: 1px solid var(--panel-border);
523
- background: rgba(255, 255, 255, 0.65);
986
+ }
987
+
988
+ .auth-dialog__methods legend {
989
+ padding: 0 8px;
990
+ color: var(--text-muted);
991
+ font-size: 13px;
992
+ font-weight: 500;
993
+ margin-left: -4px;
994
+ }
995
+
996
+ .auth-dialog__option {
997
+ border: 1px solid var(--border-subtle);
998
+ border-radius: 6px;
524
999
  padding: 12px;
525
- border-radius: 4px;
1000
+ cursor: pointer;
1001
+ background: var(--bg-surface);
1002
+ transition: all 0.2s;
1003
+ display: flex;
1004
+ flex-direction: column;
1005
+ position: relative;
526
1006
  }
527
1007
 
528
- .hero-banner h2 {
1008
+ .auth-dialog__option:hover {
1009
+ border-color: var(--accent-primary);
1010
+ background: var(--bg-list-hover);
1011
+ }
1012
+
1013
+ .auth-dialog__option input[type="radio"] {
1014
+ position: absolute;
1015
+ top: 14px;
1016
+ left: 12px;
529
1017
  margin: 0;
530
- font-size: 18px;
1018
+ accent-color: var(--accent-primary);
1019
+ cursor: pointer;
531
1020
  }
532
1021
 
533
- .summary-list {
534
- display: grid;
535
- gap: 6px;
1022
+ .auth-dialog__option:has(input:checked) {
1023
+ border-color: var(--accent-primary);
1024
+ background: var(--bg-list-hover);
1025
+ }
1026
+
1027
+ .auth-dialog__option label {
1028
+ margin-left: 24px;
1029
+ font-weight: 500;
1030
+ color: var(--text-main);
1031
+ font-size: 14px;
1032
+ cursor: pointer;
1033
+ }
1034
+
1035
+ .auth-dialog__option-meta {
1036
+ margin-left: 24px;
536
1037
  font-size: 12px;
1038
+ margin-top: 2px;
1039
+ color: var(--text-muted);
1040
+ cursor: pointer;
1041
+ }
1042
+
1043
+ .auth-dialog__actions,
1044
+ .message-dialog__actions {
1045
+ display: flex;
1046
+ justify-content: flex-end;
1047
+ gap: 12px;
1048
+ padding: 16px 20px;
1049
+ border-top: 1px solid var(--border-subtle);
1050
+ background: var(--bg-panel);
1051
+ }
1052
+
1053
+ .auth-dialog__actions button,
1054
+ .message-dialog__actions button {
1055
+ padding: 8px 16px;
1056
+ border-radius: 6px;
1057
+ font-size: 14px;
1058
+ font-weight: 500;
1059
+ cursor: pointer;
1060
+ transition: all 0.2s;
1061
+ }
1062
+
1063
+ /* Secondary Button */
1064
+ .auth-dialog__actions button:not(.default),
1065
+ .message-dialog__actions button:not(.default) {
1066
+ background: transparent;
1067
+ border: 1px solid var(--border-subtle);
1068
+ color: var(--text-main);
1069
+ }
1070
+
1071
+ .auth-dialog__actions button:not(.default):hover,
1072
+ .message-dialog__actions button:not(.default):hover {
1073
+ background: var(--bg-surface);
1074
+ border-color: var(--text-muted);
1075
+ }
1076
+
1077
+ /* Primary Button */
1078
+ .auth-dialog__actions button.default,
1079
+ .message-dialog__actions button.default {
1080
+ background: var(--accent-primary) !important;
1081
+ border: 1px solid var(--accent-primary) !important;
1082
+ color: var(--accent-primary-text) !important;
537
1083
  }
538
1084
 
539
- .summary-list div {
1085
+ .auth-dialog__actions button.default:hover,
1086
+ .message-dialog__actions button.default:hover {
1087
+ background: var(--accent-primary-hover) !important;
1088
+ border-color: var(--accent-primary-hover) !important;
1089
+ }
1090
+
1091
+ .auth-dialog__code-value {
1092
+ font-family: monospace;
1093
+ font-size: 24px;
1094
+ letter-spacing: 4px;
1095
+ background: var(--bg-surface);
1096
+ padding: 4px 4px 4px 16px;
1097
+ border-radius: 8px;
1098
+ border: 1px solid var(--border-strong);
1099
+ color: var(--accent-primary);
540
1100
  display: flex;
541
1101
  justify-content: space-between;
1102
+ align-items: center;
1103
+ gap: 8px;
1104
+ }
1105
+
1106
+ .auth-dialog__label {
1107
+ display: block;
1108
+ font-size: 13px;
1109
+ font-weight: 500;
1110
+ color: var(--text-muted);
1111
+ margin-bottom: 8px;
1112
+ }
1113
+
1114
+ .auth-dialog__status {
1115
+ display: flex;
1116
+ flex-direction: column;
1117
+ align-items: center;
1118
+ gap: 8px;
1119
+ margin-top: 24px;
1120
+ color: var(--text-muted);
1121
+ font-size: 13px;
1122
+ text-align: center;
1123
+ }
1124
+
1125
+ .auth-dialog__status-text {
1126
+ font-weight: 600;
1127
+ color: var(--accent-primary);
1128
+ font-size: 14px;
1129
+ }
1130
+
1131
+ .url-copy-row {
1132
+ display: flex;
1133
+ gap: 8px;
1134
+ align-items: center;
1135
+ background: var(--bg-surface);
1136
+ border: 1px solid var(--border-subtle);
1137
+ border-radius: 6px;
1138
+ padding: 4px;
1139
+ }
1140
+
1141
+ .url-copy-row a {
1142
+ flex: 1;
1143
+ border: none;
1144
+ background: transparent;
1145
+ padding: 8px;
1146
+ font-family: monospace;
1147
+ font-size: 13px;
1148
+ text-decoration: none;
1149
+ min-width: 0;
1150
+ overflow: hidden;
1151
+ text-overflow: ellipsis;
1152
+ white-space: nowrap;
1153
+ color: var(--accent-primary) !important;
1154
+ transition: color 0.2s;
1155
+ }
1156
+
1157
+ .url-copy-row a:hover {
1158
+ text-decoration: underline;
1159
+ color: var(--accent-primary-hover) !important;
1160
+ }
1161
+
1162
+ .copy-btn {
1163
+ background: transparent;
1164
+ border: 1px solid var(--border-subtle);
1165
+ color: var(--text-muted);
1166
+ font-size: 12px;
1167
+ padding: 8px 12px;
1168
+ border-radius: 4px;
1169
+ cursor: pointer;
1170
+ transition: color 0.2s, border-color 0.2s, background 0.2s;
1171
+ flex-shrink: 0;
1172
+ width: 70px;
1173
+ text-align: center;
1174
+ box-sizing: border-box;
1175
+ }
1176
+
1177
+ .copy-btn:hover {
1178
+ background: var(--bg-card);
1179
+ color: var(--text-main);
1180
+ border-color: var(--text-muted);
1181
+ }
1182
+
1183
+ .copy-btn.copy-success {
1184
+ color: #10b981 !important;
1185
+ border-color: #10b981 !important;
1186
+ }
1187
+
1188
+ .auth-dialog__status-meta {
1189
+ display: flex;
1190
+ align-items: center;
1191
+ justify-content: center;
542
1192
  gap: 8px;
1193
+ margin-top: 4px;
1194
+ }
1195
+
1196
+ .status-bar {
1197
+ position: fixed;
1198
+ bottom: 0;
1199
+ left: 0;
1200
+ right: 0;
1201
+ display: flex;
1202
+ gap: 16px;
1203
+ padding: 8px 24px;
1204
+ background: var(--bg-panel);
1205
+ border-top: 1px solid var(--border-subtle);
1206
+ color: var(--text-muted);
1207
+ font-size: 12px;
1208
+ z-index: 20;
1209
+ }
1210
+
1211
+ .animate {
1212
+ animation: spin 1s linear infinite;
543
1213
  }
1214
+
1215
+ @keyframes spin {
1216
+ 100% {
1217
+ transform: rotate(360deg);
1218
+ }
1219
+ }
1220
+
1221
+ /* Loading State */
1222
+ .loading-overlay {
1223
+ position: absolute;
1224
+ inset: 0;
1225
+ background: var(--bg-app);
1226
+ z-index: 15;
1227
+ display: flex;
1228
+ align-items: center;
1229
+ justify-content: center;
1230
+ }
1231
+
1232
+ .loading-panel {
1233
+ display: flex;
1234
+ flex-direction: column;
1235
+ align-items: center;
1236
+ gap: 16px;
1237
+ color: var(--text-muted);
1238
+ font-size: 14px;
1239
+ }
1240
+
1241
+ .spinner {
1242
+ width: 24px;
1243
+ height: 24px;
1244
+ border: 2px solid var(--border-strong);
1245
+ border-top-color: var(--accent-primary);
1246
+ border-radius: 50%;
1247
+ display: block;
1248
+ }