├── .gitignore ├── content ├── _index.md ├── 2022-04-27-being-shikamaru-104.md ├── 2022-04-28-being-shikamaru-103.md ├── 2022-05-03-being-shikamaru-101.md └── being-shikamaru-102 │ └── index.md ├── .github └── FUNDING.yml ├── screenshot.png ├── static ├── images │ ├── shikamaru_avatar.webp │ ├── kangae-desktop-dark.webp │ ├── kangae-mobile-dark.webp │ ├── kangae-mobile-light.webp │ └── kangae-desktop-light.webp └── css │ ├── variables-dark-theme.css │ ├── style-external-links.css │ ├── variables-light-theme.css │ └── style.css ├── templates ├── shortcodes │ ├── kaomoji.html │ └── quote.html ├── page.html ├── index.html ├── tags │ ├── list.html │ └── single.html ├── 404.html ├── macros │ ├── article.html │ └── head.html └── base.html ├── netlify.toml ├── theme.toml ├── LICENSE ├── config.toml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | public/ 2 | -------------------------------------------------------------------------------- /content/_index.md: -------------------------------------------------------------------------------- 1 | +++ 2 | sort_by = "date" 3 | +++ 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: ayushnix 2 | ko_fi: ayushnix 3 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayushnix/kangae/HEAD/screenshot.png -------------------------------------------------------------------------------- /static/images/shikamaru_avatar.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayushnix/kangae/HEAD/static/images/shikamaru_avatar.webp -------------------------------------------------------------------------------- /templates/shortcodes/kaomoji.html: -------------------------------------------------------------------------------- 1 | {{ text }} 2 | -------------------------------------------------------------------------------- /static/images/kangae-desktop-dark.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayushnix/kangae/HEAD/static/images/kangae-desktop-dark.webp -------------------------------------------------------------------------------- /static/images/kangae-mobile-dark.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayushnix/kangae/HEAD/static/images/kangae-mobile-dark.webp -------------------------------------------------------------------------------- /static/images/kangae-mobile-light.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayushnix/kangae/HEAD/static/images/kangae-mobile-light.webp -------------------------------------------------------------------------------- /static/images/kangae-desktop-light.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayushnix/kangae/HEAD/static/images/kangae-desktop-light.webp -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # base = "project/" 3 | publish = "public/" 4 | command = "zola build" 5 | 6 | [build.environment] 7 | ZOLA_VERSION = "0.15.3" 8 | 9 | [context.deploy-preview] 10 | command = "zola build --base-url $DEPLOY_PRIME_URL" 11 | -------------------------------------------------------------------------------- /static/css/variables-dark-theme.css: -------------------------------------------------------------------------------- 1 | /* modus vivendi colorscheme */ 2 | 3 | :root { 4 | --fg-color: #e0e6f0; 5 | --bg-color: #323232; 6 | --fg-href: #f2e4c4; 7 | --fg-border: #969696; 8 | --bg-mark: #dfdfb0; 9 | --fg-mark: #100f10; 10 | } 11 | -------------------------------------------------------------------------------- /templates/page.html: -------------------------------------------------------------------------------- 1 | {% import "macros/article.html" as article %} 2 | {%- extends "base.html" -%} 3 | 4 | {%- block main %} 5 |
6 | {{ article::header(page=page) }} 7 | {{ article::content(page=page) }} 8 | {{ article::footer(page=page) }} 9 |
10 | {% endblock -%} 11 | -------------------------------------------------------------------------------- /theme.toml: -------------------------------------------------------------------------------- 1 | name = "kangae" 2 | description = "a lightweight microblog theme for zola" 3 | license = "NCSA" 4 | homepage = "https://github.com/ayushnix/kangae" 5 | demo = "https://kangae.ayushnix.com/" 6 | min_version = "0.15.0" 7 | 8 | [author] 9 | name = "Ayush Agarwal" 10 | homepage = "https://microblog.ayushnix.com" 11 | -------------------------------------------------------------------------------- /static/css/style-external-links.css: -------------------------------------------------------------------------------- 1 | a[href]:not(:where( 2 | [href^="#"], 3 | [href^="/"]:not([href^="//"]), 4 | [href^=".."], 5 | [href*="//ayushnix.com"], 6 | [href*="//microblog.ayushnix.com"], 7 | [href*="//wiki.ayushnix.com"], 8 | ))::after { 9 | font-size: var(--step-s1); 10 | content: " ↗"; 11 | vertical-align: middle; 12 | } 13 | -------------------------------------------------------------------------------- /content/2022-04-27-being-shikamaru-104.md: -------------------------------------------------------------------------------- 1 | +++ 2 | title = "Being Shikamaru 104" 3 | [taxonomies] 4 | tags = [ "tag2" ] 5 | +++ 6 | 7 | You will eventually be the one treating others to ramen… and you'll be called Naruto-sensei, or 8 | something. We can't stay brats forever. If we want to become super cool ninja like Asuma and Lord 9 | Jiraiya, that is. 10 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | {% import "macros/article.html" as article %} 2 | {% extends "base.html" -%} 3 | 4 | {%- block main %} 5 | {%- for post in section.pages %} 6 |
7 | {{ article::header(page=post) }} 8 | {{ article::content(page=post) }} 9 | {{ article::footer(page=post) }} 10 |
11 | {% endfor -%} 12 | {% endblock -%} 13 | -------------------------------------------------------------------------------- /static/css/variables-light-theme.css: -------------------------------------------------------------------------------- 1 | /* modus operandi colorscheme */ 2 | 3 | :root { 4 | --fg-color: #282828; 5 | --bg-color: #f8f8f8; 6 | --fg-href: #0000c0; 7 | /* deliberaty choose a color with a lesser contrast */ 8 | /* APCA contrast value of 83.77 against bg-color */ 9 | --fg-border: #505050; 10 | --bg-mark: #f9ff00; 11 | --fg-mark: #282828; 12 | } 13 | -------------------------------------------------------------------------------- /content/2022-04-28-being-shikamaru-103.md: -------------------------------------------------------------------------------- 1 | +++ 2 | +++ 3 | 4 | Laziness is the mother of all bad habits, but ultimately she is a mother and we should respect her. 5 | 6 | In fact, I've respected her right now by omitting both the title and the date in the markdown file 7 | for this post. 8 | 9 | *but ... but ... that's not right* 10 | 11 | Oh, stop complaining, Zola will pick up the date from the filename. 12 | 13 | *The title?* 14 | 15 | Well, let's just forget about it. 16 | 17 | *If you won't specify the title, the `discuss on github` link won't be shown* 18 | 19 | Meh, who cares about that anyways. 20 | 21 | *What about the tags?* 22 | 23 | Yeah, let's skip those as well. What a drag ... {{ kaomoji(label="shrug kaomoji", text="╮( ˘_˘ )╭") }} 24 | -------------------------------------------------------------------------------- /templates/tags/list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {%- block total_posts %} 4 | {%- if terms and terms | length == 1 %} 5 |
  • {{ terms | length }} tag and counting ...
  • 6 | {%- elif terms and terms | length > 1 %} 7 |
  • {{ terms | length }} tags and counting ...
  • 8 | {% endif -%} 9 | {% endblock -%} 10 | 11 | {%- block main %} 12 | 19 | {% endblock -%} 20 | -------------------------------------------------------------------------------- /templates/404.html: -------------------------------------------------------------------------------- 1 | {% import "macros/head.html" as head -%} 2 | {% extends "base.html" %} 3 | 4 | {%- block opengraph_basic_meta %} 5 | {% endblock -%} 6 | 7 | {%- block opengraph_optional_meta %} 8 | {% endblock -%} 9 | 10 | {%- block base_canonical %} 11 | 12 | {% endblock -%} 13 | 14 | {%- block ogtitle %} 15 | {{ head::ogtitle(tl="404") }} 16 | {% endblock -%} 17 | 18 | {%- block title %} 19 | {{ head::head_title(tl="404") }} 20 | {% endblock -%} 21 | 22 | {%- block main %} 23 |
    24 | 25 |

    You're looking for something that doesn't exist

    26 |
    27 | {% endblock -%} 28 | -------------------------------------------------------------------------------- /templates/shortcodes/quote.html: -------------------------------------------------------------------------------- 1 | {%- if citation and author %} 2 |
    3 | 4 |

    {{ body }}

    5 |
    6 |

    — {{ author }}

    7 | 8 |
    {{ citation }}
    9 |
    10 | {%- elif citation %} 11 |
    12 | 13 |

    {{ body }}

    14 | 15 |
    {{ citation }}
    16 |
    17 | {%- elif author %} 18 | 19 |

    {{ body }}

    20 |
    21 |

    — {{ author }}

    22 | 23 | {% endif -%} 24 | -------------------------------------------------------------------------------- /templates/tags/single.html: -------------------------------------------------------------------------------- 1 | {% import "macros/article.html" as article %} 2 | {%- extends "base.html" -%} 3 | 4 | {%- block total_posts %} 5 | {%- if term and term.pages and term.pages | length == 1 %} 6 |
  • {{ term.name }} - {{ term.pages | length }} post and counting ...
  • 7 | {%- elif term and term.pages and term.pages | length > 1 %} 8 |
  • {{ term.name }} - {{ term.pages | length }} posts and counting ...
  • 9 | {% endif -%} 10 | {% endblock -%} 11 | 12 | {%- block main %} 13 | {%- for post in term.pages %} 14 |
    15 | {{ article::header(page=post) }} 16 | {{ article::content(page=post) }} 17 | {{ article::footer(page=post) }} 18 |
    19 | {% endfor -%} 20 | {% endblock -%} 21 | -------------------------------------------------------------------------------- /content/2022-05-03-being-shikamaru-101.md: -------------------------------------------------------------------------------- 1 | +++ 2 | title = "Being Shikamaru 101" 3 | [taxonomies] 4 | tags = [ "tag1" ] 5 | +++ 6 | 7 | I never really liked Sasuke, but all the same, he's a member of Konoha; he's a comrade and I'll put 8 | my life on the line to help him, that's the way of our village. I know I usually seem like a pretty 9 | lazy guy but not today, because now I'm responsible for your lives too. 10 | 11 | How many times do I have to tell you? The first move is always a feint. It's the most basic thing to 12 | land a hit with the second move. 13 | 14 | ```css,linenos 15 | html { 16 | box-sizing: border-box; 17 | } 18 | ``` 19 | 20 | > Oh, man … those clouds are so lucky … so free … More to the point, I didn't feel like doing this 21 | in the first place … And I only became a ninja because I thought life would've been more interesting 22 | as one … I suppose things aren't gonna be that simple. 23 | 24 | See, you and I have different beliefs. I believe in the `Will of Fire`. That pathetic Lord Jashin or 25 | whatever isn't your God any more. I am. The only one bringing down vengeance is me. Let 26 | me just go ahead and press ALT+F4 to erase your existence once and forever by trapping 27 | you in this forest which overlooked by deers that are allied to me and my clan. 28 | 29 | Here's a sample list 30 | 31 | - shogi 32 | - asuma 33 | - choji 34 | - ino 35 | 36 | Here's another sample list 37 | 38 | 1. shogi 39 | 2. asuma 40 | 3. choji 41 | 4. ino 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | University of Illinois/NCSA Open Source License 2 | 3 | Copyright (c) 2022 Ayush Agarwal . All rights reserved. 4 | 5 | Developed by: Ayush Agarwal 6 | https://git.sr.ht/~ayushnix/kangae 7 | 8 | Permission is hereby granted, free of charge, to any person 9 | obtaining a copy of this software and associated documentation files 10 | (the "Software"), to deal with the Software without restriction, 11 | including without limitation the rights to use, copy, modify, merge, 12 | publish, distribute, sublicense, and/or sell copies of the Software, 13 | and to permit persons to whom the Software is furnished to do so, 14 | subject to the following conditions: 15 | 16 | * Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimers. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimers in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the names of Ayush Agarwal nor the names of its contributors 24 | may be used to endorse or promote products derived from this 25 | Software without specific prior written permission. 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 28 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 30 | CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 31 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH 33 | THE SOFTWARE. 34 | -------------------------------------------------------------------------------- /content/being-shikamaru-102/index.md: -------------------------------------------------------------------------------- 1 | +++ 2 | title = "Being Shikamaru 102" 3 | date = 2022-04-29 4 | [taxonomies] 5 | tags = [ "tag2" ] 6 | +++ 7 | 8 | Ughh. Great. What's the point in setting the alarm if I'm going to wake up before it goes off? What 9 | a total waste. Now I've gotta shut it off but I don't feel like moving. But if I don't shut it off 10 | it will just keep ringing and ringing. It makes me tired just thinking about the whole thing. Some 11 | mornings are such a drag … 12 | 13 | Here's a code block without a language identifier or line numbers 14 | 15 | ``` 16 | # nihilism in a nutshell 17 | cat /dev/urandom > /dev/null 18 | ``` 19 | 20 | Here's a wise quote using a custom shortcode without any citations or the name of the author 21 | 22 | {% quote(author="Nara Shikamaru") %} 23 | You would think just this once, when it was life or death, I could pull through. 24 | {% end %} 25 | 26 | Here's a wise quote with a citation but without an author 27 | 28 | {% quote(citation="Shingeki no Kyojin, Volume 24, Chapter 97") %} 29 | Every day I'm here, I think: Why did it ever come to this? Damaged minds and bodies ... their freedom taken away ... even losing themselves. If people knew it would come to this, nobody would go to war. But most people are pushed by something, forced to march into hell. That "something" wasn't their choice. Their situation or others made them do it. But people who push their own backs see a different kind of hell. They can see something beyond the hell. It might be hope. It may even be another hell. Only those who keep moving forward will ever know. 30 | {% end %} 31 | 32 | Here's a wise quote with a citation and the name of the author 33 | 34 | {% quote(citation="Mass Effect 3", author="Javik") %} 35 | Stand in the ashes of a trillion dead souls, and ask the ghosts if honor matters. The silence is your answer. 36 | {% end %} 37 | 38 | And that's all folks! 39 | -------------------------------------------------------------------------------- /templates/macros/article.html: -------------------------------------------------------------------------------- 1 | {% macro header(page) %} 2 |
    3 |

    4 | {%- if page.date %} 5 | 6 | {% endif -%} 7 | {%- if page.title %} 8 | {{ page.title }} 9 | {% endif -%} 10 |

    11 | {%- if page.taxonomies and page.taxonomies.tags %} 12 |
      13 | {%- for tag in page.taxonomies.tags %} 14 |
    • {{ tag }}
    • 15 | {% endfor -%} 16 |
    17 | {% endif -%} 18 |
    19 | {% endmacro %} 20 | 21 | {% macro content(page) %} 22 | {{ page.content | safe }} 23 | {% endmacro %} 24 | 25 | {% macro footer(page) %} 26 | {%- if config.extra.post_footer %} 27 | {%- set foot = config.extra.post_footer -%} 28 |
    29 |
      30 | {%- if foot.share %} 31 |
    • share
    • 32 | {% endif -%} 33 | {%- if foot.discuss_github and foot.github_url and page.title %} 34 | {%- set discuss = "/discussions/new?category=general&title=" -%} 35 |
    • 36 | discuss on github 37 |
    • 38 | {% endif -%} 39 | {%- if foot.misc %} 40 | {%- for link in foot.misc %} 41 | {%- if link.url and link.url is starting_with("https://") and link.url is not starting_with(config.base_url) %} 42 | {%- set link_url = true %} 43 | {% endif -%} 44 |
    • {{ link.name }}
    • 45 | {% endfor -%} 46 | {% endif -%} 47 |
    48 |
    49 | {% endif -%} 50 | {% endmacro %} 51 | -------------------------------------------------------------------------------- /config.toml: -------------------------------------------------------------------------------- 1 | # please refer to 2 | # https://www.getzola.org/documentation/getting-started/configuration/ 3 | # for the complete configuration file 4 | 5 | # [MANDATORY] the URL of the microblog 6 | base_url = "https://kangae.ayushnix.com" 7 | 8 | # [recommended] kangae doesn't use sass for its global stylesheet 9 | compile_sass = false 10 | 11 | # enable this when using kangae as a theme 12 | # theme = "kangae" 13 | 14 | # [optional] minify HTML to save space at the cost of readability 15 | minify_html = false 16 | 17 | # [recommended] generate an atom or rss feed 18 | generate_feed = true 19 | 20 | # [recommended] the name of the feed 21 | # if it's set to 'rss.xml', an RSS feed will be generated 22 | feed_filename = "atom.xml" 23 | 24 | # [recommended] the title of the website 25 | title = "shikamaru microblog" 26 | 27 | # [recommended] the description of the website 28 | description = "the personal microblog of shikamaru" 29 | 30 | # [recommended] the default language of the website 31 | default_language = "en" 32 | 33 | # [recommended] the different kinds of taxonomies for the website 34 | taxonomies = [ 35 | { name = "tags", feed = true } 36 | ] 37 | 38 | # ---------------------------------------------------------------------------- # 39 | 40 | # configuration for how the markdown blog posts are rendered 41 | [markdown] 42 | 43 | # [optional] enable syntax highlighting for source code 44 | # syntax highlight, in itself isn't sufficient and if enabled, it needs to 45 | # support both light and dark modes which will add an overhead of approximately 46 | # 6kb of unminified CSS. you can decide if it's worth it or not 47 | highlight_code = false 48 | 49 | # [optional] convert text emoji, such as :smile:,to the actual iconic emoji 50 | render_emoji = true 51 | 52 | # [optional] open external links in a new tab and add `rel="noopener"` 53 | external_links_target_blank = true 54 | 55 | # [optional] tell search engines not to follow external links 56 | external_links_no_follow = false 57 | 58 | # [optional] add `rel=noreferrer` for privacy 59 | external_links_no_referrer = true 60 | 61 | # [optional] change "quote" to “curly” and other style changes 62 | smart_punctuation = false 63 | 64 | # ---------------------------------------------------------------------------- # 65 | 66 | [extra] 67 | # [recommended] your name 68 | author = "Nara Shikamaru" 69 | 70 | # [recommended] your internet username 71 | username = "shikamaru" 72 | 73 | # [optional] your 128x128 avatar, preferably svg 74 | avatar = "images/shikamaru_avatar.webp" 75 | 76 | # [optional] the keywords which highlight the type of content on your microblog 77 | keywords = [ "microblog", "linux", "devops", "openbsd" ] 78 | 79 | # [optional] add custom css 80 | # custom_css = "css/custom.css" 81 | 82 | # [optional] add a web app manifest 83 | # manifest = "/site.webmanifest" 84 | 85 | # [optional] additional links that should be present in the navbar 86 | # `name` and `url` should be present for visibility, `rel` is optional 87 | navbar = [ 88 | { name = "mastodon", url = "https://social.treehouse.systems/@ayushnix", rel="me" }, 89 | { name = "github", url = "https://github.com/ayushnix/kangae", rel="me" } 90 | ] 91 | 92 | # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name/theme-color 93 | # [optional] the light color for the user interface of the web browser 94 | # the default value is written below 95 | # light_theme_color = "#f0f0f0" 96 | 97 | # [optional] the dark color for the user interface of the web browser 98 | # the default value is written below 99 | # dark_theme_color = "#282c34" 100 | 101 | [extra.content_license] 102 | # [recommended] the spdx identifier of the license of content on your microblog 103 | spdx = "CC-BY-NC-ND-4.0" 104 | 105 | # [recommended] the url of the license 106 | url = "https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode.txt" 107 | 108 | [extra.source_license] 109 | # [recommended] the spdx identifier for the license of source code on your microblog 110 | spdx = "0BSD" 111 | 112 | # [recommended] the url of the license 113 | url = "https://spdx.org/licenses/0BSD.html" 114 | 115 | # [recommended] the url of the source code of the microblog itself 116 | src_url = "https://github.com/ayushnix/kangae" 117 | 118 | [extra.opengraph] 119 | # [optional] opengraph image that should be visible when sharing links on social media 120 | # websites and messaging apps 121 | # img = "/images/apple-touch-icon.png" 122 | 123 | # [optional] specifying the alt text is recommended if opengraph img is enabled 124 | # alt = "opengraph image description" 125 | 126 | [extra.favicon] 127 | 128 | # [recommended] a SVG favicon 129 | # svg = "/images/favicon.svg" 130 | 131 | # [recommended] generate a 32px PNG favicon from the SVG 132 | # png = "/images/favicon-32x32.png" 133 | 134 | # [recommended] generate either a 180px or a 192px PNG image 135 | # 180px - if you want to use the size recommended by apple 136 | # 192px - if you want to use a single 192px image both for apple devices and for 137 | # the android web app manifest; the image will be automatically resized to 180px 138 | # for apple devices 139 | # apple = "/images/apple-touch-icon.png" 140 | 141 | [extra.post_footer] 142 | 143 | # [recommended] show a permalink to microblog posts 144 | share = true 145 | 146 | # [optional] show a link which redirects to github discussions for writing comments 147 | # in the example provided below, the URL will be 148 | # https://github.com/ayushnix/kangae/discussions/new?category=general&title=The+Post+Title 149 | discuss_github = true 150 | github_url = "https://github.com/ayushnix/kangae" 151 | 152 | # [optional] other misc urls that should be shown in the post footers 153 | # both `name` and `url` should be defined for visibility 154 | # misc = [ 155 | # { name = "misc", url = "https://misc.xyz" } 156 | # ] 157 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kangae (考え, idea or thought) 2 | 3 | [kangae][1] is a lightweight microblog theme for [zola][2]. 4 | 5 |
    6 | kangae screenshots on desktop and mobile 7 | 8 | ![kangae screenshot light mode on desktop](static/images/kangae-desktop-light.webp) 9 | ![kangae screenshot dark mode on desktop](static/images/kangae-desktop-dark.webp) 10 | ![kangae screenshot light mode on mobile](static/images/kangae-mobile-light.webp) 11 | ![kangae screenshot dark mode on mobile](static/images/kangae-mobile-dark.webp) 12 |
    13 | 14 | I've created kangae from scratch and it is not based on any other theme. However, I was inspired to 15 | create kangae after I came across [Wolfgang Müller's microblog][3]. Thanks Wolf! 16 | 17 | kangae is licensed under the [NCSA license][5], which is quite similar to the BSD-3-Clause license. 18 | Unlike BSD-3-Clause, NCSA also covers documentation of a project. 19 | 20 | # Showcase 21 | 22 | Here's a list of websites using the kangae theme 23 | 24 | - [ayushnix microblog][4] 25 | 26 | If you want to mention your website in this section, please raise a pull request. 27 | 28 | # Installation 29 | 30 | Before using this theme, [install zola][6]. After you've installed zola, 31 | 32 | ``` 33 | $ zola init microblog 34 | > What is the URL of your site? (https://example.com): 35 | > Do you want to enable Sass compilation? [Y/n]: 36 | > Do you want to enable syntax highlighting? [y/N]: 37 | > Do you want to build a search index of the content? [y/N]: 38 | $ cd microblog/ 39 | ``` 40 | 41 | kangae doesn't use Sass or syntax highlighting so if you don't want to use custom Sass code or 42 | enable syntax highlighting, answer the 2nd and 3rd question with a 'no'. kangae also doesn't use any 43 | JavaScript library to search content. If you don't intend to install a JavaScript library to enable 44 | search on your microblog, answer 'no' to the last question as well. 45 | 46 | If you intend to publish your microblog on a forge like GitHub, initialize an empty git repository 47 | using 48 | 49 | ``` 50 | $ git init 51 | $ git commit --allow-empty -m 'initial empty root commit' 52 | ``` 53 | 54 | If you don't want to make an empty commit, add and commit a README or a LICENSE file instead. 55 | 56 | At this point, you can install kangae using one of the following methods 57 | 58 | ## using `git subtree` 59 | 60 | ``` 61 | $ git subtree add -P themes/kangae/ --squash https://github.com/ayushnix/kangae.git master 62 | ``` 63 | 64 | ## using `git submodule` 65 | 66 | ``` 67 | $ git submodule add https://github.com/ayushnix/kangae.git themes/kangae 68 | ``` 69 | 70 | ## download kangae in themes directory 71 | 72 | If you want to keep things simple and figure out version control later, you can 73 | 74 | ``` 75 | $ git clone https://github.com/ayushnix/kangae.git themes/kangae 76 | ``` 77 | 78 | # Configuration 79 | 80 | To begin using kangae after installing it, 81 | 82 | ``` 83 | $ cp themes/kangae/config.toml ./ 84 | $ sed -i 's;# theme =\(.*\);theme =\1;' config.toml 85 | ``` 86 | 87 | The [`config.toml`][7] file of kangae has been documented carefully using TOML comments. If you have 88 | any questions about configuring kangae which haven't been answered in the `config.toml` file itself, 89 | please [raise an issue][8]. 90 | 91 | ## Shortcodes 92 | 93 | kangae provides several shortcodes that can be used to add content in an accessible manner 94 | 95 | ### kaomoji `(・_・)ノ` 96 | 97 | If you want to use kaomoji in your posts, you can use insert them in an accessbile manner using 98 | 99 | ``` 100 | I don't know. {{ kaomoji(label="shrug kaomoji", text="╮( ˘_˘ )╭") }} I've never thought about it. 101 | ``` 102 | 103 | Providing a value for the `label` is optional but highly recommended. A short text should be 104 | mentioned that explains what the kaomoji means to convey. The value of `text` should be the actual 105 | emoticon itself. 106 | 107 | This shortcode can also be used for any other ASCII emoticon that can fit in an inline paragraph. 108 | This includes western emoticons such as `;)` and combination emoticons such as `<(^_^<)`. 109 | 110 | ### Quotes 111 | 112 | You can add quotes in your microblog posts using 113 | 114 | ``` 115 | {% quote(author="Nara Shikamaru") %} 116 | You would think just this once, when it was life or death, I could pull through. 117 | {% end %} 118 | ``` 119 | 120 | This is the most basic form of improvement in writing quotes over simply using `>` in markdown. 121 | 122 | If you want to mention the name of the source from where the quote has been taken, such as the name 123 | of the book or a movie, you can use 124 | 125 | ``` 126 | {% quote(citation="Mass Effect 3", author="Javik") %} 127 | Stand in the ashes of a trillion dead souls, and ask the ghosts if honor matters. The silence is your answer. 128 | {% end %} 129 | ``` 130 | 131 | A `citeurl` can also be given as an argument to this shortcode to provide the actual URL from where 132 | the source is borrowed. 133 | 134 | ``` 135 | {% quote(author="Edward Snowden", citeurl="https://old.reddit.com/r/IAmA/comments/36ru89/just_days_left_to_kill_mass_surveillance_under/crglgh2/") %} 136 | Arguing that you don't care about the right to privacy because you have nothing to hide is no different than saying you don't care about free speech because you have nothing to say. 137 | {% end %} 138 | ``` 139 | 140 | A live preview of these how these shortcodes look like can be found on [this blog post][14]. 141 | 142 | ## Optional Features 143 | 144 | kangae includes some optional features that aren't enabled by default 145 | 146 | - [style external links using a ↗ unicode symbol][11] 147 | 148 | # Donate 149 | 150 | If you found kangae helpful in creating your own microblog website, please consider supporting me by 151 | buying me a coffee :coffee: 152 | 153 | buy ayushnix a coffee at buymeacoffee.com 154 | buy ayusnix a coffee at ko-fi.com 155 | 156 | If you're in India, you can also use UPI for donations. My UPI address is `ayushnix@ybl`. 157 | 158 | # Notes 159 | 160 | Although I'm not a web developer, I am interested in learning HTML and CSS to create lightweight 161 | textual websites. You may be interested in reading [my log about how I learned HTML and CSS][12]. 162 | However, that page is just an unorganized dump of my thoughts and isn't a polished blog post. 163 | [Seirdy's blog post on creating textual websites][13] is probably a better reference. 164 | 165 | # TODO (maybe?) 166 | 167 | - (responsive) image shortcodes 168 | - run prettier on HTML and CSS before deployment 169 | - twitter and mastodon shortcodes 170 | - add optional support for cross posting and commenting on mastodon without using JS 171 | - add optional support for [giscus][9] and [loading mastodon comments][10] 172 | - add shortcode for asciinema 173 | - add shortcode for blockquote and citation 174 | - pagination 175 | - light and dark mode switch 176 | - content tabs 177 | - microdata and microformats2 178 | 179 | [1]: https://kangae.ayushnix.com/ 180 | [2]: https://www.getzola.org/ 181 | [3]: https://zunzuncito.oriole.systems/ 182 | [4]: https://microblog.ayushnix.com 183 | [5]: LICENSE 184 | [6]: https://www.getzola.org/documentation/getting-started/installation/ 185 | [7]: config.toml 186 | [8]: https://github.com/ayushnix/kangae/issues/new 187 | [9]: https://giscus.app/ 188 | [10]: https://carlschwan.eu/2020/12/29/adding-comments-to-your-static-blog-with-mastodon/ 189 | [11]: https://github.com/ayushnix/kangae/blob/master/static/css/style-external-links.css 190 | [12]: https://wiki.ayushnix.com/frontend/creating-a-website/ 191 | [13]: https://seirdy.one/2020/11/23/website-best-practices.html 192 | [14]: https://kangae.ayushnix.com/being-shikamaru-102/ 193 | -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | {%- import "macros/head.html" as head -%} 2 | 3 | 4 | 5 | 6 | {%- block basic_meta -%} 7 | {{ head::basic_meta() }} 8 | {%- endblock -%} 9 | 10 | {%- block color_meta -%} 11 | {{ head::color_meta() }} 12 | {%- endblock %} 13 | 14 | {%- block ogtitle -%} 15 | {{ head::ogtitle(tl="") }} 16 | {%- endblock -%} 17 | 18 | {%- block opengraph_basic_meta -%} 19 | {{ head::opengraph_basic_meta() }} 20 | {%- endblock -%} 21 | 22 | {%- block opengraph_optional_meta -%} 23 | {{ head::opengraph_optional_meta() }} 24 | {%- endblock -%} 25 | 26 | {%- block favicon -%} 27 | {{ head::favicon() }} 28 | {%- endblock -%} 29 | 30 | {%- block manifest -%} 31 | {{ head::manifest() }} 32 | {%- endblock -%} 33 | 34 | {%- block feed -%} 35 | {{ head::feed() }} 36 | {%- endblock -%} 37 | 38 | {%- block style -%} 39 | {{ head::style() }} 40 | {%- endblock -%} 41 | 42 | {%- block base_canonical -%} 43 | {{ head::base_canonical() }} 44 | {%- endblock -%} 45 | 46 | {%- block title -%} 47 | {{ head::head_title(tl="") }} 48 | {%- endblock -%} 49 | 50 | 51 |
    52 | {%- if config.extra.avatar %} 53 | 54 | 55 | {%- set meta = get_image_metadata(path=config.extra.avatar) -%} 56 | 57 | 58 | the avatar image of {{ config.extra.author }} 59 | 60 | 61 | {% endif -%} 62 |
      63 | {%- block primary_header %} 64 | {%- if config.extra.author %} 65 |
    • {{ config.extra.author }}

    • 66 | {% endif -%} 67 | {%- if config.extra.username %} 68 |
    • @{{ config.extra.username }}
    • 69 | {% endif -%} 70 | {%- block header_description %} 71 | {%- if config.description %} 72 |
    • {{ config.description }}
    • 73 | {% endif -%} 74 | {% endblock -%} 75 | {%- block total_posts %} 76 | {%- if section.pages and section.pages | length == 1 %} 77 |
    • {{ section.pages | length }} post and counting ...
    • 78 | {%- elif section.pages and section.pages | length > 1 %} 79 |
    • {{ section.pages | length }} posts and counting ...
    • 80 | {% endif -%} 81 | {% endblock -%} 82 | {% endblock -%} 83 |
    84 | {%- block extra_site_header %} 85 | {% endblock -%} 86 |
    87 | 124 |
    125 | {%- block main %} 126 | {% endblock -%} 127 |
    128 |
    129 |
      130 | {%- block site_footer %} 131 | {%- if config.extra.author %} 132 |
    • © 133 | {{ config.extra.author }} 136 |
    • 137 | {% endif -%} 138 | {%- set cl = config.extra.content_license -%} 139 | {%- set sl = config.extra.source_license -%} 140 | {%- if cl.spdx and cl.url %} 141 | {%- if cl.url is starting_with("https://") and cl.url is not starting_with(config.base_url) %} 142 | {%- set newtab_license = true %} 143 | {% endif -%} 144 |
    • 145 | Content {{ cl.spdx }} 146 |
    • 147 | {% endif -%} 148 | {%- if sl.src_url and sl.src_url is starting_with("https://") and sl.src_url is not starting_with(config.base_url) %} 149 | {%- set newtab_srcurl = true %} 150 | {% endif -%} 151 | {%- if sl.url and sl.url is starting_with("https://") and sl.url is not starting_with(config.base_url) %} 152 | {%- set newtab_srclicense = true %} 153 | {% endif -%} 154 | {%- if sl.spdx and sl.url and sl.src_url %} 155 |
    • 156 | Source Code 157 | {{ sl.spdx }} 158 |
    • 159 | {%- elif sl.spdx and sl.url %} 160 |
    • 161 | Source Code {{ sl.spdx }} 162 |
    • 163 | {% endif -%} 164 | {% endblock -%} 165 |
    166 | {%- block extra_site_footer %} 167 | {% endblock -%} 168 |
    169 | 170 | 171 | -------------------------------------------------------------------------------- /templates/macros/head.html: -------------------------------------------------------------------------------- 1 | {% macro keywords() %} 2 | {%- for word in config.extra.keywords -%} 3 | {%- if loop.last -%} 4 | {{ word }} 5 | {%- else -%} 6 | {{ word }}, 7 | {%- endif -%} 8 | {%- endfor -%} 9 | {% endmacro %} 10 | 11 | {% macro basic_meta() %} 12 | 13 | 14 | {%- if config.description %} 15 | {%- if page.content %} 16 | 17 | {%- else %} 18 | 19 | {%- endif -%} 20 | {% endif -%} 21 | {%- if config.extra.keywords %} 22 | 23 | {%- endif -%} 24 | {% endmacro %} 25 | 26 | {% macro color_meta() %} 27 | 28 | {%- if config.extra.light_theme_color %} 29 | 30 | {%- else %} 31 | 32 | {%- endif -%} 33 | {%- if config.extra.dark_theme_color %} 34 | 35 | {%- else %} 36 | 37 | {% endif -%} 38 | {% endmacro %} 39 | 40 | {% macro opengraph_basic_meta() %} 41 | 42 | 43 | {%- if config.extra.opengraph.img %} 44 | 45 | {% endif -%} 46 | {% endmacro %} 47 | 48 | {% macro opengraph_optional_meta() %} 49 | {%- if config.title %} 50 | 51 | {% endif -%} 52 | {%- if config.description %} 53 | {%- if page.content %} 54 | 55 | {%- else %} 56 | 57 | {% endif -%} 58 | {% endif -%} 59 | {# https://github.com/getzola/zola/issues/1161 #} 60 | {%- if config.extra.opengraph.img %} 61 | {% set ogimgmeta = get_image_metadata(path=config.extra.opengraph.img) %} 62 | 63 | 64 | 65 | {%- if config.extra.opengraph.alt %} 66 | 67 | {% endif -%} 68 | {% endif -%} 69 | {% endmacro %} 70 | 71 | {% macro favicon() %} 72 | {%- if config.extra.favicon.png %} 73 | 74 | {% endif -%} 75 | {%- if config.extra.favicon.svg %} 76 | 77 | {% endif -%} 78 | {%- if config.extra.favicon.apple %} 79 | 80 | {% endif -%} 81 | {% endmacro %} 82 | 83 | {% macro manifest() %} 84 | {%- if config.extra.manifest %} 85 | 86 | {% endif -%} 87 | {% endmacro %} 88 | 89 | {# can't think of a way to determine if the custom feed is atom or rss #} 90 | {# in this case, I'll assume that the custom feed is an atom feed #} 91 | {# feel free to raise a PR if you know how to fix this #} 92 | {% macro feed() %} 93 | {%- if config.title %} 94 | {%- for tax in config.taxonomies %} 95 | {%- if term.name and tax.feed and config.feed_filename == "atom.xml" %} 96 | {%- set atom_path = term.path ~ config.feed_filename -%} 97 | 98 | {%- elif term.name and tax.feed and config.feed_filename == "rss.xml" %} 99 | {%- set rss_path = term.path ~ config.feed_filename -%} 100 | 101 | {%- elif term.name and tax.feed and config.feed_filename %} 102 | {% set feed_path = term.path ~ config.feed_filename %} 103 | 104 | {%- elif config.generate_feed and config.feed_filename == "rss.xml" %} 105 | 106 | {%- elif config.generate_feed and config.feed_filename == "atom.xml" %} 107 | 108 | {%- elif config.generate_feed and config.feed_filename %} 109 | 110 | {% endif -%} 111 | {% endfor -%} 112 | {% else %} 113 | {%- for tax in config.taxonomies %} 114 | {%- if term.name and tax.feed and config.feed_filename == "atom.xml" %} 115 | {%- set atom_path = term.path ~ config.feed_filename -%} 116 | 117 | {%- elif term.name and tax.feed and config.feed_filename == "rss.xml" %} 118 | {%- set rss_path = term.path ~ config.feed_filename -%} 119 | 120 | {%- elif term.name and tax.feed and config.feed_filename %} 121 | {%- set feed_path = term.path ~ config.feed_filename -%} 122 | 123 | {%- elif config.generate_feed and config.feed_filename == "rss.xml" %} 124 | 125 | {%- elif config.generate_feed and config.feed_filename == "atom.xml" %} 126 | 127 | {%- elif config.generate_feed and config.feed_filename %} 128 | 129 | {% endif -%} 130 | {% endfor -%} 131 | {% endif -%} 132 | {% endmacro %} 133 | 134 | {% macro style() %} 135 | 136 | {%- if config.extra.custom_css %} 137 | 138 | {% endif -%} 139 | {% endmacro %} 140 | 141 | {% macro base_canonical() %} 142 | 143 | 144 | {% endmacro %} 145 | 146 | {% macro title() %} 147 | {%- if page.title and config.extra.username %} 148 | {{ page.title }} by {{ config.extra.username }} 149 | {%- elif page.title and config.extra.author %} 150 | {{ page.title }} by {{ config.extra.author }} 151 | {%- elif page.title %} 152 | {{ page.title }} 153 | {%- elif config.title %} 154 | {{ config.title }} 155 | {%- else %} 156 | microblog 157 | {% endif -%} 158 | {% endmacro %} 159 | 160 | {% macro ogtitle(tl) %} 161 | {%- if tl %} 162 | 163 | {%- else %} 164 | 165 | {% endif -%} 166 | {% endmacro %} 167 | 168 | {% macro head_title(tl) %} 169 | {%- if tl %} 170 | {{ tl }} 171 | {%- else %} 172 | {{ self::title() }} 173 | {% endif -%} 174 | {% endmacro %} 175 | -------------------------------------------------------------------------------- /static/css/style.css: -------------------------------------------------------------------------------- 1 | /*@import url("variables-light-theme.css") (prefers-color-scheme: light);*/ 2 | /*@import url("variables-dark-theme.css") (prefers-color-scheme: dark);*/ 3 | :root { 4 | --fg-color: #e0e6f0; 5 | --bg-color: #323232; 6 | --fg-href: #f2e4c4; 7 | --fg-border: #969696; 8 | --bg-mark: #dfdfb0; 9 | --fg-mark: #100f10; 10 | } 11 | 12 | @media (prefers-color-scheme: light) { 13 | :root { 14 | --fg-color: #282828; 15 | --bg-color: #f8f8f8; 16 | --fg-href: #0000c0; 17 | /* deliberaty choose a color with a lesser contrast */ 18 | /* APCA contrast value of 83.77 against bg-color */ 19 | --fg-border: #505050; 20 | --bg-mark: #f9ff00; 21 | --fg-mark: #282828; 22 | } 23 | } 24 | 25 | :root { 26 | --sans-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji"; 27 | --mono-font: ui-monospace, "Cascadia Mono", Consolas, "SF Mono", Inconsolata, monospace; 28 | 29 | /* @link https://utopia.fyi/type/calculator?c=320,14,1.125,1280,18,1.25,4,5,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l */ 30 | --step-s5: clamp(0.37rem, calc(0.52rem + -0.19vw), 0.49rem); 31 | --step-s4: clamp(0.46rem, calc(0.57rem + -0.14vw), 0.55rem); 32 | --step-s3: clamp(0.58rem, calc(0.63rem + -0.06vw), 0.61rem); 33 | --step-s2: clamp(0.69rem, calc(0.68rem + 0.05vw), 0.72rem); 34 | --step-s1: clamp(0.78rem, calc(0.74rem + 0.20vw), 0.90rem); 35 | --step-x0: clamp(0.88rem, calc(0.79rem + 0.42vw), 1.13rem); 36 | --step-x1: clamp(0.98rem, calc(0.84rem + 0.70vw), 1.41rem); 37 | --step-x2: clamp(1.11rem, calc(0.89rem + 1.08vw), 1.76rem); 38 | --step-x3: clamp(1.25rem, calc(0.93rem + 1.59vw), 2.20rem); 39 | --step-x4: clamp(1.40rem, calc(0.95rem + 2.24vw), 2.75rem); 40 | 41 | /* @link https://utopia.fyi/space/calculator?c=320,14,1.125,1280,18,1.25,4,5,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l */ 42 | --space-3xs: clamp(0.25rem, calc(0.23rem + 0.10vw), 0.31rem); 43 | --space-2xs: clamp(0.44rem, calc(0.40rem + 0.21vw), 0.56rem); 44 | --space-xs: clamp(0.69rem, calc(0.63rem + 0.31vw), 0.88rem); 45 | --space-s: clamp(0.88rem, calc(0.79rem + 0.42vw), 1.13rem); 46 | --space-m: clamp(1.31rem, calc(1.19rem + 0.63vw), 1.69rem); 47 | --space-l: clamp(1.75rem, calc(1.58rem + 0.83vw), 2.25rem); 48 | --space-xl: clamp(2.63rem, calc(2.38rem + 1.25vw), 3.38rem); 49 | --space-2xl: clamp(3.50rem, calc(3.17rem + 1.67vw), 4.50rem); 50 | --space-3xl: clamp(5.25rem, calc(4.75rem + 2.50vw), 6.75rem); 51 | 52 | --width: 70ch; 53 | --body-line-height: 1.5; 54 | --head-line-height: 1.3; 55 | } 56 | 57 | html { 58 | /* use the border-box box model instead of the browser default content-box */ 59 | box-sizing: border-box; 60 | /* fallback for safari - remove if it starts supporting scrollbar-gutter */ 61 | overflow-y: scroll; 62 | } 63 | 64 | /* if a web browser supports `scrollbar-gutter`, use that instead */ 65 | @supports (scrollbar-gutter: stable both-edges) { 66 | html { 67 | overflow-y: auto; 68 | scrollbar-gutter: stable both-edges; 69 | } 70 | } 71 | 72 | /* inherit the border-box model in all elements */ 73 | /* this allows elements to override the box-model if needed and make their 74 | * children inherit their custom box-model */ 75 | *, 76 | *::before, 77 | *::after { 78 | box-sizing: inherit; 79 | } 80 | 81 | /* remove all browser default margins and paddings */ 82 | * { 83 | margin: 0; 84 | padding: 0; 85 | } 86 | 87 | /* if any of the following elements don't exist, the rule still applies */ 88 | :is(code, kbd, samp, pre) { 89 | font-family: var(--mono-font); 90 | overflow-x: auto; 91 | } 92 | 93 | /* reduce distraction from text by removing underlines from hyperlinks */ 94 | /* rely on color to distinguish hyperlinks */ 95 | /* the order of pseudo classes should follow the LVHA order */ 96 | /* :link, :visited, :hover, :active */ 97 | a { 98 | color: var(--fg-href); 99 | text-decoration: none; 100 | } 101 | 102 | /* subdue the color of visited hyperlinks */ 103 | a:visited { 104 | color: var(--fg-color); 105 | } 106 | 107 | /* underline hyperlinks on hover and increase their underline offset */ 108 | a:hover { 109 | text-decoration: underline; 110 | text-underline-offset: var(--space-3xs); 111 | } 112 | 113 | /* if the role of a list is explicitly defined, it isn't being used as a list */ 114 | ul[role="list"] { 115 | padding: 0; 116 | list-style: none; 117 | } 118 | 119 | /* prevent overflow of possibly long lines */ 120 | :is(p, li, h1) { 121 | overflow-wrap: break-word; 122 | } 123 | 124 | :is(img, video) { 125 | /* never render images/videos wider than their containing element */ 126 | max-inline-size: 100%; 127 | height: auto; 128 | /* preserve the aspect ratio of the image */ 129 | block-size: auto; 130 | margin-inline: auto; 131 | } 132 | 133 | /* -------------------------------------------------------------------------- */ 134 | 135 | body { 136 | /* layout */ 137 | display: flex; 138 | flex-direction: column; 139 | /* align-items: center; */ 140 | /* readability */ 141 | margin: var(--space-m) auto; 142 | width: min(90%, var(--width)); 143 | font-size: var(--step-x0); 144 | line-height: var(--body-line-height); 145 | /* aesthetics */ 146 | font-family: var(--sans-font); 147 | color: var(--fg-color); 148 | background: var(--bg-color); 149 | } 150 | 151 | /* add margins on the left and right of the child elements of body */ 152 | /* body > * { */ 153 | /* margin-inline: auto; */ 154 | /* } */ 155 | 156 | /* -------------------------------------------------------------------------- */ 157 | 158 | .primary-header { 159 | display: flex; 160 | flex-flow: row wrap; 161 | justify-content: center; 162 | gap: var(--space-xs); 163 | } 164 | 165 | :is(img, video) { 166 | /* make images/videos blocks rather than inline elements */ 167 | display: block; 168 | } 169 | 170 | .avatar { 171 | border-radius: var(--step-x1); 172 | } 173 | 174 | h1 { 175 | font-size: var(--step-x3); 176 | line-height: var(--head-line-height); 177 | } 178 | 179 | /* -------------------------------------------------------------------------- */ 180 | 181 | :is(.primary-nav, .primary-footer, .article-footer, .tag-list-nav) > ul[role="list"] { 182 | display: flex; 183 | flex-flow: row wrap; 184 | /* prevent accidental incorrect clicks by increasing space between elements */ 185 | justify-content: space-evenly; 186 | gap: var(--space-s); 187 | } 188 | 189 | .primary-footer { 190 | font-size: var(--step-s1); 191 | border-block-start: 0.1rem dotted var(--fg-border); 192 | } 193 | 194 | /* add a hash symbol before the taxonomy tag links */ 195 | .tag::before { 196 | content: "#"; 197 | } 198 | 199 | .tag-sup { 200 | padding-inline: var(--space-3xs); 201 | } 202 | 203 | /* the stack layout for the child elements of article */ 204 | article > * + * { 205 | margin-top: var(--space-s); 206 | } 207 | 208 | /* the stack layout for the body and the main element */ 209 | :is(body, main) > * + * { 210 | margin-top: var(--space-l); 211 | } 212 | 213 | .article-header > ul[role="list"] { 214 | display: inline-flex; 215 | flex-flow: row wrap; 216 | justify-content: flex-end; 217 | gap: var(--space-2xs); 218 | } 219 | 220 | .article-header { 221 | display: flex; 222 | gap: var(--space-2xs); 223 | justify-content: space-between; 224 | border-block-end: 0.1rem dotted var(--fg-border); 225 | } 226 | 227 | /* borrowed from the html5-boilerplate css file on github */ 228 | /* h5bp/html5-boilerplate/blob/5382f78315be9ed31546131ec543353d9c4ee5b3/dist/css/style.css#L109 */ 229 | /* hide the title by default */ 230 | .post-title { 231 | border: 0; 232 | clip: rect(0, 0, 0, 0); 233 | height: 1px; 234 | margin: -1px; 235 | overflow: hidden; 236 | position: absolute; 237 | white-space: nowrap; 238 | width: 1px; 239 | } 240 | 241 | .post-title::before { 242 | content: " · "; 243 | } 244 | 245 | /* show the title on devices which are at least as wide as the iPad Mini */ 246 | @media screen and (min-width: 48rem) { 247 | .post-title { 248 | clip: inherit; 249 | height: inherit; 250 | margin: inherit; 251 | overflow: inherit; 252 | position: inherit; 253 | white-space: inherit; 254 | width: inherit; 255 | } 256 | } 257 | 258 | .unknown-page { 259 | display: flex; 260 | flex-direction: column; 261 | align-items: center; 262 | margin-block: var(--space-xl); 263 | } 264 | 265 | /* code blocks inside pre should be a block otherwise it doesn't work well when 266 | * text overflows inside code */ 267 | pre > code { 268 | display: block; 269 | } 270 | 271 | code[role="img"] { 272 | display: inline-block; 273 | vertical-align: middle; 274 | } 275 | 276 | .figquote { 277 | display: flex; 278 | flex-direction: column; 279 | place-items: center; 280 | } 281 | 282 | /* -------------------------------------------------------------------------- */ 283 | 284 | /* don't style h2 to h6 because it's not needed on this website */ 285 | :is(h2, h3, h4, h5, h6) { 286 | font-size: var(--step-x0); 287 | } 288 | 289 | pre { 290 | padding: var(--space-2xs); 291 | border: 0.1rem solid var(--fg-border); 292 | border-radius: var(--step-s5); 293 | } 294 | 295 | /* show the name of the programming language inside pre */ 296 | pre[data-lang]::before { 297 | display: block; 298 | content: attr(data-lang); 299 | text-decoration: underline var(--fg-border) solid; 300 | text-underline-offset: var(--space-3xs); 301 | text-decoration-thickness: 0.1rem; 302 | text-transform: uppercase; 303 | padding-block-end: var(--space-2xs); 304 | } 305 | 306 | /* add space after line numbers and don't select the line numbers for copying */ 307 | pre[data-linenos] table tbody tr td:first-child { 308 | padding-inline-end: var(--space-s); 309 | user-select: none; 310 | } 311 | 312 | pre[data-linenos] table { 313 | /* if we set table width to 100% and if text overflows, the space separation 314 | * between cells is removed */ 315 | /* width: 100%; */ 316 | border-collapse: collapse; 317 | border-spacing: 0; 318 | text-indent: 0; 319 | } 320 | 321 | .unknown-page-emoticon { 322 | font-size: var(--step-x3); 323 | padding: var(--space-2xs); 324 | border: 0; 325 | border-radius: 0; 326 | } 327 | 328 | blockquote { 329 | margin-inline-start: var(--space-l); 330 | padding: var(--space-2xs); 331 | border-inline-start: var(--step-s4) solid var(--fg-border); 332 | } 333 | 334 | figcaption { 335 | text-align: center; 336 | } 337 | 338 | :is(ul, ol) { 339 | padding-inline: var(--space-l); 340 | } 341 | 342 | mark { 343 | /* plays well with at least 1.5 line-height or more */ 344 | padding-inline: var(--space-3xs); 345 | padding-block: 0.1rem; 346 | color: var(--fg-mark); 347 | background: var(--bg-mark); 348 | border-radius: var(--step-s5); 349 | } 350 | 351 | kbd { 352 | border-inline: 0.1rem solid var(--fg-border); 353 | border-block-start: 0.1rem solid var(--fg-border); 354 | border-block-end: 0.2rem solid var(--fg-border); 355 | border-radius: var(--step-s5); 356 | padding-inline: var(--space-3xs); 357 | padding-block: 0.1rem; 358 | } 359 | 360 | /* -------------------------------------------------------------------------- */ 361 | --------------------------------------------------------------------------------