Commit 307a6f3
Eric Bower
·
2026-05-13 22:31:44 -0400 EDT
parent 84dd9bd
style: design tweaks
13 files changed,
+407,
-797
M
Makefile
+5,
-6
1@@ -29,16 +29,15 @@ test:
2 go test ./...
3 .PHONY: test
4
5-static: build clean
6- ./pgit \
7+static:
8+ go run main.go \
9 --out ./public \
10 --label pgit \
11- --desc "static site generator for git" \
12 --clone-url "https://github.com/picosh/pgit.git" \
13- --home-url "https://git.erock.io" \
14- --theme "dracula" \
15+ --issues-url "https://github.com/picosh/pgit/issues" \
16+ --contrib-url "https://github.com/picosh/pgit/pulls" \
17 --revs main
18-.PHONY:
19+.PHONY: static
20
21 dev: static
22 rsync -rv --delete ./public/ pgs.sh:/git-pgit-local/
+0,
-3
1@@ -11,14 +11,11 @@
2 {{template "meta" .}}
3
4 <link rel="stylesheet" href="{{.Repo.RootRelative}}vars.css" />
5- <link rel="stylesheet" href="{{.Repo.RootRelative}}smol.css" />
6 <link rel="stylesheet" href="{{.Repo.RootRelative}}main.css" />
7 </head>
8 <body>
9 <header class="box">{{template "header" .}}</header>
10- <hr class="my" />
11 <main>{{template "content" .}}</main>
12- <hr class="my" />
13 <footer>{{template "footer" .}}</footer>
14 </body>
15 </html>
+12,
-12
1@@ -5,19 +5,19 @@
2 {{end}}
3
4 {{define "content"}}
5- <dl>
6- <dt>commit</dt>
7- <dd><a href="{{.CommitURL}}">{{.CommitID}}</a></dd>
8+ <h2>Commit <code>{{.CommitID}}</code></h2>
9
10- <dt>parent</dt>
11- <dd><a href="{{.ParentURL}}">{{.Parent}}</a></dd>
12-
13- <dt>author</dt>
14- <dd>{{.Commit.Author.Name}}</dd>
15+ <div class="flex justify-between">
16+ <div class="flex items-center gap-xs">
17+ <span>{{.Commit.Author.Name}}</span>
18+ <span> · </span>
19+ <span>{{.Commit.Author.When}}</span>
20+ </div>
21
22- <dt>date</dt>
23- <dd>{{.Commit.Author.When}}</dd>
24- </dl>
25+ <div>
26+ parent <a href="{{.ParentURL}}">{{.Parent}}</a>
27+ </div>
28+ </div>
29
30 <pre class="white-space-bs">{{.Commit.Message}}</pre>
31
32@@ -30,7 +30,7 @@
33
34 <div>
35 {{range .Diff.Files}}
36- <div class="my-sm">
37+ <div class="my">
38 <span>{{.FileType}}</span>
39 <a href="#diff-{{.Name}}">{{.Name}}</a>
40 </div>
+7,
-4
1@@ -5,10 +5,15 @@
2 {{end}}
3
4 {{define "content"}}
5- <div class="text-md text-transform-none">
6+ <div class="box sticky flex items-center gap border-visited" style="margin: 0 !important;">
7+ <code>{{.RevData.Name}}</code>
8+
9 {{range .Item.Crumbs}}
10- <a href="{{.URL}}">{{.Text}}</a> {{if .IsLast}}{{else}}/{{end}}
11+ <a href="{{.URL}}">{{.Text}}</a>
12+ <span>/</span>
13 {{end}}
14+
15+ {{.Item.Name}}
16 </div>
17
18 {{if .Repo.HideTreeLastCommit}}
19@@ -31,7 +36,5 @@
20 </div>
21 {{end}}
22
23- <h2 class="text-lg text-transform-none">{{.Item.Name}}</h2>
24-
25 {{.Contents}}
26 {{end }}
1@@ -1,5 +1,5 @@
2 {{define "footer"}}
3-<div>
4+<div class="mb">
5 built with <a href="https://pgit.pico.sh">pgit</a>
6 </div>
7 {{end}}
+37,
-9
1@@ -1,14 +1,42 @@
2 {{define "header"}}
3 <div class="flex flex-col">
4- <nav>
5- <h1 class="text-xl p-0">
6- {{.Repo.RepoName}}
7- </h1>
8- <a href="{{.SiteURLs.SummaryURL}}">README</a> |
9- <a href="{{.SiteURLs.RefsURL}}">refs</a> |
10- <span class="font-bold">{{.RevData.Name}}</span> |
11- <a href="{{.RevData.TreeURL}}">code</a> |
12- <a href="{{.RevData.LogURL}}">commits</a>
13+ <nav class="flex gap">
14+ <a class="btn-nav {{if eq .ActivePage `readme`}}btn-active{{end}}" href="{{.SiteURLs.SummaryURL}}">{{.Repo.RepoName}}</a>
15+ <a class="btn-nav flex items-center {{if eq .ActivePage `code`}}btn-active{{end}}" href="{{.RevData.TreeURL}}">
16+ <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="16" width="16" viewBox="0 0 16 16" style="margin-right: 5px;">
17+ <path fill="currentColor" d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path>
18+ </svg>
19+ code
20+ </a>
21+ <a class="btn-nav flex items-center {{if eq .ActivePage `commits`}}btn-active{{end}}" href="{{.RevData.LogURL}}">
22+ <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="16" width="16" viewBox="0 0 16 16" style="margin-right: 5px;">
23+ <path fill="currentColor" d="M11.93 8.5a4.002 4.002 0 0 1-7.86 0H.75a.75.75 0 0 1 0-1.5h3.32a4.002 4.002 0 0 1 7.86 0h3.32a.75.75 0 0 1 0 1.5Zm-1.43-.75a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0Z"></path>
24+ </svg>
25+ commits
26+ </a>
27+ <a class="btn-nav flex items-center {{if eq .ActivePage `refs`}}btn-active{{end}}" href="{{.SiteURLs.RefsURL}}">
28+ <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="16" width="16" viewBox="0 0 16 16" style="margin-right: 5px;">
29+ <path fill="currentColor" d="M1 7.775V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.752 1.752 0 0 1 1 7.775Zm1.5 0c0 .066.026.13.073.177l6.25 6.25a.25.25 0 0 0 .354 0l5.025-5.025a.25.25 0 0 0 0-.354l-6.25-6.25a.25.25 0 0 0-.177-.073H2.75a.25.25 0 0 0-.25.25ZM6 5a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z"></path>
30+ </svg>
31+ refs
32+ </a>
33+ {{if .SiteURLs.IssuesURL}}
34+ <a class="btn-nav flex items-center" href="{{.SiteURLs.IssuesURL}}">
35+ <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="16" width="16" viewBox="0 0 16 16" style="margin-right: 5px;">
36+ <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path>
37+ <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path>
38+ </svg>
39+ issues
40+ </a>
41+ {{end}}
42+ {{if .SiteURLs.ContribURL}}
43+ <a class="btn-nav flex items-center" href="{{.SiteURLs.ContribURL}}">
44+ <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="16" width="16" viewBox="0 0 16 16" style="margin-right: 5px;">
45+ <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path>
46+ </svg>
47+ contrib
48+ </a>
49+ {{end}}
50 </nav>
51 </div>
52 {{end}}
+19,
-15
1@@ -5,27 +5,31 @@
2
3 {{define "content"}}
4 <div class="group-2">
5- <div><span class="font-bold">({{.NumCommits}})</span> commits</div>
6+ <div class="box sticky flex items-center gap border-visited" style="margin: 0 !important;">
7+ <code>{{.RevData.Name}}</code>
8+ <div><span class="font-bold">{{.NumCommits}}</span> commits</div>
9+ </div>
10+
11 {{range .Logs}}
12 <div>
13- <div class="flex justify-between items-center">
14+ <div class="flex items-center gap mb text-sm">
15 <a href="{{.URL}}" class="mono">{{.ShortID}}</a>
16
17- <div class="mono">
18- {{range .Refs}}
19- {{if .URL}}
20- <a href="{{.URL}}">({{.Refspec}})</a>
21- {{else}}
22- ({{.Refspec}})
23- {{end}}
24- {{end}}
25+ <div class="flex items-center gap-xs">
26+ <span>{{.AuthorStr}}</span>
27+ <span> · </span>
28+ <span>{{.WhenStr}}</span>
29 </div>
30- </div>
31
32- <div class="flex items-center gap-xs text-sm">
33- <span>{{.AuthorStr}}</span>
34- <span> · </span>
35- <span>{{.WhenStr}}</span>
36+ {{range .Refs}}
37+ {{if .URL}}
38+ <code>
39+ <a href="{{.URL}}">{{.Refspec}}</a>
40+ </code>
41+ {{else}}
42+ <code>{{.Refspec}}</code>
43+ {{end}}
44+ {{end}}
45 </div>
46
47 <div>
+11,
-9
1@@ -4,15 +4,17 @@
2 {{define "meta"}}{{end}}
3
4 {{define "content"}}
5- <h2 class="text-lg font-bold">refs</h2>
6+ <h2>refs</h2>
7
8- <ul>
9- {{range .Refs}}
10- {{if .URL}}
11- <li><a href="{{.URL}}">{{.Refspec}}</a></li>
12- {{else}}
13- <li>{{.Refspec}}</li>
14+ <div class="box" style="padding: 0 !important;">
15+ {{range .Refs}}
16+ <div class="flex justify-between items-center gap-2 py px tree-row border-b">
17+ {{if .URL}}
18+ <div><a href="{{.URL}}">{{.Refspec}}</a></div>
19+ {{else}}
20+ <div>{{.Refspec}}</div>
21+ {{end}}
22+ </div>
23 {{end}}
24- {{end}}
25- </ul>
26+ </div>
27 {{end}}
+6,
-5
1@@ -1,13 +1,14 @@
2 {{template "base" .}}
3
4-{{define "title"}}{{.Repo.RepoName}}{{if .Repo.Desc}}- {{.Repo.Desc}}{{end}}{{end}}
5+{{define "title"}}{{.Repo.RepoName}}{{end}}
6 {{define "meta"}}
7 <link rel="stylesheet" href="{{.Repo.RootRelative}}syntax.css" />
8 {{end}}
9
10 {{define "content"}}
11- <div>
12- {{if .SiteURLs.CloneURL}}<pre class="mb-0">git clone {{.SiteURLs.CloneURL}}</pre>{{end}}
13- </div>
14- {{.Readme}}
15+ {{if .SiteURLs.CloneURL}}
16+ <div class="box sticky border-visited mono">git clone {{.SiteURLs.CloneURL}}</div>
17+ {{end}}
18+
19+ {{.Readme}}
20 {{end}}
+12,
-10
1@@ -4,19 +4,21 @@
2 {{define "meta"}}{{end}}
3
4 {{define "content"}}
5- <div>
6- <div class="text-md text-transform-none mb">
7- {{range .Tree.Crumbs}}
8- {{if .IsLast}}
9- <span class="font-bold">{{.Text}}</span>
10- {{else}}
11- <a href="{{.URL}}">{{.Text}}</a> {{if .IsLast}}{{else}}/{{end}}
12- {{end}}
13+ <div class="box sticky flex items-center gap border-visited">
14+ <code>{{.RevData.Name}}</code>
15+
16+ {{range .Tree.Crumbs}}
17+ {{if .IsLast}}
18+ <span class="font-bold">{{.Text}}</span>
19+ {{else}}
20+ <a href="{{.URL}}">{{.Text}}</a> {{if .IsLast}}{{else}}<span>/</span>{{end}}
21 {{end}}
22- </div>
23+ {{end}}
24+ </div>
25
26+ <div class="box" style="padding: 0 !important;">
27 {{range .Tree.Items}}
28- <div class="flex justify-between items-center gap-2 p tree-row border-b">
29+ <div class="flex justify-between items-center gap-2 py px tree-row border-b">
30 <div class="flex-1 tree-path flex items-center gap">
31 {{if .IsDir}}
32 <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="16" width="16" viewBox="0 0 512 512">
M
main.go
+40,
-30
1@@ -40,8 +40,6 @@ type Config struct {
2 // optional params
3 // generate logs anad tree based on the git revisions provided
4 Revs []string
5- // description of repo used in the header of site
6- Desc string
7 // maximum number of commits that we will process in descending order
8 MaxCommits int
9 // name of the readme file
10@@ -53,8 +51,11 @@ type Config struct {
11 HideTreeLastCommit bool
12
13 // user-defined urls
14- HomeURL template.URL
15 CloneURL template.URL
16+ // repo bug tracking url
17+ IssuesURL template.URL
18+ // repo code contribution url (e.g. pull requests, patches)
19+ ContribURL template.URL
20
21 // https://developer.mozilla.org/en-US/docs/Web/API/URL_API/Resolving_relative_references#root_relative
22 RootRelative string
23@@ -164,16 +165,18 @@ type BranchOutput struct {
24 }
25
26 type SiteURLs struct {
27- HomeURL template.URL
28+ IssuesURL template.URL
29+ ContribURL template.URL
30 CloneURL template.URL
31 SummaryURL template.URL
32 RefsURL template.URL
33 }
34
35 type PageData struct {
36- Repo *Config
37- SiteURLs *SiteURLs
38- RevData *RevData
39+ Repo *Config
40+ SiteURLs *SiteURLs
41+ RevData *RevData
42+ ActivePage string
43 }
44
45 type SummaryPageData struct {
46@@ -454,58 +457,63 @@ func (c *Config) copyStatic(dir string) error {
47 return nil
48 }
49
50-func (c *Config) writeRootSummary(data *PageData, readme template.HTML) {
51+func (c *Config) writeRootSummary(data PageData, readme template.HTML) {
52+ data.ActivePage = "readme"
53 c.Logger.Info("writing root html", "repoPath", c.RepoPath)
54 c.writeHtml(&WriteData{
55 Filename: "index.html",
56 Template: "html/summary.page.tmpl",
57 Data: &SummaryPageData{
58- PageData: data,
59+ PageData: &data,
60 Readme: readme,
61 },
62 })
63 }
64
65-func (c *Config) writeTree(data *PageData, tree *TreeRoot) {
66+func (c *Config) writeTree(data PageData, tree *TreeRoot) {
67+ data.ActivePage = "code"
68 c.Logger.Info("writing tree", "treePath", tree.Path)
69 c.writeHtml(&WriteData{
70 Filename: "index.html",
71 Subdir: tree.Path,
72 Template: "html/tree.page.tmpl",
73 Data: &TreePageData{
74- PageData: data,
75+ PageData: &data,
76 Tree: tree,
77 },
78 })
79 }
80
81-func (c *Config) writeLog(data *PageData, logs []*CommitData) {
82+func (c *Config) writeLog(data PageData, logs []*CommitData) {
83+ data.ActivePage = "commits"
84 c.Logger.Info("writing log file", "revision", data.RevData.Name())
85 c.writeHtml(&WriteData{
86 Filename: "index.html",
87 Subdir: getLogBaseDir(data.RevData),
88 Template: "html/log.page.tmpl",
89 Data: &LogPageData{
90- PageData: data,
91+ PageData: &data,
92 NumCommits: len(logs),
93 Logs: logs,
94 },
95 })
96 }
97
98-func (c *Config) writeRefs(data *PageData, refs []*RefInfo) {
99+func (c *Config) writeRefs(data PageData, refs []*RefInfo) {
100+ data.ActivePage = "refs"
101 c.Logger.Info("writing refs", "repoPath", c.RepoPath)
102 c.writeHtml(&WriteData{
103 Filename: "refs.html",
104 Template: "html/refs.page.tmpl",
105 Data: &RefPageData{
106- PageData: data,
107+ PageData: &data,
108 Refs: refs,
109 },
110 })
111 }
112
113-func (c *Config) writeHTMLTreeFile(pageData *PageData, treeItem *TreeItem) string {
114+func (c *Config) writeHTMLTreeFile(pageData PageData, treeItem *TreeItem) string {
115+ pageData.ActivePage = "code"
116 d := filepath.Dir(treeItem.Path)
117 readme := ""
118 b, err := treeItem.Entry.Blob().Bytes()
119@@ -531,7 +539,7 @@ func (c *Config) writeHTMLTreeFile(pageData *PageData, treeItem *TreeItem) strin
120 Filename: fmt.Sprintf("%s.html", treeItem.Entry.Name()),
121 Template: "html/file.page.tmpl",
122 Data: &FilePageData{
123- PageData: pageData,
124+ PageData: &pageData,
125 Contents: template.HTML(contents),
126 Item: treeItem,
127 },
128@@ -540,7 +548,8 @@ func (c *Config) writeHTMLTreeFile(pageData *PageData, treeItem *TreeItem) strin
129 return readme
130 }
131
132-func (c *Config) writeLogDiff(repo *git.Repository, pageData *PageData, commit *CommitData) {
133+func (c *Config) writeLogDiff(repo *git.Repository, pageData PageData, commit *CommitData) {
134+ pageData.ActivePage = "commits"
135 commitID := commit.ID.String()
136
137 c.Mutex.RLock()
138@@ -601,7 +610,7 @@ func (c *Config) writeLogDiff(repo *git.Repository, pageData *PageData, commit *
139 rnd.Files = fls
140
141 commitData := &CommitPageData{
142- PageData: pageData,
143+ PageData: &pageData,
144 Commit: commit,
145 CommitID: getShortID(commitID),
146 Diff: rnd,
147@@ -680,7 +689,8 @@ func (c *Config) getCommitURL(commitID string) template.URL {
148
149 func (c *Config) getURLs() *SiteURLs {
150 return &SiteURLs{
151- HomeURL: c.HomeURL,
152+ IssuesURL: c.IssuesURL,
153+ ContribURL: c.ContribURL,
154 CloneURL: c.CloneURL,
155 RefsURL: c.getRefsURL(),
156 SummaryURL: c.getSummaryURL(),
157@@ -808,8 +818,8 @@ func (c *Config) writeRepo() *BranchOutput {
158 Repo: c,
159 SiteURLs: c.getURLs(),
160 }
161- c.writeRefs(data, refInfoList)
162- c.writeRootSummary(data, template.HTML(mainOutput.Readme))
163+ c.writeRefs(*data, refInfoList)
164+ c.writeRootSummary(*data, template.HTML(mainOutput.Readme))
165 return mainOutput
166 }
167
168@@ -1066,13 +1076,13 @@ func (c *Config) writeRevision(repo *git.Repository, pageData *PageData, refs []
169 })
170 }
171
172- c.writeLog(pageData, logs)
173+ c.writeLog(*pageData, logs)
174
175 for _, cm := range logs {
176 wg.Add(1)
177 go func(commit *CommitData) {
178 defer wg.Done()
179- c.writeLogDiff(repo, pageData, commit)
180+ c.writeLogDiff(repo, *pageData, commit)
181 }(cm)
182 }
183 }()
184@@ -1107,7 +1117,7 @@ func (c *Config) writeRevision(repo *git.Repository, pageData *PageData, refs []
185 return
186 }
187
188- readmeStr := c.writeHTMLTreeFile(pageData, entry)
189+ readmeStr := c.writeHTMLTreeFile(*pageData, entry)
190 if readmeStr != "" {
191 readme = readmeStr
192 }
193@@ -1122,7 +1132,7 @@ func (c *Config) writeRevision(repo *git.Repository, pageData *PageData, refs []
194 wg.Add(1)
195 go func(tree *TreeRoot) {
196 defer wg.Done()
197- c.writeTree(pageData, tree)
198+ c.writeTree(*pageData, tree)
199 }(t)
200 }
201 }()
202@@ -1170,8 +1180,8 @@ func main() {
203 var themeFlag = flag.String("theme", "dracula", "theme to use for site")
204 var labelFlag = flag.String("label", "", "pretty name for the subdir where we create the repo, default is last folder in --repo")
205 var cloneFlag = flag.String("clone-url", "", "git clone URL for upstream")
206- var homeFlag = flag.String("home-url", "", "URL for breadcumbs to go to root page, hidden if empty")
207- var descFlag = flag.String("desc", "", "description for repo")
208+ var issuesFlag = flag.String("issues-url", "", "where the repo tracks bug reports")
209+ var contribFlag = flag.String("contrib-url", "", "where the repo tracks code contributions")
210 var rootRelativeFlag = flag.String("root-relative", "/", "html root relative")
211 var maxCommitsFlag = flag.Int("max-commits", 0, "maximum number of commits to generate")
212 var hideTreeLastCommitFlag = flag.Bool("hide-tree-last-commit", false, "dont calculate last commit for each file in the tree")
213@@ -1212,8 +1222,8 @@ func main() {
214 Theme: theme,
215 Logger: logger,
216 CloneURL: template.URL(*cloneFlag),
217- HomeURL: template.URL(*homeFlag),
218- Desc: *descFlag,
219+ IssuesURL: template.URL(*issuesFlag),
220+ ContribURL: template.URL(*contribFlag),
221 MaxCommits: *maxCommitsFlag,
222 HideTreeLastCommit: *hideTreeLastCommitFlag,
223 RootRelative: *rootRelativeFlag,
+257,
-5
1@@ -1,10 +1,232 @@
2+*,
3+::before,
4+::after {
5+ box-sizing: border-box;
6+}
7+
8+::-moz-focus-inner {
9+ border-style: none;
10+ padding: 0;
11+}
12+:-moz-focusring {
13+ outline: 1px dotted ButtonText;
14+}
15+:-moz-ui-invalid {
16+ box-shadow: none;
17+}
18+
19+:root {
20+ --line-height: 1.3rem;
21+ --grid-height: 0.65rem;
22+}
23+
24+html {
25+ background-color: var(--bg-color);
26+ color: var(--text-color);
27+ font-size: 16px;
28+ line-height: var(--line-height);
29+ font-family:
30+ -apple-system,
31+ BlinkMacSystemFont,
32+ "Segoe UI",
33+ Roboto,
34+ Oxygen,
35+ Ubuntu,
36+ Cantarell,
37+ "Fira Sans",
38+ "Droid Sans",
39+ "Helvetica Neue",
40+ Arial,
41+ sans-serif,
42+ "Apple Color Emoji",
43+ "Segoe UI Emoji",
44+ "Segoe UI Symbol";
45+ -webkit-text-size-adjust: 100%;
46+ -moz-tab-size: 4;
47+ -o-tab-size: 4;
48+ tab-size: 4;
49+}
50+
51+body {
52+ margin: 0 auto;
53+ padding: 0 1rem;
54+}
55+
56+img {
57+ max-width: 100%;
58+ height: auto;
59+}
60+
61+b,
62+strong {
63+ font-weight: bold;
64+}
65+
66+code,
67+kbd,
68+samp,
69+pre {
70+ font-family: monospace;
71+}
72+
73+code,
74+kbd,
75+samp {
76+ border: 2px solid var(--code);
77+}
78+
79+pre > code {
80+ background-color: inherit;
81+ padding: 0;
82+ border: none;
83+ border-radius: 0;
84+}
85+
86+code {
87+ font-size: 90%;
88+ border-radius: 0.3rem;
89+ padding: 0.025rem 0.3rem;
90+ border: 1px solid var(--border);
91+}
92+
93 pre {
94 border: 1px solid var(--border);
95 padding: var(--grid-height);
96+ border-radius: 1px;
97+ overflow-x: auto;
98 }
99
100-body {
101- max-width: 900px;
102+h1,
103+h2,
104+h3,
105+h4 {
106+ font-style: normal;
107+ font-size: 1rem;
108+ font-weight: bold;
109+ line-height: var(--line-height);
110+ margin: 0 0 var(--grid-height) 0;
111+ padding: 0;
112+ border: 0;
113+}
114+
115+path {
116+ fill: var(--text-color);
117+}
118+
119+a {
120+ text-decoration: none;
121+ color: var(--text-color);
122+}
123+
124+a:hover,
125+a:visited:hover {
126+ color: var(--visited);
127+ text-decoration: underline;
128+}
129+
130+a:visited {
131+ color: var(--text-color);
132+}
133+
134+header {
135+ margin: 1rem auto;
136+}
137+
138+p {
139+ margin-top: var(--line-height);
140+ margin-bottom: var(--line-height);
141+}
142+
143+footer {
144+ text-align: center;
145+}
146+
147+.font-bold {
148+ font-weight: bold;
149+}
150+
151+.mono {
152+ font-family: monospace;
153+}
154+
155+.text-sm {
156+ font-size: 0.8rem;
157+}
158+
159+.flex {
160+ display: flex;
161+}
162+
163+.flex-col {
164+ flex-direction: column;
165+}
166+
167+.items-center {
168+ align-items: center;
169+}
170+
171+.m-0 {
172+ margin: 0;
173+}
174+
175+.mb {
176+ margin-bottom: var(--grid-height);
177+}
178+
179+.mb-0 {
180+ margin-bottom: 0;
181+}
182+
183+.my {
184+ margin-top: var(--grid-height);
185+ margin-bottom: var(--grid-height);
186+}
187+
188+.px {
189+ padding-left: 0.5rem;
190+ padding-right: 0.5rem;
191+}
192+
193+.py {
194+ padding-top: var(--grid-height);
195+ padding-bottom: var(--grid-height);
196+}
197+
198+.justify-between {
199+ justify-content: space-between;
200+}
201+
202+.justify-center {
203+ justify-content: center;
204+}
205+
206+.gap {
207+ gap: var(--grid-height);
208+}
209+
210+.gap-2 {
211+ gap: var(--line-height);
212+}
213+
214+.group {
215+ display: flex;
216+ flex-direction: column;
217+ gap: var(--grid-height);
218+}
219+
220+.group-2 {
221+ display: flex;
222+ flex-direction: column;
223+ gap: var(--line-height);
224+}
225+
226+.flex-1 {
227+ flex: 1;
228+}
229+
230+.box {
231+ border: 2px solid var(--grey-light);
232+ padding: var(--grid-height);
233 }
234
235 .border-b {
236@@ -21,6 +243,10 @@ body {
237 border: 1px solid var(--border);
238 }
239
240+.border-visited {
241+ border-color: var(--visited);
242+}
243+
244 .tree-size {
245 width: 60px;
246 text-align: right;
247@@ -30,9 +256,15 @@ body {
248 text-wrap: wrap;
249 }
250
251+.sticky {
252+ position: sticky;
253+ top: 0;
254+ left: 0;
255+ background-color: var(--bg-color);
256+}
257+
258 .diff-file {
259 align-items: center;
260- height: 62px;
261 position: sticky;
262 top: 0;
263 left: 0;
264@@ -43,11 +275,31 @@ body {
265 white-space: break-spaces;
266 }
267
268-.mb-0 {
269- margin-bottom: 0;
270+.btn-nav {
271+ border-radius: 4px;
272+ padding: 6px 10px;
273+ border: 1px solid var(--border);
274+}
275+
276+.btn-nav:hover, .btn-active {
277+ border-color: var(--visited);
278+ text-decoration: none;
279+ color: var(--text-color);
280 }
281
282 @media only screen and (max-width: 900px) {
283+ body {
284+ padding: 0 1rem;
285+ }
286+
287+ header {
288+ margin: 0;
289+ }
290+
291+ .flex-collapse {
292+ flex-direction: column;
293+ }
294+
295 .tree-commit {
296 display: none;
297 }
+0,
-688
1@@ -1,688 +0,0 @@
2-*,
3-::before,
4-::after {
5- box-sizing: border-box;
6-}
7-
8-::-moz-focus-inner {
9- border-style: none;
10- padding: 0;
11-}
12-:-moz-focusring {
13- outline: 1px dotted ButtonText;
14-}
15-:-moz-ui-invalid {
16- box-shadow: none;
17-}
18-
19-:root {
20- --line-height: 1.3rem;
21- --grid-height: 0.65rem;
22-}
23-
24-html {
25- background-color: var(--bg-color);
26- color: var(--text-color);
27- font-size: 16px;
28- line-height: var(--line-height);
29- font-family:
30- -apple-system,
31- BlinkMacSystemFont,
32- "Segoe UI",
33- Roboto,
34- Oxygen,
35- Ubuntu,
36- Cantarell,
37- "Fira Sans",
38- "Droid Sans",
39- "Helvetica Neue",
40- Arial,
41- sans-serif,
42- "Apple Color Emoji",
43- "Segoe UI Emoji",
44- "Segoe UI Symbol";
45- -webkit-text-size-adjust: 100%;
46- -moz-tab-size: 4;
47- -o-tab-size: 4;
48- tab-size: 4;
49-}
50-
51-body {
52- margin: 0 auto;
53-}
54-
55-img {
56- max-width: 100%;
57- height: auto;
58-}
59-
60-b,
61-strong {
62- font-weight: bold;
63-}
64-
65-code,
66-kbd,
67-samp,
68-pre {
69- font-family: monospace;
70-}
71-
72-code,
73-kbd,
74-samp {
75- border: 2px solid var(--code);
76-}
77-
78-pre > code {
79- background-color: inherit;
80- padding: 0;
81- border: none;
82- border-radius: 0;
83-}
84-
85-code {
86- font-size: 90%;
87- border-radius: 0.3rem;
88- padding: 0.025rem 0.3rem;
89-}
90-
91-pre {
92- font-size: 0.8rem;
93- border-radius: 1px;
94- padding: var(--line-height);
95- overflow-x: auto;
96- background-color: var(--pre);
97-}
98-
99-small {
100- font-size: 0.8rem;
101-}
102-
103-details {
104- border: 2px solid var(--grey-light);
105- padding: calc(var(--grid-height) - 2px) 1ch;
106- margin-bottom: var(--grid-height);
107-}
108-
109-details[open] summary {
110- margin-bottom: var(--grid-height);
111-}
112-
113-summary {
114- display: list-item;
115- cursor: pointer;
116-}
117-
118-h1,
119-h2,
120-h3,
121-h4 {
122- margin: 0;
123- padding: 0;
124- border: 0;
125- font-style: normal;
126- font-weight: inherit;
127- font-size: inherit;
128-}
129-
130-path {
131- fill: var(--text-color);
132- stroke: var(--text-color);
133-}
134-
135-hr {
136- color: inherit;
137- border: 0;
138- height: 2px;
139- background: var(--grey);
140- margin: calc(var(--grid-height) - 2px) auto;
141-}
142-
143-a {
144- text-decoration: none;
145- color: var(--link-color);
146-}
147-
148-a:hover,
149-a:visited:hover {
150- text-decoration: underline;
151-}
152-
153-a:visited {
154- color: var(--visited);
155-}
156-
157-section {
158- margin-bottom: 1.4rem;
159-}
160-
161-section:last-child {
162- margin-bottom: 0;
163-}
164-
165-header {
166- margin: 1rem auto;
167-}
168-
169-p {
170- margin-top: var(--line-height);
171- margin-bottom: var(--line-height);
172-}
173-
174-article {
175- overflow-wrap: break-word;
176-}
177-
178-blockquote {
179- border-left: 5px solid var(--blockquote);
180- background-color: var(--blockquote-bg);
181- padding: var(--grid-height);
182- margin: var(--line-height) 0;
183-}
184-
185-blockquote > p {
186- margin: 0;
187-}
188-
189-blockquote code {
190- border: 1px solid var(--blockquote);
191-}
192-
193-ul {
194- padding: 0 0 0 var(--line-height);
195- list-style-position: inside;
196- list-style-type: square;
197- margin: var(--line-height) 0;
198-}
199-
200-ul[style*="list-style-type: none;"] {
201- padding: 0;
202-}
203-
204-ol {
205- padding: 0 0 0 var(--line-height);
206- list-style-type: decimal;
207- margin: var(--line-height) 0;
208-}
209-
210-ol[style*="list-style-type: none;"] {
211- padding: 0;
212-}
213-
214-ol ul, ol ol, ul ol, ul ul {
215- padding: 0 0 0 3ch;
216- margin: 0;
217-}
218-
219-li {
220- margin: 0;
221- padding: 0;
222-}
223-
224-li::marker {
225- line-height: 0;
226-}
227-
228-footer {
229- text-align: center;
230- margin-bottom: calc(var(--line-height) * 3);
231-}
232-
233-dt {
234- font-weight: bold;
235-}
236-
237-dd {
238- margin-left: 0;
239-}
240-
241-dd:not(:last-child) {
242- margin-bottom: 0.5rem;
243-}
244-
245-figure {
246- margin: 0;
247-}
248-
249-sup {
250- line-height: 0;
251-}
252-
253-#toc {
254- margin-top: var(--line-height);
255-}
256-
257-.container {
258- max-width: 50em;
259- width: 100%;
260-}
261-
262-.container-sm {
263- max-width: 40em;
264- width: 100%;
265-}
266-
267-.mono {
268- font-family: monospace;
269-}
270-
271-.link-alt-hover,
272-.link-alt-hover:visited,
273-.link-alt-hover:visited:hover,
274-.link-alt-hover:hover {
275- color: var(--hover);
276- text-decoration: none;
277-}
278-
279-.link-alt-hover:visited:hover,
280-.link-alt-hover:hover {
281- text-decoration: underline;
282-}
283-
284-.link-alt,
285-.link-alt:visited,
286-.link-alt:visited:hover,
287-.link-alt:hover {
288- color: var(--white);
289- text-decoration: none;
290-}
291-
292-.link-alt:visited:hover,
293-.link-alt:hover {
294- text-decoration: underline;
295-}
296-
297-.text-2xl code, .text-xl code, .text-lg code, .text-md code {
298- text-transform: none;
299-}
300-
301-.text-2xl {
302- font-size: var(--line-height);
303- font-weight: bold;
304- line-height: var(--line-height);
305- margin-bottom: var(--grid-height);
306- text-transform: uppercase;
307-}
308-
309-.text-xl, .text-lg, .text-md {
310- font-size: 1rem;
311- font-weight: bold;
312- line-height: var(--line-height);
313- margin-bottom: var(--grid-height);
314- text-transform: uppercase;
315-}
316-
317-.text-sm {
318- font-size: 0.8rem;
319-}
320-
321-.w-full {
322- width: 100%;
323-}
324-
325-.border {
326- border: 2px solid var(--grey-light);
327-}
328-
329-.text-left {
330- text-align: left;
331-}
332-
333-.text-center {
334- text-align: center;
335-}
336-
337-.text-underline {
338- text-decoration: underline;
339- text-decoration-thickness: 2px;
340-}
341-
342-.text-hdr {
343- color: var(--hover);
344-}
345-
346-.font-bold {
347- font-weight: bold;
348-}
349-
350-.font-italic {
351- font-style: italic;
352-}
353-
354-.inline {
355- display: inline;
356-}
357-
358-.inline-block {
359- display: inline-block;
360-}
361-
362-.max-w-half {
363- max-width: 50%;
364-}
365-
366-.flex {
367- display: flex;
368-}
369-
370-.flex-col {
371- flex-direction: column;
372-}
373-
374-.flex-wrap {
375- flex-wrap: wrap;
376-}
377-
378-.items-center {
379- align-items: center;
380-}
381-
382-.m-0 {
383- margin: 0;
384-}
385-
386-.mt-0 {
387- margin-top: 0;
388-}
389-
390-.mt {
391- margin-top: var(--grid-height);
392-}
393-
394-.mt-2 {
395- margin-top: var(--line-height);
396-}
397-
398-.mt-4 {
399- margin-top: calc(var(--line-height) * 2);
400-}
401-
402-.mb {
403- margin-bottom: var(--grid-height);
404-}
405-
406-.mb-2 {
407- margin-bottom: var(--line-height);
408-}
409-
410-.mb-4 {
411- margin-bottom: calc(var(--line-height) * 2);
412-}
413-
414-.mr {
415- margin-right: 0.5rem;
416-}
417-
418-.ml {
419- margin-left: 0.5rem;
420-}
421-
422-.my {
423- margin-top: var(--grid-height);
424- margin-bottom: var(--grid-height);
425-}
426-
427-.my-2 {
428- margin-top: var(--line-height);
429- margin-bottom: var(--line-height);
430-}
431-
432-.my-4 {
433- margin-top: calc(var(--line-height) * 2);
434- margin-bottom: calc(var(--line-height) * 2);
435-}
436-
437-.p-0 {
438- padding: 0;
439-}
440-
441-.px {
442- padding-left: 0.5rem;
443- padding-right: 0.5rem;
444-}
445-
446-.px-4 {
447- padding-left: 2rem;
448- padding-right: 2rem;
449-}
450-
451-.py {
452- padding-top: var(--grid-height);
453- padding-bottom: var(--grid-height);
454-}
455-
456-.py-4 {
457- padding-top: calc(var(--line-height) * 2);
458- padding-bottom: calc(var(--line-height) * 2);
459-}
460-
461-.justify-between {
462- justify-content: space-between;
463-}
464-
465-.justify-center {
466- justify-content: center;
467-}
468-
469-.gap {
470- gap: var(--grid-height);
471-}
472-
473-.gap-2 {
474- gap: var(--line-height);
475-}
476-
477-.group {
478- display: flex;
479- flex-direction: column;
480- gap: var(--grid-height);
481-}
482-
483-.group-2 {
484- display: flex;
485- flex-direction: column;
486- gap: var(--line-height);
487-}
488-
489-.group-h {
490- display: flex;
491- gap: var(--grid-height);
492- align-items: center;
493-}
494-
495-.flex-1 {
496- flex: 1;
497-}
498-
499-.items-end {
500- align-items: end;
501-}
502-
503-.items-start {
504- align-items: start;
505-}
506-
507-.justify-end {
508- justify-content: end;
509-}
510-
511-.font-grey-light {
512- color: var(--grey-light);
513-}
514-
515-.hidden {
516- display: none;
517-}
518-
519-.align-right {
520- text-align: right;
521-}
522-
523-.text-transform-none {
524- text-transform: none;
525-}
526-
527-/* ==== MARKDOWN ==== */
528-
529-.md h1,
530-.md h2,
531-.md h3,
532-.md h4 {
533- padding: 0;
534- margin: 0;
535- /* margin: 1.5rem 0 0.9rem 0; */
536- font-weight: bold;
537-}
538-
539-.md h1 a,
540-.md h2 a,
541-.md h3 a,
542-.md h4 a {
543- color: var(--grey-light);
544- text-decoration: none;
545-}
546-
547-h1 code, h2 code, h3 code, h4 code {
548- text-transform: none;
549-}
550-
551-.md h1 {
552- font-size: 1rem;
553- line-height: var(--line-height);
554- margin-top: calc(var(--line-height) * 2);
555- margin-bottom: var(--grid-height);
556- text-transform: uppercase;
557-}
558-
559-.md h2, .md h3, .md h4 {
560- font-size: 1rem;
561- line-height: var(--line-height);
562- margin-top: calc(var(--line-height) * 2);
563- margin-bottom: var(--line-height);
564- text-transform: uppercase;
565- color: var(--white-dark);
566-}
567-
568-/* ==== HELPERS ==== */
569-
570-.logo-header {
571- line-height: 1;
572- display: inline-block;
573- background-color: #ff79c6;
574- background-image: linear-gradient(to right, #ff5555, #ff79c6, #f8f859);
575- color: transparent;
576- background-clip: text;
577- border: 3px solid #ff79c6;
578- padding: 8px 10px 10px 10px;
579- border-radius: 10px;
580- background-size: 100%;
581- margin: 0;
582- -webkit-background-clip: text;
583- -moz-background-clip: text;
584- -webkit-text-fill-color: transparent;
585- -moz-text-fill-color: transparent;
586-}
587-
588-.btn {
589- border: 2px solid var(--link-color);
590- color: var(--link-color);
591- padding: 0.4rem 1rem;
592- font-weight: bold;
593- display: inline-block;
594-}
595-
596-.btn-link,
597-.btn-link:visited {
598- border: 2px solid var(--link-color);
599- color: var(--link-color);
600- padding: var(--grid-height);
601- text-decoration: none;
602- font-weight: bold;
603- display: inline-block;
604-}
605-
606-.box {
607- border: 2px solid var(--grey-light);
608- padding: var(--grid-height);
609-}
610-
611-.box-sm {
612- border: 2px solid var(--grey-light);
613- padding: var(--grid-height);
614-}
615-
616-.box-alert {
617- border: 2px solid var(--hover);
618- padding: var(--line-height);
619-}
620-
621-.box-sm-alert {
622- border: 2px solid var(--hover);
623- padding: var(--grid-height);
624-}
625-
626-.list-none {
627- list-style-type: none;
628-}
629-
630-.list-square {
631- list-style-type: square;
632-}
633-
634-.list-disc {
635- list-style-type: disc;
636-}
637-
638-.list-decimal {
639- list-style-type: decimal;
640-}
641-
642-.pill {
643- border: 1px solid var(--link-color);
644- color: var(--link-color);
645-}
646-
647-.pill-alert {
648- border: 1px solid var(--hover);
649- color: var(--hover);
650-}
651-
652-.pill-info {
653- border: 1px solid var(--visited);
654- color: var(--visited);
655-}
656-
657-@media only screen and (max-width: 40em) {
658- body {
659- padding: 0 1rem;
660- }
661-
662- header {
663- margin: 0;
664- }
665-
666- .flex-collapse {
667- flex-direction: column;
668- }
669-}
670-
671-#debug {
672- position: relative;
673-}
674-
675-#debug .debug-grid {
676- width: 100%;
677- height: 100%;
678- position: absolute;
679- top: 0;
680- left: 0;
681- right: 0;
682- bottom: 0;
683- z-index: -1;
684- background-image:
685- repeating-linear-gradient(var(--code) 0 1px, transparent 1px 100%),
686- repeating-linear-gradient(90deg, var(--code) 0 1px, transparent 1px 100%);
687- background-size: 1ch var(--grid-height);
688- margin: 0;
689-}