aboutsummaryrefslogtreecommitdiff
path: root/static
diff options
context:
space:
mode:
authorLena <lena@omega>2026-08-01 00:00:00 +0000
committerLena <lena@omega>2026-08-01 00:00:00 +0000
commitbb6bc2387d58c737dbf92e73f8544bf39319dbd8 (patch)
tree6d5eaf5dac213074cd832da50f64260fce728fed /static
downloadgit-forge-bb6bc2387d58c737dbf92e73f8544bf39319dbd8.tar.gz
Enter git-forgeHEADmaster
A small self-hosted git forge: HTTP push and pull, cgit browsing, local and OIDC accounts, TOTP, scoped push tokens, per-repo permissions, issues, a wiki, and outbound mail. It does not reimplement git. git-http-backend and cgit run as CGI behind its own listener, which authorises every request before exec'ing either. One binary, one data directory, one listener: no database, no JavaScript, and state is JSON in a git repo with a working tree.
Diffstat (limited to 'static')
-rw-r--r--static/forge.css135
1 files changed, 135 insertions, 0 deletions
diff --git a/static/forge.css b/static/forge.css
new file mode 100644
index 0000000..f03fa5a
--- /dev/null
+++ b/static/forge.css
@@ -0,0 +1,135 @@
+/*
+ * cgit's own stylesheet does the work; this is the rest. The forge's pages
+ * wrap themselves in div#cgit and use cgit's markup, so both kinds of page are
+ * the same page. Nothing here may carry meaning of its own: every page still
+ * has to work with all of it missing.
+ */
+
+/* Readability. cgit's 10pt suits a dense table; prose wants more. */
+
+div#cgit { color: #222; }
+div#cgit .dim { color: #666; }
+div#cgit article { font-size: 11pt; line-height: 1.5; max-width: 46em; }
+
+/* A row of alternating shade, which is what makes a long list scannable. */
+div#cgit table.list tr:nth-child(even) { background: #f6f6f6; }
+div#cgit table.list tr.nohover { background: #fff; }
+
+/* cgit sizes the header cell and not the image in it, so a large upload drags
+ * the header, and the page under it, out to its own width. Both axes, or a
+ * tall one pushes the page down instead. */
+div#cgit table#header td.logo img { max-width: 96px; max-height: 96px; }
+
+/* Forms. cgit only styles the two in its own header. */
+
+div#cgit label { display: block; color: #666; margin-bottom: 0.2em; }
+div#cgit label.inline, div#cgit label.choice { display: inline-block; color: #222; }
+div#cgit label.choice { display: block; margin: 0.3em 0; }
+div#cgit label.inline { margin-right: 1em; }
+div#cgit fieldset { border: solid 1px #ccc; margin: 1em 0; padding: 0.5em 1em; }
+div#cgit legend { color: #666; padding: 0 0.3em; }
+div#cgit form p { margin: 0.9em 0; }
+
+div#cgit input, div#cgit textarea, div#cgit select, div#cgit button {
+ font: inherit;
+ color: #222;
+ border: solid 1px #bbb;
+ padding: 0.3em;
+}
+
+div#cgit input[type=checkbox], div#cgit input[type=radio] { width: auto; }
+/* cgit's own header and tab controls size themselves, and the forge's must not
+ * stretch them across the row. */
+div#cgit table#header td.form input, div#cgit table#header td.form select,
+div#cgit table.tabs td.form input, div#cgit table.tabs td.form select {
+ width: auto;
+ max-width: none;
+ font-size: 90%;
+}
+/* A control inside a list row sizes itself, or it stretches the column. */
+div#cgit table.list td input { width: auto; }
+div#cgit input, div#cgit textarea { width: 100%; max-width: 34em; }
+div#cgit textarea { max-width: none; min-height: 12em; font-family: monospace; }
+div#cgit button { background: #eee; padding: 0.3em 1em; cursor: pointer; }
+div#cgit button:hover { background: #ddd; }
+
+/* Sign out is a form because it changes something. Inline, or the button lands
+ * on its own line away from the name it belongs to. */
+div#cgit table#header td.form form { display: inline; }
+div#cgit table#header td.form a { padding: 0 0.2em; }
+
+div#cgit button.link {
+ background: none;
+ border: none;
+ padding: 0;
+ color: blue;
+ cursor: pointer;
+}
+div#cgit button.link:hover { text-decoration: underline; }
+
+/* A row of controls that belong together. */
+div#cgit .bar {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1em;
+ align-items: center;
+ margin: 1em 0;
+ padding: 0.5em 0;
+ border-top: solid 1px #eee;
+ border-bottom: solid 1px #eee;
+}
+div#cgit .bar form { display: flex; gap: 0.5em; align-items: center; margin: 0; }
+div#cgit .bar input { width: auto; }
+div#cgit .bar span { display: flex; gap: 0.8em; }
+
+/* One person's say in a thread. */
+div#cgit .comment { border: solid 1px #ddd; margin: 1em 0; }
+div#cgit .comment .byline { background: #f6f6f6; border-bottom: solid 1px #ddd; padding: 0.3em 0.6em; }
+div#cgit .comment article { margin: 0; padding: 0.2em 0.8em 0.8em 0.8em; }
+div#cgit img.avatar { vertical-align: middle; border: solid 1px #ccc; }
+
+div#cgit .label {
+ background: #eee;
+ border: solid 1px #ccc;
+ padding: 0 0.4em;
+ margin-right: 0.3em;
+ font-size: 90%;
+}
+
+div#cgit .state-open { color: #007700; font-weight: bold; }
+div#cgit .state-closed { color: #770000; font-weight: bold; }
+div#cgit .notice { color: #007700; font-weight: bold; margin: 1em 0; }
+
+/* Markdown, so that a comment reads as one. */
+div#cgit article h1, div#cgit article h2, div#cgit article h3 { font-size: 120%; margin: 1em 0 0.4em 0; }
+div#cgit article p, div#cgit article ul, div#cgit article ol { margin: 0.6em 0; }
+div#cgit article code { background: #f0f0f0; padding: 0 0.2em; font-size: 95%; }
+div#cgit article pre { background: #f6f6f6; border: solid 1px #e0e0e0; padding: 0.6em; overflow-x: auto; }
+div#cgit article pre code { background: none; padding: 0; }
+div#cgit article blockquote { border-left: solid 3px #ccc; margin: 0.6em 0; padding-left: 0.8em; color: #555; }
+
+/* What cannot be undone is marked, so that it is never a slip. */
+
+div#cgit .danger {
+ border: solid 1px #770000;
+ border-left-width: 4px;
+ background: #fff6f6;
+ padding: 0.5em 1em;
+ margin: 2em 0;
+}
+
+div#cgit .danger h2, div#cgit .danger h3, div#cgit .danger h4 { color: #770000; }
+div#cgit .danger button { background: #ffdddd; border-color: #770000; }
+
+/* highlight's classes, which cgit's stylesheet has nothing to say about. */
+
+.hl.com, .hl.slc { color: #767676; font-style: italic; }
+.hl.sng, .hl.str { color: #a11; }
+.hl.num, .hl.esc { color: #7a5600; }
+.hl.ppc, .hl.pps, .hl.ipl { color: #616100; }
+.hl.kwa { color: #000; font-weight: bold; }
+.hl.kwb { color: #0057ae; }
+.hl.kwc { color: #000; }
+.hl.kwd, .hl.kwe, .hl.kwf { color: #010181; }
+.hl.lin { color: #555; }
+.hl.err, .hl.erm { color: #c00; font-weight: bold; }