1
0
Fork 0
mirror of https://git.sr.ht/~seirdy/seirdy.one synced 2024-11-23 21:02:09 +00:00

Compare commits

..

7 commits

Author SHA1 Message Date
Rohan Kumar
1aed7a66d4
Switch to XHTML5 markup
The site now has polygot markup and can handle both XHTML5 and HTML5
parsing rules. My staging site will be XHTML but my main site will be
HTML5, just in case of parse errors.

If other tools (e.g. LightHouse) end up supporting XHTML5, I'll consider
switching the content-type to XHTML.
2022-05-30 17:39:45 -07:00
Rohan Kumar
499c99245c
Fix whitespace 2022-05-30 14:02:09 -07:00
Rohan Kumar
9356055f6c
Fix: webmention form partial has missing context 2022-05-30 13:50:09 -07:00
Rohan Kumar
4201b1ad05
New note: "Things can get better" 2022-05-30 13:24:35 -07:00
Rohan Kumar
753f55c09e
Viewport: disable shrink-to-fit (WebKit)
I go out of my way to make sure the site works on viewports well under
240 CSS pixels wide. Some pages are very long, so a single mistake in
one part of the page shouldn't cause small text throughout the page.
2022-05-30 12:28:13 -07:00
Rohan Kumar
232ca4639c
New note: Prologue to the meta post 2022-05-30 12:12:01 -07:00
Rohan Kumar
927987093e
Form improvements
- Make webmention submission form a fieldset
- Re-order CSS to avoid descending specificity
- Make search label mention Search My Site
2022-05-30 12:07:33 -07:00
45 changed files with 289 additions and 219 deletions

View file

@ -128,10 +128,10 @@ deploy-prod:
# linting and compression can happen in parallel
.PHONY: deploy-staging
deploy-staging:
@$(MAKE) HUGO_BASEURL=https://staging.seirdy.one HUGO_FLAGS='--gc' DOMAIN=staging.seirdy.one USER=deploy@seirdy.one OUTPUT_DIR=public_staging clean
@$(MAKE) HUGO_BASEURL=https://staging.seirdy.one HUGO_FLAGS='--gc' DOMAIN=staging.seirdy.one USER=deploy@seirdy.one OUTPUT_DIR=public_staging hugo
@$(MAKE) HUGO_BASEURL=https://staging.seirdy.one HUGO_FLAGS='--gc' DOMAIN=staging.seirdy.one USER=deploy@seirdy.one OUTPUT_DIR=public_staging lint-local compress
@$(MAKE) HUGO_BASEURL=https://staging.seirdy.one HUGO_FLAGS='--gc' DOMAIN=staging.seirdy.one USER=deploy@seirdy.one OUTPUT_DIR=public_staging deploy
@$(MAKE) HUGO_FLAGS='--gc' DOMAIN=staging.seirdy.one USER=deploy@seirdy.one OUTPUT_DIR=public_staging clean
@$(MAKE) HUGO_FLAGS='--gc' DOMAIN=staging.seirdy.one USER=deploy@seirdy.one OUTPUT_DIR=public_staging hugo
@$(MAKE) HUGO_FLAGS='--gc' DOMAIN=staging.seirdy.one USER=deploy@seirdy.one OUTPUT_DIR=public_staging compress
@$(MAKE) HUGO_FLAGS='--gc' DOMAIN=staging.seirdy.one USER=deploy@seirdy.one OUTPUT_DIR=public_staging deploy
.PHONY: deploy-onion
deploy-onion:

View file

@ -179,41 +179,6 @@ nav ul li {
margin-right: .375em;
}
/* Make search box and submit button as wide as possible while keeping
* them next to each other. */
/* Use table-style layout (no, not actual tables. eww.). It's like a
* single-row flexbox that supports more browsers. Kanged this CSS from
* ww.gov.uk. Give the entire width of the row to the search box, but
* allow the minimum width for the submit button. */
form > div {
display: table;
width: 100%
}
/* A text box should not look like a button */
input:not([type="submit"]) {
display: table-cell;
width: 98%;
}
form > div > div {
display: table-cell;
vertical-align: top; /* IE and some botique browsers need this */
width: 1%;
}
input {
/* Browsers like Safari make the submit button pill-shaped which
* clashes with the input box. The only purely-cosmetic change on this
* site. */
appearance: none;
/* Don't shrink the size of the text in forms or make it system-ui. */
font-family: sans-serif;
font-size: inherit;
}
/* narrow screens: reduce margin for blockquotes a lot, using
* a border instead. Put it on the left and right to make it
* LTR/RTL-neutral, for machine translators that change text
@ -284,8 +249,11 @@ samp {
font-family: monospace, monospace;
}
/* Some browsers don't support the hidden attr */
span[hidden] {
/* Some browsers don't support the hidden attr.
* I use hidden spans in backlinks to provide ARIA labels.
* Some ancient browsers don't support input[type="hidden"] */
span[hidden],
input[type="hidden"] {
display: none;
}
@ -354,6 +322,42 @@ section[aria-labelledby="webmentions"] {
content-visibility: auto;
}
/* Make search box and submit button as wide as possible while keeping
* them next to each other. */
/* Use table-style layout (no, not actual tables. eww.). It's like a
* single-row flexbox that supports more browsers. Kanged this CSS from
* ww.gov.uk. Give the entire width of the row to the search box, but
* allow the minimum width for the submit button. */
form > div {
display: table;
width: 100%
}
input {
/* Browsers like Safari make the submit button pill-shaped which
* clashes with the input box. The only purely-cosmetic change on this
* site. */
appearance: none;
/* Don't shrink the size of the text in forms or make it system-ui. */
font-family: sans-serif;
font-size: inherit;
}
/* A text box should take all available width */
input:not([type="submit"]) {
display: table-cell;
width: 98%;
}
/* Pseudo-table-cell containing the submit button */
form > div > div {
display: table-cell;
vertical-align: top; /* IE and some botique browsers need this */
width: 1%;
}
/* Some browser focus indicators are inaccessible; override them with
* something more visible. See WCAG 2.x SC 2.4.12. I also tried to

View file

@ -74,6 +74,7 @@ disableKinds = ["taxonomy", "term"]
notes = "/notes/:year/:month/:day/:filename"
[markup.goldmark.renderer]
xhtml = true
unsafe = true
[markup.tableOfContents]
@ -103,6 +104,9 @@ disableKinds = ["taxonomy", "term"]
isPlainText = true
mediaType = "application/xml"
[outputformats.html]
mediaType = "application/xhtml+xml"
[outputs]
home = ["HTML", "atom", "GEMTEXT", "RSS"]
section = ["HTML", "atom", "RSS"]

View file

@ -8,9 +8,9 @@ sitemap:
- ChangeFreq: weekly
- Priority: 0.9
---
<div itemprop="author" itemscope itemtype="https://schema.org/Person" itemid="https://seirdy.one/#seirdy" class="p-author author h-card vcard" id="seirdy">
<div itemprop="author" itemscope="" itemtype="https://schema.org/Person" itemid="https://seirdy.one/#seirdy" class="p-author author h-card vcard" id="seirdy">
Seirdy's Home
Seirdys Home
=============
I'm <a itemprop="url" href="https://seirdy.one" rel="author home canonical me" class="u-url u-uid url"> {{% indieweb-icon %}} <span itemprop="name" class="p-name fn n"> <span itemprop="givenName" class="p-given-name given-name">Rohan</span> <span itemprop="familyName" class="p-family-name family-name">Kumar</span></span></a>, a.k.a. <span itemprop="alternateName" class="p-nickname nickname">Seirdy</span> (online handle).
@ -38,9 +38,9 @@ Git repos: [Sourcehut](https://sr.ht/~seirdy "{rel='me'}"), [GitHub](https://git
Contact
-------
Contact me via [email](mailto:seirdy@seirdy.one "{class='u-email' itemprop='email' rel='me'}") ([PGP](./publickey.asc "{rel='pgpkey authn' type='application/pgp-keys' class='u-key'}")), or on the Fediverse where I'm [@Seirdy<wbr>@pleroma<wbr>.envs.net](https://pleroma.envs.net/seirdy "{rel='me' itemprop='sameAs' class='u-url'}").
Contact me via [email](mailto:seirdy@seirdy.one "{class='u-email' itemprop='email' rel='me'}") ([PGP](./publickey.asc "{rel='pgpkey authn' type='application/pgp-keys' class='u-key'}")), or on the Fediverse where I'm [@Seirdy<wbr />@pleroma<wbr />.envs.net](https://pleroma.envs.net/seirdy "{rel='me' itemprop='sameAs' class='u-url'}").
Chat with me: I'm on several IRC networks. Alternatively, I'm [@seirdy<wbr>:seirdy.one](https://matrix.to/#/@seirdy:seirdy.one "{class='u-url' rel='me'}") on Matrix. My secondary Matrix account for Synapse-only rooms is `@seirdy:fairydust.space`.
Chat with me: I'm on several IRC networks. Alternatively, I'm [@seirdy<wbr />:seirdy.one](https://matrix.to/#/@seirdy:seirdy.one "{class='u-url' rel='me'}") on Matrix. My secondary Matrix account for Synapse-only rooms is `@seirdy:fairydust.space`.
</div>

View file

@ -36,13 +36,13 @@ My handle is "Seirdy" on all the platforms I use.
- Software forges: [Sourcehut](https://sr.ht/~seirdy), [GitHub](https://github.com/Seirdy), [GitLab](https://gitlab.com/Seirdy), and [Codeberg](https://codeberg.org/Seirdy).
- Social (federated): I'm [@Seirdy<wbr>@pleroma<wbr>.envs.net](https://pleroma.envs.net/seirdy) on the Fediverse.
- Social (federated): I'm [@Seirdy<wbr />@pleroma<wbr />.envs.net](https://pleroma.envs.net/seirdy) on the Fediverse.
- Social (non-federated): I'm Seirdy on [Hacker News](https://news.ycombinator.com/user?id=Seirdy), [Lobsters](https://lobste.rs/u/Seirdy), [Reddit](https://www.reddit.com/user/Seirdy/), [Tildes.net](https://tildes.net/user/Seirdy), and Linux Weekly News.
- Email: my address is [seirdy<wbr>@seirdy.one](mailto:seirdy@seirdy.one). I typically sign my emails with my public PGP key: [`1E892DB2A5F84479`](../publickey.asc). My key is also available via WKD.
- Email: my address is [seirdy<wbr />@seirdy.one](mailto:seirdy@seirdy.one). I typically sign my emails with my public PGP key: [`1E892DB2A5F84479`](../publickey.asc). My key is also available via WKD.
- Chat: for IRC, my nick is Seirdy on Libera.chat, Snoonet, OFTC, Tilde.Chat, and a few smaller networks. I'm also [@seirdy<wbr>:seirdy.one](https://matrix.to/#/@seirdy:seirdy.one) on Matrix.
- Chat: for IRC, my nick is Seirdy on Libera.chat, Snoonet, OFTC, Tilde.Chat, and a few smaller networks. I'm also [@seirdy<wbr />:seirdy.one](https://matrix.to/#/@seirdy:seirdy.one) on Matrix.
My secondary Matrix account for Synapse-only rooms is `@seirdy:fairydust.space`. My Matrix account used to be `@seirdy:envs.net` but I've since migrated to my own Conduit server.

View file

@ -0,0 +1,37 @@
---
title: "Prologue to the meta post"
date: 2022-05-30T12:12:01-07:00
---
I've been planning on writing a big "meta" post explaining how this site is built, but first I want to reach a few milestones, most of which are IndieWeb-related. Here's what I've already done:
- Microformats
- More semantic markup: Creative Commons and Schema.org vocabularies
- Web sign-in (using an IndieAuth service)
- multiple types of posts
- Sending Webmentions
- Displaying Webmentions
- User-sendable Webmentions with a form
- RSS feeds for posts and notes
- Atom feed for posts and notes with ActivityStreams metadata
- Automatic POSSE of bookmarks to TinyGem (bookmarking service)
However, I still have a ways to go. Here's what I plan on adding:
- Add some semantic markup to list online "friends", probably using [FOAF ontology](http://xmlns.com/foaf/spec/)
- Preview Webmention entry contents
- Related to previous point: create a blogroll
- Automatic POSSE of notes to Fedi (it's mostly manual right now)
- Combined Atom feed
- WebSub
- Permalinks for bookmarks
- Atom feed for bookmarks
- Automatic POSSE of bookmarks to Fedi
- Time-period based pagination/navigation on notes/posts page.
Once I finish the above, I'll be ready for a "meta" post. Some more tasks after that:
- Run my own WebSub hub.
- Add my own front-end for search results (my first non-static content).
- Pingback support
- Create a webring. What I've learned while doing the above will inform inclusion criteria.

View file

@ -0,0 +1,18 @@
---
title: "Things can get better"
date: 2022-05-30T13:24:30-07:00
---
<aside role="note">
Reply to {{< mention-work itemprop="about" itemtype="SocialMediaPosting" reply=true >}}{{<cited-work name="Being annoyed with software is always going to be a part of the experience" url="https://mastodon.art/@TerryHancock/108392295120692087">}} by {{<indieweb-person first-name="Terry" last-name="Hancock" url="https://mastodon.art/@TerryHancock" itemprop="author">}}
{{</mention-work>}}
</aside>
I'm in partial agreement with this take.
On one hand, expectations change with time. Most people outside my bubble look at interfaces I like using and say they look "ugly" and that they're "weird" (their words); they wouldn't have said that when I was younger.
On the other hand, some "annoyances" are actually removable *barriers*. Accessibility comes to mind. If you take software that does not work with assistive technologies (ATs) and fix it, AT-users might move on to the next accessibility issue. But they'll be markedly happier than before, when they just couldn't use it.
Similar examples include localization and compatibility.
Man, positive takes like this feel really out of character for me.

View file

@ -130,7 +130,7 @@ Decompilers are seldom used alone in this context. Instead, they're typically a
### Example: malware analysis
These reverse-engineering techniques--a combination of tracing, packet sniffing, binary analysis, and memory dumps--make up the workings of most modern malware analysis. See [this example](https://www.hybrid-analysis.com/sample/1ef3b7e9ba5f486afe53fcbd71f69c3f9a01813f35732222f64c0981a0906429/5e428f69c88e9e64c33afe64) of a fully-automated analysis of the Zoom Windows installer. It enumerates plenty of information about Zoom without access to its source code: reading unique machine information, anti-VM and anti-reverse-engineering tricks, reading config files, various types of network access, scanning mounted volumes, and more.
These reverse-engineering techniques---a combination of tracing, packet sniffing, binary analysis, and memory dumps---make up the workings of most modern malware analysis. See [this example](https://www.hybrid-analysis.com/sample/1ef3b7e9ba5f486afe53fcbd71f69c3f9a01813f35732222f64c0981a0906429/5e428f69c88e9e64c33afe64) of a fully-automated analysis of the Zoom Windows installer. It enumerates plenty of information about Zoom without access to its source code: reading unique machine information, anti-VM and anti-reverse-engineering tricks, reading config files, various types of network access, scanning mounted volumes, and more.
To try this out yourself, use a sandbox designed for dynamic analysis. [Cuckoo](https://cuckoosandbox.org/) is a common and easy-to-use solution, while [DRAKVUF](https://drakvuf.com/) is more advanced.
@ -152,7 +152,7 @@ Unfortunately, some components are poorly understood due to being obfuscated usi
Skochinsky's and Corna's analysis was sufficient to clarify (but not completely contradict) sensationalism claiming that ME can remotely lock any PC (it was a former opt-in feature), can spy on anything the user does (they clarified that access is limited to unblocked parts of the host memory and the integrated GPU, but doesn't include e.g. the framebuffer), etc.
While claims such as "ME is a black box that can do anything" are misleading, ME not without its share of vulnerabilities. My favorite look at its issues is a presentation by <span itemprop="mentions" itemscope itemtype="https://schema.org/PresentationDigitalDocument">{{<indieweb-person itemprop="author" first-name="Mark" last-name="Ermolov" url="https://www.blackhat.com/eu-17/speakers/Mark-Ermolov.html">}} and {{<indieweb-person itemprop="author" first-name="Maxim" last-name="Goryachy" url="https://www.blackhat.com/eu-17/speakers/Maxim-Goryachy.html">}} at Black Hat Europe 2017: [How to Hack a Turned-Off Computer, or Running Unsigned Code in Intel Management Engine](https://www.blackhat.com/docs/eu-17/materials/eu-17-Goryachy-How-To-Hack-A-Turned-Off-Computer-Or-Running-Unsigned-Code-In-Intel-Management-Engine-wp.pdf)</span>.
While claims such as "ME is a black box that can do anything" are misleading, ME not without its share of vulnerabilities. My favorite look at its issues is a presentation by <span class="h-cite" itemprop="mentions" itemscope="" itemtype="https://schema.org/PresentationDigitalDocument">{{<indieweb-person itemprop="author" first-name="Mark" last-name="Ermolov" url="https://www.blackhat.com/eu-17/speakers/Mark-Ermolov.html">}} and {{<indieweb-person itemprop="author" first-name="Maxim" last-name="Goryachy" url="https://www.blackhat.com/eu-17/speakers/Maxim-Goryachy.html">}} at Black Hat Europe 2017: [How to Hack a Turned-Off Computer, or Running Unsigned Code in Intel Management Engine](https://www.blackhat.com/docs/eu-17/materials/eu-17-Goryachy-How-To-Hack-A-Turned-Off-Computer-Or-Running-Unsigned-Code-In-Intel-Management-Engine-wp.pdf)</span>.
In short: ME being proprietary doesn't mean that we can't find out how (in)secure it is. Binary analysis when paired with runtime inspection can give us a good understanding of what trade-offs we make by using it. While ME has a history of serious vulnerabilities, they're nowhere near what [borderline conspiracy theories](https://web.archive.org/web/20210302072839/themerkle.com/what-is-the-intel-management-engine-backdoor/) claim.[^11]
@ -181,12 +181,12 @@ I've said it before but let me say it again: fuzzing is really the top method to
If you want to get started with fuzzing, I recommend checking out [the quick-start guide for American Fuzzy Loop](https://github.com/google/AFL/blob/master/docs/QuickStartGuide.txt). Some languages like Go 1.18 also have fuzzing tools available right in the standard library.
### Example: CVE-<wbr>2022-0185
### Example: CVE-<wbr />2022-0185
A recent example of how fuzzing helps spot a vulnerability in an open-source project is [CVE-<wbr>2022-0185](https://www.openwall.com/lists/oss-security/2022/01/18/7): a Linux 0-day found by the Crusaders of Rust a few weeks ago. It was discovered using the [syzkaller](https://github.com/google/syzkaller) kernel fuzzer. The process was documented on Will's Root:
A recent example of how fuzzing helps spot a vulnerability in an open-source project is [CVE-<wbr />2022-0185](https://www.openwall.com/lists/oss-security/2022/01/18/7): a Linux 0-day found by the Crusaders of Rust a few weeks ago. It was discovered using the [syzkaller](https://github.com/google/syzkaller) kernel fuzzer. The process was documented on Will's Root:
<p class="h-cite" itemprop="citation" itemscope itemtype="https://schema.org/BlogPosting">
<cite><a class="u-url p-name" itemprop="name" href="https://www.willsroot.io/2022/01/cve-2022-0185.html">CVE-<wbr>2022-0185 - Winning a $31337 Bounty after Pwning Ubuntu and Escaping Google's KCTF Containers</a></cite> by {{<indieweb-person nickname="willsroot" url="https://willsroot.io" itemprop="author">}}
<p class="h-cite" role="doc-credit" itemprop="citation" itemscope="" itemtype="https://schema.org/BlogPosting">
<cite><a class="u-url p-name" itemprop="name" href="https://www.willsroot.io/2022/01/cve-2022-0185.html">CVE-<wbr />2022-0185 - Winning a $31337 Bounty after Pwning Ubuntu and Escaping Google's KCTF Containers</a></cite> by {{<indieweb-person nickname="willsroot" url="https://willsroot.io" itemprop="author">}}
</p>
I _highly_ encourage giving it a read; it's the perfect example of fuzzing with sanitizers to find a vulnerability, reproducing the vulnerability (by writing a tiny C program), _then_ diving into the source code to find and fix the cause, and finally reporting the issue (with a patch!). When source isn't available, the vendor would assume responsibility for the "find and fix" steps.

View file

@ -49,7 +49,7 @@ This process should pretty straightforward. You can run `git remote add` (see `g
fetch = +refs/heads/*:refs/remotes/gh_upstream/*
```
If that's too much work--a perfectly understandable complaint--automating the process is trivial. Here's [an example from my dotfiles](https://git.sr.ht/~seirdy/dotfiles/tree/master/Executables/shell-scripts/bin/git-remote-setup).
If that's too much work---a perfectly understandable complaint---automating the process is trivial. Here's [an example from my dotfiles](https://git.sr.ht/~seirdy/dotfiles/tree/master/Executables/shell-scripts/bin/git-remote-setup).
Seamless pushing and pulling
----------------------------

View file

@ -232,7 +232,7 @@ Don't use actual excerpts from pre-existing works as your password.
Conclusion, TLDR
----------------
Question: How much entropy should a password have to ensure it will _never_ be vulnerable to a brute-force attack? Can an impossibly efficient computer--the MOAC--crack your password?
Question: How much entropy should a password have to ensure it will _never_ be vulnerable to a brute-force attack? Can an impossibly efficient computer---the MOAC---crack your password?
Answer: limited only by energy, if a computer with the highest level of efficiency physically possible is made of matter, does work to compute, and obeys the conservation of energy:

View file

@ -85,7 +85,7 @@ These are large engines that pass all my standard tests and more.
- Fireball
- You.com
- Partially powers MetaGer by default; this can be turned off
- At this point, I mostly stopped adding Bing-<wbr>based search engines. There are just too many.
- At this point, I mostly stopped adding Bing-<wbr />based search engines. There are just too many.
- Yandex: originally a Russian search engine, it now has an English version. Some Russian results bleed into its English site. Like Bing, it allows submitting pages and sitemaps for crawling using the IndexNow API. Powers:
@ -112,7 +112,7 @@ These engines pass most of the tests listed in the "methodology" section. All of
FairSearch supports Open Graph and some JSON-LD at the moment. A look through the source code for Alexandria and Gigablast didn't seem to reveal the use of any structured data.
### Smaller indexes, hit-and-<wbr>miss {#smaller-indexes-hit-and-miss}
### Smaller indexes, hit-and-<wbr />miss {#smaller-indexes-hit-and-miss}
These engines fail badly at a few important tests. Otherwise, they seem to work well enough.
@ -120,7 +120,7 @@ These engines fail badly at a few important tests. Otherwise, they seem to work
- [Exalead](https://www.exalead.com/search/): slow, quality is hit-and-miss. Its indexer claims to crawl the DMOZ directory, which has since shut down and been replaced by the [Curlie](https://curlie.org) directory. No relevant results for "Oppen&shy;heimer" and some other history-related queries. Allows submitting individual URLs for indexing, but requires solving a Google reCAPTCHA and entering an email address.
- [ExactSeek](https://www.exactseek.com/): small index, disproportionately dominated by big sites. Failed multiple tests. Allows submitting individual URLs for crawling, but requires entering an email address and receiving a newsletter. Webmaster tools seem to heavily push for paid <abbr title="search-engine optimization">SEO</abbr> options. It also powers SitesOnDisplay and [Blog-<wbr>search.com](https://www.blog-search.com).
- [ExactSeek](https://www.exactseek.com/): small index, disproportionately dominated by big sites. Failed multiple tests. Allows submitting individual URLs for crawling, but requires entering an email address and receiving a newsletter. Webmaster tools seem to heavily push for paid <abbr title="search-engine optimization">SEO</abbr> options. It also powers SitesOnDisplay and [Blog-<wbr />search.com](https://www.blog-search.com).
- [Infotiger](https://alpha.infotiger.com/): A small index that seems to find relevant results. It allows site submission for English and German pages. It also features a "similarity" search to query pages similar to a given link, with mixed results.

View file

@ -49,7 +49,7 @@ Another focus is minimalism. [Progressive enhancement](https://en.wikipedia.org/
<dfn>Restricted enhancement</dfn> limits all enhancements to those that solve specific accessibility, security, performance, or significant usability problems faced by people besides the author. These enhancements must be made progressively when possible, with a preference for using older or more widespread features, taking into account unorthodox user agents. Purely-cosmetic changes should be kept to a minimum.
I'd like to re-iterate yet another time that this only applies to websites that primarily focus on text. If graphics, interactivity, etc. are an important part of your website, less of the article applies. My hope is for readers to consider a subset of this page the next time they build a website, and _address the trade-offs they make when they deviate._ I don't expect--or want--anybody to follow all of my advice, because doing so would make the Web quite a boring place!
I'd like to re-iterate yet another time that this only applies to websites that primarily focus on text. If graphics, interactivity, etc. are an important part of your website, less of the article applies. My hope is for readers to consider a subset of this page the next time they build a website, and _address the trade-offs they make when they deviate._ I don't expect---or want---anybody to follow all of my advice, because doing so would make the Web quite a boring place!
I'll cite the Web Accessibility Initiative's (<abbr title="Web Accessibility Initiative">WAI</abbr>) <cite>[Techniques for WCAG&nbsp;2.2](https://www.w3.org/WAI/WCAG22/Techniques/)</cite> a number of times. Unlike the <cite>Web Content Accessibility Guidelines</cite> (<abbr title="Web Content Accessibility Guidelines">WCAG</abbr>), the Techniques document does not list requirements; rather, it serves to non-exhaustively educate authors about _how_ to use specific technologies to comply with the WCAG. I don't find much utility in the technology-agnostic goals enumerated by the WCAG without the accompanying technology-specific techniques to meet those goals.
@ -250,7 +250,7 @@ Understanding round-trips requires understanding your server's approach to conge
Historically, TCP congestion control approaches typically set an initial window size to ten TCP packets and grew this value with each round-trip. Under most setups, this meant that the first round-trip could include 1460 bytes. The following round-trip could deliver under three kilobytes.[^5]
Nowadays, servers typically employ BBR-based congestion control. It allows for regular "spikes" in window size, but the initial window size is still small. Find more details in the slides from <span class="h-cite" itemprop="citation" itemscope itemtype="https://schema.org/PresentationDigitalDocument"> <cite class="p-name" itemprop="name headline" ><a class="u-url" itemprop="url" href="https://labs.apnic.net/presentations/store/2019-09-05-bbr.pdf">TCP and BBR</a></cite> (<span itemprop="encodingFormat">application/<wbr>pdf</span>) by {{<indieweb-person first-name="Geoff" last-name="Huston" itemprop="author" url="https://www.potaroo.net/" org="APNiC" org-url="https://www.apnic.net/">}}</span>.
Nowadays, servers typically employ BBR-based congestion control. It allows for regular "spikes" in window size, but the initial window size is still small. Find more details in the slides from <span class="h-cite" itemprop="citation" itemscope="" itemtype="https://schema.org/PresentationDigitalDocument"> <cite class="p-name" itemprop="name headline" ><a class="u-url" itemprop="url" href="https://labs.apnic.net/presentations/store/2019-09-05-bbr.pdf">TCP and BBR</a></cite> (<span itemprop="encodingFormat">application/<wbr />pdf</span>) by {{<indieweb-person first-name="Geoff" last-name="Huston" itemprop="author" url="https://www.potaroo.net/" org="APNiC" org-url="https://www.apnic.net/">}}</span>.
HTTP/3 uses QUIC instead of TCP, which makes things a bit different; the important thing to remember is that _user agents should be aware of all blocking resources **before** finishing the earliest possible round-trip._
@ -268,7 +268,7 @@ Loading content of unknown dimensions, such as images, can create layout shifts;
In-depth server configuration is a bit out of scope, so I'll keep each improvement brief.
Compression--especially static compression--dramatically reduces download sizes. My full-text RSS feed is about a quarter of a megabyte, but the Brotli-compressed version is about 70 kilobytes. Caddy supports this with a `precompressed` directive; Nginx requires the [ngx_brotli module](https://github.com/google/ngx_brotli) for Brotli compression.
Compression---especially static compression---dramatically reduces download sizes. My full-text RSS feed is about a quarter of a megabyte, but the Brotli-compressed version is about 70 kilobytes. Caddy supports this with a `precompressed` directive; Nginx requires the [ngx_brotli module](https://github.com/google/ngx_brotli) for Brotli compression.
When serving many resources at once (e.g., if a page has many images), HTTP/2 could offer a speed boost through multiplexing; use it if you can, but expect many clients to only support HTTP/1.1. HTTP/3 is unlikely to help textual websites much, so run a benchmark to see if it's worthwhile.
@ -289,7 +289,7 @@ Tor users are encouraged to set the [Tor Browser's security settings](https://tb
Additionally, hopping between nodes in Tor circuits incurs latency, worsening the impacts of requiring multiple requests and round-trips. Try to minimise the number of requests to view a page.
If you use a CDN or some over&shy;complicated website security stack, make sure it doesn't block Tor users or require them to enable JavaScript to complete a CAPTCHA. Tor Browser users are supposed to avoid fingerprinting vectors like JS and browser extensions, so requiring a JavaScript-<wbr>based CAPTCHA will effectively block many Tor users.
If you use a CDN or some over&shy;complicated website security stack, make sure it doesn't block Tor users or require them to enable JavaScript to complete a CAPTCHA. Tor Browser users are supposed to avoid fingerprinting vectors like JS and browser extensions, so requiring a JavaScript-<wbr />based CAPTCHA will effectively block many Tor users.
Tor users are unable to leverage media queries or client-hints to signal special needs. Pages need to be as accessible as possible by default, as per the ["inclusive by default" directive outlined earlier](#inc-by-default). This should be a given, but it's doubly important when serving fingerprinting-averse readers.
@ -407,7 +407,7 @@ Long pages with many DOM nodes may benefit from CSS containment, a more recently
<blockquote itemprop="text">
`content-visibility: auto` is a more complex directive than `content-visibility: hidden`; rather than being similar to `display: none`, it adaptively hides/<wbr>displays an element's contents as they become <a href="https://drafts.csswg.org/css-contain/#relevant-to-the-user">relevant to the user</a>. It also doesnt hide its <a href="https://drafts.csswg.org/css-contain/#skips-its-contents">skipped contents</a> from the user agent, so screen readers, in-page search, and other tools can still interact with it.
`content-visibility: auto` is a more complex directive than `content-visibility: hidden`; rather than being similar to `display: none`, it adaptively hides/<wbr />displays an element's contents as they become <a href="https://drafts.csswg.org/css-contain/#relevant-to-the-user">relevant to the user</a>. It also doesnt hide its <a href="https://drafts.csswg.org/css-contain/#skips-its-contents">skipped contents</a> from the user agent, so screen readers, in-page search, and other tools can still interact with it.
</blockquote>
{{< quotecaption partOfType="TechArticle" >}}
@ -518,7 +518,7 @@ Accordingly, follow good practices for alt-text:
* Concisely summarize the image content the best you can, without repeating the surrounding content.
* Images should usually have alt-text under 100 char&shy;acters, excluding punctuation.[^13] Save longer descriptions for a caption or <code>aria-<wbr>des&shy;cribedby</code>. Exceptions exist.
* Images should usually have alt-text under 100 char&shy;acters, excluding punctuation.[^13] Save longer descriptions for a caption or <code>aria-<wbr />des&shy;cribedby</code>. Exceptions exist.
* Don't include significant information that isn't present in the image; I'll cover how to handle supple&shy;mentary information in the next subsections.
@ -543,7 +543,7 @@ This is somewhat similar to the way most students in primary and secondary schoo
### Figures
A <dfn>figure</dfn> is any sort of self-contained information that is referenced by--but somewhat distinct from--body content. Items that make for good figures are often found in [floating blocks](https://en.wikipedia.org/wiki/Page_layout#Floating_block) of print material.
A <dfn>figure</dfn> is any sort of self-contained information that is referenced by---but somewhat distinct from---body content. Items that make for good figures are often found in [floating blocks](https://en.wikipedia.org/wiki/Page_layout#Floating_block) of print material.
Consider using a `<figure>` element when employing the previous section's two-part strategy. Place one of the two aforementioned pieces of information in a `<figcaption>`; the caption can come before or after the image.
@ -594,7 +594,7 @@ A <dfn>`longdesc`</dfn> attribute used to be another way to reference an image t
The recommended way to link to a transcript is by hyperlinking the image (i.e., wrapping it with `<a>`) or semantically grouping the image with its transcript. Put a short summary in the alt-text, and mention the availability of a transcript in a visible caption.
A [StackOverflow thread about comic transcripts](https://stackoverflow.com/questions/65564539/what-is-the-semantically-correct-way-to-include-transcript-from-a-comic) outlines a good approach to semantically grouping images and transcripts, and my approach is similar. I group an image, alt-text, and caption in a `<figure>` element and follow it with a transcript in a `<details>` element. I use <code>aria-<wbr>des&shy;cribedby</code> to semantically link the figure and the transcript.[^14]
A [StackOverflow thread about comic transcripts](https://stackoverflow.com/questions/65564539/what-is-the-semantically-correct-way-to-include-transcript-from-a-comic) outlines a good approach to semantically grouping images and transcripts, and my approach is similar. I group an image, alt-text, and caption in a `<figure>` element and follow it with a transcript in a `<details>` element. I use <code>aria-<wbr />des&shy;cribedby</code> to semantically link the figure and the transcript.[^14]
An image, alt-text, figure caption, and transcript combine to form a complex relationship that should be grouped together in a single landmark. I put all three inside a `<section>` with a heading, and give the group an `aria-label` that indicates the presence of the three sub-elements. Using a `section` landmark ensures that the figure and caption remain together as a single unit. The [html code](#xkcd-html) for the [xkcd comic earlier in the page](#infinite-scrolling) is a representative example.
@ -660,7 +660,7 @@ Chris also describes the importance of visited link colors in <cite>[Visited Lin
<figcaption itemprop="caption">
This is an unreadable screenshot of <span itemprop="encodesCreativeWork" itemscope itemtype="https://schema.org/WebSite">{{<cited-work name="Better Motherfucking Website" url="http://bettermotherfuckingwebsite.com/">}}</span>. I had set my browser foreground and background colors to white and dark gray, respectively. The website overrode the foreground colors while assuming that everyone browses with a white background.
This is an unreadable screenshot of <span class="h-cite" itemprop="encodesCreativeWork" itemscope="" itemtype="https://schema.org/WebSite">{{<cited-work name="Better Motherfucking Website" url="http://bettermotherfuckingwebsite.com/">}}</span>. I had set my browser foreground and background colors to white and dark gray, respectively. The website overrode the foreground colors while assuming that everyone browses with a white background.
</figcaption>
{{< /transcribed-image-figure >}}
@ -694,7 +694,7 @@ Not all approaches completely discard a designer's specified color palette. The
- Some stuff will disappear in Win HCM, some won't. Best advice is to use semantic HTML to keep things visible.
- You can use transparent `outline` to keep things visible like focus indicators and surface boundaries or use <code>current<wbr>Color</code> to maintain SVG `fill` colors in Win HCM.
- You can use transparent `outline` to keep things visible like focus indicators and surface boundaries or use <code>current<wbr />Color</code> to maintain SVG `fill` colors in Win HCM.
- You can use a special media query combined with special CSS color key&shy;words to give elements the user defined colors.
@ -915,7 +915,7 @@ Light and dark variants of legacy formats (PNG, JPG, GIF), WebP, and AVIF can ca
### SVG images
I only recommend using SVG in images; avoid using them in embeds, objects, or directly in the body. Remember that users may save images, and open them in a non-browser image viewer with reduced SVG compatibility. To maintain maximum compatibility, stick a the subset of the [secure static processing mode](https://www.w3.org/TR/SVG/conform.html#secure-static-mode) of [SVG Static](https://www.w3.org/TR/SVG11/feature#SVG-static). Specifically, the subset that appears in the [SVG Tiny Portable<wbr>/Secure (<abbr title="Portable/Secure">PS</abbr>) spec](https://datatracker.ietf.org/doc/draft-svg-tiny-ps-abrotman/). SVG Tiny PS is a subset of [SVG Tiny&nbsp;1.2](https://www.w3.org/TR/SVGTiny12/intro.html), which is a supported export format in most vector drawing programs. Ignore the elements specifically required for SVG Tiny PS; your image can be a standard SVG that only utilizes a tiny subset of the full SVG spec.
I only recommend using SVG in images; avoid using them in embeds, objects, or directly in the body. Remember that users may save images, and open them in a non-browser image viewer with reduced SVG compatibility. To maintain maximum compatibility, stick a the subset of the [secure static processing mode](https://www.w3.org/TR/SVG/conform.html#secure-static-mode) of [SVG Static](https://www.w3.org/TR/SVG11/feature#SVG-static). Specifically, the subset that appears in the [SVG Tiny Portable<wbr />/Secure (<abbr title="Portable/Secure">PS</abbr>) spec](https://datatracker.ietf.org/doc/draft-svg-tiny-ps-abrotman/). SVG Tiny PS is a subset of [SVG Tiny&nbsp;1.2](https://www.w3.org/TR/SVGTiny12/intro.html), which is a supported export format in most vector drawing programs. Ignore the elements specifically required for SVG Tiny PS; your image can be a standard SVG that only utilizes a tiny subset of the full SVG spec.
This advice might seem daunting, but its usually easy to use existing tools to generate an SVG Tiny file and manually edit it to support the SVG secure static mode. SVGs that conform to this subset should be compatible with Qt5's SVG implemen&shy;tation, librsvg (used by Wikipedia and GNOME), and most operating systems' icon renderers.
@ -983,7 +983,7 @@ Neither situation looks great.
### Sidebar alternatives
Common items in sidebars include tag clouds, an author bio, and an index of entries; these aren't useful while reading an article. Consider putting them in the article footer or--even better--dedicated pages. This does mean that readers will have to navigate to a different page to see that content, but they probably prefer things that way; almost nobody who clicked on "An opinionated list of best practices for textual websites" did so because they wanted to read my bio.
Common items in sidebars include tag clouds, an author bio, and an index of entries; these aren't useful while reading an article. Consider putting them in the article footer or---even better---dedicated pages. This does mean that readers will have to navigate to a different page to see that content, but they probably prefer things that way; almost nobody who clicked on "An opinionated list of best practices for textual websites" did so because they wanted to read my bio.
Don't boost engagement by giving readers information they didn't ask for; earn engagement with good content, and let readers navigate to your other pages _after_ they've decided they want to read more.
@ -1151,7 +1151,7 @@ Line spacing (leading) is at least space-and-a-half within paragraphs, and parag
{{< /quotecaption >}}
{{</quotation>}}
Non-<wbr>brow&shy;sers: reading mode {#non-browsers-reading-mode}
Non-<wbr />brow&shy;sers: reading mode {#non-browsers-reading-mode}
------------------------------------
Fully standards-compliant browsers aren't the only programs people use. They also use "reading mode" tools and services.
@ -1280,7 +1280,7 @@ You can use `:focus` and `:focus-visible` to highlight selected and keyboard-foc
{{< codecaption lang="CSS" >}}
I do not re-style `:focus` when `:focus-visible` works, to match existing behavior. I also override `:focus` styling only on the subset of focusable elements that would normally show an outline. Based on the post {{<mention-work itemprop="isBasedOn" itemtype="BlogPosting">}}{{<cited-work name=":focus-visible and backwards compatibility" url="https://www.tpgi.com/focus-visible-and-backwards-compatibility/" extraName="headline">}} by <span itemprop="publisher" itemscope itemtype="https://schema.org/Organization" class="h-card vcard p-author"> <a itemprop="url" href="https://www.tpgi.com/" class="u-url url"> <span itemprop="name" class="p-name">TPGi</span></a></span>{{</mention-work>}}.
I do not re-style `:focus` when `:focus-visible` works, to match existing behavior. I also override `:focus` styling only on the subset of focusable elements that would normally show an outline. Based on the post {{<mention-work itemprop="isBasedOn" itemtype="BlogPosting">}}{{<cited-work name=":focus-visible and backwards compatibility" url="https://www.tpgi.com/focus-visible-and-backwards-compatibility/" extraName="headline">}} by <span itemprop="publisher" itemscope="" itemtype="https://schema.org/Organization" class="h-card vcard p-author"> <a itemprop="url" href="https://www.tpgi.com/" class="u-url url"> <span itemprop="name" class="p-name">TPGi</span></a></span>{{</mention-work>}}.
{{< /codecaption >}}
@ -1346,7 +1346,7 @@ The best solution for possessive nouns is to include the "apostrophe + s" inside
### Other tips for screen readers
Designers already test their websites with multiple browser engines to ensure cross-browser compatibility. Screen readers deserve the same treatment. Orca, VoiceOver, NVDA, Narrator, JAWS, TalkBack, ChromeVox, KaiOS Readout, et al. all have unique behavior. In addition, different browsers--even different Chromium forks--expose content to screen readers differently. You'll need to test multiple screen readers in multiple browsers, and keep track of updates to both. See why standards compliance is important?
Designers already test their websites with multiple browser engines to ensure cross-browser compatibility. Screen readers deserve the same treatment. Orca, VoiceOver, NVDA, Narrator, JAWS, TalkBack, ChromeVox, KaiOS Readout, et al. all have unique behavior. In addition, different browsers---even different Chromium forks---expose content to screen readers differently. You'll need to test multiple screen readers in multiple browsers, and keep track of updates to both. See why standards compliance is important?
Screen readers on touch screen devices are also quite different from their desktop counterparts, and typically feature fewer capabilities. Be sure to test on both desktop and mobile.
@ -1379,7 +1379,7 @@ No matter how simple a page is, I don't think simplicity eliminates the need for
### Automated tests
Automated tests--especially accessibility tests--are a supplement to manual tests, not a replacement for them. Think of them as time-savers that bring up issues for further research, containing both false positives and false negatives.
Automated tests---especially accessibility tests---are a supplement to manual tests, not a replacement for them. Think of them as time-savers that bring up issues for further research, containing both false positives and false negatives.
These are the tools I use regularly. I've deliberately excluded tools that would be redundant.[^22]
@ -1452,9 +1452,9 @@ These tests begin reasonably, but gradually grow absurd. Once again, use your ju
15. Download your webpage and test how multiple word processors render and generate PDFs from it.[^25]
16. Combine conversion tools. Combine an HTML-<wbr>to-<wbr>EPUB converter and an EPUB-<wbr>to-<wbr>PDF converter, or stack multiple article-extraction utilities. Be creative and enjoy breaking your site. When something breaks, examine the breakage and see if it's caused by an issue in your markup, or a CSS feature with an equivalent alternative.
16. Combine conversion tools. Combine an HTML-<wbr />to-<wbr />EPUB converter and an EPUB-<wbr />to-<wbr />PDF converter, or stack multiple article-extraction utilities. Be creative and enjoy breaking your site. When something breaks, examine the breakage and see if it's caused by an issue in your markup, or a CSS feature with an equivalent alternative.
17. Build a time machine. Travel decades--or perhaps centuries--into the future. Keep going forward until the WWW is breathing its last breath. Test your site on future browsers. Figuring out how to transfer your files onto their computers might take some time, but you have a time machine so that shouldn't be too hard. When you finish, go back in time to [meet Benjamin Franklin](https://xkcd.com/567/).
17. Build a time machine. Travel decades---or perhaps centuries---into the future. Keep going forward until the WWW is breathing its last breath. Test your site on future browsers. Figuring out how to transfer your files onto their computers might take some time, but you have a time machine so that shouldn't be too hard. When you finish, go back in time to [meet Benjamin Franklin](https://xkcd.com/567/).
I'm still on step 16, trying to find new ways to break this page. If you come up with a new test, please [share it](mailto:~seirdy/seirdy.one-comments@lists.sr.ht).
@ -1500,7 +1500,7 @@ This article is, and will probably always be, an ongoing work-in-progress. Some
* Ways to improve compre&shy;hension by readers who struggle to understand non-literal language (certain cognitive disabilities, non-native speakers unfamiliar with idioms, etc.). I might wait until the <abbr title="Web Accessibility Initiative">WAI</abbr> <cite>[Personali&shy;zation Help and Support 1.0](https://w3c.github.io/personalization-semantics/help/index.html)</cite> draft specification matures and its vocabularies gain adoption before going in depth.
* Other accessible writing tips, maybe after I get a copy of <span itemprop="mentions" itemscope itemtype="https://schema.org/Book">{{<cited-work name="Writing Is Designing" url="https://rosenfeldmedia.com/books/writing-is-designing/">}} by {{<indieweb-person first-name="Michael" last-name="Metts" url="https://mjmetts.com/" itemprop="author">}} and {{<indieweb-person first-name="Andy" last-name="Welfe" url="https://www.andy.wtf/" itemprop="author">}}</span>. A relevant excerpt on writing accessibly is [on A List Apart](https://alistapart.com/article/standards-for-writing-accessibly/).<!--Hugo does something weird when I use my mention-work shortcode here.-->
* Other accessible writing tips, maybe after I get a copy of <span class="h-cite" itemprop="mentions" itemscope="" itemtype="https://schema.org/Book">{{<cited-work name="Writing Is Designing" url="https://rosenfeldmedia.com/books/writing-is-designing/">}} by {{<indieweb-person first-name="Michael" last-name="Metts" url="https://mjmetts.com/" itemprop="author">}} and {{<indieweb-person first-name="Andy" last-name="Welfe" url="https://www.andy.wtf/" itemprop="author">}}</span>. A relevant excerpt on writing accessibly is [on A List Apart](https://alistapart.com/article/standards-for-writing-accessibly/).<!--Hugo does something weird when I use my mention-work shortcode here.-->
* Rules for descriptive link text, for screen reader navigation and for user-agents that display links as footnotes (e.g. some textual browsers with the `dump` flag).
@ -1613,7 +1613,7 @@ A special thanks goes out to GothAlice for the questions she answered in <samp>#
[^8]: Ironically, that page doesn't load the main text without JavaScript despite citing a JavaScript requirement as a downside. If you can't load the page, the same issues with infinte scroll are outlined in the "Accessibility concerns for infinite scroll" section of {{<mention-work itemprop="citation" itemtype="BlogPosting">}}{{<cited-work url="https://addyosmani.com/blog/infinite-scroll-without-layout-shifts/" name="Infinite Scroll without Layout Shifts" extraName="headline">}} by {{<indieweb-person itemprop="author" first-name="Addy" last-name="Osmani" url="https://addyosmani.com/">}}{{</mention-work>}}.
[^9]: Firefox users [can enable "find as you type"](https://website-archive.mozilla.org/www.mozilla.org/access/access/type-ahead/) by toggling a preference in <samp>about:<wbr>config</samp>. Chromium (and derivatives) users can [install an extension](https://github.com/Foxy/chrome-type-ahead); note that it requires full-page access and performs script injection to work.
[^9]: Firefox users [can enable "find as you type"](https://website-archive.mozilla.org/www.mozilla.org/access/access/type-ahead/) by toggling a preference in <samp>about:<wbr />config</samp>. Chromium (and derivatives) users can [install an extension](https://github.com/Foxy/chrome-type-ahead); note that it requires full-page access and performs script injection to work.
[^10]: Iterating through a list of font names to see if each one is available on a user's system is a slow but effective way to determine installed fonts without being granted permission to use the Font Access API. [Browser&shy;Leaks has a demo](https://browserleaks.com/fonts) of this approach. Warning: the page might hog your CPU for a while.
@ -1623,7 +1623,7 @@ A special thanks goes out to GothAlice for the questions she answered in <samp>#
[^13]: [WebAIM](https://wave.webaim.org/api/docs?format=html) and the [University of Illinois](https://fae.disability.illinois.edu/rulesets/IMAGE_4_EN/) recommend 100 characters; [Tangaru](https://www.tanaguru.com/en/) recommends an even smaller limit of 80 characters. I sometimes exceed 100 characters for detailed images but usually stay below 80.
[^14]: Once it gains basic support across all browsers and screen readers, I might recommend using `aria-details` instead of <code>aria-<wbr>des&shy;cribedby</code> for more complex descriptions. At the time of writing, [`aria-details` is only supported by JAWS](https://a11ysupport.io/tech/aria/aria-details_attribute). {{<mention-work itemtype="TechArticle">}}{{<cited-work name="WAI-ARIA 1.2" url="https://www.w3.org/TR/wai-aria-1.2/#aria-details">}}{{</mention-work>}} describes `aria-details` with an example similar to the one I gave in [code snippet 5](#xkcd-html).
[^14]: Once it gains basic support across all browsers and screen readers, I might recommend using `aria-details` instead of <code>aria-<wbr />des&shy;cribedby</code> for more complex descriptions. At the time of writing, [`aria-details` is only supported by JAWS](https://a11ysupport.io/tech/aria/aria-details_attribute). {{<mention-work itemtype="TechArticle">}}{{<cited-work name="WAI-ARIA 1.2" url="https://www.w3.org/TR/wai-aria-1.2/#aria-details">}}{{</mention-work>}} describes `aria-details` with an example similar to the one I gave in [code snippet 5](#xkcd-html).
[^15]: Since <abbr title="Windows High Contrast Mode">WHCM</abbr> sets colors indepen&shy;dently of explicitly-defined ARIA roles, it's a good way to test adherence to [the First Rule of ARIA](#first-rule-of-aria).
@ -1643,13 +1643,13 @@ A special thanks goes out to GothAlice for the questions she answered in <samp>#
[^21]: Screen readers aren't alone here. Several programs strip inline formatting: certain feed readers, search result snippets, and textual browsers invoked with the `-dump` flag are some examples I use every day.
[^22]: I excluded PageSpeed Insights and GTMetrix since those are mostly covered by Lighthouse. I excluded Security Headers, since its approach seems to be recommen&shy;ding headers regardless of whether or not they are necessary. It penalizes forgoing the <code>Per&shy;missions-<wbr>Policy</code> header even if the CSP blocks script loading and execution; see [Security Headers issue #103](https://github.com/securityheaders/securityheaders-bugs/issues/103). I personally find the <code>Per&shy;missions-<wbr>Policy</code> header quite problematic, as I noted in August 2021 on [webappsec-permissions-policy issue #189](https://github.com/w3c/webappsec-permissions-policy/issues/189#issuecomment-904783021).
[^22]: I excluded PageSpeed Insights and GTMetrix since those are mostly covered by Lighthouse. I excluded Security Headers, since its approach seems to be recommen&shy;ding headers regardless of whether or not they are necessary. It penalizes forgoing the <code>Per&shy;missions-<wbr />Policy</code> header even if the CSP blocks script loading and execution; see [Security Headers issue #103](https://github.com/securityheaders/securityheaders-bugs/issues/103). I personally find the <code>Per&shy;missions-<wbr />Policy</code> header quite problematic, as I noted in August 2021 on [webappsec-permissions-policy issue #189](https://github.com/w3c/webappsec-permissions-policy/issues/189#issuecomment-904783021).
[^23]: My site caches HTML documents for ten minutes and caches the RSS feed for several hours. I disagree with webhint's recommen&shy;dations against this: cache durations should be based on request rates and how often a resource is updated. I also disagree with some of its `content-type` recommen&shy;dations: you don't need to declare UTF-8 charsets for SVG content-type headers if the SVG is ASCII-only and called from a UTF-8 HTML document. You gain nothing but header bloat by doing so.
[^24]: Consider disabling the JIT for your normal browsing too; doing so removes whole classes of vulnera&shy;bilities. In Firefox, navigate to <samp>about:<wbr>config</samp> and toggle some flags under <code>javascript<wbr>.options</code>.
[^24]: Consider disabling the JIT for your normal browsing too; doing so removes whole classes of vulnera&shy;bilities. In Firefox, navigate to <samp>about:<wbr />config</samp> and toggle some flags under <code>javascript<wbr />.options</code>.
<figure itemprop="hasPart" itemscope itemtype="https://schema.org/SoftwareSourceCode">
<figure itemprop="hasPart" itemscope="" itemtype="https://schema.org/SoftwareSourceCode">
<figcaption>
<strong id="code-snippet=12" itemprop="name"> <span itemprop="codeSampleType">Code snippet</span> 12</strong>:
Firefox prefs to turn off JIT compilation

View file

@ -92,7 +92,7 @@ The bait-and-switch operation incurred backlash significant enough for a noticea
<figcaption itemprop="caption">
WhatsApp ad, taken from <span itemprop="encodesCreativeWork" itemscope itemtype="https://schema.org/WebPage">{{<cited-work name="Answering your questions about WhatsApps Privacy Policy" url="https://faq.whatsapp.com/general/security-and-privacy/answering-your-questions-about-whatsapps-privacy-policy">}} (archived: <a href="https://web.archive.org/web/20210121163337/https://faq.whatsapp.com/general/security-and-privacy/answering-your-questions-about-whatsapps-privacy-policy" itemprop="archivedAt">Wayback Machine <time datetime="2021-01-21T16:33:37+00:00">2021-01-21</time> snapshot</a>)</span>
WhatsApp ad, taken from <span itemprop="encodesCreativeWork" itemscope="" itemtype="https://schema.org/WebPage">{{<cited-work name="Answering your questions about WhatsApps Privacy Policy" url="https://faq.whatsapp.com/general/security-and-privacy/answering-your-questions-about-whatsapps-privacy-policy">}} (archived: <a href="https://web.archive.org/web/20210121163337/https://faq.whatsapp.com/general/security-and-privacy/answering-your-questions-about-whatsapps-privacy-policy" itemprop="archivedAt">Wayback Machine <time datetime="2021-01-21T16:33:37+00:00">2021-01-21</time> snapshot</a>)</span>
</figcaption>
{{< /transcribed-image-figure >}}
@ -188,7 +188,7 @@ Despite not liking Signal, I still recommended it to my non-technical friends be
Food for thought
----------------
Both of the prior two case studies--Mozilla and Signal--are examples of well-meaning organizations unintentionally leaving users vulnerable to user domestication. The former represents a lack of simplicity but the presence of an open platform. The latter represents a closed platform with a higher degree of simplicity. Intent isn't in the picture when examining the three steps and countermeasures to user domestication.
Both of the prior two case studies---Mozilla and Signal---are examples of well-meaning organizations unintentionally leaving users vulnerable to user domestication. The former represents a lack of simplicity but the presence of an open platform. The latter represents a closed platform with a higher degree of simplicity. Intent isn't in the picture when examining the three steps and countermeasures to user domestication.
[paulsnar](https://mastodon.technology/@paulsnar) pointed out a potential conflict between simplicity and open platforms:
@ -205,7 +205,7 @@ Closing notes
Before it turned into a manifesto of sorts, this post was intended to be an expanded version of a comment I left under a [Fediverse post](https://fosstodon.org/@binyamin/105608407071699797) by [Binyamin Green](https://binyam.in/).
I initially decided to expand it to its current form for personal reasons. Nowadays, people demand a thorough explanation every time I refuse to use something that "everybody" uses (WhatsApp, Microsoft Office, Windows, macOS, Google Docs...). They'll usually ignore the explanation, but they expect one anyway. By the next time I meet them, they'll have forgotten our prior conversation and will re-enact the same dialogue again. Justifying all my life choices by sending logically correct statements into the void--knowing that everything I say will be ignored--is an emotionally draining process that has taken a toll on my mental health for the past few years; sending my friends this article and changing the subject should save me a few gray hairs in the years to come.
I initially decided to expand it to its current form for personal reasons. Nowadays, people demand a thorough explanation every time I refuse to use something that "everybody" uses (WhatsApp, Microsoft Office, Windows, macOS, Google Docs...). They'll usually ignore the explanation, but they expect one anyway. By the next time I meet them, they'll have forgotten our prior conversation and will re-enact the same dialogue again. Justifying all my life choices by sending logically correct statements into the void---knowing that everything I say will be ignored---is an emotionally draining process that has taken a toll on my mental health for the past few years; sending my friends this article and changing the subject should save me a few gray hairs in the years to come.
This article extends the guiding philosophies of the Free Software and Copyleft movements. Thanks to [Barna Zsombor](https://bzsombor.web.elte.hu/) for giving good feedback over IRC.

View file

@ -15,7 +15,7 @@ This privacy policy applies to the following services:
1. The Web site <https://seirdy.one>
2. The hidden Web service [http://wgq3\[...\]d<wbr>.onion](http://wgq3bd2kqoybhstp77i3wrzbfnsyd27wt34psaja4grqiezqircorkyd.onion/ "{title='http://wgq3bd2kqoybhstp77i3wrzbfnsyd27wt34psaja4grqiezqircorkyd.onion'}"), accessible over the Tor network
2. The hidden Web service [http://wgq3\[...\]d<wbr />.onion](http://wgq3bd2kqoybhstp77i3wrzbfnsyd27wt34psaja4grqiezqircorkyd.onion/ "{title='http://wgq3bd2kqoybhstp77i3wrzbfnsyd27wt34psaja4grqiezqircorkyd.onion'}"), accessible over the Tor network
3. The Gemini capsule <gemini://seirdy.one>
@ -87,13 +87,13 @@ By default, web browsers may share arbitrary information with a server through H
By default, web browsers can share near-arbitrary identifying data with a server by executing near-arbitrary JavaScript, or store this information for future transmission. I have disabled this behavior with a `Content-Security-Policy` HTTP header that forbids script loading (`script-src: none`), script execution (`sandbox`), and making connections for any purpose other than downloading a page a user navigated to (`connect-src`).
By default, web browsers may "pre-fetch" DNS queries for links on a page, potentially leaking information to third parties without a user's consent; I have disabled this behavior with the <code>X-DNS-Prefetch-<wbr>Control</code> header. This header is respected by Chromium, Firefox, and Chromium derivatives (e.g. Google Chrome, Microsoft Edge).
By default, web browsers may "pre-fetch" DNS queries for links on a page, potentially leaking information to third parties without a user's consent; I have disabled this behavior with the <code>X-DNS-Prefetch-<wbr />Control</code> header. This header is respected by Chromium, Firefox, and Chromium derivatives (e.g. Google Chrome, Microsoft Edge).
By default, user agents using HTTPS may contact a certificate authority to check the revocation status of an TLS certificate. I have disabled and replaced this behavior by including an "OCSP Must-Staple" directive in the TLS certificates used by my Web servers.
By default, user agents using HTTP or HTTPS may share a "referring" location with the destination website when following a link. I have disabled this by sending a `Referrer-Policy: no-referrer` header.
By default, Web browsers may share characteristics about the user's hardware, connection type, and personalizations using Client Hints and media queries. Browsers may request Web content according conditionally, in response to a `media` attribute in HTML or XHTML documents. Browsers may leverage stylesheets that use media queries to select varying `background-image` files. No Web content on seirdy.one will send network traffic in response to media queries except <code>prefers-color-<wbr>scheme</code>, assuming the use of a standards-compliant browser. Media queries and client hints will have no impact on HTTP responses except for dark image variants. This is a single binary piece of information that isn't enough to let me realistically identify anyone.
By default, Web browsers may share characteristics about the user's hardware, connection type, and personalizations using Client Hints and media queries. Browsers may request Web content according conditionally, in response to a `media` attribute in HTML or XHTML documents. Browsers may leverage stylesheets that use media queries to select varying `background-image` files. No Web content on seirdy.one will send network traffic in response to media queries except <code>prefers-color-<wbr />scheme</code>, assuming the use of a standards-compliant browser. Media queries and client hints will have no impact on HTTP responses except for dark image variants. This is a single binary piece of information that isn't enough to let me realistically identify anyone.
By default, many networks and Internet service providers often alter requests by redirecting them or injecting content. I have prevented this behavior by using a secure TLS cipher suite.

View file

@ -4,7 +4,7 @@ keywords: intern, python, golang, go, lua, moonscript, shell, bash, zsh, posix,
title: Rohan Kumar
disableMeta: true
---
[https://seirdy<wbr>.one](https://seirdy.one/) | [seirdy<wbr>@seirdy.one](mailto:seirdy@seirdy.one)
[https://seirdy<wbr />.one](https://seirdy.one/) | [seirdy<wbr />@seirdy.one](mailto:seirdy@seirdy.one)
Detail oriented, committed, self-motivated, open-source enthusiast proficient in Python, Go, Linux/UNIX systems, and cloud-native computing looking for an internship.
@ -38,17 +38,17 @@ Technical Skills
- Monitoring systems: Grafana and the InfluxData stack (InfluxDB, Telegraf, Kapacitor, Chronograf).
- Programming languages: Proficient in Go, Python, Lua, and shell languages (Bash, Zsh, POSIX sh). Familiar with Java, C, SageMath.
- Python: Familiar with math and data science libraries such as the SciPy stack, Jupyter notebooks, and Pandas.
- Other tools: Git, Continuous Integration/<wbr>Delivery (Jenkins, GitLab CI, Travis CI), Nginx.
- Other tools: Git, Continuous Integration/<wbr />Delivery (Jenkins, GitLab CI, Travis CI), Nginx.
Portfolio
---------
Git repositories mirrored across [Sourcehut](https://sr.ht/~seirdy), [GitHub](https://github.com/Seirdy), and [GitLab](https://gitlab.com/Seirdy). Selected projects:
### Clogstats: [sr.ht<wbr>/~seirdy<wbr>/clogstats](https://sr.ht/~seirdy/clogstats)
### Clogstats: [sr.ht<wbr />/~seirdy<wbr />/clogstats](https://sr.ht/~seirdy/clogstats)
Gathers IRC channel activity statistics from WeeChat logs and performs time-series analysis and forecasting on them. It can quantify, rank, and chart chatting activity over time and display forecasts. It can also detect anomalous increases in activity. Written in Python with NumPy and Pandas.
### MOAC: [sr.ht<wbr>/~seirdy<wbr>/MOAC](https://sr.ht/~seirdy/MOAC/)
### MOAC: [sr.ht<wbr />/~seirdy<wbr />/MOAC](https://sr.ht/~seirdy/MOAC/)
Analyze password strength given physical limits to computing, and generate secure passwords. Computes theoretical limits to a brute-force attack limited by given physical quantities (mass, energy, power, temperature, etc.) and generates passwords to withstand them. This provides a future-proof understanding of password strength. Extensively tested. Written in Go.

View file

@ -1,8 +1,9 @@
<!DOCTYPE html>
<html lang={{- default "" .Site.LanguageCode }} prefix="og: https://ogp.me/ns# article: https://ogp.me/ns/article# cc: http://creativecommons.org/ns#">
<html xmlns="http://www.w3.org/1999/xhtml" lang="{{- default "" .Site.LanguageCode }}" xml:lang="{{- default "" .Site.LanguageCode }}" prefix="og: https://ogp.me/ns# article: https://ogp.me/ns/article# cc: http://creativecommons.org/ns#">
{{ partial "head.html" . -}}
<body itemscope itemtype="https://schema.org/WebPage">
<body itemscope="" itemtype="https://schema.org/WebPage">
{{ partial "header.html" . -}}
{{- block "main" . }}{{- end -}}
{{ partialCached "footer.html" . }}
</body>
</html>

View file

@ -1,7 +1,7 @@
{{ define "main" }}
<main itemprop="mainEntity" class="h-feed hfeed" itemscope itemtype="https://schema.org/DataFeed">
<h1 id="bookmarks" class="p-name" itemprop="name headline">My book&shy;marks</h1>
{{ .Content }}
<main itemprop="mainEntity" class="h-feed hfeed" itemscope="" itemtype="https://schema.org/DataFeed">
<h1 id="bookmarks" class="p-name" itemprop="name headline">My book&#173;marks</h1>
{{ partial "processed-content.html" . }}
<p role="doc-tip">
Timestamp format: <code>YYYY-MM-DD HH:MM</code>, as per <cite><a href="https://www.ietf.org/rfc/rfc3339.txt">RFC 3339</a></cite>
</p>
@ -12,18 +12,18 @@
{{- $tags := split $bookmark.tags "," -}}
{{- $firstTag := index $tags 0 }}
{{- $timestamp := dateFormat "2006-01-02 15:04:05-0700" $firstTag }}
<li itemprop="dataFeedElement" itemscope itemtype="https://schema.org/DataFeedItem">
<meta itemprop="dateCreated" content="{{ $timestamp }}"><!--Just because we can't have one timestap refer to two items-->
<article class="h-entry hentry" itemprop="item" itemscope itemtype="https://schema.org/SocialMediaPosting">
<meta itemprop="headline" content="{{ $bookmark.title }}"><!--Just because we can't have one headline refer to two items-->
<h2 itemprop="sharedContent" itemscope itemtype="https://schema.org/WebPage" class="p-name">
<li itemprop="dataFeedElement" itemscope="" itemtype="https://schema.org/DataFeedItem">
<meta itemprop="dateCreated" content="{{ $timestamp }}" /><!--Just because we can't have one timestap refer to two items-->
<article class="h-entry hentry" itemprop="item" itemscope="" itemtype="https://schema.org/SocialMediaPosting">
<meta itemprop="headline" content="{{ $bookmark.title }}" /><!--Just because we can't have one headline refer to two items-->
<h2 itemprop="sharedContent" itemscope="" itemtype="https://schema.org/WebPage" class="p-name">
<a itemprop="url" href="{{ $bookmark.uri }}" class="u-bookmark-of h-cite">
<span itemprop="headline">{{ $bookmark.title | replaceRE `Defunctionalisation` `Defunction&shy;alisation` | safeHTML }}</span>
<span itemprop="headline">{{ $bookmark.title | replaceRE `Defunctionalisation` `Defunction&#173;alisation` | safeHTML }}</span>
</a>
</h2>
<p>
Bookmarked on: <time class="dt-published published" itemprop="datePublished" datetime="{{ dateFormat "2006-01-02 15:04:05Z07:00" $timestamp }}">{{ dateFormat "2006-01-02 15:04" $timestamp }}</time>
<br>Tags: <span itemprop="keywords">
<br />Tags: <span itemprop="keywords">
{{- $start := 2 -}}
{{- $firstTag := (index $tags 1) -}}
{{- if (eq $firstTag "public") -}}
@ -39,7 +39,7 @@
{{- end }}
</span>
</p>
<p class="e-summary entry-summary" itemprop="description">{{ markdownify $bookmark.description }}</p>
<p class="e-summary entry-summary" itemprop="description">{{ $bookmark.description | markdownify | replaceRE `\&rsquo;` `` | replaceRE `\&nbsp;` `\&#160;` | replaceRE `\&ldquo;` `“` | replaceRE `\&rdquo;` `”` | replaceRE `\&hellip;` `—` | replaceRE `\&mdash;` `—` | replaceRE `\&shy;` `\&#173;` | replaceRE `&lsquo;` `` | safeHTML }}</p>
</article>
</li>
{{- end }}

View file

@ -1,5 +1,5 @@
{{ define "main" }}
<main itemprop="mainEntity" class="h-feed hfeed" itemscope itemtype="https://schema.org/DataFeed">
<main itemprop="mainEntity" class="h-feed hfeed" itemscope="" itemtype="https://schema.org/DataFeed">
<h1 class="p-name" itemprop="name headline" id="notes">Notes</h1>
<p>This is my microblog. These are my short informal entries, sorted by date (newest first). For longer entries, <a href="../posts/">see my blog</a>.</p>
<p>An <a href="./atom.xml">Atom</a> and <a href="./index.xml">RSS</a> feed is availabe, containing the full text of all my notes.</p>
@ -10,8 +10,8 @@
{{- $posts := (where site.RegularPages "Section" "notes") -}}
{{- range $posts -}}
{{- $canonicalRelPermalink := .RelPermalink | replaceRE "^/~seirdy/" "/" -}}
<li itemprop="dataFeedElement" itemscope itemtype="https://schema.org/DataFeedItem">
<article class="h-entry hentry" itemprop="item" itemscope itemtype="https://schema.org/SocialMediaPosting" itemid="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">
<li itemprop="dataFeedElement" itemscope="" itemtype="https://schema.org/DataFeedItem">
<article class="h-entry hentry" itemprop="item" itemscope="" itemtype="https://schema.org/SocialMediaPosting" itemid="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">
<h2 itemprop="name headline" class="p-name entry-title">
<a href="{{ .Permalink }}" itemprop="url" class="u-url url" rel="bookmark">
{{ .Title }}
@ -21,7 +21,7 @@
{{ if gt (sub .Lastmod.Unix .Date.Unix) 3600 -}}
, updated <time{{ if not (.Params.evergreen) }} itemprop="dateModified" class="dt-updated updated"{{ end }} datetime="{{ .Lastmod.Format "2006-01-02 15:04:05Z07:00" }}">{{ .Lastmod.Format "2006-01-02 15:04:05" }}</time>
{{- end }}
<div class="e-content entry-content" itemprop="articleBody">{{ .Content }}</div>
<div class="e-content entry-content" itemprop="articleBody">{{ partial "processed-content.html" . }}</div>
</article>
</li>
{{- end }}

View file

@ -1,6 +1,6 @@
{{ define "main" }}
{{- $canonicalRelPermalink := .RelPermalink | replaceRE "^/~seirdy/" "/" }}
<main itemprop="mainEntity" itemscope itemtype="https://schema.org/Article" itemid="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">
<main itemprop="mainEntity" itemscope="" itemtype="https://schema.org/Article" itemid="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">
{{ partial "full-article.html" . }}
</main>
{{ end }}

View file

@ -1,6 +1,6 @@
{{ define "main" }}
<main>
{{ .Content }}
{{ partial "processed-content.html" . }}
{{ partial "posts.html" . }}
{{ partial "webrings.html" . }}
</main>

View file

@ -1,7 +1,7 @@
{{- define "main" -}}
{{- $canonicalRelPermalink := .RelPermalink | replaceRE "^/~seirdy/" "/" }}
<main itemprop="hasPart" itemscope itemtype="https://schema.org/SocialMediaPosting" itemid="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">
<link itemprop="isPartOf" href="{{ .Site.Params.CanonicalBaseURL }}/">
<main itemprop="hasPart" itemscope="" itemtype="https://schema.org/SocialMediaPosting" itemid="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">
<link itemprop="isPartOf" href="{{ .Site.Params.CanonicalBaseURL }}/" />
{{ partial "full-article.html" . }}
{{ partial "webmentions.html" . }}
</main>

View file

@ -5,7 +5,7 @@
{{ partial "search.html" }}
<nav aria-label="site info">
<ul>
<li itemprop="license" itemscope itemtype="https://schema.org/CreativeWork">
<li itemprop="license" itemscope="" itemtype="https://schema.org/CreativeWork">
<a rel="license" itemprop="url" href="https://creativecommons.org/licenses/by-sa/4.0/"><span itemprop="name">CC BY-SA 4.0</span></a>
</li>
<li>

View file

@ -4,10 +4,10 @@
{{- if not .Params.disableMeta }}
{{ partial "post-meta.html" . }}
{{- end }}
<hr>
<hr />
</header>
<div class="e-content entry-content" itemprop="articleBody">
<meta itemprop="author" content="Rohan Kumar">
<meta itemprop="author" content="Rohan Kumar" />
<!--That was needed bc some reading modes get confused by other authors referenced in the text-->
{{- partial "processed-content" . -}}
</div>

View file

@ -1,54 +1,54 @@
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
{{- $canonicalRelPermalink := .RelPermalink | replaceRE "^/~seirdy/" "/" }}
<meta charset="utf-8">
<meta name="disabled-adaptations" content="watch"><meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="disabled-adaptations" content="watch" /><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
{{ if or (eq site.BaseURL site.Params.CanonicalBaseURL) (in site.BaseURL "wgq3bd2kqoybhstp77i3wrzbfnsyd27wt34psaja4grqiezqircorkyd.onion") -}}
<meta name="robots" content="index,follow,max-image-preview:large,max-snippet=-1">
<meta name="robots" content="index,follow,max-image-preview:large,max-snippet=-1" />
{{ end -}}
<link href="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}" rel="canonical">
<link href="{{ .Site.Params.WebmentionEndpoint }}" rel="webmention">
<link href="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}" rel="canonical" />
<link href="{{ .Site.Params.WebmentionEndpoint }}" rel="webmention" />
{{ $webmanifest := resources.Get "/manifest.webmanifest" | resources.ExecuteAsTemplate "manifest.webmanifest" . | resources.Minify | resources.Fingerprint "md5" -}}
{{- printf `<link href="%s" rel="manifest">` $webmanifest.RelPermalink | safeHTML }}
{{- printf `<link href="%s" rel="manifest" />` $webmanifest.RelPermalink | safeHTML }}
<!--Feeds for both notes and posts; posts come first unless we're in the notes section.-->
{{- $isNotes := false -}}
{{- if or (eq .Section "notes") (eq .Title "Notes") -}}
{{- $isNotes = true -}}
<link rel="alternate" type="application/atom+xml" href="{{ site.BaseURL }}notes.xml" title="Notes">
<link rel="alternate" type="application/atom+xml" href="{{ site.BaseURL }}notes.xml" title="Notes" />
{{- end }}
<link rel="alternate" type="application/atom+xml" href="{{ site.BaseURL }}posts.xml" title="Posts">
<link rel="alternate" type="application/atom+xml" href="{{ site.BaseURL }}posts.xml" title="Posts" />
{{ if not $isNotes -}}
<link rel="alternate" type="application/atom+xml" href="{{ site.BaseURL }}notes.xml" title="Notes">
<link rel="alternate" type="application/atom+xml" href="{{ site.BaseURL }}notes.xml" title="Notes" />
{{- end }}
<title>{{ .Title }}{{ if and (lt (len .Title) 54) (ne $canonicalRelPermalink "/") }} - Seirdy{{ end }}</title>
{{ $description := .Site.Params.Description -}}
{{- if .Params.description -}}
{{- $description = .Params.Description -}}
{{- else if .Summary -}}
{{- $description = .Summary | replaceRE `\n` ` ` | safeHTML -}}
{{- $description = .Summary | replaceRE `\n` ` ` | replaceRE `\&rsquo;` `` | replaceRE `\&nbsp;` `\&#160;` | replaceRE `\&ldquo;` `“` | replaceRE `\&rdquo;` `”` | replaceRE `\&hellip;` `—` | replaceRE `\&mdash;` `—` | replaceRE `\&shy;` `\&#173;` | replaceRE `&lsquo;` `` | safeHTML -}}
{{- end -}}
<meta name="description" content="{{ $description }}">
<meta name="author" content="{{ .Site.Author.name }}">
<meta property="article:author" content="{{ .Site.Author.name }}">
<meta name="description" content="{{ $description }}" />
<meta name="author" content="{{ .Site.Author.name }}" />
<meta property="article:author" content="{{ .Site.Author.name }}" />
{{ if and (gt .Date 0) (not .Params.evergreen) -}}
<meta property="article:published_time" content="{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}">
<meta property="article:published_time" content="{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}" />
{{ end -}}
{{ if lt .Date .Lastmod -}}
<meta property="article:modified_time" content="{{ .Lastmod.Format "2006-01-02T15:04:05Z07:00" }}">
<meta property="article:modified_time" content="{{ .Lastmod.Format "2006-01-02T15:04:05Z07:00" }}" />
{{- end -}}
<!--the Tor Browser's safest setting disables SVGs but still downloads them to avoid fingerprinting-->
{{ if not (in site.BaseURL ".onion") -}}
{{ $icon_svg := resources.Get "/favicon.svg" | resources.Fingerprint "md5" }}
{{- printf `<link rel="icon" sizes="any" href="%s" type="image/svg+xml">` $icon_svg.RelPermalink | safeHTML }}
{{- printf `<link rel="icon" sizes="any" href="%s" type="image/svg+xml" />` $icon_svg.RelPermalink | safeHTML }}
{{- end }}
{{ $icon_192 := resources.Get "/apple-touch-icon.png" | resources.Fingerprint "md5" }}
{{- printf `<link rel="icon" sizes="192x192" href="%s" type="image/png">` $icon_192.RelPermalink | safeHTML -}}
{{- printf `<link rel="icon" sizes="192x192" href="%s" type="image/png" />` $icon_192.RelPermalink | safeHTML -}}
{{ $favicon := resources.Get "/favicon.png" -}}
{{ $favicon_base64 := $favicon.Content | base64Encode }}
{{ printf `<link rel="icon" sizes="32x32" href="data:image/png;base64,%s" type="image/png">` $favicon_base64 | safeHTML }}
<meta name="color-scheme" content="light dark">
<meta name="format-detection" content="telephone=no"><!-- Why does apple do this -->
<meta name="theme-color" content="#111" media="(prefers-color-scheme:dark)">
<meta name="theme-color" content="#fff" media="(prefers-color-scheme:light)">
{{ printf `<link rel="icon" sizes="32x32" href="data:image/png;base64,%s" type="image/png" />` $favicon_base64 | safeHTML }}
<meta name="color-scheme" content="light dark" />
<meta name="format-detection" content="telephone=no" /><!-- Why does apple do this -->
<meta name="theme-color" content="#111" media="(prefers-color-scheme:dark)" />
<meta name="theme-color" content="#fff" media="(prefers-color-scheme:light)" />
<!-- inline CSS; remember to allow it with a hash in the CSP -->
{{- $resources := slice -}}
{{- $resources = $resources | append (resources.Get "/css/main.css") -}}
@ -59,10 +59,10 @@
{{ $resources = $resources | append (resources.Get "css/print.css" | resources.ExecuteAsTemplate "print.css" .) -}}
{{- $css := $resources | resources.Concat "css/style.css" | minify -}}
<style>{{ $css.Content | safeCSS }}</style>
<meta property="og:title" content="{{ .Title }}">
<meta property="og:site_name" content="{{ $.Site.Title }}">
<meta property="og:title" content="{{ .Title }}" />
<meta property="og:site_name" content="{{ $.Site.Title }}" />
{{- if not (or (ne "page" .Kind) (eq $canonicalRelPermalink "/bookmarks/") (eq $canonicalRelPermalink "/posts/")) }}
<meta property="og:type" content="article">
<meta property="og:type" content="article" />
{{- end -}}
<!-- ANOTHER meta image?! When will it end? -->
{{- $og_image := resources.Get "/favicon512.png" | resources.Fingerprint "md5" -}}
@ -73,11 +73,11 @@
{{- with .Params.image_alt -}}
{{- $og_image_alt = . -}}
{{- end }}
{{ printf `<meta property="og:image" content="%s">` $og_image.Permalink | safeHTML }}
<meta property="og:image:type" content="image/png">
<meta property="og:image:height" content="{{ $og_image.Height }}"><meta property="og:image:width" content="{{ $og_image.Width }}">
<meta property="og:image:alt" content="{{ $og_image_alt }}">
<meta property="og:url" content="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">
<meta property="og:description" content="{{ $description }}">
{{ hugo.Generator | replaceRE " />" ">" | safeHTML}}
{{ printf `<meta property="og:image" content="%s" />` $og_image.Permalink | safeHTML }}
<meta property="og:image:type" content="image/png" />
<meta property="og:image:height" content="{{ $og_image.Height }}" /><meta property="og:image:width" content="{{ $og_image.Width }}" />
<meta property="og:image:alt" content="{{ $og_image_alt }}" />
<meta property="og:url" content="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}" />
<meta property="og:description" content="{{ $description }}" />
{{ hugo.Generator }}
</head>

View file

@ -13,7 +13,7 @@
{{ else -}}
itemprop="isPartOf"
{{ end -}}
itemscope itemtype="https://schema.org/Blog https://schema.org/WebSite"
itemscope="" itemtype="https://schema.org/Blog https://schema.org/WebSite"
itemid="{{ .Site.Params.CanonicalBaseURL }}/">
<a rel="home" itemprop="url" href="{{ .Site.BaseURL }}"{{- if $isHome }} aria-current="page"{{- end -}}>
{{- if $isHome -}}
@ -25,7 +25,7 @@
</li>
{{ range .Site.Menus.main -}}
{{ $isCurrent := false }}
<li itemProp="hasPart" itemscope itemtype="https://schema.org/SiteNavigationElement">
<li itemProp="hasPart" itemscope="" itemtype="https://schema.org/SiteNavigationElement">
<a href="{{ .URL }}" itemprop="url" {{- if or (eq $currentPage.RelPermalink .URL) ($currentPage.HasMenuCurrent "main" .) -}}{{- $isCurrent = true }} aria-current="page"{{- end -}}>
{{- if or $isCurrent (eq $currentPage.Section .Title) -}}
<strong itemprop="name">{{- .Name -}}</strong>

View file

@ -11,10 +11,10 @@
{{- $action }} <time{{ if not (.Params.evergreen) }} itemprop="dateCreated datePublished" class="dt-published published"{{ end }} datetime="{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}">{{ .Date.Format "2006-01-02" }}</time>
by {{- partial "indieweb-author.html" -}} on his <a rel="canonical" itemprop="mainEntityOfPage url" class="u-url url" href="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">Website</a>{{- with .OutputFormats.Get "gemtext" -}}{{- printf " " -}}and <a rel="syndication" class="u-syndication" href="{{replace .Permalink "/gemini" "" 1 | safeURL}}">Gemini capsule</a>{{- end -}}.
{{ if gt (sub .Lastmod.Unix .Date.Unix) 3600 -}}
<br>
<br />
Last updated <time itemprop="dateModified" class="dt-updated updated" datetime="{{ .Lastmod.Format "2006-01-02T15:04:05Z07:00" }}">{{ .Lastmod.Format "2006-01-02" }}</time>. <a href="{{ $logURL }}">Changelog</a>.
{{- end }}
{{ if not $isNotes -}}
<br>
<br />
{{ partial "wordcount.html" . -}}
{{ end }}

View file

@ -3,16 +3,16 @@
{{- $isStandalone = true -}}
{{- end -}}
{{- if $isStandalone -}}
<main itemprop="mainEntity" class="h-feed hfeed" itemscope itemtype="https://schema.org/CompleteDataFeed">
<main itemprop="mainEntity" class="h-feed hfeed" itemscope="" itemtype="https://schema.org/CompleteDataFeed">
<h1 class="p-name" itemprop="name headline" id="posts">Posts</h1>
<p>These are all of my posts, sorted by date (newest first).</p>
<p>An <a href="./atom.xml">Atom</a> and <a href="./index.xml">RSS</a> feed is availabe, containing the full text of all my posts.</p>
{{- else -}}
<section class="h-feed hfeed" itemprop="hasPart" itemscope itemtype="https://schema.org/DataFeed">
<section class="h-feed hfeed" itemprop="hasPart" itemscope="" itemtype="https://schema.org/DataFeed">
<h2 class="p-name" itemprop="name" id="posts">Posts</h2>
<p>Here&rsquo;s a selection of my best posts, in featured order. To see the rest, visit <a href="posts/">my Posts page</a>.</p>
<p>Heres a selection of my best posts, in featured order. To see the rest, visit <a href="posts/">my Posts page</a>.</p>
{{- end }}
<p>I edit some of these posts quite often; some are updated indefinitely. Check the &ldquo;updated&rdquo; timestamps.</p>
<p>I edit some of these posts quite often; some are updated indefinitely. Check the “updated” timestamps.</p>
<p role="doc-tip">
Timestamp format: <code>YYYY-MM-DD</code>, as per <cite><a href="https://www.ietf.org/rfc/rfc3339.txt">RFC 3339</a></cite> and <cite><a href="https://xkcd.com/1179/">ISO 8601</a></cite>
</p>
@ -23,8 +23,8 @@
{{- end -}}
{{- range $posts -}}
{{- $canonicalRelPermalink := .RelPermalink | replaceRE "^/~seirdy/" "/" -}}
<li itemprop="dataFeedElement" itemscope itemtype="https://schema.org/DataFeedItem">
<article class="h-entry hentry" itemprop="item" itemscope itemtype="https://schema.org/BlogPosting" itemid="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">
<li itemprop="dataFeedElement" itemscope="" itemtype="https://schema.org/DataFeedItem">
<article class="h-entry hentry" itemprop="item" itemscope="" itemtype="https://schema.org/BlogPosting" itemid="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">
{{ if $isStandalone -}}
<h2
{{- else -}}

View file

@ -9,7 +9,7 @@
endnotes from a <section> to a <div>.
-->
{{- $referencesWithoutHeading := `(<div class="footnotes" role="doc-endnotes">
<hr>)` -}}
<hr />)` -}}
{{- $referencesWithHeading := printf `<section role="doc-endnotes" aria-labelledby="note-hd">
<h2 id="note-hd">%s</h2>` ($footnote_heading) -}}
@ -28,27 +28,26 @@
backlink id in <a> since <a> is focusable, remove unused class.
-->
{{- $badNoteRef := `<sup id="fnref([0-9\:]*)"><a( [^>]*)class="footnote-ref" role="doc-noteref">([0-9]*)</a>` -}}
{{- $goodNoteRef := `<sup><a${2}id="fnref${1}" role="doc-noteref">note&nbsp;${3}</a>` -}}
{{- $goodNoteRef := `<sup><a${2}id="fnref${1}" role="doc-noteref">note&#160;${3}</a>` -}}
<!--Move the Table of Contents heading *inside* the <nav> element-->
{{- $tocHeadingOutside := `<h2>Table of Contents</h2><nav(?:.*)>` -}}
{{- $tocHeadingInside := `<nav id=TableOfContents role="doc-toc" aria-labelledby="toc-hd" tabindex="-1">
{{- $tocHeadingInside := `<nav id="TableOfContents" role="doc-toc" aria-labelledby="toc-hd" tabindex="-1">
<h2 id="toc-hd">Table of Contents</h2>` -}}
<!--Give footnote backlinks accessible names-->
{{- $footnoteBacklinksBad := `<a href="#fnref:([0-9]*)" class="footnote-backref"(.*role="doc-backlink"(?:[^>]*)?)>([^<]*)` -}}
{{- $footnoteBacklinksGood := `<a href="#fnref:${1}" aria-labelledby="bl-${1}"${2}>${3} <span id="bl-${1}" hidden>back to reference ${1}</span>` -}}
{{- $footnoteBacklinksGood := `<a href="#fnref:${1}" aria-labelledby="bl-${1}"${2}>${3} <span id="bl-${1}" hidden="">back to reference ${1}</span>` -}}
<!--
If two backlinks exist, give them different names.
I currently don't have any triple backlinks; if I ever do, I'll implement this properly with a loop.
-->
{{- $repeatedFootnoteBacklinksBad := `<a href="#fnref([0-9]):([0-9]*)"(.*role="doc-backlink"(?:[^>]*)?)>([^<]*)` -}}
{{- $repeatedFootnoteBacklinksGood := `<a href="#fnref${1}:${2}" aria-labelledby="bl-${2}-2"${3}>${4} <span id="bl-${2}-2" hidden>back to reference ${2}, instance 2</span>` -}}
{{- $repeatedFootnoteBacklinksGood := `<a href="#fnref${1}:${2}" aria-labelledby="bl-${2}-2"${3}>${4} <span id="bl-${2}-2" hidden="">back to reference ${2}, instance 2</span>` -}}
<!--Make endnotes focusable by ATs. Necessary for VoiceOver compatibility.-->
{{- $endNotesNotFocusable := `<li id="fn:([0-9]*)">` -}}
{{- $endNotesFocusable := `<li id="fn:${1}" tabindex="-1">` -}}
{{- .Content | replaceRE $referencesWithoutHeading $referencesWithHeading | replaceRE $badNoteRef $goodNoteRef | replaceRE $endnotesClosingDiv $endnotesClosingSection | replaceRE $tocHeadingOutside $tocHeadingInside | replaceRE $footnoteBacklinksBad $footnoteBacklinksGood | replaceRE $repeatedFootnoteBacklinksBad $repeatedFootnoteBacklinksGood | replaceRE $endNotesNotFocusable $endNotesFocusable | safeHTML -}}
{{- .Content | replaceRE $referencesWithoutHeading $referencesWithHeading | replaceRE $badNoteRef $goodNoteRef | replaceRE $endnotesClosingDiv $endnotesClosingSection | replaceRE $tocHeadingOutside $tocHeadingInside | replaceRE $footnoteBacklinksBad $footnoteBacklinksGood | replaceRE $repeatedFootnoteBacklinksBad $repeatedFootnoteBacklinksGood | replaceRE $endNotesNotFocusable $endNotesFocusable | replaceRE `\&rsquo;` `` | replaceRE `\&nbsp;` `\&#160;` | replaceRE `\&ldquo;` `“` | replaceRE `\&rdquo;` `”` | replaceRE `\&hellip;` `—` | replaceRE `\&mdash;` `—` | replaceRE `\&shy;` `\&#173;` | replaceRE `&lsquo;` ``| safeHTML -}}

View file

@ -1,9 +1,9 @@
<form
itemprop="potentialAction" itemscope itemtype="https://schema.org/SearchAction"
itemprop="potentialAction" itemscope="" itemtype="https://schema.org/SearchAction"
action="https://searchmysite.net/search/" method="get">
<label for="search">Search this site:</label>
<label for="search">Search this site (powered by <a rel="nofollow" href="https://searchmysite.net/">Search My Site</a>):</label>
<div><!--We need the extra divs to serve as pseudo-table-cells.-->
<input id="search" itemprop="query" type="search" value="domain:seirdy.one " name="q">
<div><input type="submit" value="search"></div>
<input id="search" itemprop="query" type="search" value="domain:seirdy.one " name="q" />
<div><input type="submit" value="search" /></div>
</div>
</form>

View file

@ -1,12 +1,15 @@
<fieldset>
<legend>Publish a response on your own website and share the link here to send me a webmention! Include a link to this page's canonical location for it to be accepted.</legend>
<form
itemprop="potentialAction" itemscope itemtype="https://schema.org/CommentAction"
itemprop="potentialAction" itemscope="" itemtype="https://schema.org/CommentAction"
action="https://seirdy.one/webmentions/receive" method="post">
<meta itemprop="actionStatus" content="PotentialActionStatus">
<label for="menchie">Publish a response on your own website and share the link here to send me a webmention! Include a link to this page's canonical location for it to be accepted.</label>
<meta itemprop="actionStatus" content="PotentialActionStatus" />
{{ $canonicalRelPermalink := .RelPermalink | replaceRE "^/~seirdy/" "/" -}}
<input type="hidden" name="target" value="{{ .Site.Params.canonicalBaseURL }}{{ $canonicalRelPermalink }}">
<input type="hidden" name="target" value="{{ .Site.Params.canonicalBaseURL }}{{ $canonicalRelPermalink }}" />
<label for="menchie">URL of page linking here</label>
<div><!--We need the extra divs to serve as pseudo-table-cells.-->
<input id="menchie" type="url" name="source">
<div><input type="submit" value="submit"></div>
<input id="menchie" type="url" name="source" />
<div><input type="submit" value="submit" /></div>
</div>
</form>
</fieldset>

View file

@ -1,7 +1,7 @@
<section aria-labelledby="webmentions">
<h2 id="webmentions" tabindex="-1">Webmen&shy;tions</h2>
<h2 id="webmentions" tabindex="-1">Webmen&#173;tions</h2>
<p>This site supports <a href="https://indieweb.org/webmention">Webmentions</a>. Webmentions received for this post will appear in the following list after I approve them. I sometimes send Webmentions to myself on behalf of linking sites that don't support them. Check the <a href="https://web.archive.org/">Wayback Machine</a> if any links are broken.</p>
{{ partial "webmention-form.html" }}
{{ partial "webmention-form.html" . }}
<dl>
{{- $target := .RelPermalink | replaceRE "^/~seirdy/" "/" }}
{{- $oldTarget := $target | replaceRE "/posts" "" | replaceRE "/$" ".html" -}}
@ -11,9 +11,9 @@
{{ range sort $webmentions "created_at" -}}
{{ $webmention := . -}}
{{ if (eq $webmention.type "like") -}}
<div itemprop="potentialAction" itemscope itemtype="https://schema.org/LikeAction" class="u-like h-cite">
<div itemprop="potentialAction" itemscope="" itemtype="https://schema.org/LikeAction" class="u-like h-cite">
{{- else -}}
<div itemprop="comment" itemscope itemtype="https://schema.org/Comment" class="u-comment h-cite">
<div itemprop="comment" itemscope="" itemtype="https://schema.org/Comment" class="u-comment h-cite">
{{- end -}}
<!--Will eventually add role="comment" once WAI-ARIA 1.3 starts seeing some adoption.-->
<dt>
@ -27,7 +27,7 @@
<dd>
{{ if (eq $webmention.type "like") -}}
{{ if $webmention.author_name -}}
<span itemprop="agent" itemscope itemtype="https://schema.org/Person" class="h-card p-author vcard"><span itemprop="name" class="p-name fn n">{{ $webmention.author_name }}</span></span>
<span itemprop="agent" itemscope="" itemtype="https://schema.org/Person" class="h-card p-author vcard"><span itemprop="name" class="p-name fn n">{{ $webmention.author_name }}</span></span>
{{ else if $webmention.title -}}
<span itemprop="name" class="p-name">{{ $webmention.title -}}</span>
{{ else -}}
@ -41,11 +41,11 @@
{{ $webmention.title | truncate 200 -}}
{{ else -}}
{{- $webmention.source | strings.TrimPrefix "https://" | strings.TrimPrefix "www." | strings.TrimRight "/" | truncate 35 -}}
{{ end }}
</span>
</a>
{{ end -}}
</span
></a>
{{- if $webmention.author_name }}
by <span itemprop="author" itemscope itemtype="https://schema.org/Person" class="h-card p-author vcard"><span itemprop="name" class="p-name fn n">{{ $webmention.author_name }}</span></span>
by <span itemprop="author" itemscope="" itemtype="https://schema.org/Person" class="h-card p-author vcard"><span itemprop="name" class="p-name fn n">{{ $webmention.author_name }}</span></span>
{{- end -}}
{{- end }}
</dd>

View file

@ -33,4 +33,4 @@
{{- end -}}
</ol>
</details>
<p>If you&rsquo;re part of a webring and would like me to join, just ask. I&rsquo;ll probably accept if joining only requires me to add hyperlinks to this page (no scripts, external content, or images), and if the ring doesn&rsquo;t seem to promote anything I find objectionable.</p>
<p>If youre part of a webring and would like me to join, just ask. Ill probably accept if joining only requires me to add hyperlinks to this page (no scripts, external content, or images), and if the ring doesnt seem to promote anything I find objectionable.</p>

View file

@ -12,8 +12,8 @@ About
{{- if gt . 60 -}}
{{- $hours := div . 60 -}}
{{- $minutes := mod . 60 -}}
{{- $displayTime = (printf "%d&nbsp;hour and %d" $hours $minutes) | safeHTML -}}
{{- $displayTime = (printf "%d&#160;hour and %d" $hours $minutes) | safeHTML -}}
{{- end -}}
; a{{ if lt . 10 }} short{{ else if and (gt . 20) (lt . 30) }} somewhat long{{ else if and (gt . 29) (lt . 60) }} long{{ else if gt . 59 }} very long{{ end }}
<time itemprop="timeRequired" datetime="PT{{ . }}M">{{ $displayTime }}&nbsp;minute</time> read
<time itemprop="timeRequired" datetime="PT{{ . }}M">{{ $displayTime }}&#160;minute</time> read
{{- end }}

View file

@ -1,8 +1,8 @@
{{- define "main" -}}
{{- $canonicalRelPermalink := .RelPermalink | replaceRE "^/~seirdy/" "/" }}
{{- .Scratch.Set "codeIndex" 1 -}}
<main itemprop="hasPart" itemscope itemtype="https://schema.org/BlogPosting{{ if .Params.techarticle }} https://schema.org/TechArticle{{ end }}" itemid="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">
<link itemprop="isPartOf" href="{{ .Site.Params.CanonicalBaseURL }}/">
<main itemprop="hasPart" itemscope="" itemtype="https://schema.org/BlogPosting{{ if .Params.techarticle }} https://schema.org/TechArticle{{ end }}" itemid="{{ .Site.Params.CanonicalBaseURL }}{{ $canonicalRelPermalink }}">
<link itemprop="isPartOf" href="{{ .Site.Params.CanonicalBaseURL }}/" />
{{ partial "full-article.html" . }}
{{ partial "webmentions.html" . }}
</main>

View file

@ -7,6 +7,6 @@
The full caption is too long for an aria-label;
just use the beginning for the label and the full thing for the aria description.
-->
<figure aria-labelledby="{{ $id }}" itemprop="hasPart" itemscope itemtype="https://schema.org/SoftwareSourceCode">
<figure aria-labelledby="{{ $id }}" itemprop="hasPart" itemscope="" itemtype="https://schema.org/SoftwareSourceCode">
{{ .Inner | markdownify -}}
</figure>

View file

@ -1,7 +1,7 @@
<figure itemscope itemtype="https://schema.org/ImageObject"
<figure itemscope="" itemtype="https://schema.org/ImageObject"
{{- with .Get "id" }} id="{{ . }}" tabindex="-1"{{ end -}}
{{- if .Get "representative" }} itemprop="image">
<meta itemprop="representativeOfPage" content="true">
<meta itemprop="representativeOfPage" content="true" />
{{- else }} itemprop="hasPart">
{{- end }}
{{ .Inner | markdownify | safeHTML }}

View file

@ -23,7 +23,7 @@
(btw this is all made of <span> cuz it is supposed to be inline)
-->
<span itemprop="author copyrightHolder" itemscope itemtype="https://schema.org/Person" itemid="https://seirdy.one/#seirdy" class="h-card p-author author vcard">
<span itemprop="author copyrightHolder" itemscope="" itemtype="https://schema.org/Person" itemid="https://seirdy.one/#seirdy" class="h-card p-author author vcard">
<a itemprop="url" href="https://seirdy.one/" rel="author home cc:attributionURL" class="u-url url" property="cc:attributionName">
{{ partial "indieweb-icon.html" -}}
<span itemprop="name" class="p-name fn n">

View file

@ -6,5 +6,4 @@
src="data:image/png;base64,{{ $favicon_base64 }}"
{{- else -}}
src="{{ $favicon_svg.RelPermalink }}"
{{- end -}}
>
{{- end }} />

View file

@ -1,5 +1,5 @@
<span {{ if (.Get "itemprop") -}}itemprop="{{- .Get "itemprop" -}}"{{- end }}
itemscope itemtype="https://schema.org/Person"
itemscope="" itemtype="https://schema.org/Person"
class="h-card vcard{{if eq (.Get "itemprop") "author"}} p-author{{end}}">
<a itemprop="url" href="{{- .Get "url" -}}" class="u-url url">
{{- if (.Get "avatar") -}}
@ -14,7 +14,7 @@
</span>{{- if (.Get "appendString") -}}{{- .Get "appendString" -}}{{- end -}}{{- /* Strip trailing newline: https://github.com/gohugoio/hugo/issues/1753 */ -}}
</a>{{- /* Strip trailing newline: https://github.com/gohugoio/hugo/issues/1753 */ -}}
{{- if (.Get "org") }}
from <span class="p-org org" itemprop="affiliation" itemscope itemtype="https://schema.org/Organization">
from <span class="p-org org" itemprop="affiliation" itemscope="" itemtype="https://schema.org/Organization">
<a itemprop="url" class="organization-name" href="{{- .Get "org-url" -}}">
<span itemprop="name">{{- .Get "org" -}}</span>{{- /* Strip trailing newline: https://github.com/gohugoio/hugo/issues/1753 */ -}}
</a></span>

View file

@ -2,6 +2,6 @@
{{- with .Get "itemprop" -}}
{{ $itemprop = . }}
{{- end -}}
<span class="h-cite{{ with .Get "reply" }} in-reply-to{{ end }}" itemprop="{{ $itemprop }}"{{ with .Get "role" }} role="{{ . }}"{{ end }} itemscope itemtype="https://schema.org/{{ .Get "itemtype" }}">
<span class="h-cite{{ with .Get "reply" }} in-reply-to{{ end }}" itemprop="{{ $itemprop }}"{{ with .Get "role" }} role="{{ . }}"{{ end }} itemscope="" itemtype="https://schema.org/{{ .Get "itemtype" }}">
{{- .Inner | markdownify | safeHTML -}}
</span>

View file

@ -21,64 +21,64 @@
<source
srcset="{{ $dark_svg_src.RelPermalink }}"
type="image/svg+xml"
media="screen and (prefers-color-scheme: dark)">
media="screen and (prefers-color-scheme: dark)" />
{{ end -}}
{{ with $dark_jxl -}}
{{ $dark_jxl_src := . | resources.Fingerprint "md5" -}}
<source
srcset="{{ $dark_jxl_src.RelPermalink }}"
type="image/jxl"
media="screen and (prefers-color-scheme: dark)">
media="screen and (prefers-color-scheme: dark)" />
{{ end -}}
{{ with $dark_avif -}}
{{ $dark_avif_src := . | resources.Fingerprint "md5" -}}
<source
srcset="{{ $dark_avif_src.RelPermalink }}"
type="image/avif"
media="screen and (prefers-color-scheme: dark)">
media="screen and (prefers-color-scheme: dark)" />
{{ end -}}
{{ with $dark_webp -}}
{{ $dark_webp_src := . | resources.Fingerprint "md5" -}}
<source
srcset="{{ $dark_webp_src.RelPermalink }}"
type="image/webp"
media="screen and (prefers-color-scheme: dark)">
media="screen and (prefers-color-scheme: dark)" />
{{ end -}}
{{ with $dark_png -}}
{{ $dark_png_src := . | resources.Fingerprint "md5" -}}
<source
srcset="{{ $dark_png_src.RelPermalink }}"
type="image/png"
media="screen and (prefers-color-scheme: dark)">
media="screen and (prefers-color-scheme: dark)" />
{{ end -}}
{{ with $light_svg -}}
{{ $light_svg_src := . | resources.Fingerprint "md5" -}}
<source
srcset="{{ $light_svg_src.RelPermalink }}"
type="image/svg+xml">
type="image/svg+xml" />
{{ end -}}
{{ with $light_jxl -}}
{{ $light_jxl_src := . | resources.Fingerprint "md5" -}}
<source
srcset="{{ $light_jxl_src.RelPermalink }}"
type="image/jxl">
type="image/jxl" />
{{ end -}}
{{ with $light_avif -}}
{{ $light_avif_src := . | resources.Fingerprint "md5" -}}
<source
srcset="{{ $light_avif_src.RelPermalink }}"
type="image/avif">
type="image/avif" />
{{ end -}}
{{ with $light_webp -}}
{{ $light_webp_src := . | resources.Fingerprint "md5" -}}
<source
srcset="{{ $light_webp_src.RelPermalink }}"
type="image/webp">
type="image/webp" />
{{ end -}}
{{ $light_png_src := $light_png | resources.Fingerprint "md5" -}}
<source
srcset="{{ $light_png_src.RelPermalink }}"
type="image/png">
type="image/png" />
<img{{ with .Get "class" }} class="{{ . }}"{{ end }}
width="{{ $img_width }}" height="{{ $img_height }}"
src="{{ $light_png.RelPermalink }}" alt='{{ .Get "alt" }}'
@ -92,5 +92,5 @@
itemprop="contentUrl url"
{{ end -}}
{{- end -}}
decoding="async">
decoding="async" />
</picture>{{- /* Strip trailing newline: https://github.com/gohugoio/hugo/issues/1753 */ -}}

View file

@ -2,6 +2,6 @@
{{- with .Get "itemprop" -}}
{{- $itemprop = . -}}
{{- end -}}
<figure itemprop="{{ $itemprop }}"{{ with .Get "id" }} id="{{ . }}" tabindex="-1"{{ end }} itemscope itemtype="https://schema.org/Quotation">
<figure itemprop="{{ $itemprop }}"{{ with .Get "id" }} id="{{ . }}" tabindex="-1"{{ end }} itemscope="" itemtype="https://schema.org/Quotation">
{{ .Inner | markdownify }}
</figure>

View file

@ -7,7 +7,7 @@
{{- end -}}
{{- end -}}
<span class="h-cite" itemprop="citation" role="doc-credit">
<span itemprop="isPartOf" itemscope itemtype="https://schema.org/{{ .Get "partOfType" }}">
<span itemprop="isPartOf" itemscope="" itemtype="https://schema.org/{{ .Get "partOfType" }}">
{{ .Inner | markdownify | safeHTML }}
</span>
</span>

View file

@ -2,6 +2,6 @@
{{- with .Get "type" -}}
{{- $type = . -}}
{{- end -}}
<section aria-label="{{ $type }}, caption, and transcript" itemprop="mentions" itemscope itemtype="https://schema.org/ImageObject" id="{{ .Get "id" }}" tabindex="-1">
<section aria-label="{{ $type }}, caption, and transcript" itemprop="mentions" itemscope="" itemtype="https://schema.org/ImageObject" id="{{ .Get "id" }}" tabindex="-1">
{{ .Inner | markdownify | safeHTML }}
</section>

View file

@ -14,6 +14,11 @@
and .firstColumn == 1
and (.extract | test(" name=\"theme-color\""))
)
or
( # XHTML5 gang
.message == "Bad value “application/xhtml+xml; charset=utf-8” for attribute “content” on element “meta”: The legacy encoding declaration did not start with “text/html;”."
and .firstColumn == 1
)
) | not
)
)