atagen

malice

public
Star0
Watch0
dffd63b58af439639de9f8e155d0365d83605a8b
2
ssh://brewery@pls.lobotomise.me:33/atagen/malice.git
web/src/app.cssCss556 lines14.4 KB
1
:root {
2
  --bg: #14151c;
3
  --bg-soft: #1b1d27;
4
  --panel: #1e2029;
5
  --panel-2: #232634;
6
  --border: #2e3142;
7
  --text: #e6e8f0;
8
  --muted: #9aa0b4;
9
  --accent: #5865f2;
10
  --danger: #f26d6d;
11
  --warn: #e8b25a;
12
  color-scheme: dark;
13
}
14
15
* { box-sizing: border-box; }
16
17
html, body, #app {
18
  margin: 0;
19
  min-height: 100dvh;
20
}
21
22
body {
23
  background: var(--bg);
24
  color: var(--text);
25
  font: 14px/1.45 system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
26
}
27
28
button { font: inherit; }
29
input, textarea { font: inherit; }
30
31
.visually-hidden {
32
  position: absolute;
33
  width: 1px; height: 1px;
34
  overflow: hidden;
35
  clip: rect(0 0 0 0);
36
  white-space: nowrap;
37
}
38
39
.splash {
40
  min-height: 100dvh;
41
  display: flex;
42
  flex-direction: column;
43
  gap: 12px;
44
  align-items: center;
45
  justify-content: center;
46
  color: var(--muted);
47
}
48
.splash-mark {
49
  width: 52px; height: 52px;
50
  border-radius: 16px;
51
  display: grid; place-items: center;
52
  font-size: 26px; font-weight: 800; color: #fff;
53
  background: linear-gradient(135deg, var(--accent), #7c5cff);
54
}
55
56
.app {
57
  display: grid;
58
  grid-template-columns: 68px 300px 1fr;
59
  height: 100dvh;
60
  overflow: hidden;
61
}
62
.app:has(.members) { grid-template-columns: 68px 300px 1fr 260px; }
63
64
/* ——— Rail ——— */
65
.rail {
66
  background: #101117;
67
  display: flex;
68
  flex-direction: column;
69
  align-items: center;
70
  gap: 8px;
71
  padding: 12px 0;
72
  overflow-y: auto;
73
}
74
.rail-sep { width: 32px; height: 2px; border-radius: 2px; background: var(--border); }
75
.rail-btn {
76
  width: 46px; height: 46px;
77
  border-radius: 50%;
78
  border: none;
79
  background: var(--panel-2);
80
  color: var(--text);
81
  font-size: 19px;
82
  font-weight: 700;
83
  cursor: pointer;
84
  transition: border-radius 0.15s, background 0.15s;
85
  display: grid;
86
  place-items: center;
87
  overflow: hidden;
88
  padding: 0;
89
}
90
.rail-btn:hover { border-radius: 16px; background: var(--accent); color: #fff; }
91
.rail-btn.active { border-radius: 16px; background: var(--accent); color: #fff; }
92
.rail-btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
93
.rail-avatar { width: 100%; height: 100%; object-fit: cover; display: block; }
94
.rail-add { color: var(--muted); }
95
.rail-add:hover { color: #fff; }
96
.space-context {
97
  display: flex;
98
  align-items: center;
99
  gap: 10px;
100
  padding: 10px 8px 4px;
101
}
102
.space-context-text { display: flex; flex-direction: column; min-width: 0; }
103
.space-context-text strong { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
104
.space-context-text span { font-size: 11.5px; color: var(--muted); }
105
.sec-banner {
106
  display: flex;
107
  align-items: center;
108
  gap: 10px;
109
  margin: 10px 16px 0;
110
  padding: 8px 12px;
111
  background: rgba(88, 101, 242, 0.14);
112
  border: 1px solid var(--accent);
113
  color: var(--text);
114
  border-radius: 8px;
115
  font-size: 12.5px;
116
}
117
.sec-banner.warn { background: #33300f; border-color: #5c551f; color: #ecd98a; }
118
.sec-banner button {
119
  margin-left: auto;
120
  flex: none;
121
  background: transparent;
122
  border: 1px solid currentColor;
123
  border-radius: 6px;
124
  color: inherit;
125
  cursor: pointer;
126
  padding: 3px 10px;
127
  font-size: 12.5px;
128
}
129
.composer-note { margin: 0; padding: 0 16px 10px; font-size: 11.5px; color: var(--muted); }
130
.head-room { display: flex; align-items: center; gap: 12px; min-width: 0; }
131
.head-room-text { min-width: 0; flex: 1; }
132
.conn-banner.error { background: #3a1d22; border-color: #6b2a33; color: #ffc9ce; }
133
/* ——— Sidebar ——— */
134
.sidebar {
135
  background: var(--panel);
136
  border-right: 1px solid var(--border);
137
  display: flex;
138
  flex-direction: column;
139
  min-height: 0;
140
}
141
.side-search {
142
  display: flex;
143
  gap: 6px;
144
  padding: 12px;
145
  border-bottom: 1px solid var(--border);
146
}
147
.side-search input {
148
  flex: 1;
149
  min-width: 0;
150
  background: var(--bg-soft);
151
  border: 1px solid var(--border);
152
  border-radius: 8px;
153
  color: var(--text);
154
  padding: 7px 10px;
155
}
156
.side-search input:focus { outline: 2px solid var(--accent); border-color: var(--accent); }
157
.side-scroll { flex: 1; overflow-y: auto; padding: 8px; min-height: 0; }
158
.side-h {
159
  font-size: 11px;
160
  text-transform: uppercase;
161
  letter-spacing: 0.08em;
162
  color: var(--muted);
163
  margin: 12px 6px 6px;
164
}
165
.side-h:first-child { margin-top: 4px; }
166
.room-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
167
.room-row {
168
  width: 100%;
169
  display: flex;
170
  align-items: center;
171
  gap: 6px;
172
  background: transparent;
173
  border: none;
174
  border-radius: 8px;
175
  color: var(--text);
176
  padding: 7px 9px;
177
  cursor: pointer;
178
  text-align: left;
179
  font-size: 13.5px;
180
}
181
.room-row:hover { background: var(--panel-2); }
182
.room-row.active { background: rgba(88, 101, 242, 0.2); }
183
.room-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
184
.room-hash { color: var(--muted); }
185
.room-name {
186
  flex: 1;
187
  min-width: 0;
188
  overflow: hidden;
189
  text-overflow: ellipsis;
190
  white-space: nowrap;
191
}
192
.badge {
193
  flex: none;
194
  min-width: 20px;
195
  height: 20px;
196
  padding: 0 6px;
197
  border-radius: 999px;
198
  background: var(--panel-2);
199
  border: 1px solid var(--border);
200
  color: var(--text);
201
  font-size: 11px;
202
  font-weight: 700;
203
  display: inline-grid;
204
  place-items: center;
205
}
206
.badge.mention { background: var(--accent); border-color: var(--accent); color: #fff; }
207
.invite-join {
208
  flex: none;
209
  background: var(--accent);
210
  color: #fff;
211
  border-radius: 6px;
212
  padding: 2px 10px;
213
  font-size: 12px;
214
  font-weight: 600;
215
  cursor: pointer;
216
}
217
.side-note { color: var(--muted); font-size: 13px; padding: 8px 6px; }
218
.side-cta { display: flex; gap: 8px; padding: 0 6px; }
219
.side-cta button {
220
  flex: 1;
221
  background: var(--panel-2);
222
  border: 1px solid var(--border);
223
  color: var(--text);
224
  border-radius: 8px;
225
  padding: 8px;
226
  cursor: pointer;
227
}
228
.side-cta button:hover { border-color: var(--accent); }
229
.side-footer {
230
  display: flex;
231
  align-items: center;
232
  gap: 8px;
233
  padding: 10px 12px;
234
  border-top: 1px solid var(--border);
235
  background: var(--bg-soft);
236
}
237
.me { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; }
238
.me-avatar {
239
  flex: none;
240
  width: 30px; height: 30px;
241
  border-radius: 50%;
242
  background: var(--accent);
243
  color: #fff;
244
  font-weight: 700;
245
  font-size: 13px;
246
  display: inline-grid;
247
  place-items: center;
248
}
249
.me-id {
250
  min-width: 0;
251
  overflow: hidden;
252
  text-overflow: ellipsis;
253
  white-space: nowrap;
254
  font-size: 12.5px;
255
  color: var(--muted);
256
}
257
.icon-btn {
258
  flex: none;
259
  background: transparent;
260
  border: 1px solid transparent;
261
  border-radius: 8px;
262
  color: var(--muted);
263
  font-size: 16px;
264
  padding: 5px 9px;
265
  cursor: pointer;
266
}
267
.icon-btn:hover:not(:disabled) { background: var(--panel-2); color: var(--text); }
268
.icon-btn:disabled { opacity: 0.4; cursor: default; }
269
.scrim { display: none; }
270
271
/* ——— Chat ——— */
272
.chat { display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--bg); }
273
.empty {
274
  margin: auto;
275
  text-align: center;
276
  padding: 24px;
277
  max-width: 420px;
278
}
279
.empty-mark { font-size: 44px; color: var(--accent); }
280
.empty h1 { font-size: 22px; margin: 8px 0 4px; }
281
.empty p { color: var(--muted); }
282
.empty-cta { display: flex; gap: 10px; justify-content: center; margin: 16px 0; }
283
.conn-line { display: flex; align-items: center; justify-content: center; gap: 8px; font-size: 13px; }
284
285
.chat-head {
286
  display: flex;
287
  align-items: center;
288
  gap: 10px;
289
  padding: 10px 16px;
290
  border-bottom: 1px solid var(--border);
291
  background: var(--panel);
292
  min-height: 62px;
293
}
294
.head-title { flex: 1; min-width: 0; }
295
.head-title h1 {
296
  margin: 0;
297
  font-size: 15.5px;
298
  overflow: hidden;
299
  text-overflow: ellipsis;
300
  white-space: nowrap;
301
}
302
.head-meta { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
303
.pill {
304
  font-size: 11px;
305
  border: 1px solid var(--border);
306
  border-radius: 999px;
307
  padding: 0 8px;
308
  color: var(--muted);
309
}
310
.conn { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
311
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); display: inline-block; }
312
.dot-online { background: #3fb97f; }
313
.dot-busy { background: var(--warn); }
314
.dot-off { background: var(--danger); }
315
.head-actions { display: flex; align-items: center; gap: 8px; }
316
317
.primary-btn {
318
  background: var(--accent);
319
  border: none;
320
  color: #fff;
321
  font-weight: 600;
322
  border-radius: 8px;
323
  padding: 8px 16px;
324
  cursor: pointer;
325
  font-size: 13.5px;
326
}
327
.primary-btn:hover:not(:disabled) { filter: brightness(1.1); }
328
.primary-btn:disabled { opacity: 0.55; cursor: default; }
329
.primary-btn.wide { width: 100%; margin-top: 12px; }
330
.ghost-btn {
331
  background: var(--panel-2);
332
  border: 1px solid var(--border);
333
  color: var(--text);
334
  border-radius: 8px;
335
  padding: 7px 14px;
336
  cursor: pointer;
337
  font-size: 13px;
338
}
339
.ghost-btn:hover:not(:disabled) { border-color: var(--accent); }
340
.ghost-btn:disabled { opacity: 0.55; cursor: wait; }
341
.ghost-btn.danger { color: var(--danger); }
342
.ghost-btn.danger:hover:not(:disabled) { border-color: var(--danger); }
343
344
.banners { display: flex; flex-direction: column; gap: 6px; padding: 10px 16px 0; }
345
.banner {
346
  display: flex;
347
  align-items: center;
348
  gap: 10px;
349
  background: #3a1d22;
350
  border: 1px solid #6b2a33;
351
  color: #ffc9ce;
352
  border-radius: 8px;
353
  padding: 8px 12px;
354
  font-size: 13px;
355
}
356
.banner span { flex: 1; }
357
.banner button {
358
  background: transparent;
359
  border: none;
360
  color: inherit;
361
  cursor: pointer;
362
  font-size: 13px;
363
  padding: 2px 6px;
364
}
365
.conn-banner {
366
  margin: 10px 16px 0;
367
  padding: 7px 12px;
368
  background: #33300f;
369
  border: 1px solid #5c551f;
370
  color: #ecd98a;
371
  border-radius: 8px;
372
  font-size: 12.5px;
373
}
374
375
.timeline {
376
  flex: 1;
377
  overflow-y: auto;
378
  padding: 12px 20px 16px;
379
  min-height: 0;
380
}
381
.timeline-top { display: flex; justify-content: center; padding: 4px 0 12px; }
382
.start-note { text-align: center; color: var(--muted); font-size: 12.5px; }
383
.timeline-empty { text-align: center; padding: 32px 0; }
384
.day-row {
385
  display: flex;
386
  align-items: center;
387
  gap: 12px;
388
  margin: 14px 0 8px;
389
  color: var(--muted);
390
  font-size: 12px;
391
}
392
.day-row::before, .day-row::after {
393
  content: '';
394
  flex: 1;
395
  height: 1px;
396
  background: var(--border);
397
}
398
.new-row {
399
  display: flex;
400
  align-items: center;
401
  gap: 12px;
402
  margin: 8px 0;
403
  color: var(--danger);
404
  font-size: 12px;
405
  font-weight: 600;
406
}
407
.new-row::before, .new-row::after { content: ''; flex: 1; height: 1px; background: #6b2a33; }
408
.unknown-note { color: var(--muted); font-size: 12.5px; font-style: italic; }
409
.pending-actions {
410
  display: flex;
411
  align-items: center;
412
  gap: 8px;
413
  margin: -4px 0 6px 44px;
414
}
415
.pending-error { color: var(--danger); font-size: 12px; flex: 1; min-width: 0; overflow-wrap: anywhere; }
416
417
.composer {
418
  display: flex;
419
  gap: 10px;
420
  align-items: flex-end;
421
  padding: 12px 16px 16px;
422
  border-top: 1px solid var(--border);
423
  background: var(--panel);
424
}
425
.composer textarea {
426
  flex: 1;
427
  resize: none;
428
  background: var(--bg-soft);
429
  border: 1px solid var(--border);
430
  border-radius: 10px;
431
  color: var(--text);
432
  padding: 10px 12px;
433
  min-height: 40px;
434
  max-height: 160px;
435
  line-height: 1.4;
436
}
437
.composer textarea:focus { outline: 2px solid var(--accent); border-color: var(--accent); }
438
.join-bar {
439
  display: flex;
440
  align-items: center;
441
  gap: 12px;
442
  padding: 12px 16px 16px;
443
  border-top: 1px solid var(--border);
444
  background: var(--panel);
445
}
446
.join-bar p { margin: 0; color: var(--muted); font-size: 13px; flex: 1; }
447
448
/* ——— Members ——— */
449
.members {
450
  background: var(--panel);
451
  border-left: 1px solid var(--border);
452
  display: flex;
453
  flex-direction: column;
454
  min-height: 0;
455
  overflow: hidden;
456
}
457
.members-head {
458
  display: flex;
459
  align-items: center;
460
  justify-content: space-between;
461
  padding: 12px 12px 8px;
462
}
463
.members-head h2 { font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); margin: 0; }
464
.member-list { list-style: none; margin: 0; padding: 0 8px 12px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
465
.member { display: flex; align-items: center; gap: 9px; padding: 6px 8px; border-radius: 8px; }
466
.member:hover { background: var(--panel-2); }
467
.member-names { min-width: 0; display: flex; flex-direction: column; }
468
.member-name { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
469
.member-id { font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
470
471
/* ——— Modal ——— */
472
.modal-wrap {
473
  position: fixed;
474
  inset: 0;
475
  background: rgba(0, 0, 0, 0.6);
476
  display: grid;
477
  place-items: center;
478
  padding: 20px;
479
  z-index: 50;
480
}
481
.modal {
482
  width: min(420px, 100%);
483
  background: var(--panel);
484
  border: 1px solid var(--border);
485
  border-radius: 14px;
486
  padding: 18px;
487
}
488
.modal-tabs { display: flex; gap: 4px; margin-bottom: 14px; }
489
.modal-tabs button[role='tab'] {
490
  background: transparent;
491
  border: none;
492
  border-bottom: 2px solid transparent;
493
  color: var(--muted);
494
  font-weight: 600;
495
  padding: 8px 14px;
496
  cursor: pointer;
497
  font-size: 14px;
498
}
499
.modal-tabs button[role='tab'].active { color: var(--text); border-bottom-color: var(--accent); }
500
.modal-x { margin-left: auto; }
501
.modal .field { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--muted); margin-bottom: 12px; }
502
.modal .field input {
503
  background: var(--bg-soft);
504
  border: 1px solid var(--border);
505
  border-radius: 8px;
506
  color: var(--text);
507
  padding: 9px 11px;
508
  font-size: 14px;
509
}
510
.modal .field input:focus { outline: 2px solid var(--accent); border-color: var(--accent); }
511
512
.only-mobile { display: none; }
513
514
@media (max-width: 1100px) {
515
  .app, .app:has(.members) { grid-template-columns: 60px 1fr; }
516
  .sidebar {
517
    position: fixed;
518
    top: 0; bottom: 0; left: 60px;
519
    width: min(320px, 85vw);
520
    z-index: 40;
521
    transform: translateX(calc(-100% - 60px));
522
    transition: transform 0.18s ease;
523
    box-shadow: 8px 0 32px rgba(0, 0, 0, 0.5);
524
  }
525
  .sidebar.open { transform: none; }
526
  .scrim {
527
    display: block;
528
    position: fixed;
529
    inset: 0;
530
    left: 60px;
531
    background: rgba(0, 0, 0, 0.55);
532
    border: none;
533
    z-index: 30;
534
    cursor: pointer;
535
  }
536
  .members {
537
    position: fixed;
538
    top: 0; bottom: 0; right: 0;
539
    width: min(300px, 85vw);
540
    z-index: 40;
541
    box-shadow: -8px 0 32px rgba(0, 0, 0, 0.5);
542
  }
543
  .only-mobile { display: inline-block; }
544
  .head-actions .ghost-btn { display: none; }
545
  .timeline { padding: 10px 12px 14px; }
546
  .chat-head { padding: 8px 12px; }
547
  .composer { padding: 10px 12px 12px; }
548
}
549
550
@media (max-width: 640px) {
551
  .app, .app:has(.members) { grid-template-columns: 52px 1fr; }
552
  .sidebar { left: 52px; transform: translateX(calc(-100% - 52px)); }
553
  .scrim { left: 52px; }
554
  .rail-btn { width: 40px; height: 40px; font-size: 16px; }
555
  .empty-cta { flex-direction: column; }
556
}