Commit bf64c14
Eric Bower
·
2026-09-30 09:00:35 -0400 EDT
parent 4a1e923
style(prose): minimal design ethos Our previous prose blog design hasn't changed since we initially released prose. The previous design was minimalistic but it still made some assumptions about how a blog should look. In order to support customization we added support for users to upload `_styles.css` and front-matter fields like `with_styles` to provide full customization. The main thesis for this change was trying to answer the question: what if blogs came without styles by default and users are required to theme it themselves? This would make it so we are not in control of the overall theme of the blog and provides full customization for the end-user. As we were experimenting with this design we wanted to include a very minimal css reset so the default design is consistent across browsers. We are also implemented a few rules with this css reset for best practices. This is our new design ethos: - Center content on the screen - 70ch max width - Headers should be anchored to the content they are heading That's it. The rest of the reset file is for consistency across browsers. With this change we are also disabling the `with_styles` field to encourage people to preserve this new design ethos. Finally as part of this change we restructured the html tree to better adhere to semantic meaning of those html entities. We were already mostly there but some of the headers and footers were restructured slightly.
8 files changed,
+233,
-196
+1,
-4
| ... | ... | @@ -185,7 +185,6 @@ func blogHandler(w http.ResponseWriter, r *http.Request) { | |
| 185 | 185 | ||
| 186 | 186 | ts, err := router.RenderTemplate(cfg, []string{ | |
| 187 | 187 | cfg.StaticPath("html/blog-default.partial.tmpl"), | |
| 188 | - | cfg.StaticPath("html/blog-aside.partial.tmpl"), | |
| 189 | 188 | cfg.StaticPath("html/blog.page.tmpl"), | |
| 190 | 189 | }) | |
| 191 | 190 |
| ... | ... | @@ -893,9 +892,7 @@ func serveFile(file string, contentType string) http.HandlerFunc { | |
| 893 | 892 | ||
| 894 | 893 | func createStaticRoutes() []router.Route { | |
| 895 | 894 | return []router.Route{ | |
| 896 | - | router.NewRoute("GET", "/main.css", serveFile("main.css", "text/css")), | |
| 897 | - | router.NewRoute("GET", "/smol.css", serveFile("smol.css", "text/css")), | |
| 898 | - | router.NewRoute("GET", "/smol-v2.css", serveFile("smol-v2.css", "text/css")), | |
| 895 | + | router.NewRoute("GET", "/reset.css", serveFile("reset.css", "text/css")), | |
| 899 | 896 | router.NewRoute("GET", "/syntax.css", serveFile("syntax.css", "text/css")), | |
| 900 | 897 | router.NewRoute("GET", "/card.png", serveFile("card.png", "image/png")), | |
| 901 | 898 | router.NewRoute("GET", "/favicon-16x16.png", serveFile("favicon-16x16.png", "image/png")), |
+0,
-2
| ... | ... | @@ -5,9 +5,7 @@ | |
| 5 | 5 | <meta charset='utf-8'> | |
| 6 | 6 | <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| 7 | 7 | <title>{{template "title" .}}</title> | |
| 8 | - | ||
| 9 | 8 | <meta name="keywords" content="blog, blogging, write, writing, hackers, developers, terminal" /> | |
| 10 | - | ||
| 11 | 9 | {{template "meta" .}} | |
| 12 | 10 | </head> | |
| 13 | 11 | <body {{template "attrs" .}}>{{template "body" .}}</body> |
| ... | ... | @@ -1,56 +0,0 @@ | |
| 1 | - | {{define "blog-aside"}} | |
| 2 | - | <main class="flex"> | |
| 3 | - | <section class="flex-1 mr"> | |
| 4 | - | <div> | |
| 5 | - | <h1 class="text-2xl font-bold mt-2">{{.Header.Title}}</h1> | |
| 6 | - | {{if .Header.Bio}}<span>{{.Header.Bio}}</span>{{end}} | |
| 7 | - | </div> | |
| 8 | - | ||
| 9 | - | <div id="readme"> | |
| 10 | - | {{if .Readme.HasText}} | |
| 11 | - | <section class="md"> | |
| 12 | - | {{.Readme.Contents}} | |
| 13 | - | </section> | |
| 14 | - | {{end}} | |
| 15 | - | <ul> | |
| 16 | - | {{range .Header.Nav}} | |
| 17 | - | <li><a href="{{.URL}}" class="text-lg">{{.Text}}</a></li> | |
| 18 | - | {{end}} | |
| 19 | - | <li><a href="{{.RSSURL}}" class="text-lg">rss</a></li> | |
| 20 | - | </ul> | |
| 21 | - | <hr /> | |
| 22 | - | </div> | |
| 23 | - | ||
| 24 | - | {{if .HasFilter}} | |
| 25 | - | <a href="/">clear filters</a> | |
| 26 | - | {{end}} | |
| 27 | - | ||
| 28 | - | <div class="posts group mt-2"> | |
| 29 | - | {{range .Posts}} | |
| 30 | - | <article> | |
| 31 | - | <div class="flex items-center"> | |
| 32 | - | <time datetime="{{.PublishAtISO}}" class="text-sm post-date">{{.PublishAt}}</time> | |
| 33 | - | <span class="text-md flex-1 m-0 transform-none"><a href="{{.URL}}">{{.Title}}</a></span> | |
| 34 | - | </div> | |
| 35 | - | </article> | |
| 36 | - | {{end}} | |
| 37 | - | </div> | |
| 38 | - | </section> | |
| 39 | - | ||
| 40 | - | <aside> | |
| 41 | - | {{if .Readme.HasText}} | |
| 42 | - | <section class="md"> | |
| 43 | - | {{.Readme.Contents}} | |
| 44 | - | </section> | |
| 45 | - | {{end}} | |
| 46 | - | <nav> | |
| 47 | - | <ul> | |
| 48 | - | {{range .Header.Nav}} | |
| 49 | - | <li><a href="{{.URL}}" class="text-md transform-none">{{.Text}}</a></li> | |
| 50 | - | {{end}} | |
| 51 | - | <li><a href="{{.RSSURL}}" class="text-md transform-none">rss</a></li> | |
| 52 | - | </ul> | |
| 53 | - | </nav> | |
| 54 | - | </aside> | |
| 55 | - | </main> | |
| 56 | - | {{end}} |
| ... | ... | @@ -1,18 +1,23 @@ | |
| 1 | 1 | {{define "blog-default"}} | |
| 2 | - | <header class="text-center"> | |
| 3 | - | <h1 class="text-2xl font-bold mt-2">{{.Header.Title}}</h1> | |
| 4 | - | {{if .Header.Bio}}<span>{{.Header.Bio}}</span>{{end}} | |
| 2 | + | <header> | |
| 3 | + | <h1>{{.Header.Title}}</h1> | |
| 5 | 4 | <nav> | |
| 5 | + | {{if .Header.Bio}} | |
| 6 | + | <span>{{.Header.Bio}}</span> | |
| 7 | + | <br /> | |
| 8 | + | {{end}} | |
| 6 | 9 | {{range .Header.Nav}} | |
| 7 | - | <a href="{{.URL}}" class="text-lg transform-none">{{.Text}}</a> | | |
| 10 | + | <a href="{{.URL}}">{{.Text}}</a> | |
| 8 | 11 | {{end}} | |
| 9 | - | <a href="{{.RSSURL}}" class="text-lg transform-none">rss</a> | |
| 12 | + | <a href="{{.RSSURL}}">rss</a> | |
| 10 | 13 | </nav> | |
| 14 | + | ||
| 11 | 15 | <hr /> | |
| 12 | 16 | </header> | |
| 17 | + | ||
| 13 | 18 | <main> | |
| 14 | 19 | {{if .Readme.HasText}} | |
| 15 | - | <section> | |
| 20 | + | <section id="readme"> | |
| 16 | 21 | <article class="md"> | |
| 17 | 22 | {{.Readme.Contents}} | |
| 18 | 23 | </article> |
| ... | ... | @@ -20,18 +25,21 @@ | |
| 20 | 25 | </section> | |
| 21 | 26 | {{end}} | |
| 22 | 27 | ||
| 23 | - | <section class="posts group mt-2"> | |
| 28 | + | <section id="posts"> | |
| 24 | 29 | {{if .HasFilter}} | |
| 25 | - | <a href={{.URL}}>clear filters</a> | |
| 30 | + | <a href="{{.URL}}">clear filters</a> | |
| 26 | 31 | {{end}} | |
| 32 | + | ||
| 33 | + | <ul role="list"> | |
| 27 | 34 | {{range .Posts}} | |
| 28 | - | <article> | |
| 29 | - | <div class="flex items-center"> | |
| 30 | - | <time datetime="{{.PublishAtISO}}" class="text-sm post-date">{{.PublishAt}}</time> | |
| 31 | - | <span class="text-md flex-1 m-0 transform-none"><a href="{{.URL}}">{{.Title}}</a></span> | |
| 32 | - | </div> | |
| 33 | - | </article> | |
| 35 | + | <li> | |
| 36 | + | <article class="post"> | |
| 37 | + | <time datetime="{{.PublishAtISO}}">{{.PublishAt}}</time> | |
| 38 | + | <a href="{{.URL}}">{{.Title}}</a> | |
| 39 | + | </article> | |
| 40 | + | </li> | |
| 34 | 41 | {{end}} | |
| 42 | + | </ul> | |
| 35 | 43 | </section> | |
| 36 | 44 | </main> | |
| 37 | 45 | {{end}} |
+42,
-53
| ... | ... | @@ -3,61 +3,50 @@ | |
| 3 | 3 | {{define "title"}}{{.PageTitle}}{{end}} | |
| 4 | 4 | ||
| 5 | 5 | {{define "meta"}} | |
| 6 | - | {{if .Header.Favicon}} | |
| 7 | - | <link rel="icon" href="{{.Header.Favicon}}"> | |
| 8 | - | {{else}} | |
| 9 | - | <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> | |
| 6 | + | {{if .Header.Favicon}} | |
| 7 | + | <link rel="icon" href="{{.Header.Favicon}}"> | |
| 8 | + | {{else}} | |
| 9 | + | <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> | |
| 10 | + | {{end}} | |
| 11 | + | ||
| 12 | + | <meta name="description" content="{{if .Header.Bio}}{{.Header.Bio}}{{else}}{{.Header.Title}}{{end}}" /> | |
| 13 | + | <meta property="og:type" content="website"> | |
| 14 | + | <meta property="og:site_name" content="{{.Site.Domain}}"> | |
| 15 | + | <meta property="og:url" content="{{.URL}}"> | |
| 16 | + | <meta property="og:title" content="{{.Header.Title}}"> | |
| 17 | + | {{if .Header.Bio}}<meta property="og:description" content="{{.Header.Bio}}">{{end}} | |
| 18 | + | ||
| 19 | + | {{if .Header.Image}} | |
| 20 | + | <meta itemprop="image" content="{{.Header.Image}}" /> | |
| 21 | + | <meta property="og:image" content="{{.Header.Image}}" /> | |
| 22 | + | <meta name="twitter:image" content="{{.Header.Image}}" /> | |
| 23 | + | {{else}} | |
| 24 | + | <meta property="og:image:width" content="300" /> | |
| 25 | + | <meta property="og:image:height" content="300" /> | |
| 26 | + | <meta itemprop="image" content="https://{{.Site.Domain}}/card.png" /> | |
| 27 | + | <meta property="og:image" content="https://{{.Site.Domain}}/card.png" /> | |
| 28 | + | <meta name="twitter:image" content="https://{{.Site.Domain}}/card.png" /> | |
| 29 | + | {{end}} | |
| 30 | + | ||
| 31 | + | {{if .Header.ImageCard}} | |
| 32 | + | <meta property="twitter:card" content="{{.Header.ImageCard}}"> | |
| 33 | + | {{else}} | |
| 34 | + | <meta property="twitter:card" content="summary"> | |
| 35 | + | {{end}} | |
| 36 | + | <meta property="twitter:url" content="{{.URL}}"> | |
| 37 | + | <meta property="twitter:title" content="{{.Header.Title}}"> | |
| 38 | + | {{if .Header.Bio}}<meta property="twitter:description" content="{{.Header.Bio}}">{{end}} | |
| 39 | + | ||
| 40 | + | <link rel="alternate" href="{{.RSSURL}}" type="application/rss+xml" title="RSS feed for {{.Header.Title}}" /> | |
| 41 | + | ||
| 42 | + | <link rel="stylesheet" href="/reset.css" /> | |
| 43 | + | <link rel="stylesheet" href="/syntax.css" /> | |
| 44 | + | {{if .HasCSS}}<link rel="stylesheet" href="{{.CssURL}}" />{{end}} | |
| 10 | 45 | {{end}} | |
| 11 | 46 | ||
| 12 | - | <meta name="description" content="{{if .Header.Bio}}{{.Header.Bio}}{{else}}{{.Header.Title}}{{end}}" /> | |
| 13 | - | ||
| 14 | - | <meta property="og:type" content="website"> | |
| 15 | - | <meta property="og:site_name" content="{{.Site.Domain}}"> | |
| 16 | - | <meta property="og:url" content="{{.URL}}"> | |
| 17 | - | <meta property="og:title" content="{{.Header.Title}}"> | |
| 18 | - | {{if .Header.Bio}}<meta property="og:description" content="{{.Header.Bio}}">{{end}} | |
| 19 | - | ||
| 20 | - | {{if .Header.Image}} | |
| 21 | - | <meta itemprop="image" content="{{.Header.Image}}" /> | |
| 22 | - | <meta property="og:image" content="{{.Header.Image}}" /> | |
| 23 | - | ||
| 24 | - | <meta name="twitter:image" content="{{.Header.Image}}" /> | |
| 25 | - | {{else}} | |
| 26 | - | <meta property="og:image:width" content="300" /> | |
| 27 | - | <meta property="og:image:height" content="300" /> | |
| 28 | - | <meta itemprop="image" content="https://{{.Site.Domain}}/card.png" /> | |
| 29 | - | <meta property="og:image" content="https://{{.Site.Domain}}/card.png" /> | |
| 30 | - | ||
| 31 | - | <meta name="twitter:image" content="https://{{.Site.Domain}}/card.png" /> | |
| 32 | - | {{end}} | |
| 33 | - | ||
| 34 | - | {{if .Header.ImageCard}} | |
| 35 | - | <meta property="twitter:card" content="{{.Header.ImageCard}}"> | |
| 36 | - | {{else}} | |
| 37 | - | <meta property="twitter:card" content="summary"> | |
| 38 | - | {{end}} | |
| 39 | - | <meta property="twitter:url" content="{{.URL}}"> | |
| 40 | - | <meta property="twitter:title" content="{{.Header.Title}}"> | |
| 41 | - | {{if .Header.Bio}}<meta property="twitter:description" content="{{.Header.Bio}}">{{end}} | |
| 42 | - | ||
| 43 | - | <link rel="alternate" href="{{.RSSURL}}" type="application/rss+xml" title="RSS feed for {{.Header.Title}}" /> | |
| 44 | - | {{if .WithStyles}} | |
| 45 | - | <link rel="stylesheet" href="/smol.css" /> | |
| 46 | - | {{else}} | |
| 47 | - | {{end}} | |
| 48 | - | <link rel="stylesheet" href="/syntax.css" /> | |
| 49 | - | {{if .HasCSS}}<link rel="stylesheet" href="{{.CssURL}}" />{{end}} | |
| 50 | - | {{end}} | |
| 51 | - | ||
| 52 | - | {{define "attrs"}}id="blog" class="layout-{{.Header.Layout}}"{{end}} | |
| 47 | + | {{define "attrs"}}id="blog"{{end}} | |
| 53 | 48 | ||
| 54 | 49 | {{define "body"}} | |
| 55 | - | ||
| 56 | - | {{if eq .Header.Layout "aside"}} | |
| 57 | - | {{template "blog-aside" .}} | |
| 58 | - | {{else}} | |
| 59 | - | {{template "blog-default" .}} | |
| 60 | - | {{end}} | |
| 61 | - | ||
| 62 | - | {{template "footer" .}} | |
| 50 | + | {{template "blog-default" .}} | |
| 51 | + | {{template "footer" .}} | |
| 63 | 52 | {{end}} |
| ... | ... | @@ -1,6 +1,6 @@ | |
| 1 | 1 | {{define "footer"}} | |
| 2 | 2 | <footer> | |
| 3 | 3 | <hr /> | |
| 4 | - | published with <a href={{.Site.HomeURL}}>{{.Site.Domain}}</a> | |
| 4 | + | published with <a href="{{.Site.HomeURL}}">{{.Site.Domain}}</a> | |
| 5 | 5 | </footer> | |
| 6 | 6 | {{end}} |
+72,
-66
| ... | ... | @@ -3,86 +3,92 @@ | |
| 3 | 3 | {{define "title"}}{{.PageTitle}}{{end}} | |
| 4 | 4 | ||
| 5 | 5 | {{define "meta"}} | |
| 6 | - | {{if .Favicon}} | |
| 7 | - | <link rel="icon" href="{{.Favicon}}"> | |
| 8 | - | {{else}} | |
| 9 | - | <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> | |
| 10 | - | {{end}} | |
| 11 | - | ||
| 12 | - | <meta name="description" content="{{.Description}}" /> | |
| 6 | + | {{if .Favicon}} | |
| 7 | + | <link rel="icon" href="{{.Favicon}}"> | |
| 8 | + | {{else}} | |
| 9 | + | <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> | |
| 10 | + | {{end}} | |
| 13 | 11 | ||
| 14 | - | <meta property="og:type" content="website"> | |
| 15 | - | <meta property="og:site_name" content="{{.Site.Domain}}"> | |
| 16 | - | <meta property="og:url" content="{{.URL}}"> | |
| 17 | - | <meta property="og:title" content="{{.Title}}"> | |
| 18 | - | {{if .Description}}<meta property="og:description" content="{{.Description}}">{{end}} | |
| 12 | + | <meta name="description" content="{{.Description}}" /> | |
| 19 | 13 | ||
| 20 | - | {{if .Image}} | |
| 21 | - | <meta itemprop="image" content="{{.Image}}" /> | |
| 22 | - | <meta property="og:image" content="{{.Image}}" /> | |
| 14 | + | <meta property="og:type" content="website"> | |
| 15 | + | <meta property="og:site_name" content="{{.Site.Domain}}"> | |
| 16 | + | <meta property="og:url" content="{{.URL}}"> | |
| 17 | + | <meta property="og:title" content="{{.Title}}"> | |
| 18 | + | {{if .Description}}<meta property="og:description" content="{{.Description}}">{{end}} | |
| 23 | 19 | ||
| 24 | - | <meta name="twitter:image" content="{{.Image}}" /> | |
| 25 | - | {{else}} | |
| 26 | - | <meta property="og:image:width" content="300" /> | |
| 27 | - | <meta property="og:image:height" content="300" /> | |
| 28 | - | <meta itemprop="image" content="https://{{.Site.Domain}}/card.png" /> | |
| 29 | - | <meta property="og:image" content="https://{{.Site.Domain}}/card.png" /> | |
| 30 | - | ||
| 31 | - | <meta name="twitter:image" content="https://{{.Site.Domain}}/card.png" /> | |
| 32 | - | {{end}} | |
| 20 | + | {{if .Image}} | |
| 21 | + | <meta itemprop="image" content="{{.Image}}" /> | |
| 22 | + | <meta property="og:image" content="{{.Image}}" /> | |
| 23 | + | <meta name="twitter:image" content="{{.Image}}" /> | |
| 24 | + | {{else}} | |
| 25 | + | <meta property="og:image:width" content="300" /> | |
| 26 | + | <meta property="og:image:height" content="300" /> | |
| 27 | + | <meta itemprop="image" content="https://{{.Site.Domain}}/card.png" /> | |
| 28 | + | <meta property="og:image" content="https://{{.Site.Domain}}/card.png" /> | |
| 29 | + | <meta name="twitter:image" content="https://{{.Site.Domain}}/card.png" /> | |
| 30 | + | {{end}} | |
| 33 | 31 | ||
| 34 | - | {{if .ImageCard}} | |
| 35 | - | <meta property="twitter:card" content="{{.ImageCard}}"> | |
| 36 | - | {{else}} | |
| 37 | - | <meta property="twitter:card" content="summary"> | |
| 38 | - | {{end}} | |
| 39 | - | <meta property="twitter:url" content="{{.URL}}"> | |
| 40 | - | <meta property="twitter:title" content="{{.Title}}"> | |
| 41 | - | {{if .Description}}<meta property="twitter:description" content="{{.Description}}">{{end}} | |
| 32 | + | {{if .ImageCard}} | |
| 33 | + | <meta property="twitter:card" content="{{.ImageCard}}"> | |
| 34 | + | {{else}} | |
| 35 | + | <meta property="twitter:card" content="summary"> | |
| 36 | + | {{end}} | |
| 37 | + | <meta property="twitter:url" content="{{.URL}}"> | |
| 38 | + | <meta property="twitter:title" content="{{.Title}}"> | |
| 39 | + | {{if .Description}}<meta property="twitter:description" content="{{.Description}}">{{end}} | |
| 42 | 40 | ||
| 43 | - | <link rel="stylesheet" href="/syntax.css" /> | |
| 44 | - | {{if .WithStyles}} | |
| 45 | - | <link rel="stylesheet" href="/smol.css" /> | |
| 46 | - | {{else}} | |
| 47 | - | {{end}} | |
| 48 | - | {{if .HasCSS}}<link rel="stylesheet" href="{{.CssURL}}" />{{end}} | |
| 41 | + | <link rel="stylesheet" href="/reset.css" /> | |
| 42 | + | <link rel="stylesheet" href="/syntax.css" /> | |
| 43 | + | {{if .HasCSS}}<link rel="stylesheet" href="{{.CssURL}}" />{{end}} | |
| 49 | 44 | {{end}} | |
| 50 | 45 | ||
| 51 | 46 | {{define "attrs"}}id="post" class="{{.Slug}}{{if .Unlisted}} post-draft{{end}}"{{end}} | |
| 52 | 47 | ||
| 53 | 48 | {{define "body"}} | |
| 54 | - | <header> | |
| 55 | - | <h1 class="text-2xl font-bold">{{.Title}}</h1> | |
| 56 | - | <p class="font-bold m-0"> | |
| 57 | - | <span id="publish-at"> | |
| 49 | + | <main> | |
| 50 | + | <article class="md"> | |
| 51 | + | <header> | |
| 52 | + | <h1>{{.Title}}</h1> | |
| 53 | + | <p> | |
| 58 | 54 | <time datetime="{{.PublishAtISO}}">{{.PublishAt}}</time> | |
| 59 | 55 | <span>·</span> | |
| 60 | - | </span> | |
| 61 | - | <a href="{{.BlogURL}}">{{.BlogName}}</a> | |
| 62 | - | </p> | |
| 63 | - | {{if .Description}}<blockquote>{{.Description}}</blockquote>{{end}} | |
| 64 | - | <hr /> | |
| 65 | - | </header> | |
| 66 | - | <main> | |
| 67 | - | <article class="md"> | |
| 68 | - | {{if .List}} | |
| 69 | - | {{template "list" .List}} | |
| 70 | - | {{else}} | |
| 71 | - | {{.Contents}} | |
| 72 | - | {{end}} | |
| 73 | - | ||
| 74 | - | <div class="tags mt-4"> | |
| 75 | - | {{range .Tags}} | |
| 76 | - | <code class="pill tag"><a href="{{$.BlogURL}}?tag={{.}}">#{{.}}</a></code> | |
| 56 | + | <a href="{{.BlogURL}}">{{.BlogName}}</a> | |
| 57 | + | {{if .Description}} | |
| 58 | + | <br /> | |
| 59 | + | <span>{{.Description}}</span> | |
| 77 | 60 | {{end}} | |
| 78 | - | </div> | |
| 61 | + | </p> | |
| 62 | + | ||
| 63 | + | <hr /> | |
| 64 | + | </header> | |
| 65 | + | ||
| 66 | + | {{if .List}} | |
| 67 | + | {{template "list" .List}} | |
| 68 | + | {{else}} | |
| 69 | + | {{.Contents}} | |
| 70 | + | {{end}} | |
| 79 | 71 | ||
| 80 | - | <div id="last-updated" class="text-sm"> | |
| 81 | - | last updated: <time datetime="{{.UpdatedAtISO}}">{{.UpdatedAt}}</time> | |
| 82 | - | </div> | |
| 72 | + | <footer> | |
| 73 | + | <hr /> | |
| 74 | + | {{if or .Tags .UpdatedAt}} | |
| 75 | + | <p> | |
| 76 | + | {{if .Tags}} | |
| 77 | + | {{range .Tags}} | |
| 78 | + | <a href="{{$.BlogURL}}?tag={{.}}">#{{.}}</a> | |
| 79 | + | {{end}} | |
| 80 | + | {{if .UpdatedAt}}<br />{{end}} | |
| 81 | + | {{end}} | |
| 82 | + | {{if .UpdatedAt}} | |
| 83 | + | <span>last updated: <time datetime="{{.UpdatedAtISO}}">{{.UpdatedAt}}</time></span> | |
| 84 | + | {{end}} | |
| 85 | + | </p> | |
| 86 | + | {{end}} | |
| 83 | 87 | ||
| 84 | - | <div id="post-footer">{{.Footer}}</div> | |
| 88 | + | {{if .Footer}}<div id="post-footer">{{.Footer}}</div>{{end}} | |
| 89 | + | </footer> | |
| 85 | 90 | </article> | |
| 86 | - | </main> | |
| 87 | - | {{template "footer" .}} | |
| 91 | + | </main> | |
| 92 | + | ||
| 93 | + | {{template "footer" .}} | |
| 88 | 94 | {{end}} |
+95,
-0
| ... | ... | @@ -0,0 +1,95 @@ | |
| 1 | + | *, *::before, *::after { | |
| 2 | + | box-sizing: border-box; | |
| 3 | + | } | |
| 4 | + | ||
| 5 | + | :is(h1, h2, h3, h4, h5, h6, p, blockquote, hr, ul, ol, pre) + * { | |
| 6 | + | margin-top: 1rem; | |
| 7 | + | } | |
| 8 | + | ||
| 9 | + | html { | |
| 10 | + | color-scheme: light dark; | |
| 11 | + | } | |
| 12 | + | ||
| 13 | + | @media (prefers-reduced-motion: no-preference) { | |
| 14 | + | html { | |
| 15 | + | interpolate-size: allow-keywords; | |
| 16 | + | } | |
| 17 | + | } | |
| 18 | + | ||
| 19 | + | body { | |
| 20 | + | font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; | |
| 21 | + | max-width: 70ch; | |
| 22 | + | margin-inline: auto; | |
| 23 | + | padding-inline: 1rem; | |
| 24 | + | line-height: 1.5; | |
| 25 | + | -webkit-font-smoothing: antialiased; | |
| 26 | + | } | |
| 27 | + | ||
| 28 | + | img, picture, video, canvas, svg { | |
| 29 | + | display: block; | |
| 30 | + | max-width: 100%; | |
| 31 | + | height: auto; | |
| 32 | + | } | |
| 33 | + | ||
| 34 | + | input, button, textarea, select { | |
| 35 | + | font: inherit; | |
| 36 | + | } | |
| 37 | + | ||
| 38 | + | code, kbd, samp, pre { | |
| 39 | + | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; | |
| 40 | + | font-size: 1em; | |
| 41 | + | } | |
| 42 | + | ||
| 43 | + | pre { | |
| 44 | + | overflow-x: auto; | |
| 45 | + | } | |
| 46 | + | ||
| 47 | + | table { | |
| 48 | + | border-collapse: collapse; | |
| 49 | + | border-spacing: 0; | |
| 50 | + | } | |
| 51 | + | ||
| 52 | + | hr { | |
| 53 | + | border: none; | |
| 54 | + | border-top: 1px solid currentColor; | |
| 55 | + | } | |
| 56 | + | ||
| 57 | + | p, h1, h2, h3, h4, h5, h6 { | |
| 58 | + | overflow-wrap: break-word; | |
| 59 | + | } | |
| 60 | + | ||
| 61 | + | p { | |
| 62 | + | text-wrap: pretty; | |
| 63 | + | } | |
| 64 | + | ||
| 65 | + | h1, h2, h3, h4, h5, h6 { | |
| 66 | + | text-wrap: balance; | |
| 67 | + | } | |
| 68 | + | ||
| 69 | + | blockquote { | |
| 70 | + | border-inline-start: 2px solid currentColor; | |
| 71 | + | padding-inline-start: 1ch; | |
| 72 | + | margin: 0; | |
| 73 | + | } | |
| 74 | + | ||
| 75 | + | [role="list"] { | |
| 76 | + | display: flex; | |
| 77 | + | flex-direction: column; | |
| 78 | + | gap: 0.5rem; | |
| 79 | + | list-style: none; | |
| 80 | + | padding: 0; | |
| 81 | + | } | |
| 82 | + | ||
| 83 | + | [role="list"] [role="list"] { | |
| 84 | + | margin-left: 1.3rem; | |
| 85 | + | } | |
| 86 | + | ||
| 87 | + | [role="listitem"] { | |
| 88 | + | display: flex; | |
| 89 | + | align-items: flex-start; | |
| 90 | + | gap: 5px; | |
| 91 | + | } | |
| 92 | + | ||
| 93 | + | [role="listitem"]:has(pre, img, blockquote) { | |
| 94 | + | align-items: center; | |
| 95 | + | } |