Commit 4bcc586

Nick Faro committed on
dark mode, make back button clickable
commit 4bcc586d300c32c34a9db7e508386a9b0bb12aa9 parent bdd26c4
4 changed files +82−28
Modifiedinternal/site/site.go +10−4
@@ -349,7 +349,12 @@ func (g *Generator) treePage(ctx context.Context, branch, oid, dir string, summa
349 data.Entries = entries 349 data.Entries = entries
350 if dir != "" { 350 if dir != "" {
351 data.Title = path.Base(dir) + " · " + g.RepoName 351 data.Title = path.Base(dir) + " · " + g.RepoName
352 data.ParentURL = routeURL(g.BaseURL, path.Join("tree", branchRouteSegment(branch), path.Dir(dir))) 352 parent := path.Dir(dir)
353 if parent == "." && branch == g.DefaultBranch {
354 data.ParentURL = g.BaseURL
355 } else {
356 data.ParentURL = routeURL(g.BaseURL, path.Join("tree", branchRouteSegment(branch), parent))
357 }
353 } 358 }
354 if root { 359 if root {
355 data.Kind = "repo" 360 data.Kind = "repo"
@@ -566,9 +571,10 @@ func highlight(filename string, content []byte) (template.HTML, string, error) {
566 571
567 func (g *Generator) chromaCSS() string { 572 func (g *Generator) chromaCSS() string {
568 formatter := html.New(html.WithClasses(true)) 573 formatter := html.New(html.WithClasses(true))
569 var css bytes.Buffer 574 var light, dark bytes.Buffer
570 _ = formatter.WriteCSS(&css, styles.Get("github")) 575 _ = formatter.WriteCSS(&light, styles.Get("github"))
571 return "\n" + css.String() 576 _ = formatter.WriteCSS(&dark, styles.Get("github-dark"))
577 return "\n" + light.String() + "\n@media (prefers-color-scheme: dark) {\n" + dark.String() + "}\n"
572 } 578 }
573 579
574 func (g *Generator) render(data pageData) ([]byte, error) { 580 func (g *Generator) render(data pageData) ([]byte, error) {
Modifiedinternal/site/site_test.go +6−0
@@ -60,9 +60,13 @@ func TestFullAndIncrementalBuild(t *testing.T) {
60 assertPageDoesNotContain(t, full, "blob/main/vector.svg", `<div class="image-preview">`) 60 assertPageDoesNotContain(t, full, "blob/main/vector.svg", `<div class="image-preview">`)
61 assertPage(t, full, ".dumbforge/assets/gabriel-mark.svg", "<svg") 61 assertPage(t, full, ".dumbforge/assets/gabriel-mark.svg", "<svg")
62 assertPage(t, full, ".dumbforge/assets/gabriel-mark.png", "PNG") 62 assertPage(t, full, ".dumbforge/assets/gabriel-mark.png", "PNG")
63 assertPage(t, full, ".dumbforge/assets/site.css", `@media (prefers-color-scheme: dark)`)
64 assertPage(t, full, ".dumbforge/assets/site.css", `--bg: #0d1117`)
63 assertPage(t, full, "tree/main/src", "main.go") 65 assertPage(t, full, "tree/main/src", "main.go")
64 assertPage(t, full, "tree/main/src", `<div class="tree-row">`) 66 assertPage(t, full, "tree/main/src", `<div class="tree-row">`)
65 assertPageDoesNotContain(t, full, "tree/main/src", `<a class="tree-row"`) 67 assertPageDoesNotContain(t, full, "tree/main/src", `<a class="tree-row"`)
68 assertPage(t, full, "tree/main/src", `<a class="file-icon parent-icon" href="https://example.invalid/repo.git" aria-label="Parent directory">`)
69 assertPage(t, full, "tree/main/src", `<a class="file-name" href="https://example.invalid/repo.git">..</a>`)
66 assertPage(t, full, "tree/main/src", `commits/main#`+first+`" title="initial">initial</a>`) 70 assertPage(t, full, "tree/main/src", `commits/main#`+first+`" title="initial">initial</a>`)
67 assertPage(t, full, "commits/main", "Commit history") 71 assertPage(t, full, "commits/main", "Commit history")
68 assertPage(t, full, "commits/main", "gravatar.com/avatar") 72 assertPage(t, full, "commits/main", "gravatar.com/avatar")
@@ -103,11 +107,13 @@ func TestSlashBranchUsesUnambiguousRoutes(t *testing.T) {
103 if err != nil { 107 if err != nil {
104 t.Fatal(err) 108 t.Fatal(err)
105 } 109 }
110 generator.SetBranches([]string{"main", "feature/demo"}, "main")
106 build, err := generator.BuildBranch(context.Background(), "feature/demo", "", oid, false) 111 build, err := generator.BuildBranch(context.Background(), "feature/demo", "", oid, false)
107 if err != nil { 112 if err != nil {
108 t.Fatal(err) 113 t.Fatal(err)
109 } 114 }
110 assertPage(t, build, "tree/feature~demo", "feature/demo") 115 assertPage(t, build, "tree/feature~demo", "feature/demo")
116 assertPage(t, build, "tree/feature~demo/docs", `<a class="file-name" href="https://example.invalid/repo.git/tree/feature~demo">..</a>`)
111 assertPage(t, build, "blob/feature~demo/docs/guide.md", "Guide") 117 assertPage(t, build, "blob/feature~demo/docs/guide.md", "Guide")
112 assertPage(t, build, "commits/feature~demo", "Commit history") 118 assertPage(t, build, "commits/feature~demo", "Commit history")
113 assertPage(t, build, ".dumbforge/files/feature~demo.json", `/blob/feature~demo/docs/guide.md`) 119 assertPage(t, build, ".dumbforge/files/feature~demo.json", `/blob/feature~demo/docs/guide.md`)
Modifiedinternal/site/style.go +64−22
@@ -12,10 +12,51 @@ const siteCSS = `:root {
12 --green: #1f883d; 12 --green: #1f883d;
13 --green-hover: #1a7f37; 13 --green-hover: #1a7f37;
14 --shadow: 0 1px 0 rgba(31,35,40,.04); 14 --shadow: 0 1px 0 rgba(31,35,40,.04);
15 --button-border: rgba(31,35,40,.15);
16 --button-hover: #eff2f5;
17 --success-bg: #dafbe1;
18 --popover-bg: #ffffff;
19 --popover-shadow: 0 8px 24px rgba(140,149,159,.28);
20 --neutral-muted: #eaeef2;
21 --selected-bg: #ddf4ff;
22 --attention-bg: #fff8c5;
23 --checker-a: #f6f8fa;
24 --checker-b: #ffffff;
25 --dialog-backdrop: rgba(31,35,40,.45);
26 --dialog-shadow: 0 16px 48px rgba(31,35,40,.3);
27 --brand-filter: none;
15 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; 28 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
16 color: var(--text); 29 color: var(--text);
17 background: var(--bg); 30 background: var(--bg);
18 } 31 }
32 @media (prefers-color-scheme: dark) {
33 :root {
34 --bg: #0d1117;
35 --canvas: #161b22;
36 --canvas-subtle: #010409;
37 --border: #30363d;
38 --border-muted: #21262d;
39 --text: #e6edf3;
40 --muted: #8b949e;
41 --blue: #58a6ff;
42 --green: #238636;
43 --green-hover: #2ea043;
44 --shadow: 0 0 transparent;
45 --button-border: rgba(240,246,252,.1);
46 --button-hover: #21262d;
47 --success-bg: rgba(46,160,67,.15);
48 --popover-bg: #161b22;
49 --popover-shadow: 0 8px 24px rgba(1,4,9,.8);
50 --neutral-muted: #21262d;
51 --selected-bg: rgba(56,139,253,.15);
52 --attention-bg: rgba(187,128,9,.15);
53 --checker-a: #161b22;
54 --checker-b: #21262d;
55 --dialog-backdrop: rgba(1,4,9,.8);
56 --dialog-shadow: 0 16px 48px rgba(1,4,9,.8);
57 --brand-filter: invert(1);
58 }
59 }
19 * { box-sizing: border-box; } 60 * { box-sizing: border-box; }
20 [hidden] { display: none !important; } 61 [hidden] { display: none !important; }
21 body { margin: 0; min-width: 320px; background: var(--bg); font-size: 14px; line-height: 1.5; } 62 body { margin: 0; min-width: 320px; background: var(--bg); font-size: 14px; line-height: 1.5; }
@@ -30,7 +71,7 @@ button, input { font: inherit; }
30 .topbar { min-height: 64px; padding: 16px 32px; display: flex; align-items: center; gap: 12px; background: var(--canvas); } 71 .topbar { min-height: 64px; padding: 16px 32px; display: flex; align-items: center; gap: 12px; background: var(--canvas); }
31 .brand { display: inline-grid; place-items: center; color: var(--text); } 72 .brand { display: inline-grid; place-items: center; color: var(--text); }
32 .brand:hover { text-decoration: none; } 73 .brand:hover { text-decoration: none; }
33 .brand-mark { display: block; width: 32px; height: 32px; object-fit: contain; } 74 .brand-mark { display: block; width: 32px; height: 32px; object-fit: contain; filter: var(--brand-filter); }
34 .header-crumbs { min-width: 0; display: flex; align-items: center; gap: 8px; font-size: 14px; } 75 .header-crumbs { min-width: 0; display: flex; align-items: center; gap: 8px; font-size: 14px; }
35 .header-crumbs a { color: var(--text); white-space: nowrap; } 76 .header-crumbs a { color: var(--text); white-space: nowrap; }
36 .header-owner { color: var(--text); white-space: nowrap; } 77 .header-owner { color: var(--text); white-space: nowrap; }
@@ -61,15 +102,15 @@ button, input { font: inherit; }
61 .toolbar { min-height: 34px; margin-bottom: 16px; display: flex; align-items: center; gap: 8px; } 102 .toolbar { min-height: 34px; margin-bottom: 16px; display: flex; align-items: center; gap: 8px; }
62 .toolbar-spacer { flex: 1 1 auto; } 103 .toolbar-spacer { flex: 1 1 auto; }
63 .branch-menu, .clone-menu { position: relative; } 104 .branch-menu, .clone-menu { position: relative; }
64 .branch-button, .clone-button, .secondary-button, .blob-actions a, .blob-actions button { min-height: 32px; border: 1px solid rgba(31,35,40,.15); border-radius: 6px; background: var(--canvas); box-shadow: var(--shadow); color: var(--text); display: inline-flex; align-items: center; justify-content: center; gap: 7px; padding: 5px 12px; font-weight: 600; font-size: 13px; line-height: 20px; cursor: pointer; } 105 .branch-button, .clone-button, .secondary-button, .blob-actions a, .blob-actions button { min-height: 32px; border: 1px solid var(--button-border); border-radius: 6px; background: var(--canvas); box-shadow: var(--shadow); color: var(--text); display: inline-flex; align-items: center; justify-content: center; gap: 7px; padding: 5px 12px; font-weight: 600; font-size: 13px; line-height: 20px; cursor: pointer; }
65 .branch-button:hover, .secondary-button:hover, .blob-actions a:hover, .blob-actions button:hover { background: #eff2f5; text-decoration: none; } 106 .branch-button:hover, .secondary-button:hover, .blob-actions a:hover, .blob-actions button:hover { background: var(--button-hover); text-decoration: none; }
66 .branch-button { max-width: 240px; } 107 .branch-button { max-width: 240px; }
67 .branch-button span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } 108 .branch-button span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
68 .clone-button { background: var(--green); border-color: rgba(31,35,40,.15); color: white; } 109 .clone-button { background: var(--green); border-color: var(--button-border); color: white; }
69 .clone-button:hover { background: var(--green-hover); } 110 .clone-button:hover { background: var(--green-hover); }
70 .fork-button { white-space: nowrap; } 111 .fork-button { white-space: nowrap; }
71 .fork-button.is-copied { color: var(--green); background: #dafbe1; } 112 .fork-button.is-copied { color: var(--green); background: var(--success-bg); }
72 .branch-popover, .clone-popover { position: absolute; z-index: 30; top: calc(100% + 7px); border: 1px solid var(--border); border-radius: 8px; background: white; box-shadow: 0 8px 24px rgba(140,149,159,.28); } 113 .branch-popover, .clone-popover { position: absolute; z-index: 30; top: calc(100% + 7px); border: 1px solid var(--border); border-radius: 8px; background: var(--popover-bg); box-shadow: var(--popover-shadow); }
73 .branch-popover { left: 0; width: 300px; overflow: hidden; } 114 .branch-popover { left: 0; width: 300px; overflow: hidden; }
74 .branch-popover h3 { margin: 0; padding: 12px 16px 10px; border-bottom: 1px solid var(--border-muted); font-size: 14px; } 115 .branch-popover h3 { margin: 0; padding: 12px 16px 10px; border-bottom: 1px solid var(--border-muted); font-size: 14px; }
75 .branch-list { max-height: 300px; padding: 6px 0; overflow-y: auto; } 116 .branch-list { max-height: 300px; padding: 6px 0; overflow-y: auto; }
@@ -83,8 +124,8 @@ button, input { font: inherit; }
83 .clone-input-group { display: flex; } 124 .clone-input-group { display: flex; }
84 .clone-input-group input { min-width: 0; flex: 1; height: 34px; padding: 5px 9px; border: 1px solid var(--border); border-radius: 6px 0 0 6px; color: var(--text); background: var(--canvas); font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 12px; } 125 .clone-input-group input { min-width: 0; flex: 1; height: 34px; padding: 5px 9px; border: 1px solid var(--border); border-radius: 6px 0 0 6px; color: var(--text); background: var(--canvas); font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 12px; }
85 .clone-input-group button { width: 40px; display: grid; place-items: center; border: 1px solid var(--border); border-left: 0; border-radius: 0 6px 6px 0; color: var(--text); background: var(--canvas); cursor: pointer; } 126 .clone-input-group button { width: 40px; display: grid; place-items: center; border: 1px solid var(--border); border-left: 0; border-radius: 0 6px 6px 0; color: var(--text); background: var(--canvas); cursor: pointer; }
86 .clone-input-group button:hover { background: #eef1f4; } 127 .clone-input-group button:hover { background: var(--button-hover); }
87 .clone-input-group button.is-copied { color: var(--green); background: #dafbe1; } 128 .clone-input-group button.is-copied { color: var(--green); background: var(--success-bg); }
88 .clone-popover > code { display: block; margin-top: 12px; padding: 9px 10px; overflow: hidden; border-radius: 6px; color: var(--muted); background: var(--canvas); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; } 129 .clone-popover > code { display: block; margin-top: 12px; padding: 9px 10px; overflow: hidden; border-radius: 6px; color: var(--muted); background: var(--canvas); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
89 .menu-status { margin: 0; padding: 12px 16px; color: var(--muted); font-size: 13px; } 130 .menu-status { margin: 0; padding: 12px 16px; color: var(--muted); font-size: 13px; }
90 .toolbar-path { border-bottom: 1px solid var(--border-muted); padding-bottom: 14px; } 131 .toolbar-path { border-bottom: 1px solid var(--border-muted); padding-bottom: 14px; }
@@ -95,7 +136,7 @@ button, input { font: inherit; }
95 136
96 .tree-card, .readme-card, .blob-card { border: 1px solid var(--border); border-radius: 6px; overflow: hidden; background: var(--bg); } 137 .tree-card, .readme-card, .blob-card { border: 1px solid var(--border); border-radius: 6px; overflow: hidden; background: var(--bg); }
97 .commit-row { min-height: 54px; display: grid; grid-template-columns: 32px minmax(120px,1fr) auto auto auto; align-items: center; gap: 9px; padding: 9px 14px; background: var(--canvas); border-bottom: 1px solid var(--border); } 138 .commit-row { min-height: 54px; display: grid; grid-template-columns: 32px minmax(120px,1fr) auto auto auto; align-items: center; gap: 9px; padding: 9px 14px; background: var(--canvas); border-bottom: 1px solid var(--border); }
98 .avatar { width: 28px; height: 28px; display: block; border-radius: 50%; object-fit: cover; background: #eaeef2; } 139 .avatar { width: 28px; height: 28px; display: block; border-radius: 50%; object-fit: cover; background: var(--neutral-muted); }
99 .latest-commit { min-width: 0; display: flex; align-items: baseline; gap: 9px; } 140 .latest-commit { min-width: 0; display: flex; align-items: baseline; gap: 9px; }
100 .latest-commit strong { flex: none; } 141 .latest-commit strong { flex: none; }
101 .commit-message { min-width: 0; overflow: hidden; color: var(--text); text-overflow: ellipsis; white-space: nowrap; } 142 .commit-message { min-width: 0; overflow: hidden; color: var(--text); text-overflow: ellipsis; white-space: nowrap; }
@@ -108,6 +149,7 @@ button, input { font: inherit; }
108 .tree-row:first-child { border-top: 0; } 149 .tree-row:first-child { border-top: 0; }
109 .tree-row:hover { background: var(--canvas); } 150 .tree-row:hover { background: var(--canvas); }
110 .file-icon { width: 18px; height: 18px; display: inline-grid; place-items: center; color: var(--muted); } 151 .file-icon { width: 18px; height: 18px; display: inline-grid; place-items: center; color: var(--muted); }
152 .parent-icon:hover { color: var(--blue); text-decoration: none; }
111 .file-icon.folder { color: #54aeff; } 153 .file-icon.folder { color: #54aeff; }
112 .file-icon .icon { width: 16px; height: 16px; } 154 .file-icon .icon { width: 16px; height: 16px; }
113 .file-name { color: var(--text); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } 155 .file-name { color: var(--text); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -148,9 +190,9 @@ button, input { font: inherit; }
148 .contributor-avatar { width: 32px; height: 32px; } 190 .contributor-avatar { width: 32px; height: 32px; }
149 .contributor-name { overflow: hidden; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; } 191 .contributor-name { overflow: hidden; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
150 .contributor-count { color: var(--muted); font-size: 12px; } 192 .contributor-count { color: var(--muted); font-size: 12px; }
151 .language-bar { height: 10px; display: flex; overflow: hidden; margin: 12px 0 13px; border-radius: 999px; background: #eaeef2; } 193 .language-bar { height: 10px; display: flex; overflow: hidden; margin: 12px 0 13px; border-radius: 999px; background: var(--neutral-muted); }
152 .language-segment { width: var(--language-width); min-width: 2px; background: var(--language-color); } 194 .language-segment { width: var(--language-width); min-width: 2px; background: var(--language-color); }
153 .language-segment + .language-segment { border-left: 2px solid white; } 195 .language-segment + .language-segment { border-left: 2px solid var(--bg); }
154 .language-list { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 6px 12px; padding: 0; margin: 0; list-style: none; } 196 .language-list { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 6px 12px; padding: 0; margin: 0; list-style: none; }
155 .language-list li { min-width: 0; display: grid; grid-template-columns: 10px minmax(0,1fr) auto; align-items: center; gap: 6px; font-size: 12px; } 197 .language-list li { min-width: 0; display: grid; grid-template-columns: 10px minmax(0,1fr) auto; align-items: center; gap: 6px; font-size: 12px; }
156 .language-list strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } 198 .language-list strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -169,7 +211,7 @@ button, input { font: inherit; }
169 .file-tree-search { min-height: 34px; margin: 8px 10px; padding: 0 8px; display: flex; align-items: center; gap: 7px; border: 1px solid var(--border); border-radius: 6px; } 211 .file-tree-search { min-height: 34px; margin: 8px 10px; padding: 0 8px; display: flex; align-items: center; gap: 7px; border: 1px solid var(--border); border-radius: 6px; }
170 .file-tree-search:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(9,105,218,.15); } 212 .file-tree-search:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(9,105,218,.15); }
171 .file-tree-search .icon { color: var(--muted); } 213 .file-tree-search .icon { color: var(--muted); }
172 .file-tree-search input { width: 100%; min-width: 0; height: 30px; border: 0; outline: 0; background: transparent; font-size: 13px; } 214 .file-tree-search input { width: 100%; min-width: 0; height: 30px; border: 0; outline: 0; color: var(--text); background: transparent; font-size: 13px; }
173 .file-tree { position: relative; min-height: 0; flex: 1; padding: 2px 8px 12px; overflow: auto; } 215 .file-tree { position: relative; min-height: 0; flex: 1; padding: 2px 8px 12px; overflow: auto; }
174 .file-tree-node { min-width: max-content; } 216 .file-tree-node { min-width: max-content; }
175 .file-tree-children { padding-left: 16px; } 217 .file-tree-children { padding-left: 16px; }
@@ -182,7 +224,7 @@ button, input { font: inherit; }
182 .file-tree-caret { width: 10px; flex: none; color: var(--muted); font-size: 17px; line-height: 1; transform-origin: center; transition: transform .1s ease; } 224 .file-tree-caret { width: 10px; flex: none; color: var(--muted); font-size: 17px; line-height: 1; transform-origin: center; transition: transform .1s ease; }
183 .file-tree-caret.open { transform: rotate(90deg); } 225 .file-tree-caret.open { transform: rotate(90deg); }
184 .file-tree-file { padding-left: 23px; } 226 .file-tree-file { padding-left: 23px; }
185 .file-tree-file.selected { color: var(--text); background: #ddf4ff; font-weight: 600; } 227 .file-tree-file.selected { color: var(--text); background: var(--selected-bg); font-weight: 600; }
186 .blob-toolbar { min-height: 42px; } 228 .blob-toolbar { min-height: 42px; }
187 .blob-card { border-radius: 6px; } 229 .blob-card { border-radius: 6px; }
188 .blob-heading { min-height: 54px; padding: 10px 14px; display: flex; align-items: center; gap: 12px; background: var(--canvas); border-bottom: 1px solid var(--border); } 230 .blob-heading { min-height: 54px; padding: 10px 14px; display: flex; align-items: center; gap: 12px; background: var(--canvas); border-bottom: 1px solid var(--border); }
@@ -191,15 +233,15 @@ button, input { font: inherit; }
191 .blob-heading span { color: var(--muted); font-size: 12px; } 233 .blob-heading span { color: var(--muted); font-size: 12px; }
192 .blob-actions { margin-left: auto; display: flex; gap: 6px; } 234 .blob-actions { margin-left: auto; display: flex; gap: 6px; }
193 .blob-actions a, .blob-actions button { min-height: 28px; padding: 3px 10px; } 235 .blob-actions a, .blob-actions button { min-height: 28px; padding: 3px 10px; }
194 .blob-actions button.is-copied { color: var(--green); background: #dafbe1; } 236 .blob-actions button.is-copied { color: var(--green); background: var(--success-bg); }
195 .markdown-file { min-height: 240px; background: var(--bg); } 237 .markdown-file { min-height: 240px; background: var(--bg); }
196 .code-view { overflow: auto; font: 12px/1.5 ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace; } 238 .code-view { overflow: auto; font: 12px/1.5 ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace; }
197 .code-view .chroma { margin: 0; padding: 0; background: white; } 239 .code-view .chroma { margin: 0; padding: 0; background: var(--bg); }
198 .code-view .chroma table { width: 100%; border-spacing: 0; } 240 .code-view .chroma table { width: 100%; border-spacing: 0; }
199 .code-view .chroma td:first-child { width: 1%; min-width: 50px; padding: 8px 10px; color: #6e7781; text-align: right; vertical-align: top; border-right: 1px solid var(--border-muted); user-select: none; } 241 .code-view .chroma td:first-child { width: 1%; min-width: 50px; padding: 8px 10px; color: var(--muted); text-align: right; vertical-align: top; border-right: 1px solid var(--border-muted); user-select: none; }
200 .code-view .chroma td:last-child { padding: 8px 16px; } 242 .code-view .chroma td:last-child { padding: 8px 16px; }
201 .code-view pre { margin: 0; } 243 .code-view pre { margin: 0; }
202 .image-preview { padding: 32px; display: grid; place-items: center; min-height: 260px; background: repeating-conic-gradient(#f6f8fa 0 25%, #fff 0 50%) 50%/20px 20px; } 244 .image-preview { padding: 32px; display: grid; place-items: center; min-height: 260px; background: repeating-conic-gradient(var(--checker-a) 0 25%, var(--checker-b) 0 50%) 50%/20px 20px; }
203 .image-preview img { max-width: 100%; max-height: 70vh; } 245 .image-preview img { max-width: 100%; max-height: 70vh; }
204 .binary-notice { padding: 70px 20px; display: flex; flex-direction: column; align-items: center; color: var(--muted); } 246 .binary-notice { padding: 70px 20px; display: flex; flex-direction: column; align-items: center; color: var(--muted); }
205 .binary-notice > span .icon { width: 44px; height: 44px; } 247 .binary-notice > span .icon { width: 44px; height: 44px; }
@@ -216,9 +258,9 @@ button, input { font: inherit; }
216 .commit-list { overflow: hidden; border: 1px solid var(--border); border-radius: 7px; } 258 .commit-list { overflow: hidden; border: 1px solid var(--border); border-radius: 7px; }
217 .commit-list-row { min-height: 67px; display: grid; grid-template-columns: 38px minmax(0,1fr) auto; align-items: center; gap: 11px; padding: 10px 14px; border-top: 1px solid var(--border-muted); } 259 .commit-list-row { min-height: 67px; display: grid; grid-template-columns: 38px minmax(0,1fr) auto; align-items: center; gap: 11px; padding: 10px 14px; border-top: 1px solid var(--border-muted); }
218 .commit-list-row:first-child { border-top: 0; } 260 .commit-list-row:first-child { border-top: 0; }
219 .commit-list-row:target { background: #fff8c5; } 261 .commit-list-row:target { background: var(--attention-bg); }
220 .commit-list-row:hover { background: var(--canvas); } 262 .commit-list-row:hover { background: var(--canvas); }
221 .commit-list-row:target:hover { background: #fff8c5; } 263 .commit-list-row:target:hover { background: var(--attention-bg); }
222 .commit-list-row .commit-avatar { width: 34px; height: 34px; } 264 .commit-list-row .commit-avatar { width: 34px; height: 34px; }
223 .commit-list-body { min-width: 0; display: flex; flex-direction: column; } 265 .commit-list-body { min-width: 0; display: flex; flex-direction: column; }
224 .commit-list-message { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } 266 .commit-list-message { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -227,8 +269,8 @@ button, input { font: inherit; }
227 .commit-sha { padding: 4px 8px; border: 1px solid var(--border); border-radius: 6px; color: var(--text); background: var(--canvas); font: 12px ui-monospace, SFMono-Regular, Consolas, monospace; } 269 .commit-sha { padding: 4px 8px; border: 1px solid var(--border); border-radius: 6px; color: var(--text); background: var(--canvas); font: 12px ui-monospace, SFMono-Regular, Consolas, monospace; }
228 .commit-sha:hover { color: var(--blue); text-decoration: none; } 270 .commit-sha:hover { color: var(--blue); text-decoration: none; }
229 271
230 .dialog-backdrop { position: fixed; z-index: 100; inset: 0; display: grid; align-items: start; justify-items: center; padding: 12vh 20px 20px; background: rgba(31,35,40,.45); } 272 .dialog-backdrop { position: fixed; z-index: 100; inset: 0; display: grid; align-items: start; justify-items: center; padding: 12vh 20px 20px; background: var(--dialog-backdrop); }
231 .file-dialog { width: min(680px, 100%); max-height: 70vh; display: flex; flex-direction: column; overflow: hidden; border: 1px solid var(--border); border-radius: 12px; background: var(--bg); box-shadow: 0 16px 48px rgba(31,35,40,.3); } 273 .file-dialog { width: min(680px, 100%); max-height: 70vh; display: flex; flex-direction: column; overflow: hidden; border: 1px solid var(--border); border-radius: 12px; background: var(--bg); box-shadow: var(--dialog-shadow); }
232 .file-dialog > header { min-height: 48px; padding: 8px 10px 8px 16px; display: flex; align-items: center; border-bottom: 1px solid var(--border-muted); } 274 .file-dialog > header { min-height: 48px; padding: 8px 10px 8px 16px; display: flex; align-items: center; border-bottom: 1px solid var(--border-muted); }
233 .file-dialog h2 { margin: 0; font-size: 16px; } 275 .file-dialog h2 { margin: 0; font-size: 16px; }
234 .icon-button { width: 32px; height: 32px; margin-left: auto; display: grid; place-items: center; border: 0; border-radius: 6px; color: var(--muted); background: transparent; cursor: pointer; } 276 .icon-button { width: 32px; height: 32px; margin-left: auto; display: grid; place-items: center; border: 0; border-radius: 6px; color: var(--muted); background: transparent; cursor: pointer; }
@@ -236,7 +278,7 @@ button, input { font: inherit; }
236 .file-search { margin: 12px 16px; padding: 0 10px; display: flex; align-items: center; gap: 8px; border: 1px solid #818b98; border-radius: 6px; } 278 .file-search { margin: 12px 16px; padding: 0 10px; display: flex; align-items: center; gap: 8px; border: 1px solid #818b98; border-radius: 6px; }
237 .file-search:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(9,105,218,.2); } 279 .file-search:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(9,105,218,.2); }
238 .file-search .icon { color: var(--muted); } 280 .file-search .icon { color: var(--muted); }
239 .file-search input { width: 100%; height: 36px; border: 0; outline: 0; background: transparent; } 281 .file-search input { width: 100%; height: 36px; border: 0; outline: 0; color: var(--text); background: transparent; }
240 .file-results { min-height: 110px; overflow-y: auto; border-top: 1px solid var(--border-muted); } 282 .file-results { min-height: 110px; overflow-y: auto; border-top: 1px solid var(--border-muted); }
241 .file-result { padding: 8px 16px; display: block; color: var(--text); font: 13px ui-monospace, SFMono-Regular, Consolas, monospace; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } 283 .file-result { padding: 8px 16px; display: block; color: var(--text); font: 13px ui-monospace, SFMono-Regular, Consolas, monospace; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
242 .file-result:hover, .file-result:focus { background: var(--canvas); color: var(--blue); text-decoration: none; outline: 0; } 284 .file-result:hover, .file-result:focus { background: var(--canvas); color: var(--blue); text-decoration: none; outline: 0; }
Modifiedinternal/site/template.go +2−2
@@ -5,7 +5,7 @@ const pageTemplate = `<!doctype html>
5 <head> 5 <head>
6 <meta charset="utf-8"> 6 <meta charset="utf-8">
7 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <meta name="viewport" content="width=device-width, initial-scale=1">
8 <meta name="color-scheme" content="light"> 8 <meta name="color-scheme" content="light dark">
9 <title>{{.Title}}</title> 9 <title>{{.Title}}</title>
10 <link rel="icon" type="image/png" sizes="256x256" href="{{.BaseURL}}/.dumbforge/assets/gabriel-mark.png"> 10 <link rel="icon" type="image/png" sizes="256x256" href="{{.BaseURL}}/.dumbforge/assets/gabriel-mark.png">
11 <link rel="icon" type="image/svg+xml" href="{{.BaseURL}}/.dumbforge/assets/gabriel-mark.svg"> 11 <link rel="icon" type="image/svg+xml" href="{{.BaseURL}}/.dumbforge/assets/gabriel-mark.svg">
@@ -479,7 +479,7 @@ const pageTemplate = `<!doctype html>
479 <a class="commit-count-link" href="{{.CommitsURL}}">{{icon "history"}}<strong>{{.CommitCount}}</strong> commits</a> 479 <a class="commit-count-link" href="{{.CommitsURL}}">{{icon "history"}}<strong>{{.CommitCount}}</strong> commits</a>
480 </div> 480 </div>
481 <div class="tree-rows"> 481 <div class="tree-rows">
482 {{if .ParentURL}}<div class="tree-row parent-row"><span class="file-icon">{{icon "back"}}</span><a class="file-name" href="{{.ParentURL}}">..</a><span></span><span></span></div>{{end}} 482 {{if .ParentURL}}<div class="tree-row parent-row"><a class="file-icon parent-icon" href="{{.ParentURL}}" aria-label="Parent directory">{{icon "back"}}</a><a class="file-name" href="{{.ParentURL}}">..</a><span></span><span></span></div>{{end}}
483 {{range .Entries}}<div class="tree-row"> 483 {{range .Entries}}<div class="tree-row">
484 {{if eq .Type "tree"}}<span class="file-icon folder">{{icon "folder"}}</span>{{else if eq .Type "commit"}}<span class="file-icon">{{icon "repo"}}</span>{{else}}<span class="file-icon">{{icon "file"}}</span>{{end}} 484 {{if eq .Type "tree"}}<span class="file-icon folder">{{icon "folder"}}</span>{{else if eq .Type "commit"}}<span class="file-icon">{{icon "repo"}}</span>{{else}}<span class="file-icon">{{icon "file"}}</span>{{end}}
485 <a class="file-name" href="{{.URL}}">{{.Name}}</a> 485 <a class="file-name" href="{{.URL}}">{{.Name}}</a>