Skip to content
617 linesCodeBlameRaw
1/* The settings window, in the launcher's colours (launcher.css): rows of
2 settings under small headings, each with its switch on the right. */
3:root {
4 --bg: #0f0f11;
5 --fg: #ededf0;
6 --muted: #9a9aa6;
7 --line: #26262c;
8 --surface: #17171b;
9 --accent: #b6a8ff;
10 --accent-ink: #15112e;
11 --error: #ff8a8a;
12 /* States, as dots and labels: running, on its way, needs a look, failing. */
13 --ok: #4ade80;
14 --working: #60a5fa;
15 --warning: #fbbf24;
16 --raised: #1e1e24;
17 --line-strong: #34343c;
18 color-scheme: dark;
19}
20* {
21 box-sizing: border-box;
22}
23html,
24body {
25 margin: 0;
26}
27body {
28 background: var(--bg);
29 color: var(--fg);
30 font: 14px/1.45 system-ui, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
31 -webkit-font-smoothing: antialiased;
32 user-select: none;
33 cursor: default;
34}
35/* g1t's own title bar, when the window has no system frame: fixed at the top, 36px tall. */
36.titlebar {
37 position: fixed;
38 inset: 0 0 auto 0;
39 z-index: 10;
40 height: 36px;
41 display: flex;
42 align-items: center;
43 justify-content: space-between;
44 padding-left: 14px;
45 background: #050507;
46 color: var(--muted);
47 font-size: 12px;
48 font-weight: 500;
49}
50.titlebar[hidden] {
51 display: none;
52}
53.mac .titlebar {
54 padding-left: 78px;
55}
56.mac .titlebar .caption {
57 display: none;
58}
59.titlebar .caption {
60 all: unset;
61 display: inline-flex;
62 align-items: center;
63 justify-content: center;
64 width: 46px;
65 height: 36px;
66}
67.titlebar .caption:hover {
68 background: #c42b1c;
69 color: #fff;
70}
71/* Under it, the page scrolls on its own, so its scrollbar starts below the bar. */
72body.framed .page {
73 position: fixed;
74 inset: 36px 0 0 0;
75 overflow-y: auto;
76}
77main {
78 max-width: 38rem;
79 margin: 0 auto;
80 padding: 1.5rem 1.25rem 1.25rem;
81}
82h1 {
83 font-size: 1.25rem;
84 font-weight: 600;
85 margin: 0 0 0.25rem;
86}
87h2 {
88 font-size: 0.75rem;
89 font-weight: 600;
90 letter-spacing: 0.06em;
91 text-transform: uppercase;
92 color: var(--muted);
93 margin: 0 0 0.25rem;
94}
95p {
96 margin: 0;
97}
98.lede {
99 margin-bottom: 1.5rem;
100}
101.muted {
102 color: var(--muted);
103}
104.small {
105 font-size: 0.8125rem;
106}
107section {
108 margin-bottom: 1.5rem;
109}
110.setting {
111 display: flex;
112 align-items: center;
113 justify-content: space-between;
114 gap: 1rem;
115 padding: 0.75rem 0;
116 border-bottom: 1px solid var(--line);
117}
118section .setting:last-child {
119 border-bottom: 0;
120}
121.setting > span {
122 display: flex;
123 flex-direction: column;
124 gap: 0.125rem;
125 min-width: 0;
126}
127.setting strong {
128 font-weight: 500;
129 overflow-wrap: anywhere;
130}
131.setting .muted {
132 font-size: 0.8125rem;
133}
134.setting.off {
135 opacity: 0.5;
136}
137input[type="checkbox"][role="switch"] {
138 appearance: none;
139 flex: none;
140 width: 36px;
141 height: 20px;
142 margin: 0;
143 border-radius: 999px;
144 background: var(--line);
145 position: relative;
146 transition: background 0.15s;
147}
148input[type="checkbox"][role="switch"]::after {
149 content: "";
150 position: absolute;
151 top: 2px;
152 left: 2px;
153 width: 16px;
154 height: 16px;
155 border-radius: 50%;
156 background: var(--fg);
157 transition: transform 0.15s;
158}
159input[type="checkbox"][role="switch"]:checked {
160 background: var(--accent);
161}
162input[type="checkbox"][role="switch"]:checked::after {
163 transform: translateX(16px);
164 background: var(--accent-ink);
165}
166input:disabled {
167 opacity: 0.5;
168}
169@media (prefers-reduced-motion: reduce) {
170 input[type="checkbox"][role="switch"],
171 input[type="checkbox"][role="switch"]::after {
172 transition: none;
173 }
174}
175button,
176select {
177 flex: none;
178 font: inherit;
179 font-size: 0.8125rem;
180 font-weight: 500;
181 padding: 0.375rem 0.75rem;
182 border-radius: 8px;
183 border: 1px solid var(--line);
184 background: var(--surface);
185 color: var(--fg);
186 cursor: default;
187}
188button:hover,
189select:hover {
190 border-color: #3a3a44;
191}
192.setting > .buttons {
193 flex-direction: row;
194 flex: none;
195 gap: 0.5rem;
196}
197button.primary {
198 background: var(--accent);
199 border-color: var(--accent);
200 color: var(--accent-ink);
201}
202button.primary:hover {
203 filter: brightness(1.06);
204}
205button[hidden] {
206 display: none;
207}
208button:disabled {
209 opacity: 0.6;
210}
211button:focus-visible,
212select:focus-visible,
213input:focus-visible,
214a:focus-visible {
215 outline: 2px solid var(--accent);
216 outline-offset: 2px;
217}
218a {
219 color: var(--muted);
220 text-decoration: underline;
221 text-underline-offset: 3px;
222}
223a:hover {
224 color: var(--fg);
225}
226.error {
227 color: var(--error);
228 font-size: 0.875rem;
229 margin-bottom: 1rem;
230}
231.foot {
232 text-align: center;
233}
234code {
235 font: 0.8125rem ui-monospace, SFMono-Regular, Consolas, monospace;
236}
237/* The runner's state: a dot in its tone, what it is doing, and when it
238 isn't running, why and the fix, with its buttons. */
239.diagnosis {
240 display: flex;
241 align-items: flex-start;
242 gap: 0.75rem;
243 margin: 0.25rem 0 0.5rem;
244 padding: 0.75rem;
245 border: 1px solid var(--line);
246 border-radius: 10px;
247 background: var(--surface);
248}
249.diagnosis-text {
250 display: flex;
251 flex-direction: column;
252 gap: 0.25rem;
253 min-width: 0;
254 flex: 1;
255 font-size: 0.8125rem;
256}
257.diagnosis-text strong {
258 font-size: 0.875rem;
259 font-weight: 500;
260}
261.diagnosis-text .buttons {
262 display: flex;
263 flex-wrap: wrap;
264 gap: 0.5rem;
265 margin-top: 0.25rem;
266}
267.diagnosis-text .buttons:empty {
268 display: none;
269}
270.diagnosis[hidden] {
271 display: none;
272}
273.dot {
274 flex: none;
275 width: 8px;
276 height: 8px;
277 margin-top: 0.4rem;
278 border-radius: 50%;
279 background: var(--muted);
280}
281.dot.ok {
282 background: var(--ok);
283}
284.dot.working {
285 background: var(--working);
286}
287.dot.warning {
288 background: var(--warning);
289}
290.dot.problem {
291 background: var(--error);
292}
293.warning-note {
294 color: var(--warning);
295}
296.visually-hidden {
297 position: absolute;
298 width: 1px;
299 height: 1px;
300 margin: -1px;
301 padding: 0;
302 overflow: hidden;
303 clip: rect(0 0 0 0);
304 white-space: nowrap;
305 border: 0;
306}
307
308/* Sandboxed, each kind of job it runs, side by side: Linux jobs, Windows
309 jobs. Two to a row where they fit, one under the other where they don't. */
310.kinds {
311 display: grid;
312 grid-template-columns: repeat(auto-fit, minmax(15.5rem, 1fr));
313 gap: 0.75rem;
314 margin: 0.5rem 0 0.75rem;
315}
316.kinds[hidden] {
317 display: none;
318}
319.kinds.single {
320 grid-template-columns: 1fr;
321}
322.kind {
323 display: flex;
324 flex-direction: column;
325 gap: 0.625rem;
326 min-width: 0;
327 padding: 0.875rem;
328 border: 1px solid var(--line);
329 border-radius: 12px;
330 background: var(--surface);
331 transition: border-color 0.2s;
332}
333/* A kind that needs a look says so with its edge as well as its label. */
334.kind[data-tone="problem"] {
335 border-color: rgba(255, 138, 138, 0.35);
336}
337.kind[data-tone="warning"] {
338 border-color: rgba(251, 191, 36, 0.3);
339}
340/* Its icon, and beside it its name over its state. */
341.kind-head {
342 display: flex;
343 align-items: center;
344 gap: 0.75rem;
345}
346.kind-icon {
347 flex: none;
348 display: grid;
349 place-items: center;
350 width: 40px;
351 height: 40px;
352 border-radius: 10px;
353 background: var(--raised);
354 color: var(--fg);
355}
356.kind.off .kind-icon {
357 color: var(--muted);
358}
359.kind-name {
360 display: flex;
361 flex-direction: column;
362 align-items: flex-start;
363 gap: 0.25rem;
364 min-width: 0;
365 flex: 1 1 auto;
366}
367.kind-name h3 {
368 margin: 0;
369 font-size: 0.9375rem;
370 font-weight: 600;
371 letter-spacing: -0.005em;
372}
373.kind-about {
374 margin: 0;
375 color: var(--muted);
376 font-size: 0.8125rem;
377 line-height: 1.4;
378}
379/* Its state, as a label: a dot in its tone, and a few words. */
380.pill {
381 display: inline-flex;
382 align-items: center;
383 gap: 0.375rem;
384 flex: none;
385 padding: 0.0625rem 0.5rem 0.0625rem 0.4375rem;
386 border: 1px solid var(--line-strong);
387 border-radius: 999px;
388 color: var(--muted);
389 font-size: 0.75rem;
390 font-weight: 500;
391 line-height: 1.4;
392 white-space: nowrap;
393}
394.pill-dot {
395 width: 6px;
396 height: 6px;
397 border-radius: 50%;
398 background: currentColor;
399}
400.pill[data-tone="ok"] {
401 border-color: rgba(74, 222, 128, 0.35);
402 background: rgba(74, 222, 128, 0.1);
403 color: var(--ok);
404}
405.pill[data-tone="working"] {
406 border-color: rgba(96, 165, 250, 0.35);
407 background: rgba(96, 165, 250, 0.1);
408 color: var(--working);
409}
410.pill[data-tone="warning"] {
411 border-color: rgba(251, 191, 36, 0.35);
412 background: rgba(251, 191, 36, 0.1);
413 color: var(--warning);
414}
415.pill[data-tone="problem"] {
416 border-color: rgba(255, 138, 138, 0.4);
417 background: rgba(255, 138, 138, 0.1);
418 color: var(--error);
419}
420/* On its way (running a job, starting, downloading): the dot breathes. */
421.pill.live .pill-dot {
422 animation: breathe 1.6s ease-in-out infinite;
423}
424@keyframes breathe {
425 50% {
426 opacity: 0.35;
427 }
428}
429.kind-body {
430 display: flex;
431 flex-direction: column;
432 gap: 0.25rem;
433 font-size: 0.8125rem;
434 line-height: 1.45;
435}
436.kind-body[hidden] {
437 display: none;
438}
439.kind-body p {
440 margin: 0;
441}
442.kind-headline {
443 color: var(--fg);
444 font-size: 0.875rem;
445 font-weight: 500;
446}
447.kind-cause {
448 color: var(--muted);
449}
450.kind-fix {
451 color: var(--fg);
452}
453.kind-body code,
454.diagnosis-text code {
455 padding: 0.0625rem 0.3125rem;
456 border-radius: 5px;
457 background: var(--raised);
458 color: var(--fg);
459 font-size: 0.75rem;
460 overflow-wrap: anywhere;
461 user-select: text;
462}
463.kind-job {
464 display: flex;
465 flex-direction: column;
466 gap: 0.125rem;
467 padding: 0.5rem 0.625rem;
468 border-radius: 8px;
469 background: var(--raised);
470}
471.kind-job-label {
472 color: var(--muted);
473 font-size: 0.6875rem;
474 font-weight: 600;
475 letter-spacing: 0.05em;
476 text-transform: uppercase;
477}
478.kind-job-what {
479 min-width: 0;
480 overflow-wrap: anywhere;
481}
482.kind-job-what a {
483 color: var(--fg);
484 font-weight: 500;
485}
486.kind-job-what a:hover {
487 color: var(--accent);
488}
489.kind-progress {
490 display: flex;
491 align-items: center;
492 gap: 0.625rem;
493}
494.kind-progress .bar {
495 flex: 1;
496 height: 6px;
497 overflow: hidden;
498 border-radius: 999px;
499 background: var(--line);
500}
501.kind-progress .bar span {
502 display: block;
503 height: 100%;
504 border-radius: 999px;
505 background: var(--accent);
506 transition: width 0.4s ease;
507}
508.kind-progress .small {
509 min-width: 2.5rem;
510 text-align: right;
511 font-variant-numeric: tabular-nums;
512}
513/* What it is on g1t: there to read, never in the way. */
514.kind-details {
515 display: grid;
516 gap: 0.125rem;
517 margin: 0;
518 padding-top: 0.5rem;
519 border-top: 1px solid var(--line);
520 font-size: 0.75rem;
521}
522.kind-details[hidden] {
523 display: none;
524}
525.kind-details div {
526 display: flex;
527 align-items: baseline;
528 gap: 0.5rem;
529 min-width: 0;
530}
531.kind-details dt {
532 flex: none;
533 width: 4.25rem;
534 color: var(--muted);
535}
536.kind-details dd {
537 display: flex;
538 align-items: baseline;
539 flex-wrap: wrap;
540 gap: 0 0.5rem;
541 min-width: 0;
542 margin: 0;
543 color: var(--fg);
544 overflow-wrap: anywhere;
545 user-select: text;
546}
547button.link {
548 display: inline-flex;
549 align-items: center;
550 gap: 0.25rem;
551 padding: 0;
552 border: 0;
553 background: none;
554 color: var(--fg);
555 font-size: inherit;
556 font-weight: 400;
557 text-decoration: underline;
558 text-decoration-color: var(--line-strong);
559 text-underline-offset: 3px;
560}
561button.link:hover {
562 color: var(--accent);
563 text-decoration-color: currentColor;
564}
565button.link svg {
566 flex: none;
567 color: var(--muted);
568}
569.kind-actions {
570 display: flex;
571 flex-wrap: wrap;
572 align-items: center;
573 gap: 0.5rem;
574 margin-top: auto;
575}
576.kind-actions[hidden] {
577 display: none;
578}
579.kind-actions .end {
580 margin-left: auto;
581}
582button.quiet {
583 background: transparent;
584 color: var(--muted);
585}
586button.quiet:hover {
587 color: var(--fg);
588}
589@media (prefers-reduced-motion: reduce) {
590 .pill.live .pill-dot {
591 animation: none;
592 }
593 .kind,
594 .kind-progress .bar span {
595 transition: none;
596 }
597}
598details.log {
599 padding: 0.75rem 0;
600}
601details.log summary {
602 color: var(--muted);
603 font-size: 0.8125rem;
604}
605details.log pre {
606 max-height: 12rem;
607 overflow: auto;
608 margin: 0.5rem 0;
609 padding: 0.5rem;
610 border-radius: 8px;
611 background: #050507;
612 color: var(--muted);
613 font: 0.75rem/1.4 ui-monospace, SFMono-Regular, Consolas, monospace;
614 white-space: pre-wrap;
615 overflow-wrap: anywhere;
616 user-select: text;
617}