OXYGENHUB
◆ v0.9.4 oxygenhub / templates / style.css
111.2 KiB · CSS · last changed An issue's references: no line through the chips, each change once (closes #318) 10 days 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
  /* Backdrops (docs/backgrounds.md §3): a resting mark, a lit one, a link. */
22
  --bd-mark:rgba(0,224,240,.12); --bd-lit:rgba(0,240,255,.85); --bd-link:rgba(0,240,255,.35);
23
  color-scheme: dark;
24
}
25
:root[data-theme="light"] {
26
  --bg:#f4f7fc; --panel:#ffffff; --soft:#e9eef8; --ink:#1b2333; --mute:#5f6a81; --line:#d6dded; --dim:#b3bccf;
27
  --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;
28
  --ok:#1a7850; --bad:#c62d47; --warn:#6b3fd1;
29
  --add:#e1f5ee; --del:#fbe3e8; --add-ink:#176b48; --del-ink:#a1243c;
30
  --m1:#0090a8; --m2:#7a8290; --m3:#2f6fcf; --m4:#0055c0; --m5:#8a8f9c;
31
  --sy-kw:#0b4fc9; --sy-str:#1a7850; --sy-num:#1e63b8; --sy-cmt:#606b81; --sy-fn:#007394; --sy-ty:#7a3fd1; --sy-var:#1b2333; --sy-const:#6b3fd1;
32
  --bd-mark:rgba(95,106,129,.18); --bd-lit:rgba(0,100,224,.7); --bd-link:rgba(0,100,224,.25);
33
  color-scheme: light;
34
}
35
36
* { box-sizing: border-box; }
37
/* Room for the scroll bar always, so nothing shifts when it comes and goes. */
38
html { background: var(--bg); scrollbar-gutter: stable; }
39
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; }
40
a { color: var(--acc); text-decoration: none; }
41
a:hover { text-decoration: underline; }
42
code, pre, kbd, .mono { font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 13px; }
43
.px { font-family: "Press Start 2P", "Silkscreen", monospace; font-size: 13px; }
44
.pxs { font-family: "Press Start 2P", "Silkscreen", monospace; font-size: 11px; }
45
h1, h2, h3 { margin: 0; }
46
h2 { font-size: 16px; font-weight: 600; margin: 0 0 8px; }
47
h3 { font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); margin: 14px 0 6px; }
48
p { margin: 0 0 10px; }
49
.small { font-size: 12px; }
50
.mute { color: var(--mute); }
51
.dim { color: var(--mute); }
52
.center { text-align: center; }
53
.right { text-align: right; }
54
.empty { color: var(--mute); padding: 22px; text-align: center; border: 1px dashed var(--line); }
55
.lead { font-size: 16px; }
56
kbd { background: var(--soft); border: 1px solid var(--line); padding: 1px 5px; font-size: 11px; }
57
58
/* shell */
59
header { background: var(--panel); border-bottom: 1px solid var(--line); padding: 14px 22px; display: flex; align-items: center; gap: 16px; }
60
.brand { display: inline-flex; align-items: center; gap: 10px; color: var(--ink); }
61
.brand svg { height: 22px; width: auto; }
62
.brand em { font-style: normal; color: var(--acc); }
63
.brand:hover { text-decoration: none; }
64
header nav { margin-left: auto; display: flex; gap: 8px; align-items: center; }
65
header nav .me { color: var(--ink); font-weight: 600; padding: 0 6px; }
66
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; }
67
header nav .theme-toggle:hover { border-color: var(--acc); }
68
fieldset.choices { border: 0; padding: 0; margin: 0 0 10px; display: flex; gap: 18px; flex-wrap: wrap; }
69
fieldset.choices legend { padding: 0; margin-bottom: 6px; }
70
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; }
71
form.inline { display: inline; margin: 0; }
72
.band a.admin { color: var(--band-acc); }
73
form.find { margin: 0; flex: 0 1 320px; }
74
form.find input { width: 100%; background: var(--bg); border: 1px solid var(--line); color: var(--ink); padding: 6px 10px; font: inherit; }
75
form.find input:focus { outline: 2px solid var(--band); outline-offset: 0; }
76
.band { background: var(--band); display: flex; align-items: stretch; padding: 0 22px; }
77
.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); }
78
.band a:first-child { border-left: 1px solid var(--band-line); }
79
.band a.on { box-shadow: inset 0 -3px 0 var(--acc); background: rgba(0,0,0,.18); }
80
.band a:hover { text-decoration: none; background: rgba(0,0,0,.12); }
81
.band .grow { flex: 1; }
82
.band a.dim { opacity: .6; border: 0; }
83
.tabs { background: var(--panel); border-bottom: 1px solid var(--line); }
84
/* The repository bar is as wide as its contents need: at least the page
85
   column (so it lines up with it), wider for a long name, and it wraps only
86
   when the window itself is too narrow. */
87
.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; }
88
.tabs .crumb { white-space: nowrap; }
89
.tabs .crumb { margin-right: 18px; padding: 10px 0; font-size: 16px; }
90
.tabs a:not(.crumb a) { padding: 10px 12px; color: var(--ink); font-size: 13px; }
91
.tabs a.on { border-bottom: 2px solid var(--acc); font-weight: 600; }
92
.tabs a:hover { text-decoration: none; background: var(--soft); }
93
/* The bar's menus (oxygenhub#254): a summary that looks like a tab, its
94
   links in a panel below it; where the bar scrolls (narrow screens) they
95
   open inline instead, so the panel is never clipped. */
96
.tab-menu { position: relative; }
97
.tab-menu > summary { list-style: none; cursor: pointer; padding: 10px 12px; color: var(--ink); font-size: 13px; }
98
.tab-menu > summary::-webkit-details-marker { display: none; }
99
.tab-menu > summary::after { content: " \25BE"; color: var(--mute); }
100
.tab-menu > summary.on { border-bottom: 2px solid var(--acc); font-weight: 600; }
101
.tab-menu > summary:hover { background: var(--soft); }
102
.tab-menu-list { position: absolute; top: 100%; left: 0; z-index: 30; min-width: 190px; display: flex; flex-direction: column; padding: 4px 0; background: var(--panel); border: 1px solid var(--line); box-shadow: 0 6px 18px rgba(0,0,0,.18); }
103
.tabs .tab-menu-list a { padding: 8px 14px; white-space: nowrap; }
104
.tabs .tab-menu-list a[aria-current] { font-weight: 600; box-shadow: inset 2px 0 0 var(--acc); }
105
main { flex: 1; width: 100%; max-width: 1180px; margin: 0 auto; padding: 14px 22px 28px; }
106
main.wide { max-width: none; }
107
footer { background: var(--panel); border-top: 1px solid var(--line); margin-top: 28px; }
108
.foot { max-width: 1180px; margin: 0 auto; padding: 22px; display: grid; grid-template-columns: 1fr auto; gap: 22px; }
109
.foot .cols { display: flex; gap: 32px; }
110
.foot .cols a { display: block; font-size: 13px; }
111
.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; }
112
.head h1 { font-size: 30px; font-weight: 300; color: var(--mute); }
113
.head h1 small { display: block; font-size: 13px; color: var(--acc); font-weight: 400; }
114
.strip { padding: 8px 12px; margin: 0 0 12px; border: 1px solid; font-size: 13px; }
115
.strip.warn { border-color: var(--warn); color: var(--warn); background: color-mix(in srgb, var(--warn) 10%, transparent); }
116
.strip.bad { border-color: var(--bad); color: var(--bad); background: color-mix(in srgb, var(--bad) 10%, transparent); }
117
.strip a { color: inherit; text-decoration: underline; }
118
.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); }
119
.sheet td { padding: 2px 8px 2px 0; font-size: 13px; }
120
121
/* buttons, tags, chips */
122
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; }
123
button:hover, a.go:hover { background: var(--acc); color: var(--now-ink); text-decoration: none; }
124
button.small, a.go.small { padding: 2px 8px; font-size: 11px; }
125
a.go { display: inline-block; line-height: normal; }
126
/* A form's buttons in one aligned row: a CANCEL link the same height as
127
   the buttons beside it. */
128
form .actions { display: flex; gap: 10px; align-items: stretch; flex-wrap: wrap; margin: 12px 0 0; }
129
form .actions > *, form.card .actions > button[type=submit] { margin: 0; }
130
form .actions > a.go { display: inline-flex; align-items: center; }
131
/* A drop's form takes the page's width, as the notice above it does. */
132
form.card.drop-form { max-width: none; }
133
/* A page title with an action (+ NEW DROP): title left, action right, a
134
   gap between them; on a phone the action wraps below with room. */
135
.head.with-action { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px 20px; flex-wrap: wrap; }
136
.head.with-action h1 { margin: 0; }
137
.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; }
138
.tag.bad { color: var(--bad); }
139
.tag.warn { color: var(--warn); }
140
.tag.ok { color: var(--ok); }
141
.warn-text { color: var(--warn); }
142
.tag.head { color: var(--now-ink); background: var(--now); }
143
.chip { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 12px; background: var(--soft); padding: 1px 6px; border: 1px solid var(--line); }
144
.lbl { display: inline-block; font-size: 11px; padding: 1px 7px; margin-right: 4px; border: 1px solid; vertical-align: middle; }
145
.lbl-bm { color: var(--band-ink); background: var(--band); border-color: var(--band); }
146
.lbl-tag { color: var(--acc); border-color: var(--acc); }
147
.sig { display: inline-block; width: 1.2em; text-align: center; font-weight: 600; }
148
.sig-valid { color: var(--ok); }
149
.sig-unsigned { color: var(--mute); }
150
.sig-invalid { color: var(--bad); }
151
.sig-revoked { color: var(--warn); }
152
153
/* lists, tables, panels */
154
ul.plain { list-style: none; margin: 0; padding: 0; }
155
ul.plain li { padding: 2px 0; }
156
ul.rows { list-style: none; margin: 0; padding: 0; }
157
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; }
158
ul.rows .name { font-size: 16px; }
159
ul.rows p { margin: 4px 0 0; color: var(--mute); }
160
.table { border: 1px solid var(--line); overflow-x: auto; }
161
table { border-collapse: collapse; width: 100%; }
162
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); }
163
td { padding: 7px 10px; background: var(--panel); border-bottom: 1px solid var(--line); vertical-align: top; }
164
td.px { color: var(--acc); }
165
.panel { background: var(--panel); border: 1px solid var(--line); padding: 14px 16px; margin-bottom: 14px; }
166
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; }
167
dl.facts dt { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--mute); padding-top: 3px; }
168
dl.facts dd { margin: 0; }
169
code.full { word-break: break-all; }
170
pre.msg { background: var(--panel); border: 1px solid var(--line); padding: 10px 12px; white-space: pre-wrap; font-family: inherit; font-size: 14px; }
171
pre.marked { background: var(--panel); border: 1px solid var(--bad); padding: 10px 12px; overflow-x: auto; }
172
173
/* repository layout */
174
.side-layout { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 22px; }
175
.side-layout.rev { grid-template-columns: minmax(0, 1fr) 380px; }
176
/* A proposal's conversation: the page is wide for its diffs, but text and
177
   the sidebar stay together at a readable width, and the description,
178
   comments and forms fill their column. */
179
.side-layout.conversation { max-width: 1240px; }
180
.side-layout.conversation > div > article.doc,
181
.side-layout.conversation > div > form.card,
182
.side-layout.conversation > div > .comment { max-width: none; box-sizing: border-box; }
183
.side h3:first-child { margin-top: 0; }
184
.dash h2 { font-size: 15px; margin: 18px 0 8px; }
185
.dash h2:first-child { margin-top: 0; }
186
.dash .side .bar { justify-content: space-between; }
187
.dash .side .bar h3 { margin: 0; }
188
ul.feed { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); background: var(--panel); }
189
ul.feed li { padding: 8px 14px; border-top: 1px solid var(--line); }
190
ul.feed li:first-child { border-top: 0; }
191
ul.feed .who { font-weight: 600; }
192
.clone { display: flex; gap: 6px; align-items: center; }
193
.clone code { background: var(--bg); border: 1px solid var(--line); padding: 4px 8px; flex: 1; overflow-x: auto; white-space: nowrap; }
194
.quickstart { background: var(--panel); border: 1px solid var(--line); padding: 16px 20px; }
195
.quickstart h2 { margin-top: 0; }
196
.quickstart h3 { font-size: 14px; margin: 18px 0 6px; }
197
.cmds { display: flex; gap: 6px; align-items: flex-start; }
198
.cmds pre { flex: 1; margin: 0; background: var(--bg); border: 1px solid var(--line); padding: 8px 10px; overflow-x: auto; }
199
.bar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 10px; }
200
.ref { color: var(--acc); }
201
.crumbs a { color: var(--ink); }
202
/* The tree fills its column and never more (#152): a fixed column grid,
203
   long names and change titles cut with an ellipsis, so nothing runs
204
   under the sidebar. */
205
table.tree { width: 100%; table-layout: fixed; }
206
table.tree col.c-g { width: 44px; }
207
table.tree col.c-name { width: 30%; }
208
table.tree col.c-age { width: 8.5em; }
209
table.tree td { padding: 6px 10px; }
210
table.tree td.g { color: var(--acc); text-align: center; }
211
table.tree td.name, table.tree td.last { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
212
table.tree td.last { color: var(--mute); }
213
table.tree td.last a { color: var(--mute); }
214
table.tree td.age { text-align: right; white-space: nowrap; }
215
article.doc { max-width: 60rem; background: var(--panel); border: 1px solid var(--line); padding: 18px 24px; margin-top: 14px; }
216
article.doc h1 { font-size: 26px; font-weight: 500; margin: 0 0 12px; }
217
article.doc h2 { font-size: 20px; margin: 18px 0 8px; }
218
article.doc h3 { text-transform: none; letter-spacing: 0; font-size: 16px; color: var(--ink); }
219
article.doc pre { background: var(--bg); border: 1px solid var(--line); padding: 10px 12px; overflow-x: auto; }
220
article.doc code { background: var(--soft); padding: 0 3px; }
221
article.doc pre code { background: none; padding: 0; }
222
article.doc table { width: auto; }
223
article.doc img { max-width: 100%; }
224
article.doc blockquote { border-left: 3px solid var(--band); margin: 0; padding: 2px 12px; color: var(--mute); }
225
226
/* files and diffs */
227
.filebox { background: var(--panel); border: 1px solid var(--line); }
228
.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); }
229
.modes a { font-size: 12px; padding: 2px 8px; border: 1px solid var(--line); margin-left: 4px; color: var(--ink); }
230
.modes a.on { border-color: var(--acc); color: var(--acc); }
231
table.code { width: 100%; }
232
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; }
233
table.code td.n { width: 1%; min-width: 3em; text-align: right; color: var(--mute); user-select: none; cursor: pointer; padding-right: 12px; }
234
table.code td.n:hover { color: var(--acc); }
235
table.code td.t pre { margin: 0; white-space: pre; }
236
table.code tr.hl td { background: color-mix(in srgb, var(--acc) 18%, transparent); }
237
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; }
238
table.code td.blame .px { font-size: 9px; }
239
table.code td.blame .who { color: var(--ink); }
240
table.diff td.s { width: 1%; user-select: none; color: var(--mute); }
241
table.diff tr.add td { background: var(--add); color: var(--add-ink); }
242
table.diff tr.del td { background: var(--del); color: var(--del-ink); }
243
table.diff tr.gap td { background: var(--soft); color: var(--mute); font-family: "Barlow", sans-serif; font-size: 12px; padding: 2px 8px; }
244
.file-diff { background: var(--panel); border: 1px solid var(--line); margin: 0 0 14px; }
245
.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); }
246
.file-diff > summary { cursor: pointer; list-style: none; }
247
.file-diff > summary::-webkit-details-marker { display: none; }
248
.file-diff > summary::before { content: "▾"; color: var(--mute); width: 1em; }
249
.file-diff:not([open]) > summary::before { content: "▸"; }
250
.file-diff:not([open]) > summary { border-bottom: 0; }
251
.diff-bar { display: flex; gap: 16px; align-items: center; margin: 0 0 10px; }
252
.diff-bar .modes a { padding: 3px 10px; border: 1px solid var(--line); color: var(--mute); }
253
.diff-bar .modes a.on { color: var(--ink); border-color: var(--acc); }
254
table.diff .wx { border-radius: 2px; }
255
table.diff tr.add .wx, table.diff td.add .wx { background: color-mix(in srgb, var(--add-ink) 28%, transparent); }
256
table.diff tr.del .wx, table.diff td.del .wx { background: color-mix(in srgb, var(--del-ink) 28%, transparent); }
257
table.diff.split { table-layout: fixed; }
258
table.diff.split col.n { width: 3.5em; }
259
table.diff.split td.t { overflow-x: auto; }
260
table.diff.split td.t pre { white-space: pre-wrap; word-break: break-word; }
261
table.diff.split td.add { background: var(--add); color: var(--add-ink); }
262
table.diff.split td.del { background: var(--del); color: var(--del-ink); }
263
table.diff.split td.none { background: var(--soft); }
264
table.diff.split td.t.mid { border-left: 1px solid var(--line); }
265
.file-diff .counts { margin-left: auto; font-family: ui-monospace, monospace; font-size: 12px; }
266
.counts .add { color: var(--add-ink); }
267
.counts .del { color: var(--del-ink); }
268
.kind { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; padding: 1px 6px; border: 1px solid var(--line); color: var(--mute); }
269
.kind-added { color: var(--ok); border-color: var(--ok); }
270
.kind-removed { color: var(--bad); border-color: var(--bad); }
271
.kind-renamed, .kind-modified { color: var(--acc); border-color: var(--acc); }
272
nav.files { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 0 0 12px; }
273
274
/* history */
275
.hist { background: var(--panel); border: 1px solid var(--line); }
276
.hrow { display: flex; align-items: stretch; border-bottom: 1px solid var(--line); }
277
.hrow:last-child { border-bottom: 0; }
278
.hrow svg.lanes { flex: 0 0 auto; display: block; }
279
.lane { stroke: var(--band); stroke-width: 2; fill: none; }
280
.lane.none { stroke: none; }
281
.lane.dashed { stroke-dasharray: 3 3; stroke: var(--dim); }
282
.node { fill: var(--acc-2); stroke: var(--acc); stroke-width: 1.5; }
283
.node.head { fill: var(--now); stroke: var(--ink); stroke-width: 1.5; }
284
.node.res { fill: var(--ok); }
285
/* Swimlanes (hub spec §6.7): cards on lanes, dependency edges between them. */
286
.lanes-board { border: 1px solid var(--line); background: var(--panel); padding: 6px; }
287
.lanes-board rect.node { fill: var(--soft); stroke: var(--acc); }
288
.lanes-board rect.node.head { stroke: var(--now); stroke-width: 2; }
289
.lanes-board a:hover rect.node { fill: var(--line); }
290
.lanes-board text { fill: var(--ink); font-size: 11px; }
291
.chg { display: flex; justify-content: space-between; align-items: center; gap: 14px; padding: 8px 12px; flex: 1; min-width: 0; }
292
.chg + .chg, .chg:only-child { border-bottom: 1px solid var(--line); }
293
.hrow .chg { border-bottom: 0; }
294
.chg .title { color: var(--ink); font-weight: 500; }
295
/* Nothing unbroken in a change row may push it wider than its card (#216). */
296
.chg-main { min-width: 0; overflow-wrap: anywhere; }
297
.chg .meta { color: var(--mute); font-size: 12px; margin-top: 2px; }
298
.chg-side { display: flex; align-items: center; gap: 10px; white-space: nowrap; }
299
.chg .hash { font-size: 9px; }
300
.pager { display: flex; gap: 8px; justify-content: center; margin-top: 12px; }
301
302
@media (max-width: 760px) {
303
  header { flex-wrap: wrap; }
304
  .side-layout, .side-layout.rev { grid-template-columns: 1fr; }
305
  .foot { grid-template-columns: 1fr; }
306
  main { padding: 10px 14px 20px; }
307
  .band { padding: 0 8px; overflow-x: auto; }
308
  .tabs-in { padding: 0 8px; }
309
}
310
311
/* syntax (syntect scopes as classes prefixed sy-, so no scope name can collide with the page's own classes) */
312
.sy-source .sy-keyword, .sy-source .sy-storage { color: var(--sy-kw); }
313
.sy-source .sy-string { color: var(--sy-str); }
314
.sy-source .sy-constant.sy-numeric, .sy-source .sy-constant.sy-language { color: var(--sy-num); }
315
.sy-source .sy-constant { color: var(--sy-const); }
316
.sy-source .sy-comment { color: var(--sy-cmt); font-style: italic; }
317
.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); }
318
.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); }
319
.sy-source .sy-variable { color: var(--sy-var); }
320
.sy-source .sy-entity.sy-name.sy-tag { color: var(--sy-kw); }
321
.sy-source .sy-entity.sy-other.sy-attribute-name { color: var(--sy-const); }
322
.sy-source .sy-markup.sy-heading { color: var(--sy-ty); font-weight: 600; }
323
.sy-source .sy-markup.sy-bold { font-weight: 600; }
324
.sy-source .sy-markup.sy-italic { font-style: italic; }
325
.sy-source .sy-markup.sy-raw { color: var(--sy-str); }
326
.sy-source .sy-markup.sy-underline.sy-link { color: var(--sy-fn); }
327
328
/* forms */
329
form.card { max-width: 460px; background: var(--panel); border: 1px solid var(--line); padding: 18px 20px; margin: 0 0 16px; }
330
form.card.wide { max-width: 720px; }
331
/* As wide as the panel above it (a new proposal's changes, #315). */
332
form.card.full { max-width: none; }
333
form .actions > .end, form.card .actions > button.end[type=submit] { margin-left: auto; }
334
/* Assistants that fill a form's fields, under the editor: secondary,
335
   not the form's submit (#315). */
336
form.card .assist-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 0; }
337
form.card .assist-row button.agent-btn { background: var(--panel); color: var(--ink); border: 1px solid var(--line); margin: 0; }
338
form.card .assist-row button.agent-btn:hover { border-color: var(--acc); }
339
form.card label, .field label { display: block; font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); margin: 10px 0 4px; }
340
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 input[type=url], form.card textarea, form.card select,
341
.field input, .field select, .field textarea { width: 100%; background: var(--bg); border: 1px solid var(--line); color: var(--ink); padding: 7px 10px; font: inherit; }
342
form.card input:focus, form.card textarea:focus, form.card select:focus { outline: 2px solid var(--band); outline-offset: 0; }
343
form.card button[type=submit], form.card .primary { background: var(--acc); color: var(--now-ink); border: 0; margin-top: 12px; }
344
form.card .row { display: flex; gap: 10px; align-items: end; }
345
form.card .row > * { flex: 1; }
346
form.card .choice { display: flex; gap: 12px; flex-wrap: wrap; margin: 6px 0; }
347
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; }
348
.note { color: var(--ok); }
349
.error { color: var(--bad); }
350
details.danger { border: 1px solid var(--bad); padding: 10px 14px; margin-top: 18px; }
351
.panel.danger-zone { border-color: var(--bad); }
352
.danger-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; padding: 10px 0; border-top: 1px solid var(--line); }
353
.danger-row:first-of-type { border-top: 0; }
354
.danger-row > div { flex: 1; min-width: 0; }
355
.danger-row p { margin: 2px 0 0; }
356
.danger-row details.danger-act { flex: 0 0 auto; max-width: 420px; }
357
.danger-row details.danger-act summary { list-style: none; display: inline-block; cursor: pointer; border: 1px solid var(--bad); color: var(--bad); padding: 6px 12px; font-weight: 600; }
358
.danger-row details.danger-act summary::-webkit-details-marker { display: none; }
359
.danger-row details.danger-act[open] { flex: 1; }
360
.danger-row details.danger-act form.card { margin-top: 8px; }
361
details.danger summary { color: var(--bad); cursor: pointer; font-weight: 600; }
362
.secret { font-family: ui-monospace, monospace; background: var(--bg); border: 1px solid var(--acc); padding: 8px 10px; word-break: break-all; }
363
.qr { background: #fff; display: inline-block; padding: 8px; }
364
ul.codes { columns: 2; font-family: ui-monospace, monospace; }
365
table.small td, table.small th { padding: 5px 8px; font-size: 13px; }
366
form.tiny { display: inline; margin: 0; }
367
form.tiny button { padding: 1px 6px; font-size: 10px; }
368
.flow-job > form.job-rerun { display: block; margin: 0 0 8px; }
369
/* The runners table's Serves cell (#309): the scope above its input, so the inputs line up whatever the scope's length. */
370
.runner-serves form.tiny { display: flex; gap: 4px; margin-top: 4px; white-space: nowrap; }
371
372
/* proposals */
373
.comment { background: var(--panel); border: 1px solid var(--line); padding: 10px 14px; margin: 0 0 10px; }
374
.comment .who { font-weight: 600; }
375
.comment .body { margin-top: 6px; }
376
.comment .body p:last-child { margin: 0; }
377
.comment.resolved { opacity: .6; }
378
.comment.review-approve { border-color: var(--ok); }
379
.comment.review-changes { border-color: var(--bad); }
380
td.thread { background: var(--soft); padding: 8px 12px; }
381
td.thread .comment { margin: 4px 0; font-family: "Barlow", sans-serif; font-size: 14px; }
382
details.linecomment { display: inline; float: right; }
383
details.linecomment summary { list-style: none; cursor: pointer; color: var(--mute); font-size: 12px; padding: 0 4px; }
384
details.linecomment summary:hover { color: var(--acc); }
385
details.linecomment form { font-family: "Barlow", sans-serif; background: var(--panel); border: 1px solid var(--acc); padding: 8px; margin: 4px 0; }
386
details.linecomment textarea { width: 100%; font: inherit; background: var(--bg); color: var(--ink); border: 1px solid var(--line); }
387
388
/* issues and notifications */
389
.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; }
390
/* An issue's events and its references by day: indented lines, without the
391
   proposal timeline's rule (.timeline::before drew one through the chips). */
392
.tl-event { margin: 0 0 8px 14px; }
393
.refs-day summary { cursor: pointer; }
394
.board-filter { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 0 0 10px; }
395
.board-filter input[type=search] { min-width: 0; flex: 1 1 14em; max-width: 24em; }
396
.col-hidden { margin: 0 0 6px; }
397
.col-archives { margin: 0 0 6px; }
398
.board-archived-link { margin-left: auto; }
399
.col-archive { margin-top: 8px; }
400
.col-archive .inline-fields { align-items: center; }
401
.col-archive input[type=number] { width: 6em; margin: 0; }
402
.refs-chips { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0 0; max-width: 100%; }
403
.refs-chips .chip { overflow-wrap: anywhere; }
404
details.inline-edit { display: inline; margin-left: 8px; }
405
details.inline-edit summary { cursor: pointer; color: var(--acc); }
406
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; }
407
.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; }
408
header nav .bell { color: var(--ink); position: relative; font-size: 16px; padding: 0 6px; }
409
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; }
410
ul.rows li.unread { border-color: var(--acc); }
411
mark { background: color-mix(in srgb, var(--acc) 30%, transparent); color: inherit; }
412
413
/* editor */
414
form.editor { max-width: none; }
415
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; }
416
.cm-host { border: 1px solid var(--line); margin: 8px 0; min-height: 360px; max-height: 70vh; overflow: auto; font-size: 13px; }
417
.cm-host .cm-editor { min-height: 360px; }
418
button.danger-btn { color: var(--bad); border-color: var(--bad); }
419
button.primary-btn { background: var(--acc); color: var(--now-ink); }
420
button.primary-btn:hover { filter: brightness(1.1); }
421
button:disabled { opacity: .45; cursor: not-allowed; }
422
423
/* EasyMDE in the hub's colours */
424
.EasyMDEContainer .CodeMirror { background: var(--bg); color: var(--ink); border-color: var(--line); }
425
.EasyMDEContainer .CodeMirror-cursor { border-color: var(--acc); }
426
.editor-toolbar { border-color: var(--line); background: var(--soft); opacity: 1; }
427
.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; }
428
.editor-toolbar button.mde-btn:hover, .editor-toolbar button.active { background: var(--panel); color: var(--acc); }
429
.editor-preview, .editor-preview-side { background: var(--panel); color: var(--ink); }
430
431
/* code search */
432
.inline-find { flex: 0 1 220px; }
433
.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; }
434
.hits .hit code { background: none; }
435
436
.scopes label { display: block; text-transform: none; letter-spacing: 0; font-size: 14px; color: var(--ink); margin: 4px 0; }
437
438
/* avatars and owner pages */
439
img.avatar { display: inline-block; vertical-align: middle; border: 1px solid var(--line); object-fit: cover; }
440
img.avatar.xs { width: 18px; height: 18px; }
441
img.avatar.sm { width: 24px; height: 24px; }
442
img.avatar.xl { width: 100%; max-width: 240px; height: auto; aspect-ratio: 1; }
443
.profile .who-card h1.display { font-size: 24px; font-weight: 600; margin: 12px 0 0; }
444
.profile .who-card .handle { font-size: 18px; color: var(--mute); margin: 2px 0 10px; }
445
.profile .who-card .bio { margin: 0 0 10px; }
446
.profile .who-card .facts-list li { padding: 2px 0; }
447
.profile .who-card .facts-list li.social .icon { vertical-align: -2px; }
448
.profile h2 { font-size: 15px; margin: 0 0 8px; }
449
.profile h2 ~ h2 { margin-top: 18px; }
450
.profile .keys li { margin-bottom: 6px; }
451
.profile .side-layout, .side-layout.profile { grid-template-columns: 260px 1fr; }
452
@media (max-width: 760px) { .side-layout.profile { grid-template-columns: 1fr; } img.avatar.xl { max-width: 120px; } }
453
454
/* topics, stars, explore */
455
.topics { margin: 4px 0 0; display: flex; flex-wrap: wrap; gap: 4px; }
456
.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); }
457
.topic:hover { text-decoration: none; background: color-mix(in srgb, var(--acc) 24%, transparent); }
458
.explore-bar input[type=search] { flex: 1 1 240px; }
459
.counts-line span { margin-right: 2px; }
460
.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; }
461
.pager { display: flex; gap: 12px; align-items: center; justify-content: center; margin: 14px 0; }
462
463
/* repository page: the clone command sits at the right of the top bar, the README spans the column */
464
.top-clone { margin-left: auto; flex: 0 1 380px; min-width: 200px; }
465
.top-clone code { font-size: 12px; overflow: hidden; text-overflow: ellipsis; }
466
.latest-line { margin: -4px 0 8px; }
467
article.doc.readme { max-width: none; }
468
469
/* settings pages: section headings on the left, every section the same width on the right */
470
.sectioned { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 28px; align-items: start; }
471
.section-nav { position: sticky; top: 14px; display: flex; flex-direction: column; gap: 2px; }
472
.section-nav a { padding: 6px 12px; border-left: 2px solid var(--line); color: var(--mute); font-size: 14px; }
473
.section-nav a:hover, .section-nav a.on { border-left-color: var(--acc); color: var(--ink); text-decoration: none; }
474
.sections > form.card, .sections > form.card.wide, .sections > .panel, .sections > details { max-width: none; width: 100%; box-sizing: border-box; scroll-margin-top: 14px; }
475
.sections .panel form.card { max-width: 720px; }
476
.sections > details > form.card { max-width: none; }
477
/* A repository's settings (#278): grouped pages in a sidebar, one page beside it. */
478
/* The admin overview (oxygenhub#288): the site's numbers, then a card per
479
   group of pages. */
480
.admin-counts { display: flex; flex-wrap: wrap; gap: 8px 24px; align-items: baseline; }
481
.admin-counts strong { font-size: 18px; margin-right: 4px; }
482
.admin-groups { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0 16px; }
483
.settings-layout { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 28px; align-items: start; }
484
.settings-nav { position: sticky; top: 14px; display: flex; flex-direction: column; gap: 14px; }
485
.settings-group h2 { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); margin: 0 0 4px; padding: 0 12px; }
486
.settings-group ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
487
.settings-group a { display: block; padding: 5px 12px; border-left: 2px solid var(--line); color: var(--mute); font-size: 14px; }
488
.settings-group a:hover { border-left-color: var(--dim); color: var(--ink); text-decoration: none; }
489
.settings-group a.on { border-left-color: var(--acc); color: var(--ink); background: var(--soft); }
490
@media (max-width: 720px) {
491
  .settings-layout { grid-template-columns: minmax(0, 1fr); gap: 14px; }
492
  .settings-nav { position: static; gap: 8px; padding-bottom: 10px; border-bottom: 1px solid var(--line); }
493
  .settings-group { display: grid; grid-template-columns: 96px minmax(0, 1fr); align-items: baseline; gap: 10px; }
494
  .settings-group h2 { padding: 0; margin: 0; }
495
  .settings-group ul { flex-direction: row; flex-wrap: wrap; gap: 4px; min-width: 0; }
496
  .settings-group a { border-left: 0; border: 1px solid var(--line); padding: 3px 8px; font-size: 13px; }
497
  .settings-group a.on { border-color: var(--acc); }
498
}
499
@media (max-width: 760px) {
500
  .sectioned { grid-template-columns: 1fr; gap: 12px; }
501
  .section-nav { position: static; flex-direction: row; flex-wrap: wrap; }
502
  .section-nav a { border-left: 0; border-bottom: 2px solid var(--line); }
503
}
504
505
/* File view: tree sidebar, line bar, blame age (hub spec §6.6). */
506
.file-layout { display: grid; grid-template-columns: minmax(180px, 240px) minmax(0, 1fr); gap: 16px; align-items: start; }
507
.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; }
508
.file-side .side-root { display: block; padding: 2px 12px 6px; font-weight: 600; }
509
.file-side ul { list-style: none; margin: 0; padding: 0; }
510
.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; }
511
.file-side li a:hover { background: var(--soft); text-decoration: none; }
512
.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); }
513
.file-side .glyph { color: var(--mute); font-size: 10px; }
514
.file-main { min-width: 0; overflow-x: auto; }
515
.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)); }
516
.linebar[hidden] { display: none; }
517
.linebar [data-linebar-label] { margin-right: auto; }
518
table.code td.blame { box-shadow: inset 3px 0 0 color-mix(in srgb, var(--acc) calc(var(--age, 0) * 10%), transparent); }
519
table.code td.blame.age-0 { --age: 1; } table.code td.blame.age-1 { --age: 2; } table.code td.blame.age-2 { --age: 3; }
520
table.code td.blame.age-3 { --age: 4; } table.code td.blame.age-4 { --age: 5; } table.code td.blame.age-5 { --age: 6; }
521
table.code td.blame.age-6 { --age: 7; } table.code td.blame.age-7 { --age: 8; } table.code td.blame.age-8 { --age: 9; }
522
table.code td.blame.age-9 { --age: 10; }
523
table.code td.blame .before { color: var(--mute); margin-left: 4px; }
524
table.code td.blame .before:hover { color: var(--acc); text-decoration: none; }
525
@media (max-width: 900px) {
526
  .file-layout { grid-template-columns: minmax(0, 1fr); }
527
  .file-side { display: none; }
528
}
529
530
/* OxygenFlow (hub spec §13.2): runs, the job graph and logs. Status is
531
   carried by a glyph as well as colour. */
532
.flow-glyph { display: inline-block; width: 1.2em; text-align: center; font-weight: 700; }
533
.flow-glyph.st-passed, .node.st-passed .g { color: var(--ok); fill: var(--ok); }
534
.flow-glyph.st-failed, .flow-glyph.st-error, .node.st-failed .g, .node.st-error .g { color: var(--bad); fill: var(--bad); }
535
.flow-glyph.st-running, .node.st-running .g { color: var(--acc); fill: var(--acc); }
536
.flow-glyph.st-queued, .flow-glyph.st-skipped, .flow-glyph.st-cancelled, .node.st-queued .g, .node.st-skipped .g, .node.st-cancelled .g { color: var(--mute); fill: var(--mute); }
537
.flow-glyph.st-running, .node.st-running .g { animation: flow-pulse 1.2s ease-in-out infinite; }
538
@keyframes flow-pulse { 50% { opacity: .35; } }
539
@media (prefers-reduced-motion: reduce) { .flow-glyph.st-running, .node.st-running .g { animation: none; } }
540
.flow-dots .flow-glyph { width: 1em; }
541
.flow-graph-box { overflow-x: auto; padding: 12px; }
542
.flow-graph { display: block; max-width: none; font-family: "Barlow", sans-serif; }
543
.flow-graph .edge { fill: none; stroke: var(--line); stroke-width: 2; }
544
.flow-graph .edge.st-passed { stroke: color-mix(in srgb, var(--ok) 60%, var(--line)); }
545
.flow-graph .edge.st-failed, .flow-graph .edge.st-error { stroke: color-mix(in srgb, var(--bad) 60%, var(--line)); stroke-dasharray: 4 4; }
546
.flow-graph .node rect { fill: var(--panel); stroke: var(--line); stroke-width: 1.5; }
547
.flow-graph .node:hover rect, .flow-graph .node:focus rect { stroke: var(--acc); }
548
.flow-graph .node.st-passed rect { stroke: var(--ok); }
549
.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)); }
550
.flow-graph .node.st-running rect { stroke: var(--acc); fill: color-mix(in srgb, var(--acc) 8%, var(--panel)); }
551
.flow-graph .node.st-skipped rect, .flow-graph .node.st-cancelled rect { stroke-dasharray: 4 3; }
552
.flow-graph .node .g { font-size: 18px; }
553
.flow-graph text { font-family: "Barlow", sans-serif; stroke: none; }
554
.flow-graph .node .name { fill: var(--ink); font-size: 14px; font-weight: 600; }
555
.flow-graph .node .meta { fill: var(--mute); font-size: 11.5px; font-weight: 400; }
556
details.flow-job { padding: 0; margin-top: 10px; }
557
details.flow-job > summary { padding: 10px 12px; cursor: pointer; list-style-position: inside; }
558
details.flow-job .pad { padding: 0 12px 10px; margin: 0; }
559
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; }
560
pre.flow-log:empty { display: none; }
561
ul.flow-artifacts { list-style: none; margin: 0; padding: 6px 12px; border-top: 1px solid var(--line); }
562
ul.flow-artifacts li { padding: 2px 0; overflow-wrap: anywhere; }
563
ul.flow-artifacts select { font-size: 11px; }
564
.flow-tests { padding: 6px 12px; border-top: 1px solid var(--line); }
565
.flow-tests > p { margin: 0 0 4px; }
566
.flow-tests .tests-count.ok { color: var(--ok); }
567
.flow-tests .tests-count.bad, .flow-tests .bad { color: var(--bad); font-weight: 600; }
568
.tests-failure { border-left: 3px solid var(--bad); margin: 4px 0; padding: 2px 8px; }
569
.tests-failure summary { cursor: pointer; overflow-wrap: anywhere; }
570
.tests-failure pre.flow-log { padding: 6px 8px; margin: 4px 0; white-space: pre-wrap; word-break: break-word; max-height: 24em; overflow: auto; }
571
pre.flow-log .ln { display: block; padding: 0 12px; white-space: pre-wrap; word-break: break-word; }
572
pre.flow-log .t { display: inline-block; min-width: 5.5em; color: var(--mute); user-select: none; }
573
pre.flow-log details.log-group > summary { cursor: pointer; font-weight: 600; list-style: none; }
574
pre.flow-log details.log-group > summary::before { content: "▸ "; color: var(--mute); }
575
pre.flow-log details.log-group[open] > summary::before { content: "▾ "; }
576
pre.flow-log details.log-group > summary .took { font-weight: 400; color: var(--mute); margin-left: 6px; }
577
pre.flow-log .s-err { color: color-mix(in srgb, var(--bad) 75%, var(--ink)); }
578
pre.flow-log .s-flow, pre.flow-log .s-console { color: var(--mute); font-style: italic; }
579
table.flow-runs td.st { width: 1.5em; }
580
581
/* Compare pickers (hub spec §6.3). */
582
.compare-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0 0 14px; }
583
.compare-bar label { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--mute); margin: 0; }
584
.compare-bar input { width: 16em; margin: 0; }
585
.compare-bar .swap { font-size: 18px; padding: 0 4px; }
586
.compare-bar .swap:hover { text-decoration: none; color: var(--ink); }
587
.compare-bar button { margin: 0; }
588
589
/* Help (hub spec §6.3). */
590
.help section.panel { padding: 16px 20px; scroll-margin-top: 14px; }
591
.help section.panel h2 { margin-top: 0; }
592
.help ol, .help ul { padding-left: 1.3em; }
593
.help li { margin: 4px 0; }
594
table.glossary td:first-child { white-space: nowrap; color: var(--mute); }
595
table.glossary td:nth-child(2) { white-space: nowrap; }
596
597
button.linkish { background: none; border: 0; padding: 0; margin: 0; color: var(--acc); font: inherit; cursor: pointer; text-transform: none; letter-spacing: normal; }
598
button.linkish:hover { text-decoration: underline; }
599
600
/* Inbox filters (hub spec §10). */
601
.inbox-nav h3 { margin: 14px 0 4px 12px; font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--mute); }
602
.inbox .rows.threads .tag.dim { opacity: .7; }
603
604
/* Picture upload (hub spec §6.3). */
605
.picture-row { display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap; }
606
.picture-row img.avatar.xl { width: 96px; height: 96px; }
607
.picture-row > div { flex: 1; min-width: 220px; }
608
609
/* Accessibility and narrow screens (hub spec §6.13). */
610
:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
611
.band a:focus-visible, .tabs a:focus-visible { outline-offset: -2px; }
612
.skip { position: absolute; left: 12px; top: -48px; z-index: 100; padding: 8px 14px; background: var(--acc); color: var(--bg); font-weight: 600; }
613
.skip:focus { top: 8px; }
614
main:focus { outline: none; }
615
@media (max-width: 760px) {
616
  .tabs-in { flex-wrap: nowrap; overflow-x: auto; white-space: nowrap; scrollbar-width: thin; -webkit-overflow-scrolling: touch; }
617
  .side-layout > * { min-width: 0; }
618
  /* No room for the last change: its column closes to nothing (the cells
619
     stay, so the age keeps its own column). */
620
  table.tree col.c-name { width: auto; }
621
  table.tree col.c-last { width: 0; }
622
  table.tree col.c-age { width: 7.5em; }
623
  table.tree td.last { padding: 0; font-size: 0; }
624
  article.doc, .panel { overflow-x: auto; }
625
  article.doc pre, article.doc table { max-width: 100%; overflow-x: auto; }
626
  .tabs-in > * { flex-shrink: 0; }
627
  .tab-menu { position: static; }
628
  .tab-menu > summary { display: inline-block; }
629
  .tab-menu-list { position: static; display: inline-flex; flex-direction: row; min-width: 0; padding: 0; border: 0; box-shadow: none; background: var(--soft); }
630
  .band { overflow-x: auto; white-space: nowrap; }
631
  main table.list, main table.flow-runs { display: block; overflow-x: auto; }
632
  .sectioned { grid-template-columns: 1fr; }
633
  .section-nav { position: static; display: flex; flex-wrap: wrap; gap: 4px; }
634
  header .find { display: none; }
635
}
636
@media (prefers-reduced-motion: reduce) { * { scroll-behavior: auto !important; transition: none !important; } }
637
638
/* Projects (hub spec §8.2). */
639
.board { display: flex; gap: 12px; align-items: flex-start; overflow-x: auto; padding-bottom: 8px; }
640
.board-col { flex: 0 0 290px; background: var(--soft); border: 1px solid var(--line); padding: 8px; }
641
.board-col > header { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
642
.board-col h2 { font-size: 14px; margin: 2px 0 8px; }
643
.board-col ul.cards { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; min-height: 12px; }
644
.card-item { background: var(--panel); border: 1px solid var(--line); padding: 8px 10px; }
645
.card-item.note { border-left: 3px solid var(--warn); }
646
.card-item p { margin: 4px 0 0; }
647
.card-item .card-labels { display: flex; flex-wrap: wrap; gap: 4px; }
648
.card-item .card-labels .label { margin-right: 0; text-decoration: none; }
649
.card-item .card-labels .label:hover, .card-item .card-labels .label:focus-visible { background: color-mix(in srgb, var(--c, var(--acc)) 14%, transparent); }
650
.card-item .card-who { color: inherit; }
651
.card-item .card-actions { margin-top: 6px; display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }
652
.card-item .card-actions select { width: auto; margin: 0; padding: 1px 4px; font-size: 12px; }
653
.board .add-card { margin-top: 8px; }
654
.board .add-card form { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
655
.board .inline-fields { display: flex; gap: 4px; }
656
.board .inline-fields select { width: 40%; }
657
.board .add-col form { display: flex; flex-direction: column; gap: 6px; }
658
.state-open { color: var(--ok); } .state-closed, .state-landed { color: var(--acc); }
659
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
660
.card-item.note > p { color: var(--ink); }
661
662
/* Webhooks (hub spec §12.2): long URLs wrap inside the panel. */
663
ul.hooks { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
664
li.hook { border: 1px solid var(--line); background: var(--soft); padding: 8px 12px; min-width: 0; }
665
.hook-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
666
code.hook-url { overflow-wrap: anywhere; word-break: break-all; }
667
li.hook p { margin: 4px 0; }
668
li.hook .hook-edit { margin-top: 4px; }
669
670
/* Repository overview: clone popover, contributors, languages, visibility. */
671
.clone-pop { position: relative; }
672
.clone-pop > summary { list-style: none; cursor: pointer; }
673
.clone-pop > summary::-webkit-details-marker { display: none; }
674
.clone-pop[open] > summary { background: var(--soft); }
675
.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; }
676
.clone-panel .clone input { flex: 1; min-width: 0; margin: 0; font-family: var(--mono, monospace); font-size: 12px; }
677
.clone-panel p { margin: 0; overflow-wrap: anywhere; }
678
.clone-panel .download { border-top: 1px solid var(--line); padding-top: 8px; margin-top: 2px; font-weight: 600; text-decoration: none; }
679
.clone-panel .download:hover { text-decoration: underline; }
680
.bar .inline-find { flex: 1 1 200px; }
681
ul.contributors li { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 4px 0; }
682
ul.contributors img.avatar.sm { width: 20px; height: 20px; vertical-align: middle; }
683
ul.contributors ul.via-list { flex-basis: 100%; margin: 0 0 0 26px; padding: 0; }
684
ul.contributors ul.via-list li { margin: 2px 0; }
685
ul.contributors ul.via-list img.avatar.sm { width: 16px; height: 16px; }
686
.avatar-none { display: inline-block; width: 20px; text-align: center; color: var(--mute); }
687
.lang-bar { display: flex; height: 8px; overflow: hidden; background: var(--soft); margin: 6px 0 8px; }
688
.lang-bar > span { display: block; height: 100%; }
689
.lang-bar > span + span { margin-left: 1px; }
690
ul.langs { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 13px; }
691
ul.langs li { margin: 0; }
692
.lang-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; vertical-align: middle; }
693
.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; }
694
.vis-public { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
695
.vis-internal { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
696
.vis-private { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, transparent); }
697
summary.go { display: inline-block; user-select: none; }
698
.clone-pop > summary.go:hover { background: var(--soft); }
699
700
/* Release trust (hub spec §9.1) */
701
.audit ul.checks li { padding: 3px 0; }
702
.audit ul.checks li .glyph { display: inline-block; width: 1.2em; text-align: center; font-weight: 700; }
703
.audit ul.checks li.pass .glyph { color: var(--ok); }
704
.audit ul.checks li.warn .glyph { color: var(--warn); }
705
.audit ul.checks li.fail .glyph { color: var(--bad); }
706
.audit-fail { border-left: 3px solid var(--bad); }
707
.audit-warn { border-left: 3px solid var(--warn); }
708
.audit-pass { border-left: 3px solid var(--ok); }
709
.trust-graph-wrap { overflow-x: auto; }
710
svg.trust-graph { max-width: 100%; height: auto; display: block; }
711
svg.trust-graph .node .badge { fill: var(--bg); stroke: none; }
712
svg.trust-graph .node.pass .badge { fill: color-mix(in srgb, var(--ok) 15%, var(--panel)); }
713
svg.trust-graph .node.warn .badge { fill: color-mix(in srgb, var(--warn) 18%, var(--panel)); }
714
svg.trust-graph .node.fail .badge { fill: color-mix(in srgb, var(--bad) 15%, var(--panel)); }
715
svg.trust-graph .node .lock { fill: var(--ok); stroke: none; }
716
svg.trust-graph .node .shackle { fill: none; stroke: var(--ok); stroke-width: 1.6; }
717
svg.trust-graph .node.warn .mark { fill: var(--warn); font-weight: 700; font-size: 13px; }
718
svg.trust-graph .node.fail .mark { fill: var(--bad); font-weight: 700; font-size: 12px; }
719
svg.trust-graph text.t { font-weight: 600; }
720
/* Trust badges: the page's summary, and the assets' headings. */
721
ul.plain.trust-summary { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 16px; }
722
/* ul.plain li's padding would otherwise win and the text would touch the border. */
723
ul.plain.trust-summary li.tb { padding: 5px 14px 5px 12px; gap: 8px; }
724
.tb { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--line); font-size: 13px; font-weight: 500; }
725
.tb-sm { padding: 2px 10px; font-size: 12px; vertical-align: middle; }
726
.tb-mark { display: inline-flex; font-weight: 700; }
727
.tb-pass { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, var(--line)); background: color-mix(in srgb, var(--ok) 8%, transparent); }
728
.tb-warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, var(--line)); background: color-mix(in srgb, var(--warn) 8%, transparent); }
729
.tb-fail { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, var(--line)); background: color-mix(in srgb, var(--bad) 8%, transparent); }
730
svg.trust-graph .edge { fill: none; stroke: var(--line); stroke-width: 1.5; }
731
svg.trust-graph .edge.dashed { stroke-dasharray: 5 4; stroke: var(--warn); }
732
/* The history graph's .node (a dot) must not reach these groups' text. */
733
svg.trust-graph .node { fill: none; stroke: none; stroke-width: 1; }
734
svg.trust-graph text { stroke: none; }
735
svg.trust-graph .node rect { fill: var(--panel); stroke: var(--line); stroke-width: 1.5; }
736
svg.trust-graph .node.pass rect { stroke: var(--ok); }
737
svg.trust-graph .node.warn rect { stroke: var(--warn); }
738
svg.trust-graph .node.fail rect { stroke: var(--bad); }
739
svg.trust-graph text { font-size: 11px; fill: var(--ink); }
740
svg.trust-graph text.s { font-size: 10px; fill: var(--mute); }
741
/* Runners (hub spec §13.2) */
742
.runner-status { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; padding: 1px 6px; border: 1px solid var(--line); }
743
.runner-status.st-online { color: var(--ok); border-color: var(--ok); }
744
.runner-status.st-offline { color: var(--mute); }
745
.runner-status.st-draining { color: var(--warn); border-color: var(--warn); }
746
.runner-status.st-disabled { color: var(--bad); border-color: var(--bad); }
747
748
/* The chain of work: issue → proposal → bookmark (hub spec §8). Issues and
749
   proposals share one number space, so every number says which it is. */
750
.kind-issue::before { content: "◇ "; color: var(--warn); }
751
.kind-proposal::before { content: "⇄ "; color: var(--acc); }
752
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; }
753
.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; }
754
a.chain-link:hover { border-color: var(--acc); text-decoration: none; }
755
.chain-kind { font-weight: 600; }
756
.chain-state { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--mute); }
757
.st-open .chain-state, .chain-state.st-open { color: var(--ok); }
758
.st-landed .chain-state, .chain-state.st-landed { color: var(--acc); }
759
.st-closed .chain-state { color: var(--mute); }
760
.chain-arrow { color: var(--acc); font-weight: 700; }
761
.chain-and { color: var(--mute); }
762
763
/* A proposal's conversation as a timeline (hub spec §7): avatars on a rail,
764
   each entry a card with its author and time, events as quiet lines. */
765
.timeline { position: relative; min-width: 0; }
766
.timeline::before { content: ""; position: absolute; left: 17px; top: 12px; bottom: 12px; border-left: 2px solid var(--line); z-index: 0; }
767
.tl-item { position: relative; display: grid; grid-template-columns: 36px minmax(0, 1fr); gap: 14px; margin: 0 0 18px; z-index: 1; }
768
.tl-avatar { width: 36px; height: 36px; border-radius: 50%; border: 2px solid var(--bg); background: var(--panel); }
769
.tl-card { min-width: 0; background: var(--panel); border: 1px solid var(--line); }
770
.tl-head { padding: 8px 14px; border-bottom: 1px solid var(--line); background: var(--soft); font-size: 13px; color: var(--mute); }
771
.tl-head strong { color: var(--ink); }
772
.tl-head .tl-edit { float: right; }
773
.tl-card article.doc.tl-doc { max-width: none; margin: 0; border: 0; }
774
.tl-text { padding: 10px 14px; overflow-wrap: anywhere; }
775
.tl-empty { padding: 10px 14px; margin: 0; }
776
.tl-card form { padding: 10px 14px; margin: 0; }
777
.tl-card textarea { width: 100%; box-sizing: border-box; }
778
.tl-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; padding-top: 0; }
779
form.tl-actions { padding: 0 14px 12px; }
780
.tl-item.review-approve .tl-card { border-color: var(--ok); }
781
.tl-item.review-changes .tl-card { border-color: var(--bad); }
782
.tl-event { position: relative; z-index: 1; display: flex; align-items: center; gap: 6px; margin: -6px 0 16px 10px; font-size: 13px; color: var(--mute); }
783
.tl-event strong { color: var(--ink); font-weight: 600; }
784
.tl-dot { width: 14px; height: 14px; border-radius: 50%; background: var(--soft); border: 2px solid var(--line); flex: none; }
785
.tl-mini { width: 18px; height: 18px; border-radius: 50%; }
786
.timeline form.card.tl-review { max-width: none; margin-left: 50px; }
787
.tl-editbox { margin-left: 50px; }
788
.tl-editbox summary { cursor: pointer; font-weight: 600; }
789
.tl-editbox input[type=text], .tl-editbox textarea { width: 100%; box-sizing: border-box; }
790
.head-edit { margin-left: 8px; vertical-align: middle; }
791
aside.side h3 .side-edit { float: right; font-size: 11px; font-weight: 400; text-transform: none; letter-spacing: 0; }
792
.side-picker summary { cursor: pointer; font-size: 12px; color: var(--acc); }
793
.side-picker form { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
794
.side-check { display: flex; align-items: center; gap: 6px; font-size: 13px; }
795
.side-picker-inline { display: flex; gap: 6px; align-items: center; margin-top: 4px; }
796
.side-picker-inline select { flex: 1; min-width: 0; }
797
@media (max-width: 760px) { .timeline::before { display: none; } .tl-item { grid-template-columns: 1fr; } .tl-avatar { display: none; } .timeline form.card.tl-review, .tl-editbox { margin-left: 0; } }
798
799
/* The issue page's sidebar, as GitHub lays it out (oxygenhub#82): sections
800
   with a heading and a gear opening a filterable menu that applies in one
801
   go; what is set is shown under the heading; moderation as quiet actions. */
802
form.card.comment-form { max-width: none; }
803
/* Proposal and issue sidebars (#162, #163): each section a card, its
804
   heading a shaded bar across the top, as the repository page's cards.
805
   Overflow stays visible so the pickers' menus can open past the card. */
806
.side-sections { display: flex; flex-direction: column; gap: 14px; }
807
.side-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
808
/* Each card a two-column grid: the heading's bar across the top, the
809
   body in the first column, and the heading's cog in the second beside
810
   the body's first row (Andy, 2026-10-13: the cogs go in the body). The
811
   heading's box gives way (display: contents) so its heading and cog are
812
   placed in the card's grid. */
813
.side-sections .side-sec { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); padding: 0 12px 10px; }
814
.side-sections .side-sec > * { grid-column: 1; }
815
/* A long hash or path in a side panel (a check's summary) wraps rather
816
   than pushing the panel wider. */
817
.side-sections .side-sec { min-width: 0; overflow-wrap: anywhere; }
818
.side-sections .side-sec > .side-head { display: contents; }
819
.side-sections .side-sec > .side-head > h3 { grid-column: 1 / -1; grid-row: 1; margin: 0 -12px 10px; padding: 8px 12px; background: var(--soft); border-bottom: 1px solid var(--line); border-radius: 6px 6px 0 0; }
820
.side-sections .side-sec > .side-head > details.menu { grid-column: 2; grid-row: 2; margin-left: 8px; }
821
.side-sections .side-sec.side-actions { padding-top: 6px; }
822
.side-empty, .side-note { margin: 0; font-size: 12px; color: var(--mute); }
823
.side-empty button.linkish { font-size: inherit; }
824
.side-note { margin-top: 6px; }
825
.side-value { margin: 0; font-size: 14px; }
826
.side-labels { margin: 0; display: flex; flex-wrap: wrap; gap: 4px; }
827
.side-labels .label { margin: 0; }
828
.side-people { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
829
.side-people a { display: inline-flex; align-items: center; gap: 8px; color: var(--ink); font-weight: 600; font-size: 13px; }
830
.side-people img.avatar, .menu-item img.avatar { border-radius: 50%; }
831
.side-wide { width: 100%; }
832
form.inline { display: inline; margin: 0; }
833
details.menu { position: relative; }
834
details.menu > summary { list-style: none; cursor: pointer; color: var(--mute); display: inline-flex; padding: 3px; border-radius: 6px; }
835
details.menu > summary::-webkit-details-marker { display: none; }
836
details.menu > summary:hover, details.menu[open] > summary { color: var(--acc); background: var(--soft); }
837
.menu-pop { position: absolute; right: 0; top: 28px; z-index: 30; width: 290px; margin: 0; padding: 0; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, .18); }
838
.menu-title { margin: 0; padding: 9px 12px; font-size: 12px; font-weight: 600; color: var(--ink); }
839
.menu-filter { display: block; width: calc(100% - 20px); margin: 0 10px 10px; box-sizing: border-box; }
840
.menu-list { max-height: 300px; overflow-y: auto; border-top: 1px solid var(--line); }
841
aside.side .menu-item { display: flex; align-items: flex-start; gap: 10px; margin: 0; padding: 8px 12px; border-bottom: 1px solid var(--line); cursor: pointer; font-size: 13px; font-weight: 400; color: var(--ink); text-transform: none; letter-spacing: 0; }
842
aside.side .menu-item:hover { background: var(--soft); }
843
.menu-item input { margin: 2px 0 0; flex: none; }
844
.menu-name { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
845
.menu-name small { color: var(--mute); font-size: 12px; }
846
.menu-empty { margin: 0; padding: 10px 12px; font-size: 12px; color: var(--mute); }
847
.menu-foot { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 8px 12px; }
848
.menu-foot a { margin-right: auto; }
849
.swatch { flex: none; width: 12px; height: 12px; margin-top: 3px; border-radius: 50%; background: var(--c); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .15); }
850
.side-actions form { display: grid; gap: 2px; }
851
button.side-action { all: unset; cursor: pointer; display: flex; align-items: center; gap: 10px; padding: 5px 0; font-size: 13px; font-weight: 600; color: var(--ink); }
852
button.side-action span { width: 16px; text-align: center; color: var(--mute); }
853
button.side-action:hover { color: var(--acc); }
854
button.side-action:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
855
856
/* Device sign-in's answer (oxygenhub#83). */
857
.device-done h2 { display: flex; align-items: center; gap: 10px; margin-top: 0; }
858
.device-mark { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 50%; font-size: 16px; color: #fff; }
859
.device-done.ok .device-mark { background: var(--ok); }
860
.device-done.no .device-mark { background: var(--bad); }
861
.side-note-inline { font-size: 12px; color: var(--mute); font-weight: 400; }
862
.side-list li { margin: 0 0 4px; }
863
.side-list form.inline { margin-left: 6px; }
864
.side-assist { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; margin-top: 8px; }
865
.side-assist form.inline { display: block; margin: 0; }
866
.model-row { display: flex; gap: 6px; align-items: center; }
867
.model-row input { flex: 1; }
868
/* A button that asks an AI agent: its mark, then the verb and its name. */
869
button.agent-btn { display: inline-flex; align-items: center; gap: 7px; padding: 4px 10px 4px 6px; font-size: 11px; line-height: 16px; }
870
button.agent-btn img { width: 16px; height: 16px; border-radius: 50%; flex: 0 0 16px; }
871
button.agent-btn:hover img { filter: brightness(1.1); }
872
/* Forms inside a settings panel fill it, and a form that follows a table
873
   (Add a runner) stands off it (oxygenhub#99). */
874
.panel form.card { max-width: none; }
875
.panel .table + form { margin-top: 12px; }
876
877
/* The proposal conversation (oxygenhub#86): a pencil by the title, a ···
878
   menu on the description that edits it in place, one action row under
879
   the comment box, a compact review, and a card when it landed. */
880
.head-pencil { color: var(--mute); display: inline-flex; vertical-align: middle; padding: 4px; margin-left: 6px; border-radius: 6px; }
881
.head-pencil:hover { color: var(--acc); background: var(--soft); }
882
.tl-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
883
.tl-head .tl-when { color: inherit; }
884
.tl-menu > summary.dots { font-weight: 700; letter-spacing: 1px; padding: 0 6px; line-height: 20px; }
885
.menu-pop.menu-actions { width: 180px; padding: 6px 0; top: 26px; }
886
.menu-actions hr { border: 0; border-top: 1px solid var(--line); margin: 6px 0; }
887
.menu-action { all: unset; display: block; box-sizing: border-box; width: 100%; padding: 6px 14px; font-size: 13px; color: var(--ink); cursor: pointer; }
888
.menu-action:hover { background: var(--soft); color: var(--ink); }
889
.tl-editform { display: none; padding: 12px 14px; }
890
.tl-editform:target, .tl-editform.open { display: block; }
891
.tl-card:has(.tl-editform:target) .tl-view, .tl-card:has(.tl-editform.open) .tl-view { display: none; }
892
.edit-row { display: grid; grid-template-columns: 110px 1fr; align-items: center; gap: 10px; margin-bottom: 8px; }
893
.edit-row label { margin: 0; font-size: 13px; font-weight: 600; color: var(--ink); text-transform: none; letter-spacing: 0; }
894
.tl-editform .tl-actions { margin-top: 10px; align-items: center; }
895
.tl-compose { padding: 12px 14px; }
896
.tl-card.tl-compose form { padding: 0; }
897
form.tl-card.tl-compose { padding: 12px 14px; margin: 0; }
898
.tl-compose textarea:not(.md) { font: inherit; font-size: 14px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 6px; background: var(--bg); color: var(--ink); resize: vertical; }
899
.compose-title { margin: 0 0 8px; font-weight: 600; font-size: 14px; color: var(--ink); }
900
.compose-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; margin-top: 10px; }
901
.compose-actions .segmented { margin-right: auto; }
902
.compose-note { margin: 10px 0 0; font-size: 12px; color: var(--mute); }
903
.segmented { display: inline-flex; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; }
904
.segmented label { margin: 0; text-transform: none; letter-spacing: 0; cursor: pointer; }
905
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
906
.segmented span { display: block; padding: 5px 12px; font-size: 13px; font-weight: 500; color: var(--ink); border-right: 1px solid var(--line); }
907
.segmented label:last-child span { border-right: 0; }
908
.segmented input:checked + span { background: var(--acc); color: #fff; }
909
.segmented input:focus-visible + span { outline: 2px solid var(--acc); outline-offset: -2px; }
910
.tl-badge { width: 36px; height: 36px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; background: var(--mute); font-size: 15px; }
911
.tl-badge.review { background: var(--soft); color: var(--mute); border: 1px solid var(--line); }
912
.tl-outcome.landed .tl-badge { background: #8250df; }
913
.tl-outcome.closed .tl-badge { background: var(--bad); }
914
.outcome-card { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; }
915
.tl-outcome.landed .outcome-card { border-color: #8250df; }
916
.outcome-card p { margin: 4px 0 0; color: var(--mute); }
917
.outcome-card form { margin: 0; padding: 0; }
918
.outcome-card form button { white-space: nowrap; }
919
920
/* Form controls, site-wide (oxygenhub#87): every text field, textarea and
921
   select is rounded, padded and rings on focus; a select draws its own
922
   chevron. Zero specificity, so a place that sizes its controls still
923
   does. */
924
:where(input[type=text], input[type=search], input[type=email], input[type=password], input[type=number], input[type=url], input[type=date], input:not([type]), textarea, select) {
925
  box-sizing: border-box; font: inherit; font-size: 14px; line-height: 20px; color: var(--ink);
926
  background-color: var(--bg); border: 1px solid var(--line); border-radius: 6px; padding: 5px 10px;
927
}
928
:where(input[type=text], input[type=search], input[type=email], input[type=password], input[type=number], input[type=url], input[type=date], input:not([type]), textarea, select):focus {
929
  outline: none; border-color: var(--acc); box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 22%, transparent);
930
}
931
:where(input, textarea)::placeholder { color: var(--mute); opacity: 1; }
932
select:not([multiple]) {
933
  appearance: none; -webkit-appearance: none; padding-right: 30px; cursor: pointer;
934
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%238592ad' d='M4.4 6.2a.75.75 0 0 1 1.06 0L8 8.74l2.54-2.54a.75.75 0 1 1 1.06 1.06l-3.07 3.07a.75.75 0 0 1-1.06 0L4.4 7.26a.75.75 0 0 1 0-1.06Z'/%3E%3C/svg%3E");
935
  background-repeat: no-repeat; background-position: right 8px center; background-size: 16px 16px;
936
}
937
input[type=checkbox], input[type=radio] { accent-color: var(--acc); }
938
/* A row of filters: spaced, aligned to one height, wrapping when narrow;
939
   an .end item (a Charts link) sits at the far end. */
940
form.filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 6px 0 12px; }
941
form.filters > select, form.filters > input { width: auto; max-width: 100%; min-width: 0; margin: 0; }
942
form.filters > button { margin: 0; align-self: stretch; }
943
form.filters > .end { margin-left: auto; }
944
/* Insights (oxygenhub#257): headline numbers, then charts drawn by the hub
945
   as inline SVG, coloured through currentColor from these classes. */
946
.insights-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
947
.insights-bar form.filters { margin: 0; }
948
.insights-links { margin-left: auto; display: flex; flex-wrap: wrap; gap: 14px; }
949
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; margin: 14px 0; }
950
.kpi { display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; min-width: 0; }
951
.kpi-v { font-size: 28px; font-weight: 600; line-height: 1.15; font-variant-numeric: tabular-nums; }
952
.kpi-l { font-size: 13px; }
953
.kpi-s { font-size: 12px; color: var(--mute); }
954
.kpi-warn { border-color: var(--warn); }
955
.kpi-bad { border-color: var(--bad); }
956
.chart-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr)); gap: 12px; margin-bottom: 14px; }
957
.chart-card { margin: 0; padding: 10px 12px; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; min-width: 0; }
958
.chart-card figcaption { font-weight: 600; margin-bottom: 4px; }
959
svg.chart { display: block; width: 100%; height: auto; }
960
svg.chart .grid { stroke: var(--line); stroke-width: 1; }
961
svg.chart .axis { fill: var(--mute); font-size: 11px; }
962
svg.chart .line { fill: none; stroke: currentColor; stroke-width: 2; stroke-linejoin: round; }
963
svg.chart .dot, svg.chart .bar { fill: currentColor; }
964
.s-main { color: var(--acc); }
965
.s-warn { color: var(--warn); }
966
.s-ok { color: var(--ok); }
967
.s-bad { color: var(--bad); }
968
.s-mute { color: var(--mute); }
969
.legend { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 12px; margin-top: 4px; }
970
.legend .key { color: var(--ink); }
971
.legend .key::before { content: ""; display: inline-block; width: 10px; height: 10px; margin-right: 6px; border-radius: 2px; background: var(--acc); vertical-align: -1px; }
972
.legend .key.s-warn::before { background: var(--warn); }
973
.legend .key.s-ok::before { background: var(--ok); }
974
.legend .key.s-bad::before { background: var(--bad); }
975
.legend .key.s-mute::before { background: var(--mute); }
976
/* The wall view (?wall=1): for a second monitor, no menus, larger. */
977
body.wall > header, body.wall > .band, body.wall > footer, body.wall > .skip { display: none; }
978
body.wall main { max-width: none; padding: 18px 28px; }
979
body.wall .kpi-v { font-size: 40px; }
980
body.wall .kpi-l { font-size: 15px; }
981
body.wall .chart-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 560px), 1fr)); }
982
/* Landing over required checks (#261): behind a toggle, with its reason. */
983
details.land-over { margin-top: 10px; }
984
details.land-over > summary { cursor: pointer; color: var(--mute); }
985
details.land-over form { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
986
/* A Terraform state's kept versions (#255). */
987
details.tf-versions { margin-top: 14px; }
988
details.tf-versions > summary { cursor: pointer; }
989
.edit-row input { width: 100%; }
990
button.menu-item.menu-pick { all: unset; box-sizing: border-box; width: 100%; display: flex; padding: 8px 12px; border-bottom: 1px solid var(--line); cursor: pointer; font-size: 13px; color: var(--ink); }
991
button.menu-item.menu-pick:hover, button.menu-item.menu-pick:focus-visible { background: var(--soft); }
992
993
/* Mermaid diagrams drawn from ```mermaid blocks (assets/hub.js). */
994
figure.mermaid-diagram { margin: 1em 0; overflow-x: auto; text-align: center; }
995
figure.mermaid-diagram svg { max-width: 100%; height: auto; }
996
997
/* Coverage (#113): the theme's own colours, so it fits every look, light or dark. */
998
.cov-good { color: var(--ok); } .cov-fair { color: color-mix(in srgb, var(--ok) 60%, var(--warn)); } .cov-low { color: var(--warn); } .cov-poor { color: var(--bad); } .cov-none { color: var(--mute); }
999
.cov-hero { border: 1px solid var(--line); border-radius: 10px; background: linear-gradient(180deg, var(--soft), var(--panel)); padding: 1.1em 1.3em .4em; margin: 1em 0; overflow: hidden; }
1000
.cov-hero-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1em; flex-wrap: wrap; }
1001
.cov-hero h1 { margin: 0; font-size: 1.6em; letter-spacing: .01em; }
1002
.cov-sub { margin-top: .3em; font-size: .95em; }
1003
.cov-score { text-align: right; }
1004
.cov-big { font-size: 3.4em; font-weight: 700; line-height: 1; letter-spacing: -.02em; }
1005
.cov-change { font-size: .9em; font-weight: 600; }
1006
.cov-change.up { color: var(--ok); } .cov-change.down { color: var(--bad); } .cov-change.same { color: var(--mute); font-weight: 400; }
1007
.cov-hero-chart { margin: .4em -.6em 0; }
1008
.cov-chart { width: 100%; height: auto; display: block; }
1009
.cov-chart .grid { stroke: var(--line); stroke-width: 1; stroke-dasharray: 2 4; }
1010
.cov-chart .axis { font-size: 11px; fill: var(--mute); }
1011
.cov-chart .area { stroke: none; }
1012
.cov-chart .line { fill: none; stroke-width: 2.2; stroke-linejoin: round; }
1013
.cov-chart .area.cov { fill: color-mix(in srgb, var(--ok) 18%, transparent); } .cov-chart .line.cov, .cov-chart .dot.cov { stroke: var(--ok); fill: var(--ok); }
1014
.cov-chart .line.cov { fill: none; }
1015
.cov-chart .area.relevant { fill: color-mix(in srgb, var(--bad) 14%, transparent); } .cov-chart .line.relevant { stroke: var(--bad); } .cov-chart .dot.relevant { fill: var(--bad); }
1016
.cov-chart .area.covered { fill: color-mix(in srgb, var(--ok) 30%, transparent); } .cov-chart .line.covered { stroke: var(--ok); } .cov-chart .dot.covered { fill: var(--ok); }
1017
.cov-chart .hit { fill: transparent; } .cov-chart .hit:hover { fill: color-mix(in srgb, var(--acc) 10%, transparent); }
1018
.cov-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(9.5em, 1fr)); gap: .6em; margin: 0 0 1em; }
1019
.cov-facts > div { border: 1px solid var(--line); border-radius: 8px; padding: .55em .8em; background: var(--panel); }
1020
.cov-facts .k { display: block; font-size: .72em; text-transform: uppercase; letter-spacing: .06em; color: var(--mute); }
1021
.cov-facts .v { display: block; font-size: 1.25em; font-weight: 600; margin-top: .15em; }
1022
.cov-facts .v small { font-size: .7em; font-weight: 400; color: var(--mute); }
1023
.cov-badge { vertical-align: middle; }
1024
.cov-copy { font-size: .65em; margin-left: .4em; vertical-align: middle; }
1025
.cov-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(20em, 1fr)); gap: 1em; align-items: start; }
1026
.cov-card h3 { font-size: .95em; margin: 1em 0 .4em; }
1027
.cov-stats { list-style: none; padding: 0; margin: 0; line-height: 1.8; }
1028
.cov-moved, .cov-runs { width: 100%; }
1029
.cov-moved td { padding: .15em .3em; } .cov-moved td.num, .cov-files td.num, .cov-files th.num, .cov-runs .num { text-align: right; white-space: nowrap; }
1030
.cov-runs tr.on td { background: var(--soft); }
1031
.cov-bands { display: grid; gap: .55em; margin-top: .4em; }
1032
.cov-band { display: grid; grid-template-columns: 6.5em 1fr 2.5em; align-items: center; gap: .6em; }
1033
.cov-band-lbl { font-size: .9em; color: var(--mute); white-space: nowrap; }
1034
.cov-band .bar { height: .9em; background: var(--soft); border-radius: 4px; overflow: hidden; }
1035
.cov-band .bar > span { display: block; height: 100%; background: currentColor; border-radius: 4px; min-width: 2px; }
1036
.cov-band .n { text-align: right; font-weight: 600; }
1037
.cov-bar { display: inline-block; width: 8em; height: .7em; background: var(--soft); border-radius: 3px; vertical-align: middle; overflow: hidden; }
1038
.cov-bar > span { display: block; height: 100%; background: currentColor; }
1039
.cov-key { padding: 0 .4em; border-radius: 3px; font-size: .85em; }
1040
.cov-key.relevant { background: color-mix(in srgb, var(--bad) 18%, transparent); } .cov-key.covered { background: color-mix(in srgb, var(--ok) 22%, transparent); }
1041
.cov-code tr.cov-hit td.t, .cov-key.cov-hit { background: color-mix(in srgb, var(--ok) 16%, transparent); }
1042
.cov-code tr.cov-miss td.t, .cov-key.cov-miss { background: color-mix(in srgb, var(--bad) 16%, transparent); }
1043
.t-list { list-style: none; padding: 0; margin: 0; line-height: 1.7; overflow-wrap: anywhere; }
1044
.cov-code td.cov-hits { text-align: right; padding: 0 .5em; color: var(--mute); font-size: .85em; white-space: nowrap; user-select: none; }
1045
1046
/* Where a repository's data lives, when it is its owner's bucket (#123):
1047
   the provider's icon, and a card with the details on hover, focus or a
1048
   tap (it takes focus). */
1049
.store { position: relative; display: inline-flex; align-items: center; margin-left: 8px; vertical-align: middle; cursor: pointer; border-radius: 3px; }
1050
.store svg { display: block; }
1051
.store:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
1052
.store-card { display: none; position: absolute; top: calc(100% + 8px); left: -6px; z-index: 30; width: max-content; max-width: min(420px, 90vw); background: var(--panel); border: 1px solid var(--line); box-shadow: 0 8px 24px rgba(0, 0, 0, .28); padding: 10px 12px; font-size: 13px; font-weight: 400; line-height: 1.45; white-space: normal; color: var(--ink); cursor: auto; }
1053
.store-card::before { content: ""; position: absolute; top: -10px; left: 0; right: 0; height: 10px; }
1054
.store:hover .store-card, .store:focus .store-card, .store:focus-within .store-card { display: block; }
1055
.store-card strong { display: block; margin-bottom: 4px; }
1056
.store-card dl { display: grid; grid-template-columns: auto 1fr; gap: 3px 12px; margin: 6px 0 8px; }
1057
.store-card dt { color: var(--mute); }
1058
.store-card dd { margin: 0; min-width: 0; }
1059
.store-card code { word-break: break-all; }
1060
1061
/* Projects (#124): a filter and a New project button above a panel of
1062
   rows with Open and Closed tabs; the form opens from the button. */
1063
.proj-bar { display: flex; align-items: center; gap: 10px; margin: 0 0 14px; }
1064
.proj-filter { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; margin: 0; padding: 0 10px; border: 1px solid var(--line); background: var(--panel); color: var(--mute); }
1065
.proj-filter:focus-within { border-color: var(--acc); }
1066
.proj-filter input { flex: 1; min-width: 0; width: auto; margin: 0; padding: 7px 0; border: 0; background: transparent; color: var(--ink); outline: none; }
1067
.proj-new { display: none; max-width: 560px; margin: 0 0 16px; }
1068
.proj-new:target, .proj-new.open { display: block; }
1069
.proj-new h2 { margin-top: 0; }
1070
.proj-new-actions { display: flex; align-items: center; gap: 14px; margin-top: 4px; }
1071
.proj-list { border: 1px solid var(--line); background: var(--panel); }
1072
.proj-tabs { display: flex; gap: 4px; padding: 8px 12px; background: var(--soft); border-bottom: 1px solid var(--line); }
1073
.proj-tabs a { display: inline-flex; align-items: center; gap: 6px; padding: 4px 8px; color: var(--mute); font-size: 14px; }
1074
.proj-tabs a:hover { color: var(--ink); text-decoration: none; }
1075
.proj-tabs a.on { color: var(--ink); font-weight: 600; }
1076
.proj-rows { list-style: none; margin: 0; padding: 0; }
1077
.proj-rows li { display: flex; align-items: flex-start; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
1078
.proj-rows li:last-child { border-bottom: 0; }
1079
.proj-rows li:hover { background: var(--soft); }
1080
.proj-icon { flex: none; margin-top: 3px; color: var(--mute); }
1081
.proj-main { flex: 1; min-width: 0; }
1082
.proj-main p { margin: 2px 0 0; }
1083
.proj-title { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
1084
.proj-title .name { font-size: 16px; font-weight: 600; }
1085
.proj-title .vis { margin-left: 2px; }
1086
.proj-desc { color: var(--ink); font-size: 14px; }
1087
.proj-list .empty { border: 0; margin: 0; }
1088
1089
/* Reports (oxygenhub#127) */
1090
.rep-top h1 { margin-bottom: .2em; }
1091
.rep-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(21em, 1fr)); gap: 1em; margin-top: 1.2em; }
1092
.rep-card { --tone: var(--mute); position: relative; display: flex; flex-direction: column; gap: .7em; padding: 1.1em 1.2em 1em; border: 1px solid var(--line); border-top: 3px solid var(--tone); border-radius: 12px;
1093
  background: linear-gradient(180deg, color-mix(in srgb, var(--tone) 9%, var(--panel)), var(--panel) 70%); transition: border-color .15s, transform .15s, box-shadow .15s; }
1094
.rep-card:hover { transform: translateY(-1px); box-shadow: 0 6px 18px color-mix(in srgb, var(--tone) 18%, transparent); border-color: color-mix(in srgb, var(--tone) 55%, var(--line)); }
1095
.rep-card.rep-good { --tone: var(--ok); } .rep-card.rep-bad { --tone: var(--bad); } .rep-card.rep-neutral { --tone: var(--acc); }
1096
.rep-head { display: flex; align-items: center; gap: .7em; }
1097
.rep-icon { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 10px; color: var(--kind); background: color-mix(in srgb, var(--kind) 14%, transparent); }
1098
.rep-icon.rep-performance { --kind: var(--acc); } .rep-icon.rep-coverage { --kind: var(--ok); } .rep-icon.rep-tests { --kind: var(--warn); } .rep-icon.rep-custom { --kind: var(--mute); }
1099
.rep-name { display: flex; flex-direction: column; min-width: 0; flex: 1; }
1100
.rep-link { color: var(--ink); font-weight: 600; font-size: 1.08em; }
1101
.rep-link::after { content: ""; position: absolute; inset: 0; border-radius: 12px; }
1102
.rep-kindname { color: var(--mute); font-size: .8em; text-transform: uppercase; letter-spacing: .06em; }
1103
.rep-badge { flex: none; font-size: .8em; font-weight: 600; padding: .2em .65em; border-radius: 999px; color: var(--tone); background: color-mix(in srgb, var(--tone) 14%, transparent); }
1104
.rep-summary { margin: 0; color: var(--ink); }
1105
.rep-tiles { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5em; }
1106
.rep-tiles li { display: flex; flex-direction: column; padding: .5em .65em; border-radius: 8px; background: var(--soft); min-width: 0; }
1107
.rep-tiles .v { font-size: 1.15em; font-weight: 600; font-variant-numeric: tabular-nums; }
1108
.rep-tiles .v small { font-weight: 400; color: var(--mute); font-size: .7em; }
1109
.rep-tiles .k { font-size: .78em; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1110
.rep-tiles li.rep-failing { box-shadow: inset 3px 0 0 var(--bad); }
1111
.rep-hero { display: flex; flex-direction: column; gap: .1em; }
1112
.rep-big { font-size: 2em; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--tone); line-height: 1.1; }
1113
.rep-foot { margin-top: auto; font-size: .82em; color: var(--mute); display: flex; flex-wrap: wrap; align-items: center; gap: .35em; }
1114
.rep-kind { text-transform: lowercase; }
1115
.rep-performance { color: var(--acc); } .rep-coverage { color: var(--ok); } .rep-tests { color: var(--warn); } .rep-custom { color: var(--mute); }
1116
.rep-delta { font-size: .8em; font-weight: 600; font-variant-numeric: tabular-nums; }
1117
.rep-delta.better { color: var(--ok); } .rep-delta.worse { color: var(--bad); } .rep-delta.same { color: var(--mute); }
1118
.rep-failing .v, .rep-failing strong { color: var(--bad); }
1119
.rep-table { width: 100%; border-collapse: collapse; }
1120
.rep-table th, .rep-table td { padding: .45em .6em; border-bottom: 1px solid var(--line); text-align: left; vertical-align: middle; }
1121
.rep-table .num { text-align: right; font-variant-numeric: tabular-nums; }
1122
.rep-spark polyline { fill: none; stroke: var(--acc); stroke-width: 1.5; }
1123
.rep-spark circle { fill: var(--acc); }
1124
.rep-frame-wrap { margin: 1em 0; }
1125
.rep-frame { display: block; width: 100%; height: 70vh; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
1126
.rep-frame.sized { overflow: hidden; }
1127
.rep-context { display: grid; grid-template-columns: max-content 1fr; gap: .3em 1em; margin: 0; }
1128
.rep-context dt { color: var(--mute); }
1129
.rep-context dd { margin: 0; font-variant-numeric: tabular-nums; }
1130
.rep-runs { list-style: none; padding: 0; margin: 0; }
1131
.rep-runs li { padding: .25em 0; }
1132
.rep-runs li.on a { font-weight: 700; }
1133
1134
/* Reports timeline (oxygenhub#127, RP4) */
1135
.rep-timeline { margin: 1em 0; padding: .8em 1em; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); }
1136
.rep-tl-bar { display: flex; flex-wrap: wrap; align-items: center; gap: .6em 1.2em; margin-bottom: .7em; }
1137
.rep-tl-btn { font: inherit; font-weight: 600; padding: .3em .9em; border-radius: 999px; border: 1px solid var(--acc); color: var(--acc); background: transparent; cursor: pointer; }
1138
.rep-tl-btn:hover { background: color-mix(in srgb, var(--acc) 12%, transparent); }
1139
.rep-tl-keys { margin-left: auto; }
1140
.rep-tl-stops { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; gap: 2px; }
1141
.rep-tl-stops li { flex: 1; min-width: 4px; }
1142
.rep-tl-stop { display: block; height: 14px; border-radius: 3px; background: color-mix(in srgb, var(--acc) 22%, var(--soft)); }
1143
.rep-tl-stop:hover { background: color-mix(in srgb, var(--acc) 55%, var(--soft)); }
1144
.rep-tl-stop.on { background: var(--acc); height: 22px; }
1145
.rep-tl-stop.cmp { background: var(--warn); height: 22px; }
1146
.rep-tl-ends { display: flex; justify-content: space-between; margin-top: .3em; }
1147
.rep-cmp-h { display: flex; align-items: baseline; gap: 1em; font-size: 1.05em; margin: 0 0 .6em; }
1148
.rep-frame-wrap.rep-side { display: grid; grid-template-columns: 1fr 1fr; gap: 1em; }
1149
.rep-frame-wrap.rep-side > p { grid-column: 1 / -1; }
1150
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
1151
1152
/* Working (#142): a pressed button's spinner, and the Oxygen mark's rings
1153
   spinning and its arms sliding back and forth in turn while a slow page
1154
   loads (hub.js adds .oxy-wait after 300 ms; #306). The pointer keeps its own
1155
   shape: the mark beside it is the only sign. */
1156
button[aria-busy=true] { opacity: 1; }
1157
.oxy-spin { display: inline-block; width: 1em; text-align: center; }
1158
.oxy-wait-mark { display: none; position: fixed; z-index: 1000; pointer-events: none; padding: 4px 6px; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, .18); line-height: 0; }
1159
.oxy-wait-mark svg { width: 36px; height: 18px; }
1160
.oxy-wait-mark.corner { left: auto !important; top: calc(env(safe-area-inset-top, 0px) + 68px) !important; right: 16px; }
1161
.oxy-wait .oxy-wait-mark { display: block; }
1162
.oxy-wait header .brand svg circle[r="10"], .oxy-wait-mark svg circle[r="10"] { stroke-dasharray: 44 18.8; animation: oxy-ring .9s linear infinite; }
1163
.oxy-wait header .brand svg circle[cx="11"][r="10"], .oxy-wait-mark svg circle[cx="11"][r="10"] { animation-direction: reverse; }
1164
.oxy-wait header .brand svg .arm, .oxy-wait-mark svg .arm { animation: oxy-arm .9s ease-in-out infinite alternate; }
1165
.oxy-wait header .brand svg .arm + .arm, .oxy-wait-mark svg .arm + .arm { animation-direction: alternate-reverse; }
1166
@keyframes oxy-ring { to { stroke-dashoffset: -62.8; } }
1167
@keyframes oxy-arm { from { transform: translateX(-3px); } to { transform: translateX(3px); } }
1168
@media (prefers-reduced-motion: reduce) {
1169
  .oxy-wait header .brand svg circle[r="10"], .oxy-wait-mark svg circle[r="10"] { animation: none; stroke-dasharray: none; }
1170
  .oxy-wait header .brand svg .arm, .oxy-wait-mark svg .arm { animation: none; }
1171
}
1172
1173
/* Admin › Runners › Images (C0, docs/cylinder.md): where each image is. */
1174
table.images td { vertical-align: top; }
1175
table.images tr.stranded td:first-child { box-shadow: inset 3px 0 0 var(--bad); }
1176
.lbl.img-hub { color: var(--acc); border-color: var(--acc); }
1177
.lbl.img-holds { color: var(--ok); border-color: var(--ok); }
1178
.lbl.img-fetching { color: var(--warn); border-color: var(--warn); }
1179
1180
/* Diffusion (#150): each consumer's status at a glance. */
1181
.df-chip { display: inline-block; font-size: 12px; padding: 1px 8px; border-radius: 10px; border: 1px solid; white-space: nowrap; }
1182
.df-green { color: var(--ok); border-color: var(--ok); }
1183
.df-amber { color: #b7791f; border-color: #e3a008; background: color-mix(in srgb, #e3a008 12%, transparent); }
1184
.df-red { color: var(--bad); border-color: var(--bad); }
1185
.df-grey { color: var(--mute); border-color: var(--line); }
1186
.df-current { color: var(--acc); border-color: var(--acc); }
1187
.df-off { color: var(--dim); border-color: var(--line); border-style: dashed; }
1188
.df-key .df-chip { margin-right: 2px; }
1189
table.diffusion td { vertical-align: middle; }
1190
/* Every upstream's table shares one column grid (#152), so the tables on
1191
   the Diffusion pages line up with each other. */
1192
table.diffusion { table-layout: fixed; width: 100%; min-width: 880px; }
1193
table.diffusion td { overflow-wrap: anywhere; }
1194
table.diffusion .df-c-repo { width: 26%; }
1195
table.diffusion .df-c-pin { width: 10%; }
1196
table.diffusion .df-c-behind { width: 7%; }
1197
table.diffusion .df-c-pill { width: 17%; }
1198
table.diffusion .df-c-bump { width: 16%; }
1199
table.diffusion .df-c-landed { width: 14%; }
1200
table.diffusion .df-c-follow { width: 10%; }
1201
table.diffusion .df-path { display: block; }
1202
1203
/* The Diffusion pill (#150): two halves like a capsule, the upstream on
1204
   the left, the repository that pins it on the right. */
1205
.df-pill { display: inline-flex; border-radius: 999px; overflow: hidden; font-size: 12px; line-height: 1.6; vertical-align: middle; box-shadow: inset 0 0 0 1px var(--line); white-space: nowrap; }
1206
.df-half { padding: 0 9px; font-weight: 600; }
1207
.df-half + .df-half { border-left: 1px solid rgba(255, 255, 255, .55); }
1208
.df-half.df-green { background: #1a7f4b; color: #fff; }
1209
.df-half.df-amber { background: #e3a008; color: #2b1d00; }
1210
.df-half.df-red { background: #c62d47; color: #fff; }
1211
.df-half.df-grey { background: var(--soft); color: var(--mute); }
1212
.df-half.df-off { background: transparent; color: var(--mute); border-style: solid; border-width: 0; }
1213
.df-half + .df-half.df-off { border-left: 1px solid var(--line); }
1214
1215
/* Icons (#152): inline SVGs in the colour of their text. */
1216
svg.ic { width: 16px; height: 16px; vertical-align: -3px; flex: none; }
1217
.band a { display: inline-flex; align-items: center; gap: 6px; }
1218
.band a svg.ic { opacity: .8; }
1219
table.tree td.g svg.ic { vertical-align: -3px; }
1220
table.tree td.g.ic-dir { color: #54aeff; }
1221
table.tree td.g.ic-file, table.tree td.g.ic-link { color: var(--mute); }
1222
table.tree td.g.ic-sub { color: var(--acc); }
1223
1224
/* The tree's shaded head (#152): the latest change, and the history. */
1225
.tree-box { margin-top: 4px; }
1226
.tree-head { display: flex; align-items: center; gap: 10px; background: var(--soft); border: 1px solid var(--line); border-bottom: 0; border-radius: 6px 6px 0 0; padding: 8px 16px; font-size: 13px; }
1227
.tree-head .tree-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1228
.tree-head .tree-title a.t { color: var(--ink); }
1229
.tree-head .tree-title a.who { font-weight: 600; color: var(--ink); }
1230
.tree-head img.avatar { width: 20px; height: 20px; border-radius: 50%; vertical-align: middle; }
1231
.tree-head .tree-meta { display: flex; align-items: center; gap: 12px; white-space: nowrap; color: var(--mute); }
1232
.tree-head .tree-meta a { color: var(--mute); }
1233
.tree-head .tree-meta a.hist { display: inline-flex; align-items: center; gap: 4px; color: var(--ink); font-weight: 600; }
1234
.tree-box .tree-head + table.tree { border-top-left-radius: 0; border-top-right-radius: 0; margin-top: 0; }
1235
@media (max-width: 760px) { .tree-head .tree-meta .ago { display: none; } }
1236
1237
/* The sidebar as cards (#152): each section a rounded box with a shaded
1238
   heading. */
1239
aside.side.cards { display: flex; flex-direction: column; gap: 14px; }
1240
.side-card { border: 1px solid var(--line); border-radius: 6px; background: var(--panel); overflow: hidden; }
1241
.side-card > h3 { margin: 0; padding: 8px 12px; background: var(--soft); border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 6px; }
1242
.side-card > h3 .more { margin-left: auto; font-size: 12px; font-weight: 400; text-transform: none; letter-spacing: 0; }
1243
.side-card > .body { padding: 10px 12px; }
1244
.side-card > .body > :first-child { margin-top: 0; }
1245
.side-card > .body > :last-child { margin-bottom: 0; }
1246
.side-card h4 { margin: 10px 0 4px; font-size: 12px; font-weight: 600; color: var(--mute); }
1247
.side-card h4:first-child { margin-top: 0; }
1248
ul.contributors li.c { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
1249
ul.contributors li.c > .who { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1250
ul.contributors li.c > .n { margin-left: auto; }
1251
ul.df-list { margin: 0; }
1252
ul.df-list li { padding: 6px 0; border-top: 1px solid var(--line); }
1253
ul.df-list li:first-child { border-top: 0; padding-top: 0; }
1254
ul.df-list .df-name { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1255
ul.df-list .df-line { display: flex; align-items: center; gap: 8px; margin-top: 3px; font-size: 12px; }
1256
ul.bookmarks li { display: flex; align-items: center; gap: 6px; }
1257
ul.bookmarks li > a { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1258
1259
/* A main-column section as a card (#155), the counterpart of the
1260
   sidebar's side-card: a rounded box, its heading and count in a shaded
1261
   bar, its list flush inside. */
1262
.card-box { border: 1px solid var(--line); border-radius: 6px; background: var(--panel); overflow: hidden; margin-bottom: 16px; }
1263
.card-box > .card-head { display: flex; align-items: center; gap: 8px; padding: 8px 16px; background: var(--soft); border-bottom: 1px solid var(--line); }
1264
.card-box > .card-head h2, .card-box > .card-head h3 { margin: 0; font-size: 14px; font-weight: 600; }
1265
.card-box > .card-head .more { margin-left: auto; font-size: 12px; }
1266
.card-box > ul.rows, .card-box > ul.feed { border: 0; border-radius: 0; margin: 0; }
1267
.card-box > ul.rows li { margin: 0; border: 0; border-top: 1px solid var(--line); }
1268
.card-box > ul.rows li:first-child, .card-box > ul.feed li:first-child { border-top: 0; }
1269
.card-box > .empty { margin: 0; padding: 12px 16px; }
1270
ul.repo-list li { display: flex; align-items: center; gap: 6px; margin: 3px 0; }
1271
ul.repo-list li > a { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1272
1273
/* Backdrops (docs/backgrounds.md, #157): the canvas behind a page's
1274
   content, never in its way. The page's background moves to the root so
1275
   the canvas shows in the margins and between the cards. */
1276
#backdrop { position: fixed; inset: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none; display: block; }
1277
html:has(#backdrop) body { background: transparent; }
1278
.bd-label { position: fixed; z-index: -1; pointer-events: none; transform: translate(-50%, -100%); font-size: 12px; color: var(--mute); opacity: 0; transition: opacity .3s; white-space: nowrap; }
1279
@media (prefers-reduced-motion: reduce) { .bd-label { transition: none; } }
1280
1281
/* The page's primary action (#161): filled with the accent. */
1282
a.go.primary, summary.go.primary { background: var(--acc); color: var(--panel); border-color: var(--acc); }
1283
a.go.primary:hover, summary.go.primary:hover { filter: brightness(1.1); text-decoration: none; }
1284
1285
/* The About card (#159): counts in its heading, the actions centred. */
1286
.side-card.about > h3 .about-counts { display: inline-flex; align-items: center; gap: 12px; color: var(--mute); font-size: 12px; font-weight: 400; text-transform: none; letter-spacing: 0; }
1287
.side-card.about > h3 .about-counts > * { display: inline-flex; align-items: center; gap: 4px; color: var(--mute); }
1288
.side-card.about > h3 .about-counts svg.ic { width: 14px; height: 14px; vertical-align: 0; }
1289
.side-card.about .topics { margin: 10px 0; }
1290
.about-actions { display: flex; justify-content: center; align-items: center; gap: 10px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
1291
.about-actions form { margin: 0; }
1292
.about-propose { text-align: center; margin: 10px 0 0; }
1293
1294
/* Diffusion rows (#160): the repository and its pill on one line, how far
1295
   behind beneath, a rule between rows. */
1296
ul.df-list .df-row { display: flex; align-items: center; gap: 8px; }
1297
ul.df-list .df-row .df-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1298
ul.df-list .df-row .df-pill { flex: none; }
1299
ul.df-list .df-sub { display: flex; gap: 10px; margin-top: 2px; font-size: 12px; color: var(--mute); }
1300
1301
/* Every boxed section's heading as a shaded bar (#164): a panel's or a
1302
   form card's leading heading (after its hidden CSRF field, in a form)
1303
   runs across the box's top, as the cards' headings do. */
1304
.panel { --box-py: 14px; --box-px: 16px; }
1305
form.card { --box-py: 18px; --box-px: 20px; }
1306
:is(.panel, form.card) > h2:first-child,
1307
:is(.panel, form.card) > input[type=hidden]:first-child + h2 {
1308
  margin: calc(-1 * var(--box-py)) calc(-1 * var(--box-px)) 14px;
1309
  padding: 10px var(--box-px);
1310
  background: var(--soft);
1311
  border-bottom: 1px solid var(--line);
1312
  font-size: 15px;
1313
}
1314
/* A sidebar section with no heading (a wiki's own sidebar) keeps its
1315
   padding at the top. */
1316
.side-sections .side-sec:not(:has(> .side-head)) { padding-top: 10px; }
1317
.card-box > ul.card-list { margin: 0; padding: 10px 16px; }
1318
.who-card .side-card { margin-top: 14px; }
1319
1320
/* Backups (#169): each run's outcome. */
1321
.backup-status { display: inline-block; padding: 0 8px; border-radius: 10px; font-size: 12px; font-weight: 600; border: 1px solid; }
1322
.backup-status.st-ok { color: var(--ok); }
1323
.backup-status.st-partial { color: var(--warn); }
1324
.backup-status.st-failed { color: var(--bad); }
1325
.backup-status.st-running { color: var(--mute); }
1326
.backup-what { max-width: 760px; }
1327
1328
/* Nothing runs out of its card (#170): long tokens in the timeline and in
1329
   inline code wrap where they must. */
1330
.tl-event, .tl-event code { overflow-wrap: anywhere; }
1331
article.doc :not(pre) > code, .comment :not(pre) > code, .tl-card :not(pre) > code { overflow-wrap: anywhere; }
1332
/* Settings › Tokens (oxygenhub#185): one card per token, actions beside it. */
1333
.card-box > .pad, .card-box .pad { padding: 14px 16px; }
1334
.token-rows li { display: flex; align-items: flex-start; gap: 16px; padding: 12px 16px; }
1335
.token-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
1336
.token-scopes { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
1337
.token-scopes .chip { font-size: 11.5px; padding: 1px 6px; border: 1px solid var(--line); border-radius: 10px; background: var(--soft); }
1338
.token-actions { display: flex; gap: 6px; flex-shrink: 0; }
1339
button.danger { color: var(--bad); }
1340
.agent-pill { font-size: 11px; padding: 1px 7px; border-radius: 10px; background: color-mix(in srgb, var(--acc) 18%, transparent); color: var(--ink); }
1341
/* Settings › Security (#285): every box the page's width, a form's
1342
   field and button on one row. */
1343
.sec-form p { margin: 0 0 10px; }
1344
.sec-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
1345
.sec-row label { margin: 0; font-weight: 600; }
1346
.sec-row input { flex: 0 1 320px; min-width: 0; }
1347
.sec-split { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
1348
.sec-split p { margin: 0; }
1349
.card-box > .card-head form.more { margin-left: auto; }
1350
.card-box > .sec-foot { margin: 0; border-top: 1px solid var(--line); }
1351
.token-form { display: flex; flex-direction: column; gap: 6px; max-width: 720px; }
1352
.token-form .scopes { display: flex; flex-direction: column; gap: 2px; }
1353
.token-form button[type=submit] { align-self: flex-start; margin-top: 8px; }
1354
.token-form .token-agent { margin-top: 8px; }
1355
.token-form .token-hint { margin: 0 0 0 24px; }
1356
@media (max-width: 700px) { .token-rows li { flex-direction: column; } }
1357
/* Settings › Keys (oxygenhub#188) shares the token rows; Backups' form is as wide as its Runs (#189). */
1358
form.card.keys-verify { max-width: none; }
1359
form.card.backup-form { max-width: none; }
1360
/* Wiki clone box (oxygenhub#192): the command wraps inside its card. */
1361
.side-sec pre.snippet { white-space: pre-wrap; overflow-wrap: anywhere; margin: 0; }
1362
/* The overview's bookmark and tag picker (oxygenhub#191). */
1363
details.ref-pick { position: relative; }
1364
details.ref-pick > summary { list-style: none; cursor: pointer; }
1365
details.ref-pick > summary::-webkit-details-marker { display: none; }
1366
.ref-panel { position: absolute; z-index: 30; top: calc(100% + 4px); left: 0; min-width: 240px; max-width: min(360px, 90vw); max-height: 60vh; overflow: auto; background: var(--panel); border: 1px solid var(--line); border-radius: 6px; box-shadow: 0 8px 24px rgba(0,0,0,.15); padding: 8px 0; }
1367
.ref-panel p { margin: 4px 12px; }
1368
.ref-panel ul { margin: 0; }
1369
.ref-panel li a { display: block; padding: 4px 12px; overflow-wrap: anywhere; }
1370
.ref-panel li a:hover, .ref-panel li a.on { background: var(--soft); text-decoration: none; }
1371
.ref-panel li a.on { font-weight: 600; }
1372
/* The Markdown editor in GitLab's manner (oxygenhub#193): one bordered box,
1373
   a Preview tab, icon buttons, a footer. */
1374
.EasyMDEContainer { border: 1px solid var(--line); border-radius: 6px; background: var(--bg); overflow: hidden; }
1375
.EasyMDEContainer:focus-within { border-color: var(--acc); box-shadow: 0 0 0 2px color-mix(in srgb, var(--acc) 25%, transparent); }
1376
.EasyMDEContainer .editor-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; background: var(--panel); padding: 4px 6px; }
1377
.EasyMDEContainer .editor-toolbar i.separator { border-left: 1px solid var(--line); border-right: 0; height: 18px; margin: 0 4px; }
1378
.EasyMDEContainer .editor-toolbar button.mde-btn { border: 0; background: transparent; display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 28px; padding: 0; border-radius: 6px; color: var(--mute); }
1379
.EasyMDEContainer .editor-toolbar button.mde-btn.mde-text { width: auto; padding: 0 10px; font-size: 13px; font-weight: 500; color: var(--ink); }
1380
.EasyMDEContainer .editor-toolbar button.mde-btn:hover, .EasyMDEContainer .editor-toolbar button.mde-btn.active { background: var(--soft); color: var(--ink); }
1381
.EasyMDEContainer .editor-toolbar button.fullscreen { margin-left: auto; }
1382
.EasyMDEContainer .editor-toolbar .mde-ico { display: inline-flex; }
1383
.EasyMDEContainer .CodeMirror { border: 0; border-radius: 0; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 13px; }
1384
.EasyMDEContainer .CodeMirror .CodeMirror-placeholder { color: var(--mute); }
1385
.EasyMDEContainer .editor-preview { background: var(--bg); color: var(--ink); }
1386
.mde-foot { display: flex; justify-content: space-between; align-items: center; padding: 4px 10px; border-top: 1px solid var(--line); background: var(--panel); }
1387
.mde-md { font-weight: 700; border: 1px solid currentColor; border-radius: 3px; padding: 0 3px; font-size: 10px; }
1388
.EasyMDEContainer .editor-toolbar.fullscreen, .EasyMDEContainer .CodeMirror-fullscreen, .EasyMDEContainer .editor-preview-active-side { background: var(--bg); }
1389
/* Wiki pages (oxygenhub#194): a title row with who edited it and the
1390
   buttons, the page as a card, pages and contents in the side bar. */
1391
.wiki-top { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 12px; padding-bottom: 12px; margin-bottom: 16px; border-bottom: 1px solid var(--line); }
1392
.wiki-title { min-width: 0; }
1393
.wiki-title h1 { margin: 0 0 4px; text-wrap: balance; }
1394
.wiki-title p { margin: 0; }
1395
.wiki-actions { display: flex; gap: 8px; flex-shrink: 0; }
1396
article.wiki-doc.card-doc { border: 1px solid var(--line); border-radius: 6px; background: var(--panel); padding: 20px 28px; }
1397
.wiki-foot { margin-top: 8px; }
1398
.wiki-side-col .side-sec { min-width: 0; }
1399
details.wiki-pages > summary { list-style: none; cursor: pointer; }
1400
details.wiki-pages > summary::-webkit-details-marker { display: none; }
1401
details.wiki-pages > summary h3::before { content: "▸ "; color: var(--mute); }
1402
details.wiki-pages[open] > summary h3::before { content: "▾ "; }
1403
.wiki-pages ul, .wiki-toc { margin: 0; padding: 6px 12px; }
1404
.wiki-pages li a, .wiki-toc li a { display: block; padding: 2px 0; overflow-wrap: anywhere; }
1405
.wiki-pages li a.on { font-weight: 600; }
1406
.wiki-pages p { margin: 0 12px 8px; }
1407
.wiki-toc li.lv2 { padding-left: 12px; }
1408
.wiki-toc li.lv3 { padding-left: 24px; font-size: 13px; }
1409
.wiki-side-col .clone { display: flex; gap: 6px; padding: 8px 12px; }
1410
.wiki-side-col .clone input { flex: 1; min-width: 0; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; }
1411
.wiki-doc h1[id], .wiki-doc h2[id], .wiki-doc h3[id] { scroll-margin-top: 16px; }
1412
.EasyMDEContainer .editor-toolbar button.mde-btn.mde-text, .EasyMDEContainer .editor-toolbar button.mde-btn.mde-text::first-letter { text-transform: none; }
1413
/* A long hash or state address shows its two ends; the whole of it in a
1414
   wrapped, square-ish tip on hover or focus (oxygenhub#198). */
1415
.hash-tip { position: relative; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .92em; cursor: help; border-bottom: 1px dotted currentColor; white-space: nowrap; }
1416
.hash-tip::after { content: attr(data-full); position: absolute; z-index: 40; top: calc(100% + 6px); left: 0; width: min(34ch, 80vw); padding: 8px 10px; background: var(--panel); color: var(--ink); border: 1px solid var(--line); border-radius: 6px; box-shadow: 0 8px 24px rgba(0,0,0,.15); white-space: normal; overflow-wrap: anywhere; word-break: break-all; line-height: 1.45; font-size: 12px; visibility: hidden; opacity: 0; transition: opacity .12s; pointer-events: none; text-transform: none; font-weight: 400; }
1417
.hash-tip:hover::after, .hash-tip:focus::after { visibility: visible; opacity: 1; }
1418
/* Sign-in with a provider (oxygenhub#213): branded buttons beside the
1419
   sign-in box, in the style of Gitter's (the provider's colour and logo). */
1420
.signin-layout { display: flex; flex-wrap: wrap; align-items: center; gap: 24px; }
1421
.signin-layout > form.card { flex: 1 1 320px; margin: 0; }
1422
.signin-or { display: flex; flex-direction: column; align-items: center; align-self: stretch; color: var(--mute); font-size: 12px; text-transform: uppercase; letter-spacing: .08em; }
1423
.signin-or::before, .signin-or::after { content: ""; flex: 1; width: 1px; background: var(--line); }
1424
.signin-or span { padding: 8px 0; }
1425
.signin-with { display: flex; flex-direction: column; gap: 10px; flex: 0 1 280px; min-width: 0; }
1426
/* `:root .signin-with` outranks the looks' link colours (assets/github.css). */
1427
:root .signin-with a.signin-btn { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 11px 16px; border-radius: 4px; color: #fff; font-weight: 700; font-size: 13px; letter-spacing: .06em; text-transform: uppercase; text-decoration: none; border: 1px solid transparent; }
1428
:root .signin-with a.signin-btn svg { flex-shrink: 0; fill: currentColor; }
1429
:root .signin-with a.signin-btn:hover, :root .signin-with a.signin-btn:focus-visible { filter: brightness(1.08); text-decoration: none; color: #fff; }
1430
:root .signin-with a.signin-btn:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
1431
:root .signin-with a.signin-btn.gitlab { background: #cf3d1b; } /* GitLab's red-orange, dark enough for white text (4.8:1) */
1432
:root .signin-with a.signin-btn.github { background: #24292f; }
1433
:root .signin-with a.signin-btn.google { background: #fff; color: #3c4043; border-color: #dadce0; }
1434
:root .signin-with a.signin-btn.google:hover, :root .signin-with a.signin-btn.google:focus-visible { color: #3c4043; background: #f8f9fa; filter: none; }
1435
@media (max-width: 700px) {
1436
  .signin-or { flex-direction: row; width: 100%; }
1437
  .signin-or::before, .signin-or::after { height: 1px; width: auto; }
1438
  .signin-or span { padding: 0 8px; }
1439
  .signin-with { flex-basis: 100%; }
1440
}
1441
/* The profile's pulse (oxygenhub#217): repository colours that read on
1442
   both looks and both themes, and the agents' violet. */
1443
:root { --pu1: #2f81f7; --pu2: #0fb5c9; --pu3: #2da44e; --pu4: #e3832a; --pu5: #d1453b; --pu6: #c2307a; --pu7: #b08800; --pu8: #8c959f; --pu-agent: #8a63d2; }
1444
.pulse-box .card-head { flex-wrap: wrap; row-gap: 6px; }
1445
.pulse-total { font-weight: 700; font-variant-numeric: tabular-nums; }
1446
.pulse-legend { display: flex; flex-wrap: wrap; gap: 4px; }
1447
:root .pulse-legend button.pu-chip { display: inline-flex; align-items: center; gap: 5px; padding: 1px 8px; font-size: 11.5px; line-height: 1.6; border-radius: 999px; text-transform: none; letter-spacing: 0; font-weight: 500; min-height: 0; }
1448
:root .pulse-legend button.pu-chip::first-letter { text-transform: none; }
1449
:root .pulse-legend button.pu-chip i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
1450
:root .pulse-legend button.pu-chip[aria-pressed="true"] { border-color: var(--ink); background: var(--soft); }
1451
.pulse-stage { position: relative; padding: 8px 12px 4px; }
1452
.pulse-stage svg { width: 100%; height: auto; display: block; touch-action: pan-y; }
1453
.pulse-stage .pu-axis { font: 10px var(--mono, ui-monospace, monospace); fill: var(--mute); }
1454
.pulse-stage .pu-peak { font: 11px var(--mono, ui-monospace, monospace); fill: var(--ink); }
1455
.pulse-card { position: absolute; top: 6px; pointer-events: none; opacity: 0; transition: opacity .15s; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; min-width: 170px; font-size: 12px; box-shadow: 0 8px 24px rgba(0,0,0,.15); }
1456
.pulse-card b { display: block; margin-bottom: 3px; }
1457
.pulse-card .row { display: flex; justify-content: space-between; gap: 14px; color: var(--mute); font-variant-numeric: tabular-nums; }
1458
.pulse-card .row span:last-child { color: var(--ink); }
1459
.pulse-card .bar { display: flex; height: 5px; border-radius: 3px; overflow: hidden; margin-top: 6px; background: var(--soft); }
1460
@keyframes pu-ring { from { r: 4; opacity: .9; } to { r: 15; opacity: 0; } }
1461
.pu-ring { animation: pu-ring 2.4s ease-out infinite; }
1462
@media (prefers-reduced-motion: reduce) { .pu-ring { animation: none; opacity: 0; } }
1463
1464
/* Drops (oxygenhub#279). */
1465
.drop-filebox { margin-bottom: 16px; }
1466
/* A drop's page (#283): what it is on the left, what you can do on the
1467
   right, the clone line under them; a Markdown file fills its box. */
1468
.drop-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px 24px; flex-wrap: wrap; margin: 6px 0 14px; padding-bottom: 12px; border-bottom: 2px solid var(--band); border-image: linear-gradient(90deg, var(--acc), var(--acc-2)) 1; }
1469
.drop-id { flex: 1 1 320px; min-width: 0; }
1470
.drop-id h1 { font-size: 30px; font-weight: 300; color: var(--ink); margin: 0 0 6px; overflow-wrap: anywhere; }
1471
.drop-id h1 small { font-size: 13px; color: var(--acc); font-weight: 400; }
1472
.drop-id .drop-desc { margin: 0 0 6px; font-size: 15px; }
1473
.drop-id p.small { margin: 0; }
1474
.drop-actions { display: flex; gap: 8px; align-items: stretch; }
1475
.drop-actions form { margin: 0; display: flex; }
1476
.drop-actions a.go { display: inline-flex; align-items: center; }
1477
.drop-clone { display: flex; align-items: center; gap: 8px; margin: 0 0 16px; font-size: 13px; }
1478
.drop-clone label { color: var(--mute); }
1479
.drop-clone input { flex: 0 1 640px; min-width: 0; }
1480
.drop-filebox article.doc { max-width: none; margin: 0; border: 0; }
1481
/* A drop framed on another site (#280): its files and a link back. */
1482
body.drop-embedded { margin: 0; padding: 8px; }
1483
.embed-head { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; margin: 0 0 8px; }
1484
.drop-comment-rows li { align-items: flex-start; }
1485
.drop-comment { flex: 1; min-width: 0; }
1486
.drop-comment .doc { margin-top: 4px; overflow-wrap: anywhere; }
1487
.drop-comment-form textarea { width: 100%; box-sizing: border-box; }
1488
.drop-file { border: 1px solid var(--line); border-radius: 6px; padding: 8px 12px; margin: 0 0 12px; }
1489
.drop-file-actions { display: flex; align-items: flex-end; justify-content: flex-end; }