Skip to content
634 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}
197/* A row with buttons beside its words: in a narrow window, the buttons go
198 under them rather than squeezing them into a column. */
199.setting:has(> .buttons) {
200 flex-wrap: wrap;
201 row-gap: 0.5rem;
202}
203.setting:has(> .buttons) > span:first-child {
204 flex: 1 1 14rem;
205}
206button.primary {
207 background: var(--accent);
208 border-color: var(--accent);
209 color: var(--accent-ink);
210}
211button.primary:hover {
212 filter: brightness(1.06);
213}
214button[hidden] {
215 display: none;
216}
217button:disabled {
218 opacity: 0.6;
219}
220button:focus-visible,
221select:focus-visible,
222input:focus-visible,
223a:focus-visible {
224 outline: 2px solid var(--accent);
225 outline-offset: 2px;
226}
227a {
228 color: var(--muted);
229 text-decoration: underline;
230 text-underline-offset: 3px;
231}
232a:hover {
233 color: var(--fg);
234}
235.error {
236 color: var(--error);
237 font-size: 0.875rem;
238 margin-bottom: 1rem;
239}
240.foot {
241 text-align: center;
242}
243code {
244 font: 0.8125rem ui-monospace, SFMono-Regular, Consolas, monospace;
245}
246/* The runner's state: a dot in its tone, what it is doing, and when it
247 isn't running, why and the fix, with its buttons. */
248.diagnosis {
249 display: flex;
250 align-items: flex-start;
251 gap: 0.75rem;
252 margin: 0.25rem 0 0.5rem;
253 padding: 0.75rem;
254 border: 1px solid var(--line);
255 border-radius: 10px;
256 background: var(--surface);
257}
258.diagnosis-text {
259 display: flex;
260 flex-direction: column;
261 gap: 0.25rem;
262 min-width: 0;
263 flex: 1;
264 font-size: 0.8125rem;
265}
266.diagnosis-text strong {
267 font-size: 0.875rem;
268 font-weight: 500;
269}
270.diagnosis-text .buttons {
271 display: flex;
272 flex-wrap: wrap;
273 gap: 0.5rem;
274 margin-top: 0.25rem;
275}
276.diagnosis-text .buttons:empty {
277 display: none;
278}
279.diagnosis[hidden] {
280 display: none;
281}
282.dot {
283 flex: none;
284 width: 8px;
285 height: 8px;
286 margin-top: 0.4rem;
287 border-radius: 50%;
288 background: var(--muted);
289}
290.dot.ok {
291 background: var(--ok);
292}
293.dot.working {
294 background: var(--working);
295}
296.dot.warning {
297 background: var(--warning);
298}
299.dot.problem {
300 background: var(--error);
301}
302.warning-note {
303 color: var(--warning);
304}
305.visually-hidden {
306 position: absolute;
307 width: 1px;
308 height: 1px;
309 margin: -1px;
310 padding: 0;
311 overflow: hidden;
312 clip: rect(0 0 0 0);
313 white-space: nowrap;
314 border: 0;
315}
316
317/* Sandboxed, each kind of job it runs, side by side: Linux jobs, Windows
318 jobs. Two to a row where they fit, one under the other where they don't. */
319.kinds {
320 display: grid;
321 grid-template-columns: repeat(auto-fit, minmax(15.5rem, 1fr));
322 gap: 0.75rem;
323 margin: 0.5rem 0 0.75rem;
324}
325.kinds[hidden] {
326 display: none;
327}
328.kinds.single {
329 grid-template-columns: 1fr;
330}
331.kind {
332 display: flex;
333 flex-direction: column;
334 gap: 0.625rem;
335 min-width: 0;
336 padding: 0.875rem;
337 border: 1px solid var(--line);
338 border-radius: 12px;
339 background: var(--surface);
340 transition: border-color 0.2s;
341}
342/* A kind that needs a look says so with its edge as well as its label. */
343.kind[data-tone="problem"] {
344 border-color: rgba(255, 138, 138, 0.35);
345}
346.kind[data-tone="warning"] {
347 border-color: rgba(251, 191, 36, 0.3);
348}
349/* Its icon, and beside it its name over its state. */
350.kind-head {
351 display: flex;
352 align-items: center;
353 gap: 0.75rem;
354}
355.kind-icon {
356 flex: none;
357 display: grid;
358 place-items: center;
359 width: 40px;
360 height: 40px;
361 border-radius: 10px;
362 background: var(--raised);
363 color: var(--fg);
364}
365.kind.off .kind-icon {
366 color: var(--muted);
367}
368.kind-name {
369 display: flex;
370 flex-direction: column;
371 align-items: flex-start;
372 gap: 0.25rem;
373 min-width: 0;
374 flex: 1 1 auto;
375}
376.kind-name h3 {
377 margin: 0;
378 font-size: 0.9375rem;
379 font-weight: 600;
380 letter-spacing: -0.005em;
381}
382.kind-about {
383 margin: 0;
384 color: var(--muted);
385 font-size: 0.8125rem;
386 line-height: 1.4;
387}
388/* Its state, as a label: a dot in its tone, and a few words. */
389.pill {
390 display: inline-flex;
391 align-items: center;
392 gap: 0.375rem;
393 flex: none;
394 padding: 0.0625rem 0.5rem 0.0625rem 0.4375rem;
395 border: 1px solid var(--line-strong);
396 border-radius: 999px;
397 color: var(--muted);
398 font-size: 0.75rem;
399 font-weight: 500;
400 line-height: 1.4;
401 white-space: nowrap;
402}
403.pill-dot {
404 width: 6px;
405 height: 6px;
406 border-radius: 50%;
407 background: currentColor;
408}
409.pill[data-tone="ok"] {
410 border-color: rgba(74, 222, 128, 0.35);
411 background: rgba(74, 222, 128, 0.1);
412 color: var(--ok);
413}
414.pill[data-tone="working"] {
415 border-color: rgba(96, 165, 250, 0.35);
416 background: rgba(96, 165, 250, 0.1);
417 color: var(--working);
418}
419.pill[data-tone="warning"] {
420 border-color: rgba(251, 191, 36, 0.35);
421 background: rgba(251, 191, 36, 0.1);
422 color: var(--warning);
423}
424.pill[data-tone="problem"] {
425 border-color: rgba(255, 138, 138, 0.4);
426 background: rgba(255, 138, 138, 0.1);
427 color: var(--error);
428}
429/* On its way (running a job, starting, downloading): the dot breathes. */
430.pill.live .pill-dot {
431 animation: breathe 1.6s ease-in-out infinite;
432}
433@keyframes breathe {
434 50% {
435 opacity: 0.35;
436 }
437}
438.kind-body {
439 display: flex;
440 flex-direction: column;
441 gap: 0.25rem;
442 font-size: 0.8125rem;
443 line-height: 1.45;
444}
445.kind-body[hidden] {
446 display: none;
447}
448.kind-body p {
449 margin: 0;
450}
451.kind-headline {
452 color: var(--fg);
453 font-size: 0.875rem;
454 font-weight: 500;
455}
456.kind-cause {
457 color: var(--muted);
458}
459.kind-fix {
460 color: var(--fg);
461}
462.kind-body code,
463.diagnosis-text code {
464 padding: 0.0625rem 0.3125rem;
465 border-radius: 5px;
466 background: var(--raised);
467 color: var(--fg);
468 font-size: 0.75rem;
469 overflow-wrap: anywhere;
470 user-select: text;
471}
472.kind-job {
473 display: flex;
474 flex-direction: column;
475 gap: 0.125rem;
476 padding: 0.5rem 0.625rem;
477 border-radius: 8px;
478 background: var(--raised);
479}
480.kind-job-label {
481 color: var(--muted);
482 font-size: 0.6875rem;
483 font-weight: 600;
484 letter-spacing: 0.05em;
485 text-transform: uppercase;
486}
487.kind-job-what {
488 min-width: 0;
489 overflow-wrap: anywhere;
490}
491.kind-job-what a {
492 color: var(--fg);
493 font-weight: 500;
494}
495.kind-job-what a:hover {
496 color: var(--accent);
497}
498.kind-progress {
499 display: flex;
500 align-items: center;
501 gap: 0.625rem;
502}
503.kind-progress .bar {
504 flex: 1;
505 height: 6px;
506 overflow: hidden;
507 border-radius: 999px;
508 background: var(--line);
509}
510.kind-progress .bar span {
511 display: block;
512 height: 100%;
513 border-radius: 999px;
514 background: var(--accent);
515 transition: width 0.4s ease;
516}
517.kind-progress .small {
518 min-width: 2.5rem;
519 text-align: right;
520 font-variant-numeric: tabular-nums;
521}
522/* What it is on g1t: there to read, never in the way. */
523.kind-details {
524 display: grid;
525 gap: 0.125rem;
526 margin: 0;
527 padding-top: 0.5rem;
528 border-top: 1px solid var(--line);
529 font-size: 0.75rem;
530}
531.kind-details[hidden] {
532 display: none;
533}
534.kind-details div {
535 display: flex;
536 align-items: baseline;
537 gap: 0.5rem;
538 min-width: 0;
539}
540.kind-details dt {
541 flex: none;
542 width: 4.25rem;
543 color: var(--muted);
544}
545.kind-details dd {
546 display: flex;
547 align-items: baseline;
548 flex-wrap: wrap;
549 gap: 0 0.5rem;
550 min-width: 0;
551 margin: 0;
552 color: var(--fg);
553 overflow-wrap: anywhere;
554 user-select: text;
555}
556/* A newer version waiting, over when g1t last looked. */
557.kind-update {
558 display: grid;
559 gap: 0.0625rem;
560}
561.kind-update-ready {
562 color: var(--accent);
563}
564button.link {
565 display: inline-flex;
566 align-items: center;
567 gap: 0.25rem;
568 padding: 0;
569 border: 0;
570 background: none;
571 color: var(--fg);
572 font-size: inherit;
573 font-weight: 400;
574 text-decoration: underline;
575 text-decoration-color: var(--line-strong);
576 text-underline-offset: 3px;
577}
578button.link:hover {
579 color: var(--accent);
580 text-decoration-color: currentColor;
581}
582button.link svg {
583 flex: none;
584 color: var(--muted);
585}
586.kind-actions {
587 display: flex;
588 flex-wrap: wrap;
589 align-items: center;
590 gap: 0.5rem;
591 margin-top: auto;
592}
593.kind-actions[hidden] {
594 display: none;
595}
596.kind-actions .end {
597 margin-left: auto;
598}
599button.quiet {
600 background: transparent;
601 color: var(--muted);
602}
603button.quiet:hover {
604 color: var(--fg);
605}
606@media (prefers-reduced-motion: reduce) {
607 .pill.live .pill-dot {
608 animation: none;
609 }
610 .kind,
611 .kind-progress .bar span {
612 transition: none;
613 }
614}
615details.log {
616 padding: 0.75rem 0;
617}
618details.log summary {
619 color: var(--muted);
620 font-size: 0.8125rem;
621}
622details.log pre {
623 max-height: 12rem;
624 overflow: auto;
625 margin: 0.5rem 0;
626 padding: 0.5rem;
627 border-radius: 8px;
628 background: #050507;
629 color: var(--muted);
630 font: 0.75rem/1.4 ui-monospace, SFMono-Regular, Consolas, monospace;
631 white-space: pre-wrap;
632 overflow-wrap: anywhere;
633 user-select: text;
634}