├── .github └── workflows │ └── test.yaml ├── .gitignore ├── LICENSE.md ├── README.md ├── archetypes └── default.md ├── exampleSite ├── content │ ├── _index.md │ ├── contact.md │ └── posts │ │ ├── _index.md │ │ ├── first.md │ │ └── second │ │ ├── cinque-terre-g21bc04293_640.jpg │ │ └── index.md └── hugo.toml ├── layouts ├── 404.html ├── _default │ ├── baseof.html │ ├── list.html │ └── single.html ├── index.html └── shortcodes │ └── notice.html ├── screenshot.png ├── static ├── css │ ├── styles.css │ └── themes │ │ ├── dark-chroma.css │ │ ├── dark.css │ │ ├── light-chroma.css │ │ └── light.css ├── images │ ├── chain-link.svg │ ├── exclamation.svg │ ├── hamburger.svg │ ├── header-bg-dark.jpg │ ├── header-bg-light.jpg │ ├── theme-switcher-moon.svg │ └── theme-switcher-sun.svg └── js │ └── theme-switcher.js └── theme.toml /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: Test example site 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | types: [opened, synchronize] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v4 16 | with: 17 | persist-credentials: false 18 | 19 | - name: Install hugo 20 | run: | 21 | cd /tmp/ 22 | wget -O hugo.deb https://github.com/gohugoio/hugo/releases/download/v0.122.0/hugo_0.122.0_linux-amd64.deb 23 | sudo apt-get install -y ./hugo.deb 24 | 25 | - name: Build 26 | run: | 27 | mkdir exampleSite/themes 28 | ln -sT "$(pwd)" exampleSite/themes/no-js-hugo-theme 29 | cd exampleSite && hugo 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | All of the files in this repository are licensed under the MIT License, with the 2 | following exceptions: 3 | 4 | static/header-bg-light.jpg: Pixabay License 5 | static/header-bg-dark.jpg: Pixabay License 6 | exampleSite/content/posts/second/cinque-terre-g21bc04293\_640.jpg: Pixabay License 7 | 8 | ---------------------- 9 | 10 | The MIT License (MIT) 11 | 12 | Copyright (c) 2018 Steven Engler 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy of 15 | this software and associated documentation files (the "Software"), to deal in 16 | the Software without restriction, including without limitation the rights to 17 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 18 | the Software, and to permit persons to whom the Software is furnished to do so, 19 | subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in all 22 | copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 26 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 27 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 28 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ---------------------- 32 | 33 | Pixabay License (29-01-2019) 34 | 35 | Images and Videos on Pixabay are made available under the Pixabay License on the 36 | following terms. Under the Pixabay License you are granted an irrevocable, 37 | worldwide, non-exclusive and royalty free right to use, download, copy, modify 38 | or adapt the Images and Videos for commercial or non-commercial purposes. 39 | Attribution of the photographer or Pixabay is not required but is always 40 | appreciated. 41 | 42 | The Pixabay License does not allow: 43 | 44 | a. sale or distribution of Images or Videos as digital stock photos or as 45 | digital wallpapers; 46 | b. sale or distribution of Images or Videos e.g. as a posters, digital prints 47 | or physical products, without adding any additional elements or otherwise 48 | adding value; 49 | c. depiction of identifiable persons in an offensive, pornographic, obscene, 50 | immoral, defamatory or libelous way; or 51 | d. any suggestion that there is an endorsement of products and services by 52 | depicted persons, brands, and organisations, unless permission was granted. 53 | 54 | Please be aware that while all Images and Videos on Pixabay are free to use for 55 | commercial and non-commercial purposes, depicted items in the Images or Videos, 56 | such as identifiable people, logos, brands, etc. may be subject to additional 57 | copyrights, property rights, privacy rights, trademarks etc. and may require the 58 | consent of a third party or the license of these rights - particularly for 59 | commercial applications. Pixabay does not represent or warrant that such 60 | consents or licenses have been obtained, and expressly disclaims any liability 61 | in this respect. 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # No-JS Hugo Theme 2 | 3 | A minimal, responsive, and privacy-friendly [Hugo](https://gohugo.io/) theme that does not require the client to enable JavaScript. 4 | 5 | Many Hugo themes (and websites in general) don't render properly or even become unreadable when clients choose not to enable JavaScript. This theme is designed to work well if the client does not have JavaScript enabled. It is designed for both desktop and mobile browsers. All modern browsers (Chromium, Firefox, and Safari) are supported. The theme does not load any external third-party resources. 6 | 7 | See the [example site](https://stevenengler.github.io/no-js-hugo-theme-example/). 8 | 9 | ![Screenshot](/screenshot.png?raw=true) 10 | 11 | The theme works well with the Tor Browser at all security levels. Tor Browser [does not support](https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/42498) fallbacks for SVG images, so you may want to rasterize the theme's svg images as jpg/png/webp versions so that they display on the "safest" security level. 12 | 13 | Some features are not possible without JavaScript. These features can be enabled in the site config file and will never decrease the quality of the website. 14 | 15 | Additional JavaScript features: 16 | - light/dark theme switcher 17 | -------------------------------------------------------------------------------- /archetypes/default.md: -------------------------------------------------------------------------------- 1 | +++ 2 | +++ 3 | -------------------------------------------------------------------------------- /exampleSite/content/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Home 3 | menu: 4 | main: 5 | weight: 100 6 | --- 7 | 8 | # Welcome! 9 | 10 | Pellentesque placerat nec diam ut tempor. Pellentesque ut risus tincidunt, pellentesque magna nec, auctor arcu. Maecenas elementum massa nibh, sit amet interdum libero porta vel. Etiam et sem varius, ultricies lectus ut, congue nibh. Proin luctus lorem maximus odio aliquam mollis. Duis venenatis pellentesque odio in tempus. Nam gravida euismod pharetra. Quisque egestas enim ligula, facilisis malesuada lacus ultricies id. Fusce dapibus tellus ac neque facilisis interdum eu eget est. Suspendisse a pulvinar erat, ac ultricies augue. Nulla facilisi. Aenean egestas lorem eu enim bibendum luctus. 11 | -------------------------------------------------------------------------------- /exampleSite/content/contact.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Contact" 3 | date: 2021-02-12T17:19:56-04:00 4 | draft: false 5 | menu: main 6 | --- 7 | 8 | First Last\ 9 | me@example.com 10 | -------------------------------------------------------------------------------- /exampleSite/content/posts/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Posts 3 | menu: main 4 | --- 5 | -------------------------------------------------------------------------------- /exampleSite/content/posts/first.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: First Post 3 | date: 2021-05-21 16:53:00 4 | lastmod: 2021-05-22 13:12:00 5 | draft: false 6 | --- 7 | 8 | Nunc ultrices sed nisi sed interdum. Sed sagittis viverra nunc, et eleifend metus fringilla sed. Vestibulum pharetra erat eros, sit amet bibendum risus aliquam at. Quisque at semper leo, nec placerat velit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In pulvinar auctor interdum. In sed urna quis nisi consequat accumsan vitae eget est. Nullam rhoncus, odio in aliquam dignissim, orci urna venenatis nibh, in aliquet massa arcu nec enim. Suspendisse aliquam interdum mauris, quis convallis tellus varius sit amet. Maecenas convallis id lorem at euismod. Donec felis velit, ullamcorper sed felis eu, aliquet vestibulum elit. Integer facilisis non elit ut congue. Nullam dignissim urna vitae blandit varius. Morbi eu mattis erat. Morbi sit amet nibh in purus sodales molestie tincidunt eget augue. 9 | -------------------------------------------------------------------------------- /exampleSite/content/posts/second/cinque-terre-g21bc04293_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenengler/no-js-hugo-theme/6d547d6ddf28bd1327043243cb39834cfe201e7a/exampleSite/content/posts/second/cinque-terre-g21bc04293_640.jpg -------------------------------------------------------------------------------- /exampleSite/content/posts/second/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Second Post 3 | date: 2021-06-12 14:41:00 4 | lastmod: 2021-06-13 15:22:00 5 | toc: true 6 | draft: false 7 | --- 8 | 9 | ## Introduction 10 | 11 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam venenatis velit *justo*, ac mattis sem pulvinar pellentesque. Sed rutrum eu enim eleifend accumsan. Mauris ante mi, posuere ut feugiat in, blandit nec leo. Fusce **vel massa ullamcorper**, maximus augue a, viverra enim. Phasellus feugiat, elit maximus aliquet vehicula, orci mauris placerat odio, quis congue `lacus.nulla()` a nulla. Aenean congue in diam at ultricies. Etiam consectetur orci rhoncus feugiat pharetra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Praesent ultrices augue ac varius gravida. 12 | 13 | {{< notice warning >}} 14 | Duis placerat scelerisque ligula, at cursus neque *sollicitudin pretium*. Nullam et consectetur quam, et *commodo pretium*! 15 | {{< /notice >}} 16 | 17 | ``` rust 18 | let x = 52; 19 | println!("{}", x); 20 | ``` 21 | 22 | Phasellus auctor eros sit amet nunc interdum, quis iaculis neque consectetur. Nunc at tincidunt odio. Donec venenatis posuere ante, ut eleifend sapien pellentesque eget. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis a leo varius, venenatis orci sit amet, maximus dui. Quisque vehicula velit est, gravida viverra massa ornare ut. Vivamus in posuere elit, vel ultricies ante. Quisque faucibus tellus in mauris venenatis maximus. Mauris bibendum ullamcorper mi vulputate finibus. In tortor elit, iaculis sed tempus gravida, facilisis nec lectus. Aliquam id enim vel elit hendrerit posuere ac eu augue. Ut ante ligula, consectetur id pretium id, tempor vel dui. Quisque sed vehicula purus, scelerisque commodo ligula. Mauris ut orci dapibus, maximus purus at, facilisis tellus. Nulla mattis orci at sapien accumsan, vitae imperdiet ipsum aliquam. Aliquam pulvinar iaculis tincidunt. 23 | 24 | ### Example 25 | 26 | {{< highlight rust "linenos=table,hl_lines=3-4,linenostart=199" >}} 27 | let x = 52; 28 | fn foo(a: i32) -> i32 { 29 | a + 10 30 | } 31 | println!("x: {}, foo: {}", x, foo(x)); 32 | {{< / highlight >}} 33 | 34 | Integer ultrices pellentesque orci nec tempus. In in felis sit amet ex aliquam convallis. Etiam ac nunc sed elit placerat tristique. Nulla odio ex, imperdiet sit amet porttitor sed, placerat nec elit. In lorem orci, aliquam non velit et, venenatis viverra dui. Curabitur molestie urna quis dignissim vulputate. Donec ac lacus laoreet odio malesuada rutrum in sit amet dolor. Pellentesque ut porttitor ante. Cras molestie nisi in lacus eleifend tempus. Nullam ut leo bibendum, egestas tellus vel, accumsan nibh. 35 | 36 | ## Discussion 37 | 38 | Mauris consectetur magna nec nibh maximus venenatis. Nulla ut vulputate ligula. Vestibulum vestibulum est non lectus commodo commodo. Fusce dolor justo, sagittis eget congue quis, viverra ut metus. Sed volutpat aliquet eros, a lacinia tellus consectetur sed. Morbi massa est, hendrerit vitae accumsan in, fringilla laoreet diam. Duis tempor iaculis lectus, malesuada auctor massa luctus at. In bibendum viverra mauris, non eleifend nunc dignissim faucibus. Cras facilisis aliquam dui, sit amet feugiat nisl malesuada laoreet. Sed tincidunt, tellus sed fringilla viverra, nibh orci dictum magna, pharetra dapibus massa nulla vel lacus. Curabitur pulvinar tristique tristique. Nunc tristique nibh nec est ultrices, ut semper est aliquam. Vivamus non auctor tortor, sit amet vestibulum ipsum. 39 | 40 | {{< figure src="cinque-terre-g21bc04293_640.jpg" title="Vernazza" >}} 41 | 42 | Aliquam non rhoncus libero. Vivamus arcu tellus, elementum ut arcu in, porta porttitor felis. Etiam dapibus bibendum quam, a lobortis augue auctor in. Phasellus maximus turpis aliquam mauris mollis varius. Proin facilisis, orci id lobortis bibendum, augue turpis eleifend lorem, eleifend pharetra quam orci vel lacus. Nam id finibus quam. Integer lacinia nec nulla et mattis. Praesent rutrum sem mi, facilisis laoreet purus imperdiet quis. Donec elit felis, convallis nec vulputate at, bibendum in arcu. Mauris faucibus a nulla vel hendrerit. Praesent eget libero vulputate, dictum mi lobortis, pellentesque urna. Sed posuere libero purus, vitae posuere orci faucibus at. 43 | -------------------------------------------------------------------------------- /exampleSite/hugo.toml: -------------------------------------------------------------------------------- 1 | baseURL = 'http://example.org/' 2 | languageCode = 'en-us' 3 | title = "Notebook" 4 | theme = "no-js-hugo-theme" 5 | 6 | [markup] 7 | [markup.highlight] 8 | codeFences = true 9 | noClasses = false 10 | 11 | [markup.tableOfContents] 12 | startLevel = 1 13 | endLevel = 6 14 | 15 | [params] 16 | # enable javascript theme switcher 17 | # default: false 18 | themeStyleSwitcher = true 19 | 20 | # theme style if the theme switcher is disabled 21 | # default: "light.css" 22 | #themeStyle = "dark.css" 23 | 24 | # footer markdown text at the bottom of every page 25 | # default: 26 | footerText = "[no-js-hugo-theme](https://github.com/stevenengler/no-js-hugo-theme)" 27 | 28 | # enable the table of content on pages with more than this many words (negative to disable) 29 | # (can be overridden per-page by setting the 'toc' front matter parameter) 30 | # default: 31 | #tocWordThreshold = 1000 32 | 33 | # adds an "onion-location" meta attribute to the HTML of each page 34 | # default: 35 | #onionLocation = "http://.onion" 36 | -------------------------------------------------------------------------------- /layouts/404.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenengler/no-js-hugo-theme/6d547d6ddf28bd1327043243cb39834cfe201e7a/layouts/404.html -------------------------------------------------------------------------------- /layouts/_default/baseof.html: -------------------------------------------------------------------------------- 1 | {{ $themeStyleDefault := "light.css" -}} 2 | 3 | 4 | 5 | 6 | 7 | 8 | {{- if isset .Site.Params "onionlocation" }} 9 | 10 | {{- end }} 11 | {{ block "title" . }}{{ .Site.Title }}{{ end }} 12 | 13 | 14 | {{- if .Site.Params.ThemeStyleSwitcher }} 15 | 16 | {{- end }} 17 | 18 | 19 | 20 | 21 |
22 |
23 |
24 |
25 | {{ .Site.Title }} 26 |
27 |
28 |
29 | {{- if .Site.Params.ThemeStyleSwitcher }} 30 | 33 | {{- end }} 34 | 37 |
38 | {{- if .Site.Menus.main }} 39 |
40 |

41 | Links: 42 |

43 |
44 | 49 | {{- end }} 50 |
51 |
52 |
53 |
54 |
55 | {{- block "main" . }}{{ end }} 56 |
57 |
58 |
59 | {{- if .Site.Params.FooterText }} 60 |
61 |
62 |

{{ .Site.Params.FooterText | markdownify }}

63 |
64 | {{- end }} 65 | 66 | 67 | -------------------------------------------------------------------------------- /layouts/_default/list.html: -------------------------------------------------------------------------------- 1 | {{ define "title" }}{{ .Title }} – {{ .Site.Title }}{{ end }} 2 | {{ define "main" }} 3 | {{ .Content }} 4 |
5 |

{{ .Title }}

6 |
7 | {{- if gt (len .Sections) 0 }} 8 |

Categories

9 |
    10 | {{- range .Sections }} 11 |
  • {{ .Title }}
  • 12 | {{- end }} 13 |
14 |

All Posts

15 | {{- end }} 16 | {{- $cs := .CurrentSection }} 17 | {{- with $cs }} 18 | {{- range (where .Site.RegularPages "Section" .Section) }} 19 | {{- if .IsDescendant $cs }} 20 |
21 |
22 |

{{ if .Draft }}(Draft) {{ end }}{{ .Title }}

23 |
24 | {{- if eq .Date.IsZero false }} 25 | 26 | {{- end }} 27 | {{- if (and (eq .Lastmod.IsZero false) (ne .Lastmod .Date)) }} 28 | (updated) 29 | {{- end }} 30 |
31 |
32 |
33 |

{{/* Spacing is weird if we don't include this */}} 34 |

35 | {{ .Summary }} 36 |

37 | {{- if .Truncated }} 38 | Read More… 39 | {{- end }} 40 |
41 |
42 | {{- end }} 43 | {{- end }} 44 | {{- end }} 45 | {{ end }} 46 | -------------------------------------------------------------------------------- /layouts/_default/single.html: -------------------------------------------------------------------------------- 1 | {{ define "title" }}{{ .Title }} – {{ .Site.Title }}{{ end }} 2 | {{ define "main" }} 3 |
4 |

{{ if .Draft }}(Draft) {{ end }}{{ .Title }}

5 |
6 | {{- if eq .Date.IsZero false }} 7 | 8 | {{- end }} 9 | {{- if (and (eq .Lastmod.IsZero false) (ne .Lastmod .Date)) }} 10 | — last updated 11 | {{- end }} 12 |
13 | {{ if or (.Params.toc) (and (ne .Params.toc false) (isset .Site.Params "tocwordthreshold") (ge .Site.Params.TocWordThreshold 0) (gt .WordCount .Site.Params.TocWordThreshold)) }} 14 | {{/* If the front matter parameter is true, show the toc */}} 15 | {{/* Elif the front matter parameter is false, don't show the toc */}} 16 | {{/* Elif the front matter parameter is not set, show the toc if the site parameter is set, non-negative, and less than the word count */}} 17 |

18 |
19 |
20 | 21 | Table of Contents 22 | 23 | {{ $toc := .TableOfContents -}} 24 | {{/* Workaround for an extra layer of indentation (https://discourse.gohugo.io/t/2303) */}} 25 | {{- $toc := replaceRE `(\s*)
    \s*
  • \s*
      ` `${2}
        ` $toc -}} 26 | {{- $toc := replaceRE `
      \s*\s*
    (\s*)` `
${1}` $toc -}} 27 | {{- safeHTML $toc }} 28 |
29 |
30 | {{ end }} 31 |
32 | {{ .Content | replaceRE "()" (printf "${1}${3}" ("images/chain-link.svg" | relURL)) | safeHTML }} 33 | {{ end }} 34 | -------------------------------------------------------------------------------- /layouts/index.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | {{ .Content }} 3 | {{ if gt ( len ( where .Site.RegularPages "Section" "posts" )) 0 }} 4 |

Recent Posts

5 | {{ range first 2 ( where .Site.RegularPages "Section" "posts" ) }} 6 |
7 |
8 |

{{ if .Draft }}(Draft) {{ end }}{{ .Title }}

9 |
10 | {{ if eq .Date.IsZero false }} 11 | 12 | {{ end }} 13 | {{ if (and (eq .Lastmod.IsZero false) (ne .Lastmod .Date)) }} 14 | (updated) 15 | {{ end }} 16 |
17 |
18 |
19 |

{{/* Spacing is weird if we don't include this */}} 20 |

21 | {{ .Summary }} 22 |

23 | {{ if .Truncated }} 24 | Read More… 25 | {{ end }} 26 |
27 |
28 | {{ end }} 29 | {{ end }} 30 | {{ end }} 31 | -------------------------------------------------------------------------------- /layouts/shortcodes/notice.html: -------------------------------------------------------------------------------- 1 | {{- .Scratch.Set "type" "note" -}} 2 | {{- with .Get 0 }}{{ $.Scratch.Set "type" . }}{{ end -}} 3 | 12 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenengler/no-js-hugo-theme/6d547d6ddf28bd1327043243cb39834cfe201e7a/screenshot.png -------------------------------------------------------------------------------- /static/css/styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --document-margin: 15pt; 3 | } 4 | 5 | h1 { font-size: 1.50em; } 6 | h2 { font-size: 1.40em; } 7 | h3 { font-size: 1.20em; } 8 | h4 { font-size: 1.00em; } 9 | h5 { font-size: 0.85em; } 10 | h6 { font-size: 0.75em; } 11 | 12 | h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { 13 | text-decoration: none; 14 | } 15 | 16 | h1, h2, h3, h4, h5, h6 { 17 | margin-top: 1.5em; 18 | } 19 | 20 | @media (hover: hover) { 21 | /* For devices which support hover, hide the heading URL fragment 22 | link/icon until the mouse hovers over the heading */ 23 | 24 | h1:hover .heading-anchor, 25 | h2:hover .heading-anchor, 26 | h3:hover .heading-anchor, 27 | h4:hover .heading-anchor, 28 | h5:hover .heading-anchor, 29 | h6:hover .heading-anchor { 30 | visibility: visible; 31 | } 32 | 33 | h1 .heading-anchor, 34 | h2 .heading-anchor, 35 | h3 .heading-anchor, 36 | h4 .heading-anchor, 37 | h5 .heading-anchor, 38 | h6 .heading-anchor { 39 | visibility: hidden; 40 | } 41 | } 42 | 43 | .heading-anchor { 44 | /* this is used on an "aside" tag so that it's not shown in the browser's reader mode */ 45 | display: inline; 46 | color: grey; 47 | margin-left: 0.5em; 48 | font-size: 0.75em; 49 | } 50 | 51 | .heading-anchor a:hover { 52 | text-decoration: none; 53 | } 54 | 55 | .heading-anchor img { 56 | height: 1em; 57 | } 58 | 59 | a { 60 | text-decoration: none; 61 | } 62 | 63 | a:hover { 64 | text-decoration: underline; 65 | } 66 | 67 | .dont-show { 68 | display: none; 69 | } 70 | 71 | /* Improvements to Hugo Chroma syntax highlighting */ 72 | 73 | .highlight { 74 | margin-top: 1em; 75 | margin-bottom: 1em; 76 | /* set the tab size for browsers that support it */ 77 | tab-size: 4; 78 | -moz-tab-size: 4; 79 | /* needed for the iPhone so that the two columns (line numbers and code) don't have different font sizes */ 80 | -webkit-text-size-adjust: 100%; 81 | } 82 | 83 | .highlight > * { 84 | padding: 0.5em; 85 | border-width: 2px; 86 | border-style: solid; 87 | } 88 | 89 | .highlight pre { 90 | margin: 0px; 91 | overflow-x: auto; 92 | word-wrap: normal; 93 | } 94 | 95 | .highlight td.lntd pre { 96 | /* needed to fix an iPhone scrolling bug */ 97 | overflow-x: hidden; 98 | } 99 | 100 | .highlight td.lntd:last-child { 101 | /* needed until this bug is fixed: https://github.com/alecthomas/chroma/issues/225 */ 102 | width: 100%; 103 | } 104 | 105 | /* Improvements to inline code blocks */ 106 | 107 | code { 108 | font-size: 98%; 109 | } 110 | 111 | :not(pre) > code { 112 | /* inline code elements */ 113 | background-color: rgba(25, 25, 25, 0.05); 114 | border-radius: 5px; 115 | font-size: 80%; 116 | padding-top: 0.2em; 117 | padding-bottom: 0.2em; 118 | padding-left: 0.4em; 119 | padding-right: 0.4em; 120 | } 121 | 122 | /* Formatting for "notice" shortcodes */ 123 | 124 | .notice { 125 | margin: 1.5em 0; 126 | width: 70%; 127 | margin-left: auto; 128 | margin-right: auto; 129 | background-color: #E9E9E9; 130 | } 131 | 132 | @media only screen and (max-width: 500pt) { 133 | .notice { 134 | width: 100%; 135 | } 136 | } 137 | 138 | .notice > hr { 139 | display: none; /* only want the child hr elements to appear if css is disabled */ 140 | } 141 | 142 | .notice .notice-title { 143 | margin: 0; 144 | padding: 0.4em; 145 | line-height: 1em; 146 | background-color: #D5D5D5; 147 | } 148 | 149 | .notice .notice-title span { 150 | vertical-align: -10%; /* we don't want the font descender space to be centered as well */ 151 | } 152 | 153 | .notice .notice-title .notice-title-icon { 154 | display: inline-block; 155 | vertical-align: middle; 156 | margin-left: 0.15em; 157 | margin-right: 0.25em; 158 | height: 0.85em; 159 | } 160 | 161 | .notice .notice-body { 162 | padding: 0.6em; 163 | } 164 | 165 | .notice .notice-body p:first-child { 166 | margin-top: 0; 167 | } 168 | 169 | .notice .notice-body p { 170 | margin: 0.8em 0; 171 | } 172 | 173 | /* ************************ */ 174 | 175 | blockquote { 176 | color: #404040; 177 | border-left: 0.25em solid #CCC; 178 | padding-left: 0.5em; 179 | margin-left: 1.5em; 180 | } 181 | 182 | .title-header { 183 | margin-top: 1.5em; 184 | margin-bottom: 1.5em; 185 | } 186 | 187 | .title-header > h1{ 188 | margin-top: 0; 189 | margin-bottom: 0.3em; 190 | } 191 | 192 | .title-header-date { 193 | color: rgb(90, 90, 90); 194 | font-size: 80%; 195 | } 196 | 197 | .title-list > h2, .title-list > h3, .title-list > h4, .title-list > h5, .title-list > h6{ 198 | margin-bottom: 0.1em; 199 | } 200 | 201 | .body-list p { 202 | margin-top: 0.5em; 203 | margin-bottom: 0.5em; 204 | } 205 | 206 | .title-list-date { 207 | color: rgb(90, 90, 90); 208 | font-size: 80%; 209 | } 210 | 211 | .table-of-contents { 212 | border-width: 2px; 213 | border-style: solid; 214 | padding: 1em; 215 | margin-bottom: 2em; 216 | font-size: 0.9em; 217 | } 218 | 219 | .table-of-contents nav > ul { 220 | /* only the most-parent ul element */ 221 | margin-bottom: 0; 222 | } 223 | 224 | .table-of-contents ul { 225 | list-style: none; 226 | padding-left: 0; 227 | } 228 | 229 | .table-of-contents li { 230 | margin-top: 0.5em; 231 | } 232 | 233 | .table-of-contents ul ul { 234 | list-style: none; 235 | padding-left: 1.0em; 236 | } 237 | 238 | .table-of-contents-title { 239 | font-size: 1.2em; 240 | font-weight: bold; 241 | } 242 | 243 | .section-list { 244 | padding-left: 0; 245 | } 246 | 247 | .section-list li { 248 | display: inline-block; 249 | margin-right: 0.5em; 250 | } 251 | 252 | .section-list li:last-child { 253 | margin-right: 0em; 254 | } 255 | 256 | .section-list li > * { 257 | background-color: rgba(25, 25, 25, 0.05); 258 | border-radius: 5px; 259 | font-size: 90%; 260 | padding-top: 0.2em; 261 | padding-bottom: 0.2em; 262 | padding-left: 0.4em; 263 | padding-right: 0.4em; 264 | } 265 | 266 | .links { 267 | font-size: 120%; 268 | list-style-type: none; 269 | line-height: 1; 270 | padding: 0; 271 | margin: 0; 272 | margin-top: 9pt; 273 | display: flex; 274 | flex-direction: row; 275 | /* Not sure what we can do other than continue the links on the next line. 276 | * It's ugly, but probably better than hiding them altogether. */ 277 | flex-wrap: wrap; 278 | row-gap: 0.3em; 279 | } 280 | 281 | .links li { 282 | margin-right: 1em; 283 | } 284 | 285 | .links li > * { 286 | display:inline-block; 287 | } 288 | 289 | .links li:last-child { 290 | margin-right: 0; 291 | } 292 | 293 | .links a { 294 | text-decoration: none; 295 | color: inherit; 296 | } 297 | 298 | .links a:hover { 299 | color: #505050; 300 | } 301 | 302 | .overlay { 303 | position: fixed; 304 | visibility: hidden; 305 | opacity: 0; 306 | width: 100%; 307 | height: 100%; 308 | top: 0; 309 | left: 0; 310 | right: 0; 311 | bottom: 0; 312 | background-color: rgba(0, 0, 0, 0.7); 313 | z-index: 2; 314 | /* for iOS: https://stackoverflow.com/a/11885330 */ 315 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 316 | } 317 | 318 | .header-right { 319 | /* want the images to have padding to make them easier to click, but we still want them aligned correctly */ 320 | --label-padding: 0.3em; 321 | 322 | position: absolute; 323 | top: calc(var(--document-margin) - var(--label-padding)); 324 | right: calc(var(--document-margin) - var(--label-padding)); 325 | display: flex; 326 | } 327 | 328 | .header-right > * { 329 | margin-left: 0.4em; 330 | } 331 | 332 | .clickable-header-label { 333 | cursor: pointer; 334 | padding: var(--label-padding); 335 | } 336 | 337 | .clickable-header-label img { 338 | height: 1em; 339 | width: auto; /* to override the attribute when css is supported */ 340 | } 341 | 342 | #show-hide-menu-label { 343 | display: none; 344 | } 345 | 346 | #show-hide-menu-label * { 347 | /* duration for the rotation transition of the hamburger image */ 348 | transition-duration: 100ms; 349 | } 350 | 351 | body { 352 | font-size: 13pt; 353 | font-family: Lato, Arial, Helvetica, "Liberation Sans", sans-serif; 354 | line-height: 1.45; 355 | margin: 0; 356 | } 357 | 358 | .title { 359 | font-weight: bold; 360 | font-size: 140%; 361 | line-height: 1em; 362 | } 363 | 364 | .title a { 365 | text-decoration: none; 366 | color: inherit; 367 | } 368 | 369 | .header { 370 | background-color: lightgray; 371 | background-size: cover; 372 | background-position: bottom; 373 | width: 100%; 374 | /* header must be above the overlay */ 375 | /* this also prevents images with css filters from appearing above the header when in portrait mode */ 376 | z-index: 3; 377 | /* z-index doesn't apply to the default 'static' position */ 378 | position: relative; 379 | } 380 | 381 | .header-content { 382 | padding: var(--document-margin); 383 | position: relative; /* so that "position: absolute" works for the menu label */ 384 | } 385 | 386 | .body { 387 | display: inline-block; 388 | width: 100%; 389 | } 390 | 391 | .body-content { 392 | margin: var(--document-margin); 393 | word-wrap: break-word; 394 | } 395 | 396 | /* Image/Figure formatting */ 397 | 398 | .body-content :not(figure) img { 399 | /* regular image elements should be inline elements */ 400 | max-width: 100%; 401 | max-height: 60vw; /* if the image is really tall, we don't want the width to be 100% */ 402 | } 403 | 404 | .body-content figure { 405 | margin-left: auto; 406 | margin-right: auto; 407 | max-width: 70%; 408 | } 409 | 410 | .body-content figure img { 411 | display: block; 412 | margin-left: auto; 413 | margin-right: auto; 414 | margin-bottom: 0.5em; 415 | max-width: 100%; 416 | max-height: 40vw; /* if the image is really tall, we don't want the width to be 70% */ 417 | } 418 | 419 | .body-content figure:not(.color-adapting-image) img { 420 | /* if the image is designed to adapt to the theme, then don't use a background */ 421 | background-color: rgb(255, 255, 255); /* images with transparent backgrounds typically assume a light background */ 422 | } 423 | 424 | .body-content figure figcaption { 425 | font-size: 90%; 426 | line-height: 1.5em; 427 | padding-bottom: 0.3em; 428 | border-bottom: 2px solid lightgray; 429 | } 430 | 431 | .body-content figure figcaption * { 432 | margin: 0; 433 | } 434 | 435 | @media only screen and (orientation: portrait) { 436 | .body-content :not(figure) img, 437 | .body-content figure img { 438 | /* need to target both so that they're more specific */ 439 | max-height: 100vw; 440 | } 441 | } 442 | 443 | @media only screen and (max-width: 400pt) { 444 | .body-content figure { 445 | max-width: 100%; 446 | } 447 | 448 | .body-content figure figcaption { 449 | margin-left: 5%; 450 | margin-right: 5%; 451 | } 452 | } 453 | 454 | /* ************************ */ 455 | 456 | .main { 457 | width: 700pt; /* make sure to also change this in the media query */ 458 | margin: 0 auto; 459 | margin-top: 10pt; 460 | margin-bottom: 10pt; 461 | box-sizing: border-box; 462 | box-shadow: 0 0 10px rgba(50, 50, 50, .17); 463 | } 464 | 465 | .footer { 466 | text-align: center; 467 | font-size: 80%; 468 | } 469 | 470 | 471 | @media only screen and (orientation: portrait) { 472 | .header { 473 | top: 0; 474 | position: sticky; 475 | position: -webkit-sticky; /* needed for iOS */ 476 | box-shadow: 0 0 1em rgba(30, 30, 30, .3); 477 | } 478 | 479 | .body-content :target::before { 480 | /* When linking to tags with 'id's (example: 481 | 'website.com/post/#heading'), make them 482 | appear lower down the page so that they 483 | don't appear under the sticky header set 484 | above. 485 | See: https://stackoverflow.com/a/24298427 486 | Note that this causes the cursor text 487 | selection of the target to behave 488 | undesirably. 489 | */ 490 | content: ''; 491 | display: block; 492 | height: 3em; 493 | margin-top: -3em; 494 | visibility: hidden; 495 | pointer-events: none; 496 | } 497 | } 498 | 499 | 500 | @media only screen and (max-width: 700pt) { 501 | .main { 502 | width: 100%; 503 | margin-top: 0; 504 | margin-bottom: 0; 505 | } 506 | 507 | body { 508 | font-size: 12pt; 509 | background-color: white; 510 | } 511 | } 512 | 513 | @media only screen and (max-width: 400pt) { 514 | :root { 515 | --document-margin: 10pt; 516 | } 517 | 518 | .header-right { 519 | top: 0; 520 | height: 100%; 521 | align-items: center; 522 | } 523 | 524 | .clickable-header-label { 525 | display: inline-flex; 526 | } 527 | 528 | .clickable-header-label * { 529 | vertical-align: middle; 530 | } 531 | 532 | #show-hide-menu-label { 533 | display: inherit; 534 | } 535 | 536 | .show-hide-menu-input:checked ~ .main .links { 537 | display: inherit; 538 | } 539 | 540 | .show-hide-menu-input:checked ~ .main #show-hide-menu-label > img { 541 | transform: rotate(90deg); 542 | } 543 | 544 | .show-hide-menu-input:checked ~ .overlay { 545 | visibility: visible; 546 | opacity: 1; 547 | } 548 | 549 | /* prevent scrolling the main body; must be on html element and not body for iOS */ 550 | html:has(.show-hide-menu-input:checked) { 551 | overflow: hidden; 552 | height: 100%; 553 | /* prevent scrolling (of everything) on iOS */ 554 | /* any element with 'overflow-y: scroll' will allow the body to scroll for some reason */ 555 | /* use 'pan-zoom' to allow users to zoom if they need to, even though it makes scrolling weird */ 556 | touch-action: pan-zoom; 557 | } 558 | 559 | .links { 560 | /* vertical padding between list items */ 561 | --entry-padding: 9pt; 562 | 563 | display: none; 564 | position: absolute; 565 | left: 0; 566 | right: 0; 567 | padding-left: var(--document-margin); 568 | padding-right: var(--document-margin); 569 | padding-top: calc(var(--document-margin) - var(--entry-padding)); 570 | padding-bottom: calc(var(--document-margin) - var(--entry-padding)); 571 | 572 | font-size: 100%; 573 | background-color: rgb(247, 247, 247); 574 | border-top: solid 1px; 575 | border-bottom: solid 1px; 576 | } 577 | 578 | .links li { 579 | border-bottom: solid 1px; 580 | /* override all previously set margins */ 581 | margin: 0; 582 | } 583 | 584 | .links li:last-child { 585 | border-bottom: none; 586 | } 587 | 588 | .links li > * { 589 | /* make the links easily clickable */ 590 | width: 100%; 591 | padding-top: var(--entry-padding); 592 | padding-bottom: var(--entry-padding); 593 | } 594 | } 595 | 596 | @media print { 597 | :root { 598 | --document-margin: 0pt; 599 | } 600 | 601 | body { 602 | background-color: initial !important; 603 | } 604 | 605 | .main { 606 | margin-top: 0; 607 | margin-bottom: 0; 608 | width: 100%; 609 | box-shadow: none !important; 610 | } 611 | 612 | .header { 613 | background-color: initial !important; 614 | background-image: none !important; 615 | } 616 | 617 | .header-right { 618 | display: none; 619 | } 620 | 621 | .links { 622 | display: none; 623 | } 624 | } 625 | -------------------------------------------------------------------------------- /static/css/themes/dark-chroma.css: -------------------------------------------------------------------------------- 1 | /* Background */ .chroma { color: #d0d0d0; background-color: #1a1a1a } 2 | /* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2 } 3 | /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } 4 | /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block; } 5 | /* LineHighlight */ .chroma .hl { display: block; width: 100%; background-color: #404040 } 6 | /* LineNumbersTable */ .chroma .lnt { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; } 7 | /* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; } 8 | /* Keyword */ .chroma .k { color: #6ab825; font-weight: bold } 9 | /* KeywordConstant */ .chroma .kc { color: #6ab825; font-weight: bold } 10 | /* KeywordDeclaration */ .chroma .kd { color: #6ab825; font-weight: bold } 11 | /* KeywordNamespace */ .chroma .kn { color: #6ab825; font-weight: bold } 12 | /* KeywordPseudo */ .chroma .kp { color: #6ab825 } 13 | /* KeywordReserved */ .chroma .kr { color: #6ab825; font-weight: bold } 14 | /* KeywordType */ .chroma .kt { color: #6ab825; font-weight: bold } 15 | /* NameAttribute */ .chroma .na { color: #bbbbbb } 16 | /* NameBuiltin */ .chroma .nb { color: #24909d } 17 | /* NameClass */ .chroma .nc { color: #447fcf } 18 | /* NameConstant */ .chroma .no { color: #447fcf } 19 | /* NameDecorator */ .chroma .nd { color: #ffa500 } 20 | /* NameException */ .chroma .ne { color: #bbbbbb } 21 | /* NameFunction */ .chroma .nf { color: #447fcf } 22 | /* NameNamespace */ .chroma .nn { color: #447fcf } 23 | /* NameTag */ .chroma .nt { color: #6ab825; font-weight: bold } 24 | /* NameVariable */ .chroma .nv { color: #447fcf } 25 | /* LiteralString */ .chroma .s { color: #ed9d13 } 26 | /* LiteralStringAffix */ .chroma .sa { color: #ed9d13 } 27 | /* LiteralStringBacktick */ .chroma .sb { color: #ed9d13 } 28 | /* LiteralStringChar */ .chroma .sc { color: #ed9d13 } 29 | /* LiteralStringDelimiter */ .chroma .dl { color: #ed9d13 } 30 | /* LiteralStringDoc */ .chroma .sd { color: #ed9d13 } 31 | /* LiteralStringDouble */ .chroma .s2 { color: #ed9d13 } 32 | /* LiteralStringEscape */ .chroma .se { color: #ed9d13 } 33 | /* LiteralStringHeredoc */ .chroma .sh { color: #ed9d13 } 34 | /* LiteralStringInterpol */ .chroma .si { color: #ed9d13 } 35 | /* LiteralStringOther */ .chroma .sx { color: #ffa500 } 36 | /* LiteralStringRegex */ .chroma .sr { color: #ed9d13 } 37 | /* LiteralStringSingle */ .chroma .s1 { color: #ed9d13 } 38 | /* LiteralStringSymbol */ .chroma .ss { color: #ed9d13 } 39 | /* LiteralNumber */ .chroma .m { color: #3677a9 } 40 | /* LiteralNumberBin */ .chroma .mb { color: #3677a9 } 41 | /* LiteralNumberFloat */ .chroma .mf { color: #3677a9 } 42 | /* LiteralNumberHex */ .chroma .mh { color: #3677a9 } 43 | /* LiteralNumberInteger */ .chroma .mi { color: #3677a9 } 44 | /* LiteralNumberIntegerLong */ .chroma .il { color: #3677a9 } 45 | /* LiteralNumberOct */ .chroma .mo { color: #3677a9 } 46 | /* OperatorWord */ .chroma .ow { color: #6ab825; font-weight: bold } 47 | /* Comment */ .chroma .c { color: #999999; font-style: italic } 48 | /* CommentHashbang */ .chroma .ch { color: #999999; font-style: italic } 49 | /* CommentMultiline */ .chroma .cm { color: #999999; font-style: italic } 50 | /* CommentSingle */ .chroma .c1 { color: #999999; font-style: italic } 51 | /* CommentSpecial */ .chroma .cs { color: #e50808; background-color: #520000; font-weight: bold } 52 | /* CommentPreproc */ .chroma .cp { color: #cd2828; font-weight: bold } 53 | /* CommentPreprocFile */ .chroma .cpf { color: #cd2828; font-weight: bold } 54 | /* GenericDeleted */ .chroma .gd { color: #d22323 } 55 | /* GenericEmph */ .chroma .ge { font-style: italic } 56 | /* GenericError */ .chroma .gr { color: #d22323 } 57 | /* GenericHeading */ .chroma .gh { color: #ffffff; font-weight: bold } 58 | /* GenericInserted */ .chroma .gi { color: #589819 } 59 | /* GenericOutput */ .chroma .go { color: #cccccc } 60 | /* GenericPrompt */ .chroma .gp { color: #aaaaaa } 61 | /* GenericStrong */ .chroma .gs { font-weight: bold } 62 | /* GenericSubheading */ .chroma .gu { color: #ffffff } 63 | /* GenericTraceback */ .chroma .gt { color: #d22323 } 64 | /* TextWhitespace */ .chroma .w { color: #666666 } 65 | -------------------------------------------------------------------------------- /static/css/themes/dark.css: -------------------------------------------------------------------------------- 1 | @import url("dark-chroma.css"); 2 | 3 | a { 4 | color: #A1A1EA; 5 | } 6 | 7 | .highlight > * { 8 | border-color: #505050; 9 | } 10 | 11 | :not(pre) > code { 12 | /* inline code elements */ 13 | background-color: rgba(90, 90, 90, 0.25); 14 | } 15 | 16 | a > code { 17 | background-color: rgba(65, 65, 170, 0.3); 18 | } 19 | 20 | .section-list li > * { 21 | background-color: rgba(90, 90, 90, 0.25); 22 | } 23 | 24 | .section-list li > a { 25 | background-color: rgba(65, 65, 170, 0.3); 26 | } 27 | 28 | body { 29 | color: rgb(210, 210, 210); 30 | background-color: rgb(27, 27, 27); 31 | } 32 | 33 | blockquote { 34 | color: rgb(170, 170, 170); 35 | border-left: 0.25em solid #444; 36 | } 37 | 38 | hr { 39 | border: 1px solid rgb(110, 110, 110); 40 | } 41 | 42 | img.color-adapting-image, 43 | figure.color-adapting-image img { 44 | filter: invert(85%) hue-rotate(180deg); 45 | /* hue rotate trick from: https://medium.com/@mwichary/dark-theme-in-a-day-3518dde2955a */ 46 | } 47 | 48 | .header { 49 | background-color: rgb(40, 40, 40); /* still want a background color before the image loads */ 50 | background-image: url(../../images/header-bg-dark.jpg); 51 | } 52 | 53 | .links, .links li { 54 | border-color: #383838; 55 | } 56 | 57 | .main { 58 | background-color: rgb(14, 14, 14); 59 | box-shadow: none; 60 | } 61 | 62 | .footer { 63 | color: rgb(160, 160, 160); 64 | } 65 | 66 | .title-header-date { 67 | color: rgb(150, 150, 150); 68 | } 69 | 70 | .title-list-date { 71 | color: rgb(150, 150, 150); 72 | } 73 | 74 | .table-of-contents { 75 | border-color: #505050; 76 | background-color: #1A1A1A; 77 | } 78 | 79 | .notice { 80 | border-width: 2px; 81 | border-style: solid; 82 | border-top: 0; 83 | } 84 | 85 | .notice .notice-title .notice-title-icon { 86 | filter: invert(80%); 87 | } 88 | 89 | .notice.note { 90 | background-color: #001320; 91 | border-color: #00487B; 92 | } 93 | 94 | .notice.note .notice-title { 95 | background-color: #00487B; 96 | } 97 | 98 | .notice.tip { 99 | background-color: #132000; 100 | border-color: #105600; 101 | } 102 | 103 | .notice.tip .notice-title { 104 | background-color: #105600; 105 | } 106 | 107 | .notice.warning { 108 | background-color: #200000; 109 | border-color: #700000; 110 | } 111 | 112 | .notice.warning .notice-title { 113 | background-color: #700000; 114 | } 115 | 116 | @media only screen and (max-width: 400pt) { 117 | .links { 118 | background-color: rgb(23, 23, 23); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /static/css/themes/light-chroma.css: -------------------------------------------------------------------------------- 1 | /* Background */ .chroma { color: #272822; background-color: #fafafa } 2 | /* Error */ .chroma .err { color: #960050; background-color: #1e0010 } 3 | /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } 4 | /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block; } 5 | /* LineHighlight */ .chroma .hl { display: block; width: 100%;background-color: #e1e1e1 } 6 | /* LineNumbersTable */ .chroma .lnt { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; } 7 | /* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; } 8 | /* Keyword */ .chroma .k { color: #00a8c8 } 9 | /* KeywordConstant */ .chroma .kc { color: #00a8c8 } 10 | /* KeywordDeclaration */ .chroma .kd { color: #00a8c8 } 11 | /* KeywordNamespace */ .chroma .kn { color: #f92672 } 12 | /* KeywordPseudo */ .chroma .kp { color: #00a8c8 } 13 | /* KeywordReserved */ .chroma .kr { color: #00a8c8 } 14 | /* KeywordType */ .chroma .kt { color: #00a8c8 } 15 | /* Name */ .chroma .n { color: #111111 } 16 | /* NameAttribute */ .chroma .na { color: #75af00 } 17 | /* NameBuiltin */ .chroma .nb { color: #111111 } 18 | /* NameBuiltinPseudo */ .chroma .bp { color: #111111 } 19 | /* NameClass */ .chroma .nc { color: #75af00 } 20 | /* NameConstant */ .chroma .no { color: #00a8c8 } 21 | /* NameDecorator */ .chroma .nd { color: #75af00 } 22 | /* NameEntity */ .chroma .ni { color: #111111 } 23 | /* NameException */ .chroma .ne { color: #75af00 } 24 | /* NameFunction */ .chroma .nf { color: #75af00 } 25 | /* NameFunctionMagic */ .chroma .fm { color: #111111 } 26 | /* NameLabel */ .chroma .nl { color: #111111 } 27 | /* NameNamespace */ .chroma .nn { color: #111111 } 28 | /* NameOther */ .chroma .nx { color: #75af00 } 29 | /* NameProperty */ .chroma .py { color: #111111 } 30 | /* NameTag */ .chroma .nt { color: #f92672 } 31 | /* NameVariable */ .chroma .nv { color: #111111 } 32 | /* NameVariableClass */ .chroma .vc { color: #111111 } 33 | /* NameVariableGlobal */ .chroma .vg { color: #111111 } 34 | /* NameVariableInstance */ .chroma .vi { color: #111111 } 35 | /* NameVariableMagic */ .chroma .vm { color: #111111 } 36 | /* Literal */ .chroma .l { color: #ae81ff } 37 | /* LiteralDate */ .chroma .ld { color: #d88200 } 38 | /* LiteralString */ .chroma .s { color: #d88200 } 39 | /* LiteralStringAffix */ .chroma .sa { color: #d88200 } 40 | /* LiteralStringBacktick */ .chroma .sb { color: #d88200 } 41 | /* LiteralStringChar */ .chroma .sc { color: #d88200 } 42 | /* LiteralStringDelimiter */ .chroma .dl { color: #d88200 } 43 | /* LiteralStringDoc */ .chroma .sd { color: #d88200 } 44 | /* LiteralStringDouble */ .chroma .s2 { color: #d88200 } 45 | /* LiteralStringEscape */ .chroma .se { color: #8045ff } 46 | /* LiteralStringHeredoc */ .chroma .sh { color: #d88200 } 47 | /* LiteralStringInterpol */ .chroma .si { color: #d88200 } 48 | /* LiteralStringOther */ .chroma .sx { color: #d88200 } 49 | /* LiteralStringRegex */ .chroma .sr { color: #d88200 } 50 | /* LiteralStringSingle */ .chroma .s1 { color: #d88200 } 51 | /* LiteralStringSymbol */ .chroma .ss { color: #d88200 } 52 | /* LiteralNumber */ .chroma .m { color: #ae81ff } 53 | /* LiteralNumberBin */ .chroma .mb { color: #ae81ff } 54 | /* LiteralNumberFloat */ .chroma .mf { color: #ae81ff } 55 | /* LiteralNumberHex */ .chroma .mh { color: #ae81ff } 56 | /* LiteralNumberInteger */ .chroma .mi { color: #ae81ff } 57 | /* LiteralNumberIntegerLong */ .chroma .il { color: #ae81ff } 58 | /* LiteralNumberOct */ .chroma .mo { color: #ae81ff } 59 | /* Operator */ .chroma .o { color: #f92672 } 60 | /* OperatorWord */ .chroma .ow { color: #f92672 } 61 | /* Punctuation */ .chroma .p { color: #111111 } 62 | /* Comment */ .chroma .c { color: #75715e } 63 | /* CommentHashbang */ .chroma .ch { color: #75715e } 64 | /* CommentMultiline */ .chroma .cm { color: #75715e } 65 | /* CommentSingle */ .chroma .c1 { color: #75715e } 66 | /* CommentSpecial */ .chroma .cs { color: #75715e } 67 | /* CommentPreproc */ .chroma .cp { color: #75715e } 68 | /* CommentPreprocFile */ .chroma .cpf { color: #75715e } 69 | /* GenericEmph */ .chroma .ge { font-style: italic } 70 | /* GenericStrong */ .chroma .gs { font-weight: bold } 71 | -------------------------------------------------------------------------------- /static/css/themes/light.css: -------------------------------------------------------------------------------- 1 | @import url("light-chroma.css"); 2 | 3 | a { 4 | color: #0000A0; 5 | } 6 | 7 | .highlight > * { 8 | border-color: #E0E0E0; 9 | } 10 | 11 | :not(pre) > code { 12 | /* inline code elements */ 13 | background-color: rgba(25, 25, 25, 0.05); 14 | } 15 | 16 | a > code { 17 | background-color: rgba(15, 15, 150, 0.05); 18 | } 19 | 20 | .section-list li > * { 21 | background-color: rgba(25, 25, 25, 0.05); 22 | } 23 | 24 | .section-list li > a { 25 | background-color: rgba(15, 15, 150, 0.05); 26 | } 27 | 28 | body { 29 | color: #232629; 30 | background-color: rgb(247, 247, 247); 31 | } 32 | 33 | blockquote { 34 | color: #404040; 35 | border-left: 0.25em solid #CCC; 36 | } 37 | 38 | hr { 39 | border: 1px solid rgb(185, 185, 185); 40 | } 41 | 42 | .header { 43 | background-image: url(../../images/header-bg-light.jpg); 44 | } 45 | 46 | .links, .links li { 47 | border-color: rgb(211, 211, 211); 48 | } 49 | 50 | .main { 51 | background-color: white; 52 | } 53 | 54 | .footer { 55 | color: #383838; 56 | } 57 | 58 | .table-of-contents { 59 | border-color: #E0E0E0; 60 | background-color: #FAFAFA; 61 | } 62 | 63 | .notice { 64 | color: #404040; 65 | } 66 | 67 | .notice .notice-title { 68 | color: white; 69 | } 70 | 71 | .notice .notice-title .notice-title-icon { 72 | filter: invert(1); 73 | } 74 | 75 | .notice.note { 76 | background-color: #E7F2FA; 77 | } 78 | 79 | .notice.note .notice-title { 80 | background-color: #6AB0DE; 81 | } 82 | 83 | .notice.tip { 84 | background-color: #e6f9e6; 85 | } 86 | 87 | .notice.tip .notice-title { 88 | background-color: #77c577; 89 | } 90 | 91 | .notice.warning { 92 | background-color: #fae2e2; 93 | } 94 | 95 | .notice.warning .notice-title { 96 | background-color: #df6f6c; 97 | } 98 | -------------------------------------------------------------------------------- /static/images/chain-link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 67 | 74 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /static/images/exclamation.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 65 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /static/images/hamburger.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /static/images/header-bg-dark.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenengler/no-js-hugo-theme/6d547d6ddf28bd1327043243cb39834cfe201e7a/static/images/header-bg-dark.jpg -------------------------------------------------------------------------------- /static/images/header-bg-light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenengler/no-js-hugo-theme/6d547d6ddf28bd1327043243cb39834cfe201e7a/static/images/header-bg-light.jpg -------------------------------------------------------------------------------- /static/images/theme-switcher-moon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 29 | 35 | 36 | 44 | 50 | 51 | 52 | 70 | 72 | 73 | 75 | image/svg+xml 76 | 78 | 79 | 80 | 81 | 82 | 87 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /static/images/theme-switcher-sun.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 29 | 35 | 36 | 44 | 50 | 51 | 52 | 70 | 72 | 73 | 75 | image/svg+xml 76 | 78 | 79 | 80 | 81 | 82 | 87 | 93 | 98 | 103 | 108 | 113 | 118 | 123 | 128 | 133 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /static/js/theme-switcher.js: -------------------------------------------------------------------------------- 1 | // license information for librejs extension users 2 | // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt "Expat License (sometimes called MIT Licensed)" 3 | 4 | // in Firefox we need to add a new css style with document.write rather than modifying the href 5 | // of the existing one, otherwise the screen will flash white while loading on dark themes 6 | var theme_css_elem = document.getElementById('theme_css'); 7 | var js_url = document.currentScript.src; // example: http://example.com/myhugo/js/theme-switcher.js 8 | if(localStorage.getItem('theme') === 'dark'){ 9 | var clone = theme_css_elem.cloneNode(false); 10 | clone.href = new URL("../css/themes/dark.css", js_url); 11 | theme_css_elem.remove(); 12 | document.write(clone.outerHTML); 13 | }else if(localStorage.getItem('theme') === 'light'){ 14 | var clone = theme_css_elem.cloneNode(false); 15 | clone.href = new URL("../css/themes/light.css", js_url); 16 | theme_css_elem.remove(); 17 | document.write(clone.outerHTML); 18 | } 19 | 20 | window.addEventListener("load", function(event){update_toggle_button();}, false); 21 | 22 | function update_toggle_button(){ 23 | var elem = document.getElementById('theme_css'); 24 | var button = document.getElementById('change-theme-button'); 25 | button.style.display = ""; 26 | if(elem.href.endsWith('light.css')){ 27 | button.getElementsByTagName('img')[0].src = new URL('../images/theme-switcher-moon.svg', js_url); 28 | }else if(elem.href.endsWith('dark.css')){ 29 | button.getElementsByTagName('img')[0].src = new URL('../images/theme-switcher-sun.svg', js_url); 30 | } 31 | } 32 | 33 | function toggle_theme(){ 34 | var elem = document.getElementById('theme_css'); 35 | if(elem.href.endsWith('light.css')){ 36 | elem.href = new URL("../css/themes/dark.css", js_url); 37 | localStorage.setItem('theme', 'dark'); 38 | }else if(elem.href.endsWith('dark.css')){ 39 | elem.href = new URL("../css/themes/light.css", js_url); 40 | localStorage.setItem('theme', 'light'); 41 | } 42 | update_toggle_button(); 43 | } 44 | 45 | // @license-end 46 | -------------------------------------------------------------------------------- /theme.toml: -------------------------------------------------------------------------------- 1 | name = "No-JS Hugo Theme" 2 | license = "MIT (except for stock photos)" 3 | description = "A minimal and responsive Hugo theme that does not require the client to enable JavaScript." 4 | tags = [] 5 | features = [] 6 | min_version = "0.38" 7 | 8 | [author] 9 | name = "Steven Engler" 10 | --------------------------------------------------------------------------------