master
1package templates
2
3import . "html/template"
4
5// Layout CSS constants — these must be kept in sync with the inline CSS
6// block in layout.gohtml (used when --inline-styles is set). Both files
7// define the same rules; styles.go adds a [data-theme="dark"] variant
8// for the external style.css file.
9
10const LayoutCSSVarLight = `:root {
11 --c-indigo-1: #3451b2;
12 --c-indigo-2: #3a5ccc;
13 --c-indigo-3: #5672cd;
14 --c-green: #1a7f37;
15 --c-red: #c53030;
16 --c-yellow: #9a6700;
17 --c-dir: #54aeff;
18 --c-gray-soft: rgba(142, 150, 170, .14);
19 --c-bg: #ffffff;
20 --c-bg-alt: #f6f6f7;
21 --c-bg-elv: #ffffff;
22 --c-text-1: rgba(60, 60, 67);
23 --c-text-2: rgba(60, 60, 67, .78);
24 --c-text-3: rgba(60, 60, 67, .56);
25 --c-border: #c2c2c4;
26 --c-divider: #e2e2e3;
27}
28`
29
30const LayoutCSSVarDarkInline = `:root {
31 --c-indigo-1: #a8b1ff;
32 --c-indigo-2: #5c73e7;
33 --c-indigo-3: #3e63dd;
34 --c-green: #57ab5a;
35 --c-red: #e5534b;
36 --c-yellow: #c69026;
37 --c-dir: #9198a1;
38 --c-gray-soft: rgba(101, 117, 133, .16);
39 --c-bg: #1b1b1f;
40 --c-bg-alt: #161618;
41 --c-bg-elv: #202127;
42 --c-text-1: rgba(255, 255, 245, .86);
43 --c-text-2: rgba(235, 235, 245, .6);
44 --c-text-3: rgba(235, 235, 245, .38);
45 --c-border: #3c3f44;
46 --c-divider: #2e2e32;
47}
48`
49
50const LayoutCSSVarDarkCombo = `[data-theme="dark"] {
51 --c-indigo-1: #a8b1ff;
52 --c-indigo-2: #5c73e7;
53 --c-indigo-3: #3e63dd;
54 --c-green: #57ab5a;
55 --c-red: #e5534b;
56 --c-yellow: #c69026;
57 --c-dir: #9198a1;
58 --c-gray-soft: rgba(101, 117, 133, .16);
59 --c-bg: #1b1b1f;
60 --c-bg-alt: #161618;
61 --c-bg-elv: #202127;
62 --c-text-1: rgba(255, 255, 245, .86);
63 --c-text-2: rgba(235, 235, 245, .6);
64 --c-text-3: rgba(235, 235, 245, .38);
65 --c-border: #3c3f44;
66 --c-divider: #2e2e32;
67}
68`
69
70const LayoutCSSShared = `
71:root {
72 --c-brand-1: var(--c-indigo-1);
73 --c-brand-2: var(--c-indigo-2);
74 --c-brand-3: var(--c-indigo-3);
75 --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
76 --font-family-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
77 --code-line-height: 20px;
78 --code-font-size: 12px;
79 --code-color: var(--c-brand-1);
80 --code-bg: var(--c-gray-soft);
81 --code-block-bg: var(--c-bg-alt);
82 --code-block-color: var(--c-text-1);
83 --header-height: 46px;
84 --border-radius: 6px;
85 --max-content-width: 1470px;
86}
87
88* {
89 box-sizing: border-box;
90}
91
92body {
93 margin: 0;
94 padding: 0;
95 font-family: var(--font-family), sans-serif;
96 font-size: 14px;
97 line-height: 1;
98 color: var(--c-text-1);
99 background-color: var(--c-bg);
100 text-rendering: optimizeLegibility;
101 -webkit-font-smoothing: antialiased;
102 -moz-osx-font-smoothing: grayscale;
103 -moz-text-size-adjust: none;
104 -webkit-text-size-adjust: none;
105 text-size-adjust: none;
106 min-height: 100vh;
107 display: flex;
108 flex-direction: column;
109}
110
111.nowrap {
112 white-space: nowrap;
113}
114
115h1 {
116 margin-inline: 0;
117 margin-block: 16px;
118 font-size: 20px;
119 font-weight: 600;
120}
121
122a {
123 color: var(--c-brand-1);
124 font-weight: 500;
125 text-decoration: underline;
126 text-underline-offset: 2px;
127 text-decoration: inherit;
128 touch-action: manipulation;
129}
130
131a:hover {
132 color: var(--c-brand-2);
133 text-decoration: underline;
134}
135
136.menu {
137 background-color: var(--c-bg-alt);
138 border-bottom: 1px solid var(--c-divider);
139 overflow-x: auto;
140}
141
142.menu-content {
143 display: flex;
144 flex-direction: row;
145 align-items: center;
146 gap: 16px;
147 padding-inline: 16px;
148 max-width: var(--max-content-width);
149 margin-inline: auto;
150}
151
152.menu-item {
153 display: flex;
154 align-items: center;
155 border-bottom: 2px solid transparent;
156 height: 56px;
157 padding-inline: 8px;
158}
159
160.menu-item a {
161 display: flex;
162 flex-direction: row;
163 gap: 8px;
164 align-items: center;
165 color: var(--c-text-1);
166 padding: 8px 10px;
167 border-radius: 4px;
168}
169
170.menu-item a:hover {
171 background-color: var(--c-bg-elv);
172 text-decoration: none;
173}
174
175.menu-item.selected {
176 border-bottom-color: var(--c-brand-1);
177}
178
179.project-name {
180 display: flex;
181 flex-direction: row;
182 align-items: center;
183 gap: 6px;
184 height: 56px;
185 margin-inline: 16px;
186 white-space: nowrap;
187}
188
189.project-name-site {
190 font-weight: 600;
191 font-size: 16px;
192 color: var(--c-text-1);
193 text-decoration: none;
194}
195
196.project-name-site:hover {
197 text-decoration: underline;
198}
199
200.project-name-sep {
201 font-weight: 400;
202 font-size: 16px;
203 color: var(--c-text-3);
204}
205
206.project-name-repo {
207 font-weight: 600;
208 font-size: 16px;
209 color: var(--c-text-1);
210 text-decoration: none;
211}
212
213.project-name-repo:hover {
214 text-decoration: underline;
215}
216
217main {
218 flex-grow: 1;
219 width: 100%;
220 max-width: var(--max-content-width);
221 margin: 16px auto;
222}
223
224.main-content {
225 padding-inline: 16px;
226}
227
228footer {
229 padding: 12px 16px;
230 background-color: var(--c-bg-alt);
231 border-top: 1px solid var(--c-divider);
232 color: var(--c-text-3);
233 font-size: 12px;
234 text-align: center;
235}
236
237.header-container {
238 container-type: scroll-state;
239 position: sticky;
240 top: 0;
241}
242
243@container scroll-state(stuck: top) {
244 header {
245 border-top: none;
246 border-top-left-radius: 0;
247 border-top-right-radius: 0;
248 }
249
250 .goto-top {
251 display: flex;
252 }
253}
254
255header {
256 display: flex;
257 flex-direction: row;
258 align-items: center;
259 min-height: var(--header-height);
260 padding-inline: 16px;
261 background: var(--c-bg-alt);
262 border: 1px solid var(--c-border);
263 border-top-left-radius: var(--border-radius);
264 border-top-right-radius: var(--border-radius);
265}
266
267header h1 {
268 word-break: break-all;
269 font-weight: 600;
270 font-size: 16px;
271 margin: 0;
272 padding: 0;
273}
274
275.header-ref {
276 color: var(--c-text-2);
277 border: 1px solid var(--c-border);
278 border-radius: 6px;
279 padding: 6px 10px;
280 margin-right: 10px;
281 margin-left: -6px;
282}
283
284header .path {
285 font-size: 16px;
286}
287
288.breadcrumbs {
289 display: flex;
290 flex-direction: row;
291 flex-wrap: wrap;
292 gap: 6px;
293 font-size: 16px;
294}
295
296.breadcrumbs a {
297 word-break: break-all;
298}
299
300.raw-button {
301 display: inline-flex;
302 align-items: center;
303 gap: 4px;
304 padding: 4px 12px;
305 margin-left: auto;
306 font-size: 13px;
307 font-weight: 500;
308 line-height: 20px;
309 color: var(--c-text-1);
310 background: var(--c-bg);
311 border: 1px solid var(--c-border);
312 border-radius: 6px;
313 text-decoration: none;
314 cursor: pointer;
315}
316
317.raw-button:hover {
318 background: var(--c-bg-elv);
319}
320
321.goto-top {
322 display: none;
323 padding: 6px 10px;
324 background: none;
325 border: none;
326 border-radius: 6px;
327 gap: 4px;
328 align-items: center;
329 color: var(--c-text-1);
330 cursor: pointer;
331}
332
333.goto-top:hover {
334 background: var(--c-bg-elv);
335}
336`
337
338func LayoutCSSCombo() string {
339 return LayoutCSSVarLight + LayoutCSSVarDarkCombo + LayoutCSSShared
340}
341
342// LayoutCSSAdaptive returns layout CSS that adapts to the user's system
343// preference using @media (prefers-color-scheme: dark), while also
344// supporting [data-theme="dark"] for manual overrides (e.g. via JS).
345//
346// Unlike the previous non-adaptive behavior where --theme controlled
347// both code highlighting AND page appearance, adaptive mode decouples
348// these: the page follows the OS preference regardless of --theme.
349// Users who want to force a specific appearance can set [data-theme]
350// on <html> via a theme switcher.
351func LayoutCSSAdaptive() string {
352 return LayoutCSSVarLight +
353 "\n@media (prefers-color-scheme: dark) {\n" + LayoutCSSVarDarkInline + "\n}\n" +
354 LayoutCSSVarDarkCombo +
355 LayoutCSSShared
356}
357
358func LayoutCSSInline(dark bool) CSS {
359 if dark {
360 return CSS(LayoutCSSVarDarkInline + LayoutCSSShared)
361 }
362 return CSS(LayoutCSSVarLight + LayoutCSSShared)
363}