FossilRepo

fossilrepo / static / admin / css / dark_theme.css
Blame History Raw 770 lines
1
/*
2
* Fossilrepo Admin Theme — supports dark, light, and system-auto modes
3
* Brand palette:
4
* #2B2D2C charcoal (dark body background)
5
* #DC394C red (primary brand accent)
6
* #8B3138 crimson (secondary / hover states)
7
* #FAFAFA near-white (foreground on dark)
8
*/
9
10
/* ── Shared brand accents + dark defaults ───────────────────────────────── */
11
12
:root {
13
/* Brand accents — unchanged across all themes */
14
--primary: #DC394C;
15
--secondary: #8B3138;
16
--accent: #DC394C;
17
--primary-fg: #FAFAFA;
18
19
--button-fg: #FAFAFA;
20
--button-bg: #DC394C;
21
--button-hover-bg: #c42d3f;
22
--default-button-bg: #8B3138;
23
--default-button-hover-bg:#6a1921;
24
--close-button-bg: #4a4c4b;
25
--close-button-hover-bg: #5a5c5b;
26
--delete-button-bg: #8B3138;
27
--delete-button-hover-bg: #6a1921;
28
29
--object-tools-fg: #FAFAFA;
30
--object-tools-bg: #8B3138;
31
--object-tools-hover-bg: #6a1921;
32
33
--breadcrumbs-bg: #DC394C;
34
--breadcrumbs-fg: #FAFAFA;
35
--breadcrumbs-link-fg: #FAFAFA;
36
--link-selected-fg: #DC394C;
37
38
/* Header stays dark in both themes for brand consistency */
39
--header-color: #FAFAFA;
40
--header-branding-color: #FAFAFA;
41
--header-bg: #1f2120;
42
--header-link-color: #FAFAFA;
43
44
/* Dark theme defaults (applied when no explicit data-theme is set) */
45
--body-fg: #FAFAFA;
46
--body-bg: #2B2D2C;
47
--body-quiet-color: #a8aaa9;
48
--body-loud-color: #ffffff;
49
50
--link-fg: #e8677a;
51
--link-hover-color: #f0929f;
52
53
--hairline-color: #3d3f3e;
54
--border-color: #3d3f3e;
55
56
--error-fg: #ff7a7a;
57
--message-success-bg: #173317;
58
--message-success-color: #7ddf7d;
59
--message-success-border: #2d5a2d;
60
--message-warning-bg: #332e17;
61
--message-warning-color: #e6c87a;
62
--message-warning-border: #5a4d2d;
63
--message-error-bg: #331717;
64
--message-error-color: #ff7a7a;
65
--message-error-border: #5a2d2d;
66
67
--darkened-bg: #222423;
68
--selected-bg: #3d1e24;
69
--selected-row: #3d1e24;
70
--input-bg: #1f2120;
71
}
72
73
/* ── Explicit dark theme (beats Django's html[data-theme="dark"] specificity) */
74
75
:root[data-theme="dark"] {
76
--primary: #DC394C;
77
--secondary: #8B3138;
78
--accent: #DC394C;
79
--primary-fg: #FAFAFA;
80
81
--button-fg: #FAFAFA;
82
--button-bg: #DC394C;
83
--button-hover-bg: #c42d3f;
84
--default-button-bg: #8B3138;
85
--default-button-hover-bg:#6a1921;
86
--close-button-bg: #4a4c4b;
87
--close-button-hover-bg: #5a5c5b;
88
--delete-button-bg: #8B3138;
89
--delete-button-hover-bg: #6a1921;
90
91
--object-tools-fg: #FAFAFA;
92
--object-tools-bg: #8B3138;
93
--object-tools-hover-bg: #6a1921;
94
95
--breadcrumbs-bg: #DC394C;
96
--breadcrumbs-fg: #FAFAFA;
97
--breadcrumbs-link-fg: #FAFAFA;
98
--link-selected-fg: #DC394C;
99
100
--header-bg: #1f2120;
101
--header-color: #FAFAFA;
102
--header-branding-color: #FAFAFA;
103
--header-link-color: #FAFAFA;
104
105
--body-fg: #FAFAFA;
106
--body-bg: #0d0d0d;
107
--body-quiet-color: #a8aaa9;
108
--body-loud-color: #ffffff;
109
110
--link-fg: #e8677a;
111
--link-hover-color: #f0929f;
112
113
--hairline-color: #2a2c2b;
114
--border-color: #2a2c2b;
115
116
--error-fg: #ff7a7a;
117
--message-success-bg: #0f1f0f;
118
--message-success-color: #7ddf7d;
119
--message-success-border: #1e3d1e;
120
--message-warning-bg: #1f1c0f;
121
--message-warning-color: #e6c87a;
122
--message-warning-border: #3d3519;
123
--message-error-bg: #1f0f0f;
124
--message-error-color: #ff7a7a;
125
--message-error-border: #3d1a1a;
126
127
--darkened-bg: #141514;
128
--selected-bg: #2d1219;
129
--selected-row: #2d1219;
130
--input-bg: #111211;
131
}
132
133
/* ── Light theme ─────────────────────────────────────────────────────────── */
134
135
:root[data-theme="light"] {
136
/* Header — dark gray in light mode */
137
--header-bg: #3a3a3a;
138
--header-color: #FAFAFA;
139
--header-branding-color: #FAFAFA;
140
--header-link-color: #FAFAFA;
141
142
/* Brand accents — must repeat here to beat base.css html[data-theme="light"] specificity */
143
--primary: #DC394C;
144
--secondary: #8B3138;
145
--accent: #DC394C;
146
--primary-fg: #FAFAFA;
147
148
--button-fg: #FAFAFA;
149
--button-bg: #DC394C;
150
--button-hover-bg: #c42d3f;
151
--default-button-bg: #8B3138;
152
--default-button-hover-bg:#6a1921;
153
--delete-button-bg: #8B3138;
154
--delete-button-hover-bg: #6a1921;
155
156
--object-tools-fg: #FAFAFA;
157
--object-tools-bg: #8B3138;
158
--object-tools-hover-bg: #6a1921;
159
160
--breadcrumbs-bg: #DC394C;
161
--breadcrumbs-fg: #FAFAFA;
162
--breadcrumbs-link-fg: #FAFAFA;
163
--link-selected-fg: #DC394C;
164
165
--body-fg: #1a1a1a;
166
--body-bg: #f8f8f8;
167
--body-quiet-color: #666666;
168
--body-loud-color: #000000;
169
170
--link-fg: #DC394C;
171
--link-hover-color: #8B3138;
172
173
--hairline-color: #e0e0e0;
174
--border-color: #e0e0e0;
175
176
--error-fg: #c0392b;
177
--message-success-bg: #d4edda;
178
--message-success-color: #155724;
179
--message-success-border: #c3e6cb;
180
--message-warning-bg: #fff3cd;
181
--message-warning-color: #856404;
182
--message-warning-border: #ffeeba;
183
--message-error-bg: #f8d7da;
184
--message-error-color: #721c24;
185
--message-error-border: #f5c6cb;
186
187
--darkened-bg: #eeeeee;
188
--selected-bg: #fde8ea;
189
--selected-row: #fde8ea;
190
--input-bg: #ffffff;
191
}
192
193
/* ── System auto: respect prefers-color-scheme light ─────────────────────── */
194
195
@media (prefers-color-scheme: light) {
196
:root:not([data-theme="dark"]) {
197
/* Header — dark gray in light mode */
198
--header-bg: #3a3a3a;
199
--header-color: #FAFAFA;
200
--header-branding-color: #FAFAFA;
201
--header-link-color: #FAFAFA;
202
203
/* Brand accents */
204
--primary: #DC394C;
205
--secondary: #8B3138;
206
--accent: #DC394C;
207
--primary-fg: #FAFAFA;
208
209
--button-fg: #FAFAFA;
210
--button-bg: #DC394C;
211
--button-hover-bg: #c42d3f;
212
--default-button-bg: #8B3138;
213
--default-button-hover-bg:#6a1921;
214
--delete-button-bg: #8B3138;
215
--delete-button-hover-bg: #6a1921;
216
217
--object-tools-fg: #FAFAFA;
218
--object-tools-bg: #8B3138;
219
--object-tools-hover-bg: #6a1921;
220
221
--breadcrumbs-bg: #DC394C;
222
--breadcrumbs-fg: #FAFAFA;
223
--breadcrumbs-link-fg: #FAFAFA;
224
--link-selected-fg: #DC394C;
225
226
--body-fg: #1a1a1a;
227
--body-bg: #f8f8f8;
228
--body-quiet-color: #666666;
229
--body-loud-color: #000000;
230
231
--link-fg: #DC394C;
232
--link-hover-color: #8B3138;
233
234
--hairline-color: #e0e0e0;
235
--border-color: #e0e0e0;
236
237
--error-fg: #c0392b;
238
--message-success-bg: #d4edda;
239
--message-success-color: #155724;
240
--message-success-border: #c3e6cb;
241
--message-warning-bg: #fff3cd;
242
--message-warning-color: #856404;
243
--message-warning-border: #ffeeba;
244
--message-error-bg: #f8d7da;
245
--message-error-color: #721c24;
246
--message-error-border: #f5c6cb;
247
248
--darkened-bg: #eeeeee;
249
--selected-bg: #fde8ea;
250
--selected-row: #fde8ea;
251
--input-bg: #ffffff;
252
}
253
}
254
255
256
/* ── Layout ─────────────────────────────────────────────────────────────── */
257
258
/*
259
* Django's stock base.css gives `.module { background: var(--darkened-bg) }`.
260
* #changelist has class "module", so the 30px margin gap between the table and
261
* the filter also gets --darkened-bg — the same color as the filter itself.
262
* Result: no visible gap.
263
*
264
* clientcove fixes this by shipping a modified base.css with
265
* `.module { background: var(--body-bg) }`. We can't change Django's base.css,
266
* so we target #changelist specifically to make the gap show the body background.
267
*/
268
#changelist.module {
269
background: transparent;
270
border: none;
271
}
272
273
/* Prevent table from overflowing into the filter gap — layout owned by changelists.css */
274
#changelist .changelist-form-container > div {
275
overflow-x: auto;
276
}
277
278
/* ── Header — always dark, hardcoded values intentional ─────────────────── */
279
280
#header {
281
background: var(--header-bg);
282
border-bottom: 2px solid var(--primary);
283
}
284
285
#header a:link,
286
#header a:visited {
287
color: var(--header-link-color);
288
}
289
290
#header #branding h1 {
291
line-height: 1;
292
margin: 0;
293
}
294
295
#header #branding .logo img {
296
height: 40px;
297
width: auto;
298
display: block;
299
}
300
301
#header #user-tools {
302
color: #a8aaa9;
303
}
304
305
#header #user-tools a {
306
color: #a8aaa9;
307
}
308
309
#header #user-tools a:hover {
310
color: #FAFAFA;
311
}
312
313
/* Quick-links group in header */
314
.bw-links {
315
display: inline-flex;
316
gap: 2px;
317
margin-right: 8px;
318
border-right: 1px solid #3d3f3e;
319
padding-right: 10px;
320
}
321
322
.bw-links a {
323
display: inline-block;
324
padding: 2px 7px;
325
border-radius: 3px;
326
background: #2e3130;
327
color: #a8aaa9 !important;
328
font-size: 0.75em;
329
text-transform: uppercase;
330
letter-spacing: 0.04em;
331
text-decoration: none !important;
332
transition: background 0.15s, color 0.15s;
333
}
334
335
.bw-links a:hover {
336
background: var(--primary);
337
color: #FAFAFA !important;
338
}
339
340
/* ── Light mode header text overrides ───────────────────────────────────── */
341
342
/* ── Navigation ─────────────────────────────────────────────────────────── */
343
344
div.breadcrumbs {
345
background: var(--breadcrumbs-bg);
346
color: var(--breadcrumbs-fg);
347
}
348
349
div.breadcrumbs a {
350
color: var(--breadcrumbs-fg);
351
opacity: 0.85;
352
}
353
354
div.breadcrumbs a:hover {
355
opacity: 1;
356
text-decoration: underline;
357
}
358
359
/* ── Content area ───────────────────────────────────────────────────────── */
360
361
body {
362
background: var(--body-bg);
363
color: var(--body-fg);
364
}
365
366
.module h2,
367
.module caption,
368
.inline-group h2 {
369
background: var(--darkened-bg);
370
color: var(--body-loud-color);
371
border-left: 3px solid var(--primary);
372
padding-left: 12px;
373
font-size: 0.75em;
374
font-weight: 600;
375
text-transform: uppercase;
376
letter-spacing: 0.06em;
377
}
378
379
.module {
380
background: var(--darkened-bg);
381
border: 1px solid var(--border-color);
382
}
383
384
/* ── Sidebar ────────────────────────────────────────────────────────────── */
385
386
#nav-sidebar {
387
background: var(--darkened-bg);
388
border-right: 1px solid var(--border-color);
389
}
390
391
#nav-sidebar .current-app .section:link,
392
#nav-sidebar .current-app .section:visited {
393
color: var(--primary);
394
}
395
396
/* ── Tables ─────────────────────────────────────────────────────────────── */
397
398
#result_list thead th {
399
background: var(--input-bg);
400
color: var(--body-fg);
401
border-bottom: 1px solid var(--border-color);
402
}
403
404
#result_list thead th a,
405
#result_list thead th a:visited {
406
color: var(--body-fg);
407
}
408
409
#result_list tr.row1 {
410
background: var(--body-bg);
411
}
412
413
#result_list tr.row2 {
414
background: var(--darkened-bg);
415
}
416
417
#result_list tr:hover td,
418
#result_list tr.selected td {
419
background: var(--selected-bg);
420
}
421
422
/* ── Forms ──────────────────────────────────────────────────────────────── */
423
424
input, textarea, select,
425
.form-row input, .form-row textarea, .form-row select {
426
background: var(--input-bg);
427
color: var(--body-fg);
428
border: 1px solid var(--border-color);
429
}
430
431
input:focus, textarea:focus, select:focus {
432
border-color: var(--primary);
433
outline: none;
434
box-shadow: 0 0 0 2px rgba(220, 57, 76, 0.25);
435
}
436
437
.form-row {
438
border-bottom: 1px solid var(--border-color);
439
}
440
441
fieldset {
442
background: var(--darkened-bg);
443
border: 1px solid var(--border-color);
444
}
445
446
fieldset.collapsed h2 {
447
background: var(--input-bg);
448
color: var(--body-quiet-color);
449
}
450
451
/* ── Buttons ────────────────────────────────────────────────────────────── */
452
453
.button, input[type="submit"], input[type="button"], .submit-row input, a.button {
454
background: var(--button-bg);
455
color: var(--button-fg);
456
border: none;
457
}
458
459
.button:hover, input[type="submit"]:hover, input[type="button"]:hover,
460
.submit-row input:hover, a.button:hover {
461
background: var(--button-hover-bg);
462
}
463
464
.button.default, input[type="submit"].default, .submit-row input.default {
465
background: var(--default-button-bg);
466
}
467
468
.button.default:hover, input[type="submit"].default:hover,
469
.submit-row input.default:hover {
470
background: var(--default-button-hover-bg);
471
}
472
473
.deletelink-box a.deletelink,
474
.object-tools a.deletelink {
475
background: var(--delete-button-bg);
476
}
477
478
.deletelink-box a.deletelink:hover,
479
.object-tools a.deletelink:hover {
480
background: var(--delete-button-hover-bg);
481
}
482
483
/* ── Dashboard / change list ────────────────────────────────────────────── */
484
485
#changelist .actions {
486
background: var(--darkened-bg);
487
border: 1px solid var(--border-color);
488
border-top: none;
489
}
490
491
/* Search bar */
492
#changelist-search input[type="text"] {
493
background: var(--input-bg);
494
color: var(--body-fg);
495
border: 1px solid var(--border-color);
496
}
497
498
#changelist-search input[type="submit"] {
499
background: var(--hairline-color);
500
color: var(--body-fg);
501
border: none;
502
}
503
504
#changelist-search input[type="submit"]:hover {
505
background: var(--primary);
506
color: var(--primary-fg);
507
}
508
509
/* Action bar */
510
#changelist .actions label,
511
#changelist .actions span {
512
color: var(--body-quiet-color);
513
}
514
515
#changelist .actions select {
516
background: var(--input-bg);
517
color: var(--body-fg);
518
border: 1px solid var(--border-color);
519
}
520
521
/* Filter sidebar */
522
#changelist-filter {
523
background: var(--input-bg);
524
border-left: 2px solid var(--border-color);
525
}
526
527
#changelist-filter h2 {
528
background: var(--input-bg);
529
color: var(--body-quiet-color);
530
font-size: 0.8em;
531
text-transform: uppercase;
532
letter-spacing: 0.05em;
533
}
534
535
#changelist-filter h3 {
536
color: var(--body-fg);
537
border-bottom: 1px solid var(--border-color);
538
}
539
540
#changelist-filter ul {
541
border-top: none;
542
}
543
544
#changelist-filter li a,
545
#changelist-filter li a:link,
546
#changelist-filter li a:visited {
547
color: var(--link-fg);
548
}
549
550
#changelist-filter li a:hover {
551
color: var(--link-hover-color);
552
}
553
554
#changelist-filter li.selected a,
555
#changelist-filter li.selected {
556
color: var(--body-fg);
557
}
558
559
/* "Show counts" and other filter toolbar links */
560
#changelist-filter details summary,
561
#changelist-filter .xfull {
562
color: var(--body-quiet-color);
563
}
564
565
566
/* ── Pagination ─────────────────────────────────────────────────────────── */
567
568
.paginator {
569
color: var(--body-quiet-color);
570
border-top: 1px solid var(--border-color);
571
}
572
573
.paginator a:link,
574
.paginator a:visited {
575
background: var(--darkened-bg);
576
color: var(--body-fg);
577
border: 1px solid var(--border-color);
578
}
579
580
.paginator a:hover {
581
background: var(--hairline-color);
582
color: var(--body-fg);
583
border-color: var(--border-color);
584
}
585
586
.paginator .this-page {
587
background: var(--primary);
588
color: var(--primary-fg);
589
border: 1px solid var(--primary);
590
}
591
592
/* ── Login page ─────────────────────────────────────────────────────────── */
593
594
body.login {
595
background: var(--header-bg);
596
}
597
598
body.login #container {
599
background: var(--body-bg);
600
}
601
602
/* ── Messages ───────────────────────────────────────────────────────────── */
603
604
.messagelist li.success {
605
background: var(--message-success-bg);
606
color: var(--message-success-color);
607
border: 1px solid var(--message-success-border);
608
}
609
610
.messagelist li.warning {
611
background: var(--message-warning-bg);
612
color: var(--message-warning-color);
613
border: 1px solid var(--message-warning-border);
614
}
615
616
.messagelist li.error {
617
background: var(--message-error-bg);
618
color: var(--message-error-color);
619
border: 1px solid var(--message-error-border);
620
}
621
622
/* ── Calendar / date widgets ────────────────────────────────────────────── */
623
624
.calendarbox, .clockbox {
625
background: var(--darkened-bg);
626
border: 1px solid var(--border-color);
627
}
628
629
.calendar caption,
630
.calendarbox h2 {
631
background: var(--primary);
632
color: var(--primary-fg);
633
}
634
635
.calendar td a:hover {
636
background: var(--primary);
637
color: var(--primary-fg);
638
}
639
640
/* ── Misc ───────────────────────────────────────────────────────────────── */
641
642
a:link, a:visited {
643
color: var(--link-fg);
644
}
645
646
a:hover {
647
color: var(--link-hover-color);
648
}
649
650
.help, .help-tooltip {
651
color: var(--body-quiet-color);
652
}
653
654
.errornote {
655
background: var(--message-error-bg);
656
border: 1px solid var(--secondary);
657
color: var(--error-fg);
658
}
659
660
ul.errorlist {
661
color: var(--error-fg);
662
}
663
664
.inline-related h3,
665
.inline-related h4 {
666
background: var(--input-bg);
667
border-top: 2px solid var(--primary);
668
color: var(--body-fg);
669
}
670
671
/* ── Inline formsets (tabular) ──────────────────────────────────────────── */
672
673
.inline-related {
674
background: var(--darkened-bg);
675
border: 1px solid var(--border-color);
676
max-width: 100%;
677
overflow-x: auto;
678
}
679
680
.inline-related .tabular {
681
max-width: 100%;
682
overflow-x: auto;
683
display: block;
684
}
685
686
.inline-related thead {
687
background: var(--input-bg);
688
}
689
690
.inline-related thead th,
691
.inline-related thead td {
692
background: var(--input-bg);
693
color: var(--body-quiet-color);
694
border-bottom: 1px solid var(--border-color);
695
font-size: 0.75em;
696
text-transform: uppercase;
697
letter-spacing: 0.05em;
698
}
699
700
.inline-related tbody tr {
701
background: var(--darkened-bg);
702
border-bottom: 1px solid var(--border-color);
703
}
704
705
.inline-related tbody tr:hover {
706
background: var(--selected-bg);
707
}
708
709
.inline-related tbody tr.empty-form {
710
display: none;
711
}
712
713
.inline-related .add-row {
714
background: var(--input-bg);
715
border-top: 1px solid var(--border-color);
716
}
717
718
.inline-related .add-row a {
719
color: var(--primary);
720
}
721
722
.inline-related .add-row a:hover {
723
color: var(--link-hover-color);
724
}
725
726
.inline-related td.delete {
727
background: var(--darkened-bg);
728
}
729
730
.inline-related td.original p {
731
color: var(--body-quiet-color);
732
font-size: 0.8em;
733
}
734
735
/* ── Read-only field values ──────────────────────────────────────────────── */
736
737
.form-row .readonly {
738
color: var(--body-fg);
739
padding: 8px 0;
740
}
741
742
.form-row label {
743
color: var(--body-quiet-color);
744
}
745
746
/* ── Module captions: brand color in light mode ──────────────────────────── */
747
/* Needs higher specificity than Django's html[data-theme="light"] .module caption */
748
749
/* Nav sidebar section headers — dark gray in all light themes */
750
/* Scoped to #nav-sidebar so it doesn't hit #changelist-filter h2 */
751
:root[data-theme="dark"] #nav-sidebar .module caption,
752
:root[data-theme="dark"] #nav-sidebar .module h2 {
753
background: #3a3a3a !important;
754
color: #FAFAFA !important;
755
}
756
757
:root[data-theme="light"] #nav-sidebar .module caption,
758
:root[data-theme="light"] #nav-sidebar .module h2 {
759
background: #3a3a3a !important;
760
color: #FAFAFA !important;
761
}
762
763
@media (prefers-color-scheme: light) {
764
:root:not([data-theme="dark"]) #nav-sidebar .module caption,
765
:root:not([data-theme="dark"]) #nav-sidebar .module h2 {
766
background: #3a3a3a !important;
767
color: #FAFAFA !important;
768
}
769
}
770

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button