A CLI-first git forge.

cli forge git self-hosted

https://gitbay.org

Commit 968d263f38

968d263f38695861ddf253dd86a6636c79ba90b7

parent: dca7370cd1

Verified · cmc ci/build: success

cmc <hello@cleberg.net> · 2026-08-31T05:07:58Z

web: settings rows end in one column of controls

The label absorbs the row's free space, so a checkbox or a number input
finishes at the same right edge as the text inputs and selects that
stretch to reach it, instead of sitting next to its label with the button
stranded beside it.

Checkboxes are drawn rather than native, and sized to the height of a
text input, a select and a button, which is what the row's other controls
already are. The square stays square: shape is the cue that survives
greyscale and high contrast, so the size changes and the cue does not.
Radios keep the native control and its accent colour.

Closes #59
internal/web/static/style.css +35 −8
@@ -591,7 +591,10 @@ form.setform {
591591 padding: var(--sp-2) 0;
592592 border-bottom: 1px solid var(--faint);
593593}
594form.setform label { min-width: 12rem; color: var(--muted); font-size: var(--fs-2); }
594/* the label absorbs the free space, so a row whose control does not
595 stretch — a checkbox, a number — still finishes at the same right edge
596 as the rows whose input fills the line */
597form.setform label { min-width: 12rem; margin-right: auto; color: var(--muted); font-size: var(--fs-2); }
595598form.setform input[type="text"], form.setform select { flex: 1 1 16rem; }
596599form.setform input[type="number"] { width: 5rem; }
597600ul.protlist { list-style: none; padding: 0; margin: var(--sp-2) 0; }
@@ -1196,16 +1199,40 @@ select {
11961199input:hover, textarea:hover, select:hover { border-color: var(--muted); }
11971200/* the global :focus-visible ring covers these; only the border moves */
11981201input:focus, textarea:focus, select:focus { border-color: var(--accent); }
1199input[type="radio"], input[type="checkbox"] { accent-color: var(--fill); }
1202input[type="radio"] { accent-color: var(--fill); }
12001203label:has(> input[type="radio"]), label:has(> input[type="checkbox"]),
12011204label:has(> select) { display: inline-flex; align-items: center; gap: var(--sp-2); }
12021205
1203/* Shape carries the meaning on these two and nothing else does: a circle
1204 takes one answer, a square takes any number. It survives colour being
1205 removed — greyscale, high contrast, colour blindness — so the native
1206 shapes stay and only the colour joins the system. Drawing them by hand
1207 would align the corners at the cost of the one cue that always works. */
1208input[type="radio"], input[type="checkbox"] { accent-color: var(--fill); }
1206/* A radio keeps the native control: a circle takes one answer, a square
1207 takes any number, and that shape is the cue that survives greyscale,
1208 high contrast and colour blindness. The checkbox is drawn instead,
1209 because at the size the OS renders it it reads as an afterthought
1210 beside the button it shares a row with. The square is kept square —
1211 the size changes, the cue does not. */
1212input[type="checkbox"] {
1213 appearance: none;
1214 flex: none;
1215 /* the height of a text input, a select and a button, so a settings row
1216 ends in one column of controls rather than a button and a speck */
1217 width: 2.5rem;
1218 height: 2.5rem;
1219 /* an empty box has nothing but its border to announce it, so the border
1220 is --muted rather than the --line the sized controls can afford */
1221 border: 1px solid var(--muted);
1222 border-radius: var(--r-sm);
1223 background: var(--bg);
1224 cursor: pointer;
1225}
1226input[type="checkbox"]:not(:checked):hover { border-color: var(--fg); }
1227input[type="checkbox"]:checked {
1228 background: var(--fill);
1229 border-color: var(--fill);
1230 /* the mark sits on the blue ground, so it is white in both schemes */
1231 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 10'%3E%3Cpath d='M1 5l3.4 3.4L11 1.4' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
1232 background-repeat: no-repeat;
1233 background-position: center;
1234 background-size: 1.2rem;
1235}
12091236
12101237/* a segmented control for a small, mutually exclusive set: real radios
12111238 underneath, so arrow keys and screen readers behave as they always did */