OXYGENHUB
# 967ef74f6fd9 oxygenhub / templates / style.css
42.7 KiB · CSS · last changed Versions on the hub: About page, /api/v1/version, footer, oh --version 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-acc:#00f0ff; --band-line:rgba(7,12,24,.5); --now:#00f0ff; --now-ink:#070c18;
16
  --ok:#5fe3a1; --bad:#ff5e7a; --warn:#b48cff;
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:#9fd3ff; --sy-cmt:#7a86a4; --sy-fn:#00e0f0; --sy-ty:#c6a0ff; --sy-var:#e6ecf7; --sy-const:#b48cff;
21
  color-scheme: dark;
22
}
23
:root[data-theme="light"] {
24
  --bg:#f4f7fc; --panel:#ffffff; --soft:#e9eef8; --ink:#1b2333; --mute:#5f6a81; --line:#d6dded; --dim:#b3bccf;
25
  --acc:#0064e0; --acc-2:#00b8d4; --band:#0b3f9e; --band-ink:#ffffff; --band-acc:#9ff3ff; --band-line:rgba(255,255,255,.25); --now:#0064e0; --now-ink:#ffffff;
26
  --ok:#1a7850; --bad:#c62d47; --warn:#6b3fd1;
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:#1a7850; --sy-num:#1e63b8; --sy-cmt:#606b81; --sy-fn:#007394; --sy-ty:#7a3fd1; --sy-var:#1b2333; --sy-const:#6b3fd1;
30
  color-scheme: light;
31
}
32
33
* { box-sizing: border-box; }
34
/* Room for the scroll bar always, so nothing shifts when it comes and goes. */
35
html { background: var(--bg); scrollbar-gutter: stable; }
36
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; }
37
a { color: var(--acc); text-decoration: none; }
38
a:hover { text-decoration: underline; }
39
code, pre, kbd, .mono { font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 13px; }
40
.px { font-family: "Press Start 2P", "Silkscreen", monospace; font-size: 13px; }
41
.pxs { font-family: "Press Start 2P", "Silkscreen", monospace; font-size: 11px; }
42
h1, h2, h3 { margin: 0; }
43
h2 { font-size: 16px; font-weight: 600; margin: 0 0 8px; }
44
h3 { font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); margin: 14px 0 6px; }
45
p { margin: 0 0 10px; }
46
.small { font-size: 12px; }
47
.mute { color: var(--mute); }
48
.dim { color: var(--mute); }
49
.center { text-align: center; }
50
.right { text-align: right; }
51
.empty { color: var(--mute); padding: 22px; text-align: center; border: 1px dashed var(--line); }
52
.lead { font-size: 16px; }
53
kbd { background: var(--soft); border: 1px solid var(--line); padding: 1px 5px; font-size: 11px; }
54
55
/* shell */
56
header { background: var(--panel); border-bottom: 1px solid var(--line); padding: 14px 22px; display: flex; align-items: center; gap: 16px; }
57
.brand { display: inline-flex; align-items: center; gap: 10px; color: var(--ink); }
58
.brand svg { height: 22px; width: auto; }
59
.brand em { font-style: normal; color: var(--acc); }
60
.brand:hover { text-decoration: none; }
61
header nav { margin-left: auto; display: flex; gap: 8px; align-items: center; }
62
header nav .me { color: var(--ink); font-weight: 600; padding: 0 6px; }
63
header nav .theme-toggle { background: none; border: 1px solid var(--line); color: var(--ink); font-size: 15px; line-height: 1; padding: 4px 7px; cursor: pointer; }
64
header nav .theme-toggle:hover { border-color: var(--acc); }
65
fieldset.choices { border: 0; padding: 0; margin: 0 0 10px; display: flex; gap: 18px; flex-wrap: wrap; }
66
fieldset.choices legend { padding: 0; margin-bottom: 6px; }
67
form.card label.choice, label.choice { display: inline-flex; gap: 6px; align-items: center; font-weight: 400; text-transform: none; letter-spacing: 0; font-size: 14px; color: var(--ink); margin: 0; }
68
form.inline { display: inline; margin: 0; }
69
.band a.admin { color: var(--band-acc); }
70
form.find { margin: 0; flex: 0 1 320px; }
71
form.find input { width: 100%; background: var(--bg); border: 1px solid var(--line); color: var(--ink); padding: 6px 10px; font: inherit; }
72
form.find input:focus { outline: 2px solid var(--band); outline-offset: 0; }
73
.band { background: var(--band); display: flex; align-items: stretch; padding: 0 22px; }
74
.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); }
75
.band a:first-child { border-left: 1px solid var(--band-line); }
76
.band a.on { box-shadow: inset 0 -3px 0 var(--acc); background: rgba(0,0,0,.18); }
77
.band a:hover { text-decoration: none; background: rgba(0,0,0,.12); }
78
.band .grow { flex: 1; }
79
.band a.dim { opacity: .6; border: 0; }
80
.tabs { background: var(--panel); border-bottom: 1px solid var(--line); }
81
/* The repository bar is as wide as its contents need: at least the page
82
   column (so it lines up with it), wider for a long name, and it wraps only
83
   when the window itself is too narrow. */
84
.tabs-in { width: fit-content; min-width: min(1180px, 100%); max-width: 100%; box-sizing: border-box; margin: 0 auto; padding: 0 22px; display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }
85
.tabs .crumb { white-space: nowrap; }
86
.tabs .crumb { margin-right: 18px; padding: 10px 0; font-size: 16px; }
87
.tabs a:not(.crumb a) { padding: 10px 12px; color: var(--ink); font-size: 13px; }
88
.tabs a.on { border-bottom: 2px solid var(--acc); font-weight: 600; }
89
.tabs a:hover { text-decoration: none; background: var(--soft); }
90
main { flex: 1; width: 100%; max-width: 1180px; margin: 0 auto; padding: 14px 22px 28px; }
91
main.wide { max-width: none; }
92
footer { background: var(--panel); border-top: 1px solid var(--line); margin-top: 28px; }
93
.foot { max-width: 1180px; margin: 0 auto; padding: 22px; display: grid; grid-template-columns: 1fr auto; gap: 22px; }
94
.foot .cols { display: flex; gap: 32px; }
95
.foot .cols a { display: block; font-size: 13px; }
96
.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; }
97
.head h1 { font-size: 30px; font-weight: 300; color: var(--mute); }
98
.head h1 small { display: block; font-size: 13px; color: var(--acc); font-weight: 400; }
99
.strip { padding: 8px 12px; margin: 0 0 12px; border: 1px solid; font-size: 13px; }
100
.strip.warn { border-color: var(--warn); color: var(--warn); background: color-mix(in srgb, var(--warn) 10%, transparent); }
101
.strip.bad { border-color: var(--bad); color: var(--bad); background: color-mix(in srgb, var(--bad) 10%, transparent); }
102
.strip a { color: inherit; text-decoration: underline; }
103
.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); }
104
.sheet td { padding: 2px 8px 2px 0; font-size: 13px; }
105
106
/* buttons, tags, chips */
107
button, a.go, button.go, summary.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; }
108
button:hover, a.go:hover { background: var(--acc); color: var(--now-ink); text-decoration: none; }
109
button.small, a.go.small { padding: 2px 8px; font-size: 11px; }
110
.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; }
111
.tag.bad { color: var(--bad); }
112
.tag.warn { color: var(--warn); }
113
.tag.head { color: var(--now-ink); background: var(--now); }
114
.chip { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 12px; background: var(--soft); padding: 1px 6px; border: 1px solid var(--line); }
115
.lbl { display: inline-block; font-size: 11px; padding: 1px 7px; margin-right: 4px; border: 1px solid; vertical-align: middle; }
116
.lbl-bm { color: var(--band-ink); background: var(--band); border-color: var(--band); }
117
.lbl-tag { color: var(--acc); border-color: var(--acc); }
118
.sig { display: inline-block; width: 1.2em; text-align: center; font-weight: 600; }
119
.sig-valid { color: var(--ok); }
120
.sig-unsigned { color: var(--mute); }
121
.sig-invalid { color: var(--bad); }
122
.sig-revoked { color: var(--warn); }
123
124
/* lists, tables, panels */
125
ul.plain { list-style: none; margin: 0; padding: 0; }
126
ul.plain li { padding: 2px 0; }
127
ul.rows { list-style: none; margin: 0; padding: 0; }
128
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; }
129
ul.rows .name { font-size: 16px; }
130
ul.rows p { margin: 4px 0 0; color: var(--mute); }
131
.table { border: 1px solid var(--line); overflow-x: auto; }
132
table { border-collapse: collapse; width: 100%; }
133
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); }
134
td { padding: 7px 10px; background: var(--panel); border-bottom: 1px solid var(--line); vertical-align: top; }
135
td.px { color: var(--acc); }
136
.panel { background: var(--panel); border: 1px solid var(--line); padding: 14px 16px; margin-bottom: 14px; }
137
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; }
138
dl.facts dt { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--mute); padding-top: 3px; }
139
dl.facts dd { margin: 0; }
140
code.full { word-break: break-all; }
141
pre.msg { background: var(--panel); border: 1px solid var(--line); padding: 10px 12px; white-space: pre-wrap; font-family: inherit; font-size: 14px; }
142
pre.marked { background: var(--panel); border: 1px solid var(--bad); padding: 10px 12px; overflow-x: auto; }
143
144
/* repository layout */
145
.side-layout { display: grid; grid-template-columns: 1fr 280px; gap: 22px; }
146
.side h3:first-child { margin-top: 0; }
147
.dash h2 { font-size: 15px; margin: 18px 0 8px; }
148
.dash h2:first-child { margin-top: 0; }
149
.dash .side .bar { justify-content: space-between; }
150
.dash .side .bar h3 { margin: 0; }
151
ul.feed { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); background: var(--panel); }
152
ul.feed li { padding: 8px 14px; border-top: 1px solid var(--line); }
153
ul.feed li:first-child { border-top: 0; }
154
ul.feed .who { font-weight: 600; }
155
.clone { display: flex; gap: 6px; align-items: center; }
156
.clone code { background: var(--bg); border: 1px solid var(--line); padding: 4px 8px; flex: 1; overflow-x: auto; white-space: nowrap; }
157
.quickstart { background: var(--panel); border: 1px solid var(--line); padding: 16px 20px; }
158
.quickstart h2 { margin-top: 0; }
159
.quickstart h3 { font-size: 14px; margin: 18px 0 6px; }
160
.cmds { display: flex; gap: 6px; align-items: flex-start; }
161
.cmds pre { flex: 1; margin: 0; background: var(--bg); border: 1px solid var(--line); padding: 8px 10px; overflow-x: auto; }
162
.bar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 10px; }
163
.ref { color: var(--acc); }
164
.crumbs a { color: var(--ink); }
165
table.tree td { padding: 6px 10px; }
166
table.tree td.g { width: 1.6em; color: var(--acc); text-align: center; }
167
table.tree td.last { color: var(--mute); max-width: 520px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
168
table.tree td.last a { color: var(--mute); }
169
table.tree td.age { width: 9em; text-align: right; white-space: nowrap; }
170
article.doc { max-width: 60rem; background: var(--panel); border: 1px solid var(--line); padding: 18px 24px; margin-top: 14px; }
171
article.doc h1 { font-size: 26px; font-weight: 500; margin: 0 0 12px; }
172
article.doc h2 { font-size: 20px; margin: 18px 0 8px; }
173
article.doc h3 { text-transform: none; letter-spacing: 0; font-size: 16px; color: var(--ink); }
174
article.doc pre { background: var(--bg); border: 1px solid var(--line); padding: 10px 12px; overflow-x: auto; }
175
article.doc code { background: var(--soft); padding: 0 3px; }
176
article.doc pre code { background: none; padding: 0; }
177
article.doc table { width: auto; }
178
article.doc img { max-width: 100%; }
179
article.doc blockquote { border-left: 3px solid var(--band); margin: 0; padding: 2px 12px; color: var(--mute); }
180
181
/* files and diffs */
182
.filebox { background: var(--panel); border: 1px solid var(--line); }
183
.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); }
184
.modes a { font-size: 12px; padding: 2px 8px; border: 1px solid var(--line); margin-left: 4px; color: var(--ink); }
185
.modes a.on { border-color: var(--acc); color: var(--acc); }
186
table.code { width: 100%; }
187
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; }
188
table.code td.n { width: 1%; min-width: 3em; text-align: right; color: var(--mute); user-select: none; cursor: pointer; padding-right: 12px; }
189
table.code td.n:hover { color: var(--acc); }
190
table.code td.t pre { margin: 0; white-space: pre; }
191
table.code tr.hl td { background: color-mix(in srgb, var(--acc) 18%, transparent); }
192
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; }
193
table.code td.blame .px { font-size: 9px; }
194
table.code td.blame .who { color: var(--ink); }
195
table.diff td.s { width: 1%; user-select: none; color: var(--mute); }
196
table.diff tr.add td { background: var(--add); color: var(--add-ink); }
197
table.diff tr.del td { background: var(--del); color: var(--del-ink); }
198
table.diff tr.gap td { background: var(--soft); color: var(--mute); font-family: "Barlow", sans-serif; font-size: 12px; padding: 2px 8px; }
199
.file-diff { background: var(--panel); border: 1px solid var(--line); margin: 0 0 14px; }
200
.file-diff > header, .file-diff > summary { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--soft); border-bottom: 1px solid var(--line); }
201
.file-diff > summary { cursor: pointer; list-style: none; }
202
.file-diff > summary::-webkit-details-marker { display: none; }
203
.file-diff > summary::before { content: "▾"; color: var(--mute); width: 1em; }
204
.file-diff:not([open]) > summary::before { content: "▸"; }
205
.file-diff:not([open]) > summary { border-bottom: 0; }
206
.diff-bar { display: flex; gap: 16px; align-items: center; margin: 0 0 10px; }
207
.diff-bar .modes a { padding: 3px 10px; border: 1px solid var(--line); color: var(--mute); }
208
.diff-bar .modes a.on { color: var(--ink); border-color: var(--acc); }
209
table.diff .wx { border-radius: 2px; }
210
table.diff tr.add .wx, table.diff td.add .wx { background: color-mix(in srgb, var(--add-ink) 28%, transparent); }
211
table.diff tr.del .wx, table.diff td.del .wx { background: color-mix(in srgb, var(--del-ink) 28%, transparent); }
212
table.diff.split { table-layout: fixed; }
213
table.diff.split col.n { width: 3.5em; }
214
table.diff.split td.t { overflow-x: auto; }
215
table.diff.split td.t pre { white-space: pre-wrap; word-break: break-word; }
216
table.diff.split td.add { background: var(--add); color: var(--add-ink); }
217
table.diff.split td.del { background: var(--del); color: var(--del-ink); }
218
table.diff.split td.none { background: var(--soft); }
219
table.diff.split td.t.mid { border-left: 1px solid var(--line); }
220
.file-diff .counts { margin-left: auto; font-family: ui-monospace, monospace; font-size: 12px; }
221
.counts .add { color: var(--add-ink); }
222
.counts .del { color: var(--del-ink); }
223
.kind { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; padding: 1px 6px; border: 1px solid var(--line); color: var(--mute); }
224
.kind-added { color: var(--ok); border-color: var(--ok); }
225
.kind-removed { color: var(--bad); border-color: var(--bad); }
226
.kind-renamed, .kind-modified { color: var(--acc); border-color: var(--acc); }
227
nav.files { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 0 0 12px; }
228
229
/* history */
230
.hist { background: var(--panel); border: 1px solid var(--line); }
231
.hrow { display: flex; align-items: stretch; border-bottom: 1px solid var(--line); }
232
.hrow:last-child { border-bottom: 0; }
233
.hrow svg.lanes { flex: 0 0 auto; display: block; }
234
.lane { stroke: var(--band); stroke-width: 2; fill: none; }
235
.lane.none { stroke: none; }
236
.lane.dashed { stroke-dasharray: 3 3; stroke: var(--dim); }
237
.node { fill: var(--acc-2); stroke: var(--acc); stroke-width: 1.5; }
238
.node.head { fill: var(--now); stroke: var(--ink); stroke-width: 1.5; }
239
.node.res { fill: var(--ok); }
240
/* Swimlanes (hub spec §6.7): cards on lanes, dependency edges between them. */
241
.lanes-board { border: 1px solid var(--line); background: var(--panel); padding: 6px; }
242
.lanes-board rect.node { fill: var(--soft); stroke: var(--acc); }
243
.lanes-board rect.node.head { stroke: var(--now); stroke-width: 2; }
244
.lanes-board a:hover rect.node { fill: var(--line); }
245
.lanes-board text { fill: var(--ink); font-size: 11px; }
246
.chg { display: flex; justify-content: space-between; align-items: center; gap: 14px; padding: 8px 12px; flex: 1; min-width: 0; }
247
.chg + .chg, .chg:only-child { border-bottom: 1px solid var(--line); }
248
.hrow .chg { border-bottom: 0; }
249
.chg .title { color: var(--ink); font-weight: 500; }
250
.chg .meta { color: var(--mute); font-size: 12px; margin-top: 2px; }
251
.chg-side { display: flex; align-items: center; gap: 10px; white-space: nowrap; }
252
.chg .hash { font-size: 9px; }
253
.pager { display: flex; gap: 8px; justify-content: center; margin-top: 12px; }
254
255
@media (max-width: 760px) {
256
  header { flex-wrap: wrap; }
257
  .side-layout { grid-template-columns: 1fr; }
258
  .foot { grid-template-columns: 1fr; }
259
  main { padding: 10px 14px 20px; }
260
  .band { padding: 0 8px; overflow-x: auto; }
261
  .tabs-in { padding: 0 8px; }
262
}
263
264
/* syntax (syntect scopes as classes prefixed sy-, so no scope name can collide with the page's own classes) */
265
.sy-source .sy-keyword, .sy-source .sy-storage { color: var(--sy-kw); }
266
.sy-source .sy-string { color: var(--sy-str); }
267
.sy-source .sy-constant.sy-numeric, .sy-source .sy-constant.sy-language { color: var(--sy-num); }
268
.sy-source .sy-constant { color: var(--sy-const); }
269
.sy-source .sy-comment { color: var(--sy-cmt); font-style: italic; }
270
.sy-source .sy-entity.sy-name.sy-function, .sy-source .sy-support.sy-function, .sy-source .sy-meta.sy-function-call .sy-variable.sy-function { color: var(--sy-fn); }
271
.sy-source .sy-entity.sy-name.sy-type, .sy-source .sy-storage.sy-type, .sy-source .sy-support.sy-type, .sy-source .sy-entity.sy-name.sy-struct, .sy-source .sy-entity.sy-name.sy-enum, .sy-source .sy-entity.sy-name.sy-class { color: var(--sy-ty); }
272
.sy-source .sy-variable { color: var(--sy-var); }
273
.sy-source .sy-entity.sy-name.sy-tag { color: var(--sy-kw); }
274
.sy-source .sy-entity.sy-other.sy-attribute-name { color: var(--sy-const); }
275
.sy-source .sy-markup.sy-heading { color: var(--sy-ty); font-weight: 600; }
276
.sy-source .sy-markup.sy-bold { font-weight: 600; }
277
.sy-source .sy-markup.sy-italic { font-style: italic; }
278
.sy-source .sy-markup.sy-raw { color: var(--sy-str); }
279
.sy-source .sy-markup.sy-underline.sy-link { color: var(--sy-fn); }
280
281
/* forms */
282
form.card { max-width: 460px; background: var(--panel); border: 1px solid var(--line); padding: 18px 20px; margin: 0 0 16px; }
283
form.card.wide { max-width: 720px; }
284
form.card label, .field label { display: block; font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); margin: 10px 0 4px; }
285
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,
286
.field input, .field select, .field textarea { width: 100%; background: var(--bg); border: 1px solid var(--line); color: var(--ink); padding: 7px 10px; font: inherit; }
287
form.card input:focus, form.card textarea:focus, form.card select:focus { outline: 2px solid var(--band); outline-offset: 0; }
288
form.card button[type=submit], form.card .primary { background: var(--acc); color: var(--now-ink); border: 0; margin-top: 12px; }
289
form.card .row { display: flex; gap: 10px; align-items: end; }
290
form.card .row > * { flex: 1; }
291
form.card .choice { display: flex; gap: 12px; flex-wrap: wrap; margin: 6px 0; }
292
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; }
293
.note { color: var(--ok); }
294
.error { color: var(--bad); }
295
details.danger { border: 1px solid var(--bad); padding: 10px 14px; margin-top: 18px; }
296
details.danger summary { color: var(--bad); cursor: pointer; font-weight: 600; }
297
.secret { font-family: ui-monospace, monospace; background: var(--bg); border: 1px solid var(--acc); padding: 8px 10px; word-break: break-all; }
298
.qr { background: #fff; display: inline-block; padding: 8px; }
299
ul.codes { columns: 2; font-family: ui-monospace, monospace; }
300
table.small td, table.small th { padding: 5px 8px; font-size: 13px; }
301
form.tiny { display: inline; margin: 0; }
302
form.tiny button { padding: 1px 6px; font-size: 10px; }
303
304
/* proposals */
305
.comment { background: var(--panel); border: 1px solid var(--line); padding: 10px 14px; margin: 0 0 10px; }
306
.comment .who { font-weight: 600; }
307
.comment .body { margin-top: 6px; }
308
.comment .body p:last-child { margin: 0; }
309
.comment.resolved { opacity: .6; }
310
.comment.review-approve { border-color: var(--ok); }
311
.comment.review-changes { border-color: var(--bad); }
312
td.thread { background: var(--soft); padding: 8px 12px; }
313
td.thread .comment { margin: 4px 0; font-family: "Barlow", sans-serif; font-size: 14px; }
314
details.linecomment { display: inline; float: right; }
315
details.linecomment summary { list-style: none; cursor: pointer; color: var(--mute); font-size: 12px; padding: 0 4px; }
316
details.linecomment summary:hover { color: var(--acc); }
317
details.linecomment form { font-family: "Barlow", sans-serif; background: var(--panel); border: 1px solid var(--acc); padding: 8px; margin: 4px 0; }
318
details.linecomment textarea { width: 100%; font: inherit; background: var(--bg); color: var(--ink); border: 1px solid var(--line); }
319
320
/* issues and notifications */
321
.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; }
322
.timeline { margin: 0 0 8px 14px; }
323
details.inline-edit { display: inline; margin-left: 8px; }
324
details.inline-edit summary { cursor: pointer; color: var(--acc); }
325
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; }
326
.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; }
327
header nav .bell { color: var(--ink); position: relative; font-size: 16px; padding: 0 6px; }
328
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; }
329
ul.rows li.unread { border-color: var(--acc); }
330
mark { background: color-mix(in srgb, var(--acc) 30%, transparent); color: inherit; }
331
332
/* editor */
333
form.editor { max-width: none; }
334
form.editor textarea.code { width: 100%; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 13px; background: var(--bg); color: var(--ink); border: 1px solid var(--line); padding: 8px; }
335
.cm-host { border: 1px solid var(--line); margin: 8px 0; min-height: 360px; max-height: 70vh; overflow: auto; font-size: 13px; }
336
.cm-host .cm-editor { min-height: 360px; }
337
button.danger-btn { color: var(--bad); border-color: var(--bad); }
338
button:disabled { opacity: .45; cursor: not-allowed; }
339
340
/* EasyMDE in the hub's colours */
341
.EasyMDEContainer .CodeMirror { background: var(--bg); color: var(--ink); border-color: var(--line); }
342
.EasyMDEContainer .CodeMirror-cursor { border-color: var(--acc); }
343
.editor-toolbar { border-color: var(--line); background: var(--soft); opacity: 1; }
344
.editor-toolbar button.mde-btn { color: var(--ink); border: 0; background: transparent; font-weight: 600; font-size: 12px; text-transform: none; letter-spacing: 0; padding: 2px 6px; width: auto; }
345
.editor-toolbar button.mde-btn:hover, .editor-toolbar button.active { background: var(--panel); color: var(--acc); }
346
.editor-preview, .editor-preview-side { background: var(--panel); color: var(--ink); }
347
348
/* code search */
349
.inline-find { flex: 0 1 220px; }
350
.hits .hit { margin: 0; padding: 4px 8px; border-bottom: 1px solid var(--line); background: var(--panel); font-size: 13px; overflow-x: auto; white-space: nowrap; }
351
.hits .hit code { background: none; }
352
353
.scopes label { display: block; text-transform: none; letter-spacing: 0; font-size: 14px; color: var(--ink); margin: 4px 0; }
354
355
/* avatars and owner pages */
356
img.avatar { display: inline-block; vertical-align: middle; border: 1px solid var(--line); object-fit: cover; }
357
img.avatar.xs { width: 18px; height: 18px; }
358
img.avatar.sm { width: 24px; height: 24px; }
359
img.avatar.xl { width: 100%; max-width: 240px; height: auto; aspect-ratio: 1; }
360
.profile .who-card h1.display { font-size: 24px; font-weight: 600; margin: 12px 0 0; }
361
.profile .who-card .handle { font-size: 18px; color: var(--mute); margin: 2px 0 10px; }
362
.profile .who-card .bio { margin: 0 0 10px; }
363
.profile .who-card .facts-list li { padding: 2px 0; }
364
.profile h2 { font-size: 15px; margin: 0 0 8px; }
365
.profile h2 ~ h2 { margin-top: 18px; }
366
.profile .keys li { margin-bottom: 6px; }
367
.profile .side-layout, .side-layout.profile { grid-template-columns: 260px 1fr; }
368
@media (max-width: 760px) { .side-layout.profile { grid-template-columns: 1fr; } img.avatar.xl { max-width: 120px; } }
369
370
/* topics, stars, explore */
371
.topics { margin: 4px 0 0; display: flex; flex-wrap: wrap; gap: 4px; }
372
.topic { display: inline-block; font-size: 12px; padding: 1px 8px; border-radius: 10px; background: color-mix(in srgb, var(--acc) 14%, transparent); color: var(--acc); }
373
.topic:hover { text-decoration: none; background: color-mix(in srgb, var(--acc) 24%, transparent); }
374
.explore-bar input[type=search] { flex: 1 1 240px; }
375
.counts-line span { margin-right: 2px; }
376
.count-chip { display: inline-block; min-width: 1.6em; padding: 0 6px; margin-left: 4px; border-radius: 9px; background: var(--soft); color: var(--mute); font-size: 11px; text-align: center; }
377
.pager { display: flex; gap: 12px; align-items: center; justify-content: center; margin: 14px 0; }
378
379
/* repository page: the clone command sits at the right of the top bar, the README spans the column */
380
.top-clone { margin-left: auto; flex: 0 1 380px; min-width: 200px; }
381
.top-clone code { font-size: 12px; overflow: hidden; text-overflow: ellipsis; }
382
.latest-line { margin: -4px 0 8px; }
383
article.doc.readme { max-width: none; }
384
385
/* settings pages: section headings on the left, every section the same width on the right */
386
.sectioned { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 28px; align-items: start; }
387
.section-nav { position: sticky; top: 14px; display: flex; flex-direction: column; gap: 2px; }
388
.section-nav a { padding: 6px 12px; border-left: 2px solid var(--line); color: var(--mute); font-size: 14px; }
389
.section-nav a:hover, .section-nav a.on { border-left-color: var(--acc); color: var(--ink); text-decoration: none; }
390
.sections > form.card, .sections > form.card.wide, .sections > .panel, .sections > details { max-width: none; width: 100%; box-sizing: border-box; scroll-margin-top: 14px; }
391
.sections .panel form.card { max-width: 720px; }
392
.sections > details > form.card { max-width: none; }
393
@media (max-width: 760px) {
394
  .sectioned { grid-template-columns: 1fr; gap: 12px; }
395
  .section-nav { position: static; flex-direction: row; flex-wrap: wrap; }
396
  .section-nav a { border-left: 0; border-bottom: 2px solid var(--line); }
397
}
398
399
/* File view: tree sidebar, line bar, blame age (hub spec §6.6). */
400
.file-layout { display: grid; grid-template-columns: minmax(180px, 240px) minmax(0, 1fr); gap: 16px; align-items: start; }
401
.file-side { position: sticky; top: 12px; max-height: calc(100vh - 24px); overflow: auto; font-size: 13px; background: var(--panel); border: 1px solid var(--line); padding: 8px 0; }
402
.file-side .side-root { display: block; padding: 2px 12px 6px; font-weight: 600; }
403
.file-side ul { list-style: none; margin: 0; padding: 0; }
404
.file-side li a { display: block; padding: 2px 12px 2px calc(12px + var(--d, 0) * 14px); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
405
.file-side li a:hover { background: var(--soft); text-decoration: none; }
406
.file-side li.here a { background: color-mix(in srgb, var(--acc) 16%, transparent); font-weight: 600; box-shadow: inset 3px 0 0 var(--acc); }
407
.file-side .glyph { color: var(--mute); font-size: 10px; }
408
.file-main { min-width: 0; overflow-x: auto; }
409
.linebar { display: flex; align-items: center; gap: 8px; padding: 6px 12px; border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--acc) 8%, var(--panel)); }
410
.linebar[hidden] { display: none; }
411
.linebar [data-linebar-label] { margin-right: auto; }
412
table.code td.blame { box-shadow: inset 3px 0 0 color-mix(in srgb, var(--acc) calc(var(--age, 0) * 10%), transparent); }
413
table.code td.blame.age-0 { --age: 1; } table.code td.blame.age-1 { --age: 2; } table.code td.blame.age-2 { --age: 3; }
414
table.code td.blame.age-3 { --age: 4; } table.code td.blame.age-4 { --age: 5; } table.code td.blame.age-5 { --age: 6; }
415
table.code td.blame.age-6 { --age: 7; } table.code td.blame.age-7 { --age: 8; } table.code td.blame.age-8 { --age: 9; }
416
table.code td.blame.age-9 { --age: 10; }
417
table.code td.blame .before { color: var(--mute); margin-left: 4px; }
418
table.code td.blame .before:hover { color: var(--acc); text-decoration: none; }
419
@media (max-width: 900px) {
420
  .file-layout { grid-template-columns: minmax(0, 1fr); }
421
  .file-side { display: none; }
422
}
423
424
/* OxygenFlow (hub spec §13.2): runs, the job graph and logs. Status is
425
   carried by a glyph as well as colour. */
426
.flow-glyph { display: inline-block; width: 1.2em; text-align: center; font-weight: 700; }
427
.flow-glyph.st-passed, .node.st-passed .g { color: var(--ok); fill: var(--ok); }
428
.flow-glyph.st-failed, .flow-glyph.st-error, .node.st-failed .g, .node.st-error .g { color: var(--bad); fill: var(--bad); }
429
.flow-glyph.st-running, .node.st-running .g { color: var(--acc); fill: var(--acc); }
430
.flow-glyph.st-queued, .flow-glyph.st-skipped, .node.st-queued .g, .node.st-skipped .g { color: var(--mute); fill: var(--mute); }
431
.flow-glyph.st-running, .node.st-running .g { animation: flow-pulse 1.2s ease-in-out infinite; }
432
@keyframes flow-pulse { 50% { opacity: .35; } }
433
@media (prefers-reduced-motion: reduce) { .flow-glyph.st-running, .node.st-running .g { animation: none; } }
434
.flow-dots .flow-glyph { width: 1em; }
435
.flow-graph-box { overflow-x: auto; padding: 12px; }
436
.flow-graph { display: block; max-width: none; font-family: "Barlow", sans-serif; }
437
.flow-graph .edge { fill: none; stroke: var(--line); stroke-width: 2; }
438
.flow-graph .edge.st-passed { stroke: color-mix(in srgb, var(--ok) 60%, var(--line)); }
439
.flow-graph .edge.st-failed, .flow-graph .edge.st-error { stroke: color-mix(in srgb, var(--bad) 60%, var(--line)); stroke-dasharray: 4 4; }
440
.flow-graph .node rect { fill: var(--panel); stroke: var(--line); stroke-width: 1.5; }
441
.flow-graph .node:hover rect, .flow-graph .node:focus rect { stroke: var(--acc); }
442
.flow-graph .node.st-passed rect { stroke: var(--ok); }
443
.flow-graph .node.st-failed rect, .flow-graph .node.st-error rect { stroke: var(--bad); fill: color-mix(in srgb, var(--bad) 8%, var(--panel)); }
444
.flow-graph .node.st-running rect { stroke: var(--acc); fill: color-mix(in srgb, var(--acc) 8%, var(--panel)); }
445
.flow-graph .node.st-skipped rect { stroke-dasharray: 4 3; }
446
.flow-graph .node .g { font-size: 18px; }
447
.flow-graph text { font-family: "Barlow", sans-serif; stroke: none; }
448
.flow-graph .node .name { fill: var(--ink); font-size: 14px; font-weight: 600; }
449
.flow-graph .node .meta { fill: var(--mute); font-size: 11.5px; font-weight: 400; }
450
details.flow-job { padding: 0; margin-top: 10px; }
451
details.flow-job > summary { padding: 10px 12px; cursor: pointer; list-style-position: inside; }
452
details.flow-job .pad { padding: 0 12px 10px; margin: 0; }
453
pre.flow-log { margin: 0; padding: 8px 0; max-height: 70vh; overflow: auto; border-top: 1px solid var(--line); background: var(--soft); font-size: 12.5px; line-height: 1.5; }
454
pre.flow-log:empty { display: none; }
455
ul.flow-artifacts { list-style: none; margin: 0; padding: 6px 12px; border-top: 1px solid var(--line); }
456
ul.flow-artifacts li { padding: 2px 0; overflow-wrap: anywhere; }
457
ul.flow-artifacts select { font-size: 11px; }
458
pre.flow-log .ln { display: block; padding: 0 12px; white-space: pre-wrap; word-break: break-word; }
459
pre.flow-log .t { display: inline-block; min-width: 5.5em; color: var(--mute); user-select: none; }
460
pre.flow-log .s-err { color: color-mix(in srgb, var(--bad) 75%, var(--ink)); }
461
pre.flow-log .s-flow, pre.flow-log .s-console { color: var(--mute); font-style: italic; }
462
table.flow-runs td.st { width: 1.5em; }
463
464
/* Compare pickers (hub spec §6.3). */
465
.compare-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0 0 14px; }
466
.compare-bar label { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--mute); margin: 0; }
467
.compare-bar input { width: 16em; margin: 0; }
468
.compare-bar .swap { font-size: 18px; padding: 0 4px; }
469
.compare-bar .swap:hover { text-decoration: none; color: var(--ink); }
470
.compare-bar button { margin: 0; }
471
472
/* Help (hub spec §6.3). */
473
.help section.panel { padding: 16px 20px; scroll-margin-top: 14px; }
474
.help section.panel h2 { margin-top: 0; }
475
.help ol, .help ul { padding-left: 1.3em; }
476
.help li { margin: 4px 0; }
477
table.glossary td:first-child { white-space: nowrap; color: var(--mute); }
478
table.glossary td:nth-child(2) { white-space: nowrap; }
479
480
button.linkish { background: none; border: 0; padding: 0; margin: 0; color: var(--acc); font: inherit; cursor: pointer; text-transform: none; letter-spacing: normal; }
481
button.linkish:hover { text-decoration: underline; }
482
483
/* Inbox filters (hub spec §10). */
484
.inbox-nav h3 { margin: 14px 0 4px 12px; font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); }
485
.inbox .rows.threads .tag.dim { opacity: .7; }
486
487
/* Picture upload (hub spec §6.3). */
488
.picture-row { display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap; }
489
.picture-row img.avatar.xl { width: 96px; height: 96px; }
490
.picture-row > div { flex: 1; min-width: 220px; }
491
492
/* Accessibility and narrow screens (hub spec §6.13). */
493
:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
494
.band a:focus-visible, .tabs a:focus-visible { outline-offset: -2px; }
495
.skip { position: absolute; left: 12px; top: -48px; z-index: 100; padding: 8px 14px; background: var(--acc); color: var(--bg); font-weight: 600; }
496
.skip:focus { top: 8px; }
497
main:focus { outline: none; }
498
@media (max-width: 760px) {
499
  .tabs-in { overflow-x: auto; white-space: nowrap; scrollbar-width: thin; -webkit-overflow-scrolling: touch; }
500
  .tabs-in > * { flex-shrink: 0; }
501
  .band { overflow-x: auto; white-space: nowrap; }
502
  main table.list, main table.flow-runs { display: block; overflow-x: auto; }
503
  .sectioned { grid-template-columns: 1fr; }
504
  .section-nav { position: static; display: flex; flex-wrap: wrap; gap: 4px; }
505
  header .find { display: none; }
506
}
507
@media (prefers-reduced-motion: reduce) { * { scroll-behavior: auto !important; transition: none !important; } }
508
509
/* Projects (hub spec §8.2). */
510
.board { display: flex; gap: 12px; align-items: flex-start; overflow-x: auto; padding-bottom: 8px; }
511
.board-col { flex: 0 0 290px; background: var(--soft); border: 1px solid var(--line); padding: 8px; }
512
.board-col > header { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
513
.board-col h2 { font-size: 14px; margin: 2px 0 8px; }
514
.board-col ul.cards { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; min-height: 12px; }
515
.card-item { background: var(--panel); border: 1px solid var(--line); padding: 8px 10px; }
516
.card-item.note { border-left: 3px solid var(--warn); }
517
.card-item p { margin: 4px 0 0; }
518
.card-item .card-actions { margin-top: 6px; display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }
519
.card-item .card-actions select { width: auto; margin: 0; padding: 1px 4px; font-size: 12px; }
520
.board .add-card { margin-top: 8px; }
521
.board .add-card form { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
522
.board .inline-fields { display: flex; gap: 4px; }
523
.board .inline-fields select { width: 40%; }
524
.board .add-col form { display: flex; flex-direction: column; gap: 6px; }
525
.state-open { color: var(--ok); } .state-closed, .state-landed { color: var(--acc); }
526
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
527
.card-item.note > p { color: var(--ink); }
528
529
/* Webhooks (hub spec §12.2): long URLs wrap inside the panel. */
530
ul.hooks { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
531
li.hook { border: 1px solid var(--line); background: var(--soft); padding: 8px 12px; min-width: 0; }
532
.hook-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
533
code.hook-url { overflow-wrap: anywhere; word-break: break-all; }
534
li.hook p { margin: 4px 0; }
535
li.hook .hook-edit { margin-top: 4px; }
536
537
/* Repository overview: clone popover, contributors, languages, visibility. */
538
.clone-pop { position: relative; }
539
.clone-pop > summary { list-style: none; cursor: pointer; }
540
.clone-pop > summary::-webkit-details-marker { display: none; }
541
.clone-pop[open] > summary { background: var(--soft); }
542
.clone-panel { position: absolute; right: 0; top: calc(100% + 6px); z-index: 20; width: min(440px, 88vw); background: var(--panel); border: 1px solid var(--line); box-shadow: 0 6px 24px rgba(0,0,0,.25); padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
543
.clone-panel .clone input { flex: 1; min-width: 0; margin: 0; font-family: var(--mono, monospace); font-size: 12px; }
544
.clone-panel p { margin: 0; overflow-wrap: anywhere; }
545
.bar .inline-find { flex: 1 1 200px; }
546
ul.contributors li { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 4px 0; }
547
ul.contributors img.avatar.sm { width: 20px; height: 20px; vertical-align: middle; }
548
.avatar-none { display: inline-block; width: 20px; text-align: center; color: var(--mute); }
549
.lang-bar { display: flex; height: 8px; overflow: hidden; background: var(--soft); margin: 6px 0 8px; }
550
.lang-bar > span { display: block; height: 100%; }
551
.lang-bar > span + span { margin-left: 1px; }
552
ul.langs { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 13px; }
553
ul.langs li { margin: 0; }
554
.lang-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; vertical-align: middle; }
555
.vis { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; padding: 1px 8px; border: 1px solid var(--line); border-radius: 10px; margin-left: 8px; vertical-align: middle; }
556
.vis-public { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
557
.vis-internal { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
558
.vis-private { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, transparent); }
559
summary.go { display: inline-block; user-select: none; }
560
.clone-pop > summary.go:hover { background: var(--soft); }
561
562
/* Release trust (hub spec §9.1) */
563
.audit ul.checks li { padding: 3px 0; }
564
.audit ul.checks li .glyph { display: inline-block; width: 1.2em; text-align: center; font-weight: 700; }
565
.audit ul.checks li.pass .glyph { color: var(--ok); }
566
.audit ul.checks li.warn .glyph { color: var(--warn); }
567
.audit ul.checks li.fail .glyph { color: var(--bad); }
568
.audit-fail { border-left: 3px solid var(--bad); }
569
.audit-warn { border-left: 3px solid var(--warn); }
570
.audit-pass { border-left: 3px solid var(--ok); }
571
.trust-graph-wrap { overflow-x: auto; }
572
svg.trust-graph { min-width: 720px; width: 100%; height: auto; }
573
svg.trust-graph .edge { fill: none; stroke: var(--line); stroke-width: 1.5; }
574
svg.trust-graph .edge.dashed { stroke-dasharray: 5 4; stroke: var(--warn); }
575
svg.trust-graph .node rect { fill: var(--panel); stroke: var(--line); }
576
svg.trust-graph .node.pass rect { stroke: var(--ok); }
577
svg.trust-graph .node.warn rect { stroke: var(--warn); }
578
svg.trust-graph .node.fail rect { stroke: var(--bad); }
579
svg.trust-graph text { font-size: 11px; fill: var(--ink); }
580
svg.trust-graph text.s { font-size: 10px; fill: var(--mute); }
581
/* Runners (hub spec §13.2) */
582
.runner-status { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; padding: 1px 6px; border: 1px solid var(--line); }
583
.runner-status.st-online { color: var(--ok); border-color: var(--ok); }
584
.runner-status.st-offline { color: var(--mute); }
585
.runner-status.st-draining { color: var(--warn); border-color: var(--warn); }
586
.runner-status.st-disabled { color: var(--bad); border-color: var(--bad); }
587
588
/* The chain of work: issue → proposal → bookmark (hub spec §8). Issues and
589
   proposals share one number space, so every number says which it is. */
590
.kind-issue::before { content: "◇ "; color: var(--warn); }
591
.kind-proposal::before { content: "⇄ "; color: var(--acc); }
592
p.chain { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin: 10px 0 14px; padding: 8px 12px; border: 1px solid var(--line); border-left: 3px solid var(--acc); background: var(--panel); font-size: 13px; }
593
.chain-link { display: inline-flex; align-items: baseline; gap: 6px; padding: 2px 8px; border: 1px solid var(--line); background: var(--soft); color: var(--ink); text-decoration: none; }
594
a.chain-link:hover { border-color: var(--acc); text-decoration: none; }
595
.chain-kind { font-weight: 600; }
596
.chain-state { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--mute); }
597
.st-open .chain-state, .chain-state.st-open { color: var(--ok); }
598
.st-landed .chain-state, .chain-state.st-landed { color: var(--acc); }
599
.st-closed .chain-state { color: var(--mute); }
600
.chain-arrow { color: var(--acc); font-weight: 700; }
601
.chain-and { color: var(--mute); }