1diff --git a/scss/main.scss b/scss/main.scss
2index 0766f82a7ceae091b15f47a009b1f82b8bb19204..b76423f843be94eb52197bf2e42b219eada6c556 100644
3--- a/scss/main.scss
4+++ b/scss/main.scss
5@@ -74,6 +74,13 @@ property: margin-right,
6 class: me,
7 values: map-merge($spacers, (auto: auto))
8 ),
9+ "margin-start": (
10+ responsive: true,
11+ property: margin-left,
12+ class: ms,
13+ values: map-merge($spacers, (auto: auto))
14+ ),
15+
16 );
17
18 @import "bootstrap/scss/utilities/_api.scss";
19diff --git a/templates/base.qtpl b/templates/base.qtpl
20index 7063829b49a5aadc65c985dab3910c976e294224..566308f9c13c670c3106c8ba2c51230e533e00d8 100644
21--- a/templates/base.qtpl
22+++ b/templates/base.qtpl
23@@ -43,7 +43,7 @@ <head>
24 <meta charset="utf-8">
25 <link rel="icon" href="data:,">
26 <title>{%= p.Title() %}</title>
27- <link rel="stylesheet" href="/static/main{%s Slug%}.css">
28+ <link rel="stylesheet" href="/static/main{%s Slug %}.css">
29 <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
30 <meta name="viewport" content="width=device-width, initial-scale=1" />
31 </head>
32diff --git a/templates/navbar.qtpl b/templates/navbar.qtpl
33index 86141811781819433a83922bfa797b03958b9656..8f5f9e135c7cc960e0b529f044e972f792ad95fb 100644
34--- a/templates/navbar.qtpl
35+++ b/templates/navbar.qtpl
36@@ -16,6 +16,7 @@ Log
37 Summary
38 Refs
39 Tree
40+ Login
41 )
42 %}
43
44@@ -25,6 +26,9 @@ {% func Navbar (s Selection) %}
45 <nav class="container navbar navbar-expand">
46 <div class="navbar-nav">
47 <a class="nav-link{%= insertIfEqual(s, Git) %}" href="/">git</a>
48+ </div>
49+ <div class="navbar-nav ms-auto">
50+ <a class="nav-link{%= insertIfEqual(s, Login) %}" href="/login">login</a>
51 {% comment %}
52 Add this back once needed
53 <a class="nav-link{%= insertIfEqual(s, List) %}" href="/list/">list</a>
54diff --git a/templates/navbar.qtpl.go b/templates/navbar.qtpl.go
55index ca3a320443d531ae805bf6273796370bcabe604b..e6ca0aa2783df2afe1e88a57186f46649b0986a9 100644
56--- a/templates/navbar.qtpl.go
57+++ b/templates/navbar.qtpl.go
58@@ -36,208 +36,216 @@ Log
59 Summary
60 Refs
61 Tree
62+ Login
63 )
64
65-//line templates/navbar.qtpl:22
66+//line templates/navbar.qtpl:23
67 func streaminsertIfEqual(qw422016 *qt422016.Writer, s, d any) {
68-//line templates/navbar.qtpl:22
69+//line templates/navbar.qtpl:23
70 if s == d {
71-//line templates/navbar.qtpl:22
72+//line templates/navbar.qtpl:23
73 qw422016.N().S(` selected`)
74-//line templates/navbar.qtpl:22
75+//line templates/navbar.qtpl:23
76 }
77-//line templates/navbar.qtpl:22
78+//line templates/navbar.qtpl:23
79 }
80
81-//line templates/navbar.qtpl:22
82+//line templates/navbar.qtpl:23
83 func writeinsertIfEqual(qq422016 qtio422016.Writer, s, d any) {
84-//line templates/navbar.qtpl:22
85+//line templates/navbar.qtpl:23
86 qw422016 := qt422016.AcquireWriter(qq422016)
87-//line templates/navbar.qtpl:22
88+//line templates/navbar.qtpl:23
89 streaminsertIfEqual(qw422016, s, d)
90-//line templates/navbar.qtpl:22
91+//line templates/navbar.qtpl:23
92 qt422016.ReleaseWriter(qw422016)
93-//line templates/navbar.qtpl:22
94+//line templates/navbar.qtpl:23
95 }
96
97-//line templates/navbar.qtpl:22
98+//line templates/navbar.qtpl:23
99 func insertIfEqual(s, d any) string {
100-//line templates/navbar.qtpl:22
101+//line templates/navbar.qtpl:23
102 qb422016 := qt422016.AcquireByteBuffer()
103-//line templates/navbar.qtpl:22
104+//line templates/navbar.qtpl:23
105 writeinsertIfEqual(qb422016, s, d)
106-//line templates/navbar.qtpl:22
107+//line templates/navbar.qtpl:23
108 qs422016 := string(qb422016.B)
109-//line templates/navbar.qtpl:22
110+//line templates/navbar.qtpl:23
111 qt422016.ReleaseByteBuffer(qb422016)
112-//line templates/navbar.qtpl:22
113+//line templates/navbar.qtpl:23
114 return qs422016
115-//line templates/navbar.qtpl:22
116+//line templates/navbar.qtpl:23
117 }
118
119-//line templates/navbar.qtpl:24
120+//line templates/navbar.qtpl:25
121 func StreamNavbar(qw422016 *qt422016.Writer, s Selection) {
122-//line templates/navbar.qtpl:24
123+//line templates/navbar.qtpl:25
124 qw422016.N().S(`
125 <nav class="container navbar navbar-expand">
126 <div class="navbar-nav">
127 <a class="nav-link`)
128-//line templates/navbar.qtpl:27
129+//line templates/navbar.qtpl:28
130 streaminsertIfEqual(qw422016, s, Git)
131-//line templates/navbar.qtpl:27
132+//line templates/navbar.qtpl:28
133 qw422016.N().S(`" href="/">git</a>
134+ </div>
135+ <div class="navbar-nav ms-auto">
136+ <a class="nav-link`)
137+//line templates/navbar.qtpl:31
138+ streaminsertIfEqual(qw422016, s, Login)
139+//line templates/navbar.qtpl:31
140+ qw422016.N().S(`" href="/">login</a>
141 `)
142-//line templates/navbar.qtpl:31
143+//line templates/navbar.qtpl:35
144 qw422016.N().S(`
145 `)
146-//line templates/navbar.qtpl:35
147+//line templates/navbar.qtpl:39
148 qw422016.N().S(`
149 </div>
150 </nav>
151 `)
152-//line templates/navbar.qtpl:38
153+//line templates/navbar.qtpl:42
154 }
155
156-//line templates/navbar.qtpl:38
157+//line templates/navbar.qtpl:42
158 func WriteNavbar(qq422016 qtio422016.Writer, s Selection) {
159-//line templates/navbar.qtpl:38
160+//line templates/navbar.qtpl:42
161 qw422016 := qt422016.AcquireWriter(qq422016)
162-//line templates/navbar.qtpl:38
163+//line templates/navbar.qtpl:42
164 StreamNavbar(qw422016, s)
165-//line templates/navbar.qtpl:38
166+//line templates/navbar.qtpl:42
167 qt422016.ReleaseWriter(qw422016)
168-//line templates/navbar.qtpl:38
169+//line templates/navbar.qtpl:42
170 }
171
172-//line templates/navbar.qtpl:38
173+//line templates/navbar.qtpl:42
174 func Navbar(s Selection) string {
175-//line templates/navbar.qtpl:38
176+//line templates/navbar.qtpl:42
177 qb422016 := qt422016.AcquireByteBuffer()
178-//line templates/navbar.qtpl:38
179+//line templates/navbar.qtpl:42
180 WriteNavbar(qb422016, s)
181-//line templates/navbar.qtpl:38
182+//line templates/navbar.qtpl:42
183 qs422016 := string(qb422016.B)
184-//line templates/navbar.qtpl:38
185+//line templates/navbar.qtpl:42
186 qt422016.ReleaseByteBuffer(qb422016)
187-//line templates/navbar.qtpl:38
188+//line templates/navbar.qtpl:42
189 return qs422016
190-//line templates/navbar.qtpl:38
191+//line templates/navbar.qtpl:42
192 }
193
194-//line templates/navbar.qtpl:40
195+//line templates/navbar.qtpl:44
196 func StreamGitItemNav(qw422016 *qt422016.Writer, name, ref string, s GitSelection) {
197-//line templates/navbar.qtpl:40
198+//line templates/navbar.qtpl:44
199 qw422016.N().S(`
200 <div class="row">
201 <h3 id="name">`)
202-//line templates/navbar.qtpl:42
203+//line templates/navbar.qtpl:46
204 qw422016.E().S(name)
205-//line templates/navbar.qtpl:42
206+//line templates/navbar.qtpl:46
207 qw422016.N().S(` `)
208-//line templates/navbar.qtpl:42
209+//line templates/navbar.qtpl:46
210 if ref != "" && (s == Log || s == Tree) {
211-//line templates/navbar.qtpl:42
212+//line templates/navbar.qtpl:46
213 qw422016.N().S(`@ `)
214-//line templates/navbar.qtpl:42
215+//line templates/navbar.qtpl:46
216 qw422016.E().S(ref)
217-//line templates/navbar.qtpl:42
218+//line templates/navbar.qtpl:46
219 }
220-//line templates/navbar.qtpl:42
221+//line templates/navbar.qtpl:46
222 qw422016.N().S(`</h3>
223 </div>
224 <div class="row">
225 <ul class="nav">
226 <li class="nav-item">
227 <a class="nav-link`)
228-//line templates/navbar.qtpl:47
229+//line templates/navbar.qtpl:51
230 streaminsertIfEqual(qw422016, s, Readme)
231-//line templates/navbar.qtpl:47
232+//line templates/navbar.qtpl:51
233 qw422016.N().S(`" aria-current="page" href="/`)
234-//line templates/navbar.qtpl:47
235+//line templates/navbar.qtpl:51
236 qw422016.E().S(name)
237-//line templates/navbar.qtpl:47
238+//line templates/navbar.qtpl:51
239 qw422016.N().S(`/about/">about</a>
240 </li>
241 <li class="nav-item">
242 <a class="nav-link`)
243-//line templates/navbar.qtpl:50
244+//line templates/navbar.qtpl:54
245 streaminsertIfEqual(qw422016, s, Summary)
246-//line templates/navbar.qtpl:50
247+//line templates/navbar.qtpl:54
248 qw422016.N().S(`" aria-current="page" href="/`)
249-//line templates/navbar.qtpl:50
250+//line templates/navbar.qtpl:54
251 qw422016.E().S(name)
252-//line templates/navbar.qtpl:50
253+//line templates/navbar.qtpl:54
254 qw422016.N().S(`/">summary</a>
255 </li>
256 <li class="nav-item">
257 <a class="nav-link`)
258-//line templates/navbar.qtpl:53
259+//line templates/navbar.qtpl:57
260 streaminsertIfEqual(qw422016, s, Refs)
261-//line templates/navbar.qtpl:53
262+//line templates/navbar.qtpl:57
263 qw422016.N().S(`" aria-current="page" href="/`)
264-//line templates/navbar.qtpl:53
265+//line templates/navbar.qtpl:57
266 qw422016.E().S(name)
267-//line templates/navbar.qtpl:53
268+//line templates/navbar.qtpl:57
269 qw422016.N().S(`/refs">refs</a>
270 </li>
271 <li class="nav-item">
272 <a class="nav-link`)
273-//line templates/navbar.qtpl:56
274+//line templates/navbar.qtpl:60
275 streaminsertIfEqual(qw422016, s, Log)
276-//line templates/navbar.qtpl:56
277+//line templates/navbar.qtpl:60
278 qw422016.N().S(`" aria-current="page" href="/`)
279-//line templates/navbar.qtpl:56
280+//line templates/navbar.qtpl:60
281 qw422016.E().S(name)
282-//line templates/navbar.qtpl:56
283+//line templates/navbar.qtpl:60
284 qw422016.N().S(`/log/`)
285-//line templates/navbar.qtpl:56
286+//line templates/navbar.qtpl:60
287 qw422016.E().S(ref)
288-//line templates/navbar.qtpl:56
289+//line templates/navbar.qtpl:60
290 qw422016.N().S(`/">log</a>
291 </li>
292 <li class="nav-item">
293 <a class="nav-link`)
294-//line templates/navbar.qtpl:59
295+//line templates/navbar.qtpl:63
296 streaminsertIfEqual(qw422016, s, Tree)
297-//line templates/navbar.qtpl:59
298+//line templates/navbar.qtpl:63
299 qw422016.N().S(`" aria-current="page" href="/`)
300-//line templates/navbar.qtpl:59
301+//line templates/navbar.qtpl:63
302 qw422016.E().S(name)
303-//line templates/navbar.qtpl:59
304+//line templates/navbar.qtpl:63
305 qw422016.N().S(`/tree/`)
306-//line templates/navbar.qtpl:59
307+//line templates/navbar.qtpl:63
308 qw422016.E().S(ref)
309-//line templates/navbar.qtpl:59
310+//line templates/navbar.qtpl:63
311 qw422016.N().S(`/">tree</a>
312 </li>
313 </ul>
314 </div>
315 `)
316-//line templates/navbar.qtpl:63
317+//line templates/navbar.qtpl:67
318 }
319
320-//line templates/navbar.qtpl:63
321+//line templates/navbar.qtpl:67
322 func WriteGitItemNav(qq422016 qtio422016.Writer, name, ref string, s GitSelection) {
323-//line templates/navbar.qtpl:63
324+//line templates/navbar.qtpl:67
325 qw422016 := qt422016.AcquireWriter(qq422016)
326-//line templates/navbar.qtpl:63
327+//line templates/navbar.qtpl:67
328 StreamGitItemNav(qw422016, name, ref, s)
329-//line templates/navbar.qtpl:63
330+//line templates/navbar.qtpl:67
331 qt422016.ReleaseWriter(qw422016)
332-//line templates/navbar.qtpl:63
333+//line templates/navbar.qtpl:67
334 }
335
336-//line templates/navbar.qtpl:63
337+//line templates/navbar.qtpl:67
338 func GitItemNav(name, ref string, s GitSelection) string {
339-//line templates/navbar.qtpl:63
340+//line templates/navbar.qtpl:67
341 qb422016 := qt422016.AcquireByteBuffer()
342-//line templates/navbar.qtpl:63
343+//line templates/navbar.qtpl:67
344 WriteGitItemNav(qb422016, name, ref, s)
345-//line templates/navbar.qtpl:63
346+//line templates/navbar.qtpl:67
347 qs422016 := string(qb422016.B)
348-//line templates/navbar.qtpl:63
349+//line templates/navbar.qtpl:67
350 qt422016.ReleaseByteBuffer(qb422016)
351-//line templates/navbar.qtpl:63
352+//line templates/navbar.qtpl:67
353 return qs422016
354-//line templates/navbar.qtpl:63
355+//line templates/navbar.qtpl:67
356 }