OXYGENHUB
# 3f02e5ea4f2d oxygenhub / templates / style.css
20.1 KiB · CSS · last changed Milestone 0.4: issues and notifications 1 month ago source blame history raw
1
/* Oxygenhub. The RetroPlay Network theme (hub spec §6.1): dark by default
2
   on the Commander X16 palette, light under [data-theme="light"], Barlow
3
   for text and Press Start 2P for the wordmark and first columns, square
4
   corners, thin rules, a band for navigation. Fonts are vendored. */
5
6
@font-face { font-family: "Barlow"; font-weight: 300; font-display: swap; src: url(/static/fonts/Barlow-300.woff2) format("woff2"); }
7
@font-face { font-family: "Barlow"; font-weight: 400; font-display: swap; src: url(/static/fonts/Barlow-400.woff2) format("woff2"); }
8
@font-face { font-family: "Barlow"; font-weight: 500; font-display: swap; src: url(/static/fonts/Barlow-500.woff2) format("woff2"); }
9
@font-face { font-family: "Barlow"; font-weight: 600; font-display: swap; src: url(/static/fonts/Barlow-600.woff2) format("woff2"); }
10
@font-face { font-family: "Press Start 2P"; font-weight: 400; font-display: swap; src: url(/static/fonts/PressStart2P-400.woff2) format("woff2"); }
11
12
:root {
13
  /* Oxygen's mark: cyan #00F0FF to blue #0072FF on #070c18. */
14
  --bg:#070c18; --panel:#0e1526; --soft:#141d33; --ink:#e6ecf7; --mute:#8592ad; --line:#1f2b47; --dim:#43506d;
15
  --acc:#00e0f0; --acc-2:#0072ff; --band:#0b3f9e; --band-ink:#ffffff; --band-line:rgba(7,12,24,.5); --now:#00f0ff; --now-ink:#070c18;
16
  --ok:#5fe3a1; --bad:#ff5e7a; --warn:#ffb347;
17
  --add:#0d3a3a; --del:#3f1a2e; --add-ink:#8ff0d8; --del-ink:#ffa5b8;
18
  --m1:#00f0ff; --m2:#d6dcea; --m3:#5aa8ff; --m4:#0072ff; --m5:#8592ad;
19
  /* syntax */
20
  --sy-kw:#7fb4ff; --sy-str:#8ff0d8; --sy-num:#ffd479; --sy-cmt:#5b6785; --sy-fn:#00e0f0; --sy-ty:#c6a0ff; --sy-var:#e6ecf7; --sy-const:#ffb347;
21
  color-scheme: dark;
22
}
23
:root[data-theme="light"] {
24
  --bg:#f4f7fc; --panel:#ffffff; --soft:#e9eef8; --ink:#1b2333; --mute:#66718a; --line:#d6dded; --dim:#b3bccf;
25
  --acc:#0072ff; --acc-2:#00b8d4; --band:#0b3f9e; --band-ink:#ffffff; --band-line:rgba(255,255,255,.25); --now:#0072ff; --now-ink:#ffffff;
26
  --ok:#1f8f5f; --bad:#c62d47; --warn:#b8651b;
27
  --add:#e1f5ee; --del:#fbe3e8; --add-ink:#176b48; --del-ink:#a1243c;
28
  --m1:#0090a8; --m2:#7a8290; --m3:#2f6fcf; --m4:#0055c0; --m5:#8a8f9c;
29
  --sy-kw:#0b4fc9; --sy-str:#1f8f5f; --sy-num:#986801; --sy-cmt:#8a94a8; --sy-fn:#0083a8; --sy-ty:#7a3fd1; --sy-var:#1b2333; --sy-const:#b8651b;
30
  color-scheme: light;
31
}
32
33
* { box-sizing: border-box; }
34
html { background: var(--bg); }
35
body { margin: 0; min-height: 100vh; display: flex; flex-direction: column; background: var(--bg); color: var(--ink); font: 15px/1.45 "Barlow", "IBM Plex Sans", system-ui, sans-serif; }
36
a { color: var(--acc); text-decoration: none; }
37
a:hover { text-decoration: underline; }
38
code, pre, kbd, .mono { font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 13px; }
39
.px { font-family: "Press Start 2P", "Silkscreen", monospace; font-size: 13px; }
40
.pxs { font-family: "Press Start 2P", "Silkscreen", monospace; font-size: 11px; }
41
h1, h2, h3 { margin: 0; }
42
h2 { font-size: 16px; font-weight: 600; margin: 0 0 8px; }
43
h3 { font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); margin: 14px 0 6px; }
44
p { margin: 0 0 10px; }
45
.small { font-size: 12px; }
46
.mute { color: var(--mute); }
47
.dim { color: var(--dim); }
48
.center { text-align: center; }
49
.right { text-align: right; }
50
.empty { color: var(--mute); padding: 22px; text-align: center; border: 1px dashed var(--line); }
51
.lead { font-size: 16px; }
52
kbd { background: var(--soft); border: 1px solid var(--line); padding: 1px 5px; font-size: 11px; }
53
54
/* shell */
55
header { background: var(--panel); border-bottom: 1px solid var(--line); padding: 14px 22px; display: flex; align-items: center; gap: 16px; }
56
.brand { display: inline-flex; align-items: center; gap: 10px; color: var(--ink); }
57
.brand svg { height: 22px; width: auto; }
58
.brand em { font-style: normal; color: var(--acc); }
59
.brand:hover { text-decoration: none; }
60
header nav { margin-left: auto; display: flex; gap: 8px; align-items: center; }
61
header nav .me { color: var(--ink); font-weight: 600; padding: 0 6px; }
62
form.inline { display: inline; margin: 0; }
63
.band a.admin { color: var(--acc); }
64
form.find { margin: 0; flex: 0 1 320px; }
65
form.find input { width: 100%; background: var(--bg); border: 1px solid var(--line); color: var(--ink); padding: 6px 10px; font: inherit; }
66
form.find input:focus { outline: 2px solid var(--band); outline-offset: 0; }
67
.band { background: var(--band); display: flex; align-items: stretch; padding: 0 22px; }
68
.band a { color: var(--band-ink); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; padding: 9px 14px; border-right: 1px solid var(--band-line); }
69
.band a:first-child { border-left: 1px solid var(--band-line); }
70
.band a.on { box-shadow: inset 0 -3px 0 var(--acc); background: rgba(0,0,0,.18); }
71
.band a:hover { text-decoration: none; background: rgba(0,0,0,.12); }
72
.band .grow { flex: 1; }
73
.band a.dim { opacity: .6; border: 0; }
74
.tabs { background: var(--panel); border-bottom: 1px solid var(--line); }
75
.tabs-in { max-width: 1180px; margin: 0 auto; padding: 0 22px; display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }
76
.tabs .crumb { margin-right: 18px; padding: 10px 0; font-size: 16px; }
77
.tabs a:not(.crumb a) { padding: 10px 12px; color: var(--ink); font-size: 13px; }
78
.tabs a.on { border-bottom: 2px solid var(--acc); font-weight: 600; }
79
.tabs a:hover { text-decoration: none; background: var(--soft); }
80
main { flex: 1; width: 100%; max-width: 1180px; margin: 0 auto; padding: 14px 22px 28px; }
81
main.wide { max-width: none; }
82
footer { background: var(--panel); border-top: 1px solid var(--line); margin-top: 28px; }
83
.foot { max-width: 1180px; margin: 0 auto; padding: 22px; display: grid; grid-template-columns: 1fr auto; gap: 22px; }
84
.foot .cols { display: flex; gap: 32px; }
85
.foot .cols a { display: block; font-size: 13px; }
86
.head { border-bottom: 2px solid var(--band); border-image: linear-gradient(90deg, var(--acc), var(--acc-2)) 1; margin: 6px 0 16px; padding-bottom: 6px; }
87
.head h1 { font-size: 30px; font-weight: 300; color: var(--mute); }
88
.head h1 small { display: block; font-size: 13px; color: var(--acc); font-weight: 400; }
89
.strip { padding: 8px 12px; margin: 0 0 12px; border: 1px solid; font-size: 13px; }
90
.strip.warn { border-color: var(--warn); color: var(--warn); background: color-mix(in srgb, var(--warn) 10%, transparent); }
91
.strip.bad { border-color: var(--bad); color: var(--bad); background: color-mix(in srgb, var(--bad) 10%, transparent); }
92
.strip a { color: inherit; text-decoration: underline; }
93
.sheet { position: fixed; right: 22px; bottom: 22px; background: var(--panel); border: 1px solid var(--line); padding: 14px 18px; box-shadow: 0 2px 12px rgba(0,0,0,.35); }
94
.sheet td { padding: 2px 8px 2px 0; font-size: 13px; }
95
96
/* buttons, tags, chips */
97
button, a.go, button.go { font: inherit; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; background: var(--panel); color: var(--acc); border: 1px solid var(--acc); padding: 5px 10px; cursor: pointer; }
98
button:hover, a.go:hover { background: var(--acc); color: var(--now-ink); text-decoration: none; }
99
button.small, a.go.small { padding: 2px 8px; font-size: 11px; }
100
.tag { display: inline-block; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--acc); background: var(--soft); padding: 1px 6px; vertical-align: middle; }
101
.tag.bad { color: var(--bad); }
102
.tag.warn { color: var(--warn); }
103
.tag.head { color: var(--now-ink); background: var(--now); }
104
.chip { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 12px; background: var(--soft); padding: 1px 6px; border: 1px solid var(--line); }
105
.lbl { display: inline-block; font-size: 11px; padding: 1px 7px; margin-right: 4px; border: 1px solid; vertical-align: middle; }
106
.lbl-bm { color: var(--band-ink); background: var(--band); border-color: var(--band); }
107
.lbl-tag { color: var(--acc); border-color: var(--acc); }
108
.sig { display: inline-block; width: 1.2em; text-align: center; font-weight: 600; }
109
.sig-valid { color: var(--ok); }
110
.sig-unsigned { color: var(--dim); }
111
.sig-invalid { color: var(--bad); }
112
.sig-revoked { color: var(--warn); }
113
114
/* lists, tables, panels */
115
ul.plain { list-style: none; margin: 0; padding: 0; }
116
ul.plain li { padding: 2px 0; }
117
ul.rows { list-style: none; margin: 0; padding: 0; }
118
ul.rows li { display: flex; justify-content: space-between; align-items: center; gap: 14px; background: var(--panel); border: 1px solid var(--line); padding: 12px 14px; margin-bottom: 6px; }
119
ul.rows .name { font-size: 16px; }
120
ul.rows p { margin: 4px 0 0; color: var(--mute); }
121
.table { border: 1px solid var(--line); overflow-x: auto; }
122
table { border-collapse: collapse; width: 100%; }
123
th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--mute); padding: 8px 10px; border-bottom: 1px solid var(--line); background: var(--soft); }
124
td { padding: 7px 10px; background: var(--panel); border-bottom: 1px solid var(--line); vertical-align: top; }
125
td.px { color: var(--acc); }
126
.panel { background: var(--panel); border: 1px solid var(--line); padding: 14px 16px; margin-bottom: 14px; }
127
dl.facts { display: grid; grid-template-columns: max-content 1fr; gap: 6px 18px; background: var(--panel); border: 1px solid var(--line); padding: 12px 16px; margin: 0 0 14px; }
128
dl.facts dt { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--mute); padding-top: 3px; }
129
dl.facts dd { margin: 0; }
130
code.full { word-break: break-all; }
131
pre.msg { background: var(--panel); border: 1px solid var(--line); padding: 10px 12px; white-space: pre-wrap; font-family: inherit; font-size: 14px; }
132
pre.marked { background: var(--panel); border: 1px solid var(--bad); padding: 10px 12px; overflow-x: auto; }
133
134
/* repository layout */
135
.side-layout { display: grid; grid-template-columns: 1fr 280px; gap: 22px; }
136
.side h3:first-child { margin-top: 0; }
137
.clone { display: flex; gap: 6px; align-items: center; }
138
.clone code { background: var(--bg); border: 1px solid var(--line); padding: 4px 8px; flex: 1; overflow-x: auto; white-space: nowrap; }
139
.bar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 10px; }
140
.ref { color: var(--acc); }
141
.crumbs a { color: var(--ink); }
142
table.tree td { padding: 6px 10px; }
143
table.tree td.g { width: 1.6em; color: var(--acc); text-align: center; }
144
table.tree td.last { color: var(--mute); max-width: 520px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
145
table.tree td.last a { color: var(--mute); }
146
table.tree td.age { width: 9em; text-align: right; white-space: nowrap; }
147
article.doc { max-width: 60rem; background: var(--panel); border: 1px solid var(--line); padding: 18px 24px; margin-top: 14px; }
148
article.doc h1 { font-size: 26px; font-weight: 500; margin: 0 0 12px; }
149
article.doc h2 { font-size: 20px; margin: 18px 0 8px; }
150
article.doc h3 { text-transform: none; letter-spacing: 0; font-size: 16px; color: var(--ink); }
151
article.doc pre { background: var(--bg); border: 1px solid var(--line); padding: 10px 12px; overflow-x: auto; }
152
article.doc code { background: var(--soft); padding: 0 3px; }
153
article.doc pre code { background: none; padding: 0; }
154
article.doc table { width: auto; }
155
article.doc img { max-width: 100%; }
156
article.doc blockquote { border-left: 3px solid var(--band); margin: 0; padding: 2px 12px; color: var(--mute); }
157
158
/* files and diffs */
159
.filebox { background: var(--panel); border: 1px solid var(--line); }
160
.filebox > header { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; padding: 8px 12px; border-bottom: 1px solid var(--line); background: var(--soft); }
161
.modes a { font-size: 12px; padding: 2px 8px; border: 1px solid var(--line); margin-left: 4px; color: var(--ink); }
162
.modes a.on { border-color: var(--acc); color: var(--acc); }
163
table.code { width: 100%; }
164
table.code td { padding: 0 8px; border: 0; background: transparent; line-height: 1.5; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 13px; }
165
table.code td.n { width: 1%; min-width: 3em; text-align: right; color: var(--dim); user-select: none; cursor: pointer; padding-right: 12px; }
166
table.code td.n:hover { color: var(--acc); }
167
table.code td.t pre { margin: 0; white-space: pre; }
168
table.code tr.hl td { background: color-mix(in srgb, var(--acc) 18%, transparent); }
169
table.code td.blame { width: 1%; white-space: nowrap; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); background: var(--soft); font-family: "Barlow", sans-serif; font-size: 12px; padding: 0 10px; vertical-align: top; line-height: 1.5; }
170
table.code td.blame .px { font-size: 9px; }
171
table.code td.blame .who { color: var(--ink); }
172
table.diff td.s { width: 1%; user-select: none; color: var(--mute); }
173
table.diff tr.add td { background: var(--add); color: var(--add-ink); }
174
table.diff tr.del td { background: var(--del); color: var(--del-ink); }
175
table.diff tr.gap td { background: var(--soft); color: var(--mute); font-family: "Barlow", sans-serif; font-size: 12px; padding: 2px 8px; }
176
.file-diff { background: var(--panel); border: 1px solid var(--line); margin: 0 0 14px; }
177
.file-diff > header { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--soft); border-bottom: 1px solid var(--line); }
178
.file-diff .counts { margin-left: auto; font-family: ui-monospace, monospace; font-size: 12px; }
179
.counts .add { color: var(--add-ink); }
180
.counts .del { color: var(--del-ink); }
181
.kind { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; padding: 1px 6px; border: 1px solid var(--line); color: var(--mute); }
182
.kind-added { color: var(--ok); border-color: var(--ok); }
183
.kind-removed { color: var(--bad); border-color: var(--bad); }
184
.kind-renamed, .kind-modified { color: var(--acc); border-color: var(--acc); }
185
nav.files { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 0 0 12px; }
186
187
/* history */
188
.hist { background: var(--panel); border: 1px solid var(--line); }
189
.hrow { display: flex; align-items: stretch; border-bottom: 1px solid var(--line); }
190
.hrow:last-child { border-bottom: 0; }
191
.hrow svg.lanes { flex: 0 0 auto; display: block; }
192
.lane { stroke: var(--band); stroke-width: 2; fill: none; }
193
.lane.none { stroke: none; }
194
.lane.dashed { stroke-dasharray: 3 3; stroke: var(--dim); }
195
.node { fill: var(--acc-2); stroke: var(--acc); stroke-width: 1.5; }
196
.node.head { fill: var(--now); stroke: var(--ink); stroke-width: 1.5; }
197
.node.res { fill: var(--ok); }
198
.chg { display: flex; justify-content: space-between; align-items: center; gap: 14px; padding: 8px 12px; flex: 1; min-width: 0; }
199
.chg + .chg, .chg:only-child { border-bottom: 1px solid var(--line); }
200
.hrow .chg { border-bottom: 0; }
201
.chg .title { color: var(--ink); font-weight: 500; }
202
.chg .meta { color: var(--mute); font-size: 12px; margin-top: 2px; }
203
.chg-side { display: flex; align-items: center; gap: 10px; white-space: nowrap; }
204
.chg .hash { font-size: 9px; }
205
.pager { display: flex; gap: 8px; justify-content: center; margin-top: 12px; }
206
207
@media (max-width: 760px) {
208
  header { flex-wrap: wrap; }
209
  .side-layout { grid-template-columns: 1fr; }
210
  .foot { grid-template-columns: 1fr; }
211
  main { padding: 10px 14px 20px; }
212
  .band { padding: 0 8px; overflow-x: auto; }
213
  .tabs-in { padding: 0 8px; }
214
}
215
216
/* syntax (syntect scopes, spaced classes) */
217
.source .keyword, .source .storage { color: var(--sy-kw); }
218
.source .string { color: var(--sy-str); }
219
.source .constant.numeric, .source .constant.language { color: var(--sy-num); }
220
.source .constant { color: var(--sy-const); }
221
.source .comment { color: var(--sy-cmt); font-style: italic; }
222
.source .entity.name.function, .source .support.function, .source .meta.function-call .variable.function { color: var(--sy-fn); }
223
.source .entity.name.type, .source .storage.type, .source .support.type, .source .entity.name.struct, .source .entity.name.enum, .source .entity.name.class { color: var(--sy-ty); }
224
.source .variable { color: var(--sy-var); }
225
.source .entity.name.tag { color: var(--sy-kw); }
226
.source .entity.other.attribute-name { color: var(--sy-const); }
227
.source .markup.heading { color: var(--sy-ty); font-weight: 600; }
228
.source .markup.bold { font-weight: 600; }
229
.source .markup.italic { font-style: italic; }
230
.source .markup.raw { color: var(--sy-str); }
231
.source .markup.underline.link { color: var(--sy-fn); }
232
233
/* forms */
234
form.card { max-width: 460px; background: var(--panel); border: 1px solid var(--line); padding: 18px 20px; margin: 0 0 16px; }
235
form.card.wide { max-width: 720px; }
236
form.card label, .field label { display: block; font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); margin: 10px 0 4px; }
237
form.card input[type=text], form.card input[type=password], form.card input[type=email], form.card input[type=search], form.card input[type=number], form.card textarea, form.card select,
238
.field input, .field select, .field textarea { width: 100%; background: var(--bg); border: 1px solid var(--line); color: var(--ink); padding: 7px 10px; font: inherit; }
239
form.card input:focus, form.card textarea:focus, form.card select:focus { outline: 2px solid var(--band); outline-offset: 0; }
240
form.card button[type=submit], form.card .primary { background: var(--acc); color: var(--now-ink); border: 0; margin-top: 12px; }
241
form.card .row { display: flex; gap: 10px; align-items: end; }
242
form.card .row > * { flex: 1; }
243
form.card .choice { display: flex; gap: 12px; flex-wrap: wrap; margin: 6px 0; }
244
form.card .choice label { display: inline-flex; gap: 6px; align-items: center; text-transform: none; letter-spacing: 0; font-size: 14px; color: var(--ink); margin: 0; }
245
.note { color: var(--ok); }
246
.error { color: var(--bad); }
247
details.danger { border: 1px solid var(--bad); padding: 10px 14px; margin-top: 18px; }
248
details.danger summary { color: var(--bad); cursor: pointer; font-weight: 600; }
249
.secret { font-family: ui-monospace, monospace; background: var(--bg); border: 1px solid var(--acc); padding: 8px 10px; word-break: break-all; }
250
.qr { background: #fff; display: inline-block; padding: 8px; }
251
ul.codes { columns: 2; font-family: ui-monospace, monospace; }
252
table.small td, table.small th { padding: 5px 8px; font-size: 13px; }
253
form.tiny { display: inline; margin: 0; }
254
form.tiny button { padding: 1px 6px; font-size: 10px; }
255
256
/* proposals */
257
.comment { background: var(--panel); border: 1px solid var(--line); padding: 10px 14px; margin: 0 0 10px; }
258
.comment .who { font-weight: 600; }
259
.comment .body { margin-top: 6px; }
260
.comment .body p:last-child { margin: 0; }
261
.comment.resolved { opacity: .6; }
262
.comment.review-approve { border-color: var(--ok); }
263
.comment.review-changes { border-color: var(--bad); }
264
td.thread { background: var(--soft); padding: 8px 12px; }
265
td.thread .comment { margin: 4px 0; font-family: "Barlow", sans-serif; font-size: 14px; }
266
details.linecomment { display: inline; float: right; }
267
details.linecomment summary { list-style: none; cursor: pointer; color: var(--dim); font-size: 12px; padding: 0 4px; }
268
details.linecomment summary:hover { color: var(--acc); }
269
details.linecomment form { font-family: "Barlow", sans-serif; background: var(--panel); border: 1px solid var(--acc); padding: 8px; margin: 4px 0; }
270
details.linecomment textarea { width: 100%; font: inherit; background: var(--bg); color: var(--ink); border: 1px solid var(--line); }
271
272
/* issues and notifications */
273
.label { display: inline-block; font-size: 11px; padding: 1px 7px; margin-right: 4px; border: 1px solid var(--c, var(--acc)); color: var(--c, var(--acc)); vertical-align: middle; }
274
.timeline { margin: 0 0 8px 14px; }
275
details.inline-edit { display: inline; margin-left: 8px; }
276
details.inline-edit summary { cursor: pointer; color: var(--acc); }
277
details.inline-edit input, details.inline-edit textarea { width: 100%; font: inherit; background: var(--bg); color: var(--ink); border: 1px solid var(--line); margin: 4px 0; }
278
.tiny-form input[type=text], .tiny-form select { background: var(--bg); border: 1px solid var(--line); color: var(--ink); padding: 3px 6px; font: inherit; font-size: 13px; }
279
header nav .bell { color: var(--ink); position: relative; font-size: 16px; padding: 0 6px; }
280
header nav .bell .count { position: absolute; top: -6px; right: -4px; background: var(--acc); color: var(--now-ink); font-size: 10px; font-weight: 600; padding: 0 5px; border-radius: 9px; }
281
ul.rows li.unread { border-color: var(--acc); }
282
mark { background: color-mix(in srgb, var(--acc) 30%, transparent); color: inherit; }