style.css (6707B)
1 /* dashboard/style.css - the whole interface, one stylesheet */ 2 3 :root { 4 --bg: #101214; 5 --panel: #171a1d; 6 --border: #272b30; 7 --text: #dfe3e6; 8 --muted: #8b949e; 9 --link: #6cb6ff; 10 --queued: #3a4046; 11 --running: #b58900; 12 --success: #2e7d32; 13 --failed: #c62828; 14 --skipped: #4a5058; 15 --cancelled: #6a4a8a; 16 --danger: #a33; 17 } 18 19 * { box-sizing: border-box; } 20 21 body { 22 margin: 0; 23 background: var(--bg); 24 color: var(--text); 25 font: 14px/1.5 system-ui, -apple-system, Segoe UI, Roboto, sans-serif; 26 } 27 28 a { color: var(--link); text-decoration: none; } 29 a:hover { text-decoration: underline; } 30 31 code, pre, .mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; } 32 33 header { 34 display: flex; 35 align-items: center; 36 gap: 1.25rem; 37 padding: .7rem 1.25rem; 38 border-bottom: 1px solid var(--border); 39 background: var(--panel); 40 } 41 42 header h1 { font-size: 1rem; margin: 0; font-weight: 600; } 43 header h1 a { color: var(--text); } 44 header nav { flex: 1; display: flex; gap: 1rem; } 45 header nav a { color: var(--muted); } 46 header nav a.on { color: var(--text); border-bottom: 2px solid var(--link); } 47 header .session { display: flex; align-items: center; gap: .6rem; } 48 header .session form { margin: 0; } 49 50 .role { 51 font-size: .7rem; 52 text-transform: uppercase; 53 letter-spacing: .04em; 54 color: var(--muted); 55 border: 1px solid var(--border); 56 border-radius: .7rem; 57 padding: 0 .4rem; 58 } 59 60 main { padding: 1.25rem; max-width: 1100px; margin: 0 auto; } 61 62 h2 { font-size: 1.15rem; margin: 0 0 .75rem; } 63 h3 { font-size: .95rem; margin: 0 0 .5rem; } 64 65 .muted { color: var(--muted); } 66 .error { color: #ff8b8b; } 67 .ok { color: #7ddc8a; } 68 69 table { width: 100%; border-collapse: collapse; margin: .5rem 0; } 70 th, td { text-align: left; padding: .45rem .6rem; border-bottom: 1px solid var(--border); vertical-align: middle; } 71 th { color: var(--muted); font-weight: 500; font-size: .75rem; text-transform: uppercase; letter-spacing: .04em; } 72 tbody tr:hover { background: #1b1f23; } 73 74 .badge { 75 display: inline-block; 76 padding: .05rem .45rem; 77 border-radius: .75rem; 78 font-size: .72rem; 79 background: var(--queued); 80 color: #fff; 81 } 82 .badge.running { background: var(--running); color: #1a1a1a; } 83 .badge.success { background: var(--success); } 84 .badge.failed { background: var(--failed); } 85 .badge.skipped { background: var(--skipped); } 86 .badge.cancelled { background: var(--cancelled); } 87 .badge.pending, .badge.queued { background: var(--queued); } 88 .badge.online { background: var(--success); } 89 .badge.offline { background: var(--skipped); } 90 91 .panel { 92 background: var(--panel); 93 border: 1px solid var(--border); 94 border-radius: 6px; 95 padding: .85rem 1rem; 96 margin-bottom: 1rem; 97 } 98 .panel.narrow { max-width: 24rem; width: 100%; } 99 .panel.secret { border-color: var(--running); } 100 101 /* Centres a single panel, such as the sign in form, rather than leaving it 102 stranded against the left edge of a wide page. */ 103 .center { display: flex; justify-content: center; padding-top: 2.5rem; } 104 105 .row { display: flex; gap: 1.5rem; flex-wrap: wrap; margin-bottom: .5rem; } 106 .row > div { min-width: 7rem; } 107 .label { color: var(--muted); font-size: .72rem; display: block; text-transform: uppercase; letter-spacing: .04em; } 108 109 /* Stages are row groups inside the one task table rather than tables of 110 their own, so every stage shares a single set of column widths. The 111 label is a header row, so it already reads as one. */ 112 .stage-label th { padding-top: 1.2rem; border-bottom-color: transparent; } 113 tbody.stage:first-of-type .stage-label th { padding-top: .45rem; } 114 tbody.stage tr.stage-label:hover { background: none; } 115 116 /* Durations are read down the column, not across the row, so they are 117 right aligned and set in figures of one width. */ 118 td.num { text-align: right; font-variant-numeric: tabular-nums; } 119 table.tasks thead th:last-child { text-align: right; } 120 121 .logpane { max-height: 32rem; overflow: auto; border: 1px solid var(--border); border-radius: 6px; background: #0b0d0f; } 122 pre.log { 123 margin: 0; 124 padding: .75rem 1rem; 125 white-space: pre-wrap; 126 word-break: break-word; 127 font-size: .82rem; 128 } 129 130 form { margin: 0; } 131 .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: .75rem; } 132 label { display: block; color: var(--muted); font-size: .75rem; text-transform: uppercase; letter-spacing: .04em; } 133 134 input, select { 135 display: block; 136 width: 100%; 137 margin-top: .2rem; 138 background: #0b0d0f; 139 border: 1px solid var(--border); 140 border-radius: 4px; 141 color: var(--text); 142 padding: .35rem .5rem; 143 font-size: .9rem; 144 text-transform: none; 145 letter-spacing: normal; 146 } 147 input.wide { width: 100%; } 148 149 button { 150 background: #22262b; 151 color: var(--text); 152 border: 1px solid var(--border); 153 border-radius: 4px; 154 padding: .3rem .7rem; 155 cursor: pointer; 156 font-size: .85rem; 157 } 158 button:hover { background: #2b3036; } 159 button.danger { border-color: var(--danger); color: #ff9c9c; } 160 /* A button that has to sit on the same line as ordinary text. Inheriting 161 the font and line height is what keeps a row with actions exactly as 162 tall as a row without them; a button's own metrics are otherwise larger 163 than the surrounding text and stretch the line box. */ 164 button.link { 165 background: none; 166 border: none; 167 color: var(--link); 168 padding: 0; 169 margin: 0; 170 font: inherit; 171 line-height: inherit; 172 vertical-align: baseline; 173 } 174 button.link:hover { text-decoration: underline; background: none; } 175 button.link.danger { color: #ff9c9c; } 176 177 a.button { 178 display: inline-block; 179 background: #22262b; 180 border: 1px solid var(--border); 181 border-radius: 4px; 182 padding: .3rem .7rem; 183 color: var(--text); 184 } 185 a.button:hover { text-decoration: none; background: #2b3036; } 186 187 .actions { display: flex; gap: .5rem; align-items: center; margin-top: .75rem; flex-wrap: wrap; } 188 189 /* Actions inside a table row stay an ordinary table cell. Making them a 190 flex container would take them out of the row's baseline alignment and 191 give the row a different height from every other one. */ 192 td.row-actions { white-space: nowrap; text-align: right; } 193 td.row-actions button.link + button.link { margin-left: .9rem; } 194 195 /* Page links sit under their table. The count is centred between the two 196 steps so it does not shift as the labels change. */ 197 .pager { display: flex; gap: 1rem; align-items: center; margin-top: .75rem; font-size: .8rem; } 198 .pager > span { flex: 1; text-align: center; } 199 200 dialog { 201 border: 1px solid var(--border); 202 border-radius: 6px; 203 background: var(--panel); 204 color: var(--text); 205 padding: 1.25rem; 206 max-width: 28rem; 207 width: 90%; 208 } 209 dialog::backdrop { background: rgba(0, 0, 0, 0.6); } 210 dialog .actions { justify-content: flex-end; margin-top: 1rem; }