From 31436e29c97f1ceafd7e87592edb74181fa38989 Mon Sep 17 00:00:00 2001 From: Changkun Ou Date: Thu, 21 Jan 2021 10:17:55 +0100 Subject: [PATCH] all: add website --- .github/workflows/website.yml | 41 +++++++++ .gitignore | 3 + LICENSE | 8 ++ Makefile | 4 + README.md | 7 +- archetypes/default.md | 9 ++ config.toml | 39 ++++++++ .../assets/bench-time}/bench_test.go | 0 .../assets/bench-time}/cpp/main.cpp | 0 .../assets/bench-time}/cpp/solution.cpp | 0 .../assets/bench-time}/flow.png | Bin .../assets/bench-time}/go.mod | 0 .../assets/bench-time}/pprof1.png | Bin .../assets/bench-time}/pprof2.png | Bin .../assets/bench-time}/raw.graffle | Bin .../assets/pointer-params}/Makefile | 0 .../assets/pointer-params}/asm/vec.s | 0 .../assets/pointer-params}/fields/Makefile | 0 .../pointer-params}/fields/benchstat.txt | 0 .../assets/pointer-params}/fields/fields.go | 0 .../assets/pointer-params}/fields/gen.go | 0 .../pointer-params}/fields/impl_test.go | 0 .../assets/pointer-params}/fields/inline.txt | 0 .../pointer-params}/fields/noinline.txt | 0 .../assets/pointer-params}/go.mod | 0 .../assets/pointer-params}/new.txt | 0 .../assets/pointer-params}/old.txt | 0 .../assets/pointer-params}/vec.go | 0 .../assets/pointer-params}/vec_test.go | 0 .../assets/pointer-params}/vis.png | Bin bench-time.md => content/posts/bench-time.md | 31 ++++--- .../posts/pointer-params.md | 28 +++--- themes/research/archetypes/default.md | 10 +++ .../_default/_markup/render-image.html | 11 +++ themes/research/layouts/_default/baseof.html | 32 +++++++ themes/research/layouts/_default/list.html | 26 ++++++ themes/research/layouts/_default/single.html | 15 ++++ themes/research/layouts/_default/summary.html | 13 +++ themes/research/layouts/index.html | 9 ++ themes/research/layouts/partials/footer.html | 8 ++ themes/research/layouts/partials/header.html | 18 ++++ .../research/layouts/partials/pagination.html | 9 ++ themes/research/layouts/partials/sidebar.html | 14 +++ themes/research/static/css/style.css | 85 ++++++++++++++++++ 44 files changed, 390 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/website.yml create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 archetypes/default.md create mode 100644 config.toml rename {bench-time => content/assets/bench-time}/bench_test.go (100%) rename {bench-time => content/assets/bench-time}/cpp/main.cpp (100%) rename {bench-time => content/assets/bench-time}/cpp/solution.cpp (100%) rename {bench-time => content/assets/bench-time}/flow.png (100%) rename {bench-time => content/assets/bench-time}/go.mod (100%) rename {bench-time => content/assets/bench-time}/pprof1.png (100%) rename {bench-time => content/assets/bench-time}/pprof2.png (100%) rename {bench-time => content/assets/bench-time}/raw.graffle (100%) rename {pointer-params => content/assets/pointer-params}/Makefile (100%) rename {pointer-params => content/assets/pointer-params}/asm/vec.s (100%) rename {pointer-params => content/assets/pointer-params}/fields/Makefile (100%) rename {pointer-params => content/assets/pointer-params}/fields/benchstat.txt (100%) rename {pointer-params => content/assets/pointer-params}/fields/fields.go (100%) rename {pointer-params => content/assets/pointer-params}/fields/gen.go (100%) rename {pointer-params => content/assets/pointer-params}/fields/impl_test.go (100%) rename {pointer-params => content/assets/pointer-params}/fields/inline.txt (100%) rename {pointer-params => content/assets/pointer-params}/fields/noinline.txt (100%) rename {pointer-params => content/assets/pointer-params}/go.mod (100%) rename {pointer-params => content/assets/pointer-params}/new.txt (100%) rename {pointer-params => content/assets/pointer-params}/old.txt (100%) rename {pointer-params => content/assets/pointer-params}/vec.go (100%) rename {pointer-params => content/assets/pointer-params}/vec_test.go (100%) rename {pointer-params => content/assets/pointer-params}/vis.png (100%) rename bench-time.md => content/posts/bench-time.md (97%) rename pointer-params.md => content/posts/pointer-params.md (97%) create mode 100644 themes/research/archetypes/default.md create mode 100644 themes/research/layouts/_default/_markup/render-image.html create mode 100644 themes/research/layouts/_default/baseof.html create mode 100644 themes/research/layouts/_default/list.html create mode 100644 themes/research/layouts/_default/single.html create mode 100644 themes/research/layouts/_default/summary.html create mode 100644 themes/research/layouts/index.html create mode 100644 themes/research/layouts/partials/footer.html create mode 100644 themes/research/layouts/partials/header.html create mode 100644 themes/research/layouts/partials/pagination.html create mode 100644 themes/research/layouts/partials/sidebar.html create mode 100644 themes/research/static/css/style.css diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml new file mode 100644 index 0000000..3a36d14 --- /dev/null +++ b/.github/workflows/website.yml @@ -0,0 +1,41 @@ +name: research +on: + push: + branches: [ master ] +jobs: + + build: + name: research + runs-on: ubuntu-latest + steps: + + - name: Set up Go 1.15 + uses: actions/setup-go@v1 + with: + go-version: 1.15 + id: go + + - name: Setup Hugo + uses: peaceiris/actions-hugo@v2 + with: + hugo-version: '0.60.1' + extended: true + + - name: Check out code into the Go module directory + uses: actions/checkout@v1 + + - name: Build Research Website + env: + USER: ${{ secrets.SERVER_USER }} + TARGET: ${{ secrets.SERVER_PATH }} + KEY: ${{ secrets.SERVER_KEY }} + DOMAIN: ${{ secrets.SERVER_DOMAIN }} + run: | + make + mkdir ~/.ssh + echo "$KEY" | tr -d '\r' > ~/.ssh/idkey + chmod 400 ~/.ssh/idkey + eval "$(ssh-agent -s)" + ssh-add ~/.ssh/idkey + ssh-keyscan -H $DOMAIN >> ~/.ssh/known_hosts + scp -r public/* $USER@$DOMAIN:$TARGET \ No newline at end of file diff --git a/.gitignore b/.gitignore index 66fd13c..1191ab0 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ # Dependency directories (remove the comment below to include it) # vendor/ +resources +public +.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e240b2d --- /dev/null +++ b/LICENSE @@ -0,0 +1,8 @@ + License + ------- + + Copyright (c) 2020 The golang.design Initiative + All Rights Reserved + +Unauthorized using, copying, modifying and distributing, via any medium +is strictly prohibited. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e27e58e --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +all: + hugo +s: + hugo server diff --git a/README.md b/README.md index 5cdf0c7..750d535 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,8 @@ # research -(Possibly) Naïve thoughts regarding Go. - -## Table of Content +https://golang.design/research -- [Changkun Ou. Pointers Might Not Be Ideal for Parameters. Oct 27, 2020.](./pointer-params.md) -- [Changkun Ou. Eliminating A Source of Measurement Errors in Benchmarks. Sep 30, 2020.](./bench-time.md) +(Possibly) Naïve thoughts regarding Go. ## License diff --git a/archetypes/default.md b/archetypes/default.md new file mode 100644 index 0000000..ccfe607 --- /dev/null +++ b/archetypes/default.md @@ -0,0 +1,9 @@ +--- +date: {{ now.Format "2006-01-02T15:04:05Z07:00" }} +toc: true +slug: /{{ .Name }} +tags: + - Go +title: {{ .Name }} +draft: true +--- \ No newline at end of file diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..5180935 --- /dev/null +++ b/config.toml @@ -0,0 +1,39 @@ +baseURL = "https://golang.design/research" +languageCode = "en-us" +title = "golang.design/research" +theme = "research" +[permalinks] + posts = "/:slug" + +[params] + subtitle = "(Possibly) Naïve thoughts regarding Go." + dateFmt = "02.01.2006" + +[menu] + [[menu.main]] + identifier = "posts" + name = "Posts" + url = "/posts/" + weight = 1 + [[menu.main]] + identifier = "tags" + name = "Tags" + url = "/tags/" + weight = 2 + [[menu.footer]] + name = "GitHub" + url = "https://github.com/golang-design/research" + weight = 1 +[markup] + [markup.highlight] + anchorLineNos = false + codeFences = true + guessSyntax = true + hl_Lines = "" + lineAnchors = "" + lineNoStart = 1 + lineNos = true + lineNumbersInTable = false + noClasses = true + style = "native" + tabWidth = 4 \ No newline at end of file diff --git a/bench-time/bench_test.go b/content/assets/bench-time/bench_test.go similarity index 100% rename from bench-time/bench_test.go rename to content/assets/bench-time/bench_test.go diff --git a/bench-time/cpp/main.cpp b/content/assets/bench-time/cpp/main.cpp similarity index 100% rename from bench-time/cpp/main.cpp rename to content/assets/bench-time/cpp/main.cpp diff --git a/bench-time/cpp/solution.cpp b/content/assets/bench-time/cpp/solution.cpp similarity index 100% rename from bench-time/cpp/solution.cpp rename to content/assets/bench-time/cpp/solution.cpp diff --git a/bench-time/flow.png b/content/assets/bench-time/flow.png similarity index 100% rename from bench-time/flow.png rename to content/assets/bench-time/flow.png diff --git a/bench-time/go.mod b/content/assets/bench-time/go.mod similarity index 100% rename from bench-time/go.mod rename to content/assets/bench-time/go.mod diff --git a/bench-time/pprof1.png b/content/assets/bench-time/pprof1.png similarity index 100% rename from bench-time/pprof1.png rename to content/assets/bench-time/pprof1.png diff --git a/bench-time/pprof2.png b/content/assets/bench-time/pprof2.png similarity index 100% rename from bench-time/pprof2.png rename to content/assets/bench-time/pprof2.png diff --git a/bench-time/raw.graffle b/content/assets/bench-time/raw.graffle similarity index 100% rename from bench-time/raw.graffle rename to content/assets/bench-time/raw.graffle diff --git a/pointer-params/Makefile b/content/assets/pointer-params/Makefile similarity index 100% rename from pointer-params/Makefile rename to content/assets/pointer-params/Makefile diff --git a/pointer-params/asm/vec.s b/content/assets/pointer-params/asm/vec.s similarity index 100% rename from pointer-params/asm/vec.s rename to content/assets/pointer-params/asm/vec.s diff --git a/pointer-params/fields/Makefile b/content/assets/pointer-params/fields/Makefile similarity index 100% rename from pointer-params/fields/Makefile rename to content/assets/pointer-params/fields/Makefile diff --git a/pointer-params/fields/benchstat.txt b/content/assets/pointer-params/fields/benchstat.txt similarity index 100% rename from pointer-params/fields/benchstat.txt rename to content/assets/pointer-params/fields/benchstat.txt diff --git a/pointer-params/fields/fields.go b/content/assets/pointer-params/fields/fields.go similarity index 100% rename from pointer-params/fields/fields.go rename to content/assets/pointer-params/fields/fields.go diff --git a/pointer-params/fields/gen.go b/content/assets/pointer-params/fields/gen.go similarity index 100% rename from pointer-params/fields/gen.go rename to content/assets/pointer-params/fields/gen.go diff --git a/pointer-params/fields/impl_test.go b/content/assets/pointer-params/fields/impl_test.go similarity index 100% rename from pointer-params/fields/impl_test.go rename to content/assets/pointer-params/fields/impl_test.go diff --git a/pointer-params/fields/inline.txt b/content/assets/pointer-params/fields/inline.txt similarity index 100% rename from pointer-params/fields/inline.txt rename to content/assets/pointer-params/fields/inline.txt diff --git a/pointer-params/fields/noinline.txt b/content/assets/pointer-params/fields/noinline.txt similarity index 100% rename from pointer-params/fields/noinline.txt rename to content/assets/pointer-params/fields/noinline.txt diff --git a/pointer-params/go.mod b/content/assets/pointer-params/go.mod similarity index 100% rename from pointer-params/go.mod rename to content/assets/pointer-params/go.mod diff --git a/pointer-params/new.txt b/content/assets/pointer-params/new.txt similarity index 100% rename from pointer-params/new.txt rename to content/assets/pointer-params/new.txt diff --git a/pointer-params/old.txt b/content/assets/pointer-params/old.txt similarity index 100% rename from pointer-params/old.txt rename to content/assets/pointer-params/old.txt diff --git a/pointer-params/vec.go b/content/assets/pointer-params/vec.go similarity index 100% rename from pointer-params/vec.go rename to content/assets/pointer-params/vec.go diff --git a/pointer-params/vec_test.go b/content/assets/pointer-params/vec_test.go similarity index 100% rename from pointer-params/vec_test.go rename to content/assets/pointer-params/vec_test.go diff --git a/pointer-params/vis.png b/content/assets/pointer-params/vis.png similarity index 100% rename from pointer-params/vis.png rename to content/assets/pointer-params/vis.png diff --git a/bench-time.md b/content/posts/bench-time.md similarity index 97% rename from bench-time.md rename to content/posts/bench-time.md index 65ad466..6982126 100644 --- a/bench-time.md +++ b/content/posts/bench-time.md @@ -1,15 +1,24 @@ -# Eliminating A Source of Measurement Errors in Benchmarks +--- +date: 2020-09-30T09:02:20+01:00 +toc: true +slug: /bench-time +tags: + - Benchmark + - Error + - TimeMeasurement +title: Eliminating A Source of Measurement Errors in Benchmarks +--- Author(s): [Changkun Ou](https://changkun.de) -Last updated: 2020-09-30 - -## Introduction - About six months ago, I did a [presentation](https://golang.design/s/gobench) that talks about how to conduct a reliable benchmark in Go. Recently, I submitted an issue [#41641](https://golang.org/issue/41641) to the Go project, which is also a subtle issue that you might need to address in some cases. + + +## Introduction + It is all about the following code snippet: ```go @@ -141,7 +150,7 @@ go test -v -run=none -bench=WithTimer -benchtime=100000x -count=5 -cpuprofile cp Sadly, the graph shows a chunk of useless information where most of the costs shows as `runtime.ReadMemStats`: -![pprof](./bench-time/pprof1.png) +![pprof](../assets/bench-time/pprof1.png) This is because of the `StopTimer/StartTimer` implementation in the testing package calls `runtime.ReadMemStats`: @@ -203,7 +212,7 @@ func (b *B) StopTimer() { And re-run the test again, then we have: -![pprof](./bench-time/pprof2.png) +![pprof](../assets/bench-time/pprof2.png) Have you noticed where the problem is? Yes, there is a heavy cost in calling `time.Now()` in a tight loop (not really surprising because it is a system call). @@ -281,9 +290,7 @@ and you could see that the output remains end in the cost of `avg since: 16ns`. Thus, in terms of benchmarking, the actual measured time of a target code equals to the execution time of target code plus the overhead of calling `now()`: -

- -

+![](../assets/bench-time/flow.png) Assume the target code consumes in `T` ns, and the overhead of `now()` is `t` ns. Now, let's run the target code `N` times. @@ -356,7 +363,3 @@ As a take-away message, if you would like to write a micro-benchmark (whose runs - Changkun Ou. testing: inconsistent benchmark measurements when interrupts timer. Sep 26, 2020. https://golang.org/issue/41641 - Josh Bleecher Snyder. testing: consider calling ReadMemStats less during benchmarking. Jul 1, 2017. https://golang.org/issue/20875 - Beyer, D., Löwe, S. & Wendler, P. Reliable benchmarking: requirements and solutions. Int J Softw Tools Technol Transfer 21, 1–29 (2019). https://doi.org/10.1007/s10009-017-0469-y - -## License - -Copyright © 2020 The [golang.design](https://golang.design) Authors. diff --git a/pointer-params.md b/content/posts/pointer-params.md similarity index 97% rename from pointer-params.md rename to content/posts/pointer-params.md index 86a25a8..ed1bea3 100644 --- a/pointer-params.md +++ b/content/posts/pointer-params.md @@ -1,15 +1,25 @@ -# Pointers Might Not Be Ideal for Parameters +--- +date: 2020-11-05T09:14:53+01:00 +toc: true +slug: /pointer-params +tags: + - Performance + - Parameter + - Pointer +title: Pointers Might Not Be Ideal for Parameters +--- Author(s): [Changkun Ou](https://changkun.de) -Last updated: 2020-11-05 - -## Introduction We are aware that using pointers for passing parameters can avoid data copy, which will benefit the performance. Nevertheless, there are always some edge cases we might need concern. + + +## Introduction + Let's take this as an example: ```go @@ -163,7 +173,7 @@ $ mkdir asm && go tool compile -S vec.go > asm/vec.s The dumped assumbly code is as follows: -```asm +``` "".vec.addv STEXT nosplit size=89 args=0x60 locals=0x0 funcid=0x0 0x0000 00000 (vec.go:7) TEXT "".vec.addv(SB), NOSPLIT|ABIInternal, $0-96 0x0000 00000 (vec.go:7) FUNCDATA $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB) @@ -392,7 +402,7 @@ Vec/addp-s9-16 3.37ns ± 0% We could even further try a version that disables inline: ```diff - structTmpl = template.Must(template.New("ss").Parse(` +structTmpl = template.Must(template.New("ss").Parse(` type {{.Name}} struct { {{.Properties}} } @@ -412,7 +422,7 @@ func (s *{{.Name}}) addp(ss *{{.Name}}) *{{.Name}} { Eventually, we will endup with the following results: -![](./pointer-params/vis.png) +![](../assets/pointer-params/vis.png) TLDR: The above figure basically demonstrates when should you pass-by-value or pass-by-pointer. If you are certain that your code won't produce any escape @@ -427,7 +437,3 @@ then you should go for pass-by-value; otherwise, you should keep using pointers. - MOVSD. Move or Merge Scalar Double-Precision Floating-Point Value. Last access: 2020-10-27. https://www.felixcloutier.com/x86/movsd - ADDSD. Add Scalar Double-Precision Floating-Point Values. Last access: 2020-10-27. https://www.felixcloutier.com/x86/addsd - MOVEQ. Move Quadword. Last access: 2020-10-27. https://www.felixcloutier.com/x86/movq - -## License - -Copyright © 2020 The [golang.design](https://golang.design) Authors. diff --git a/themes/research/archetypes/default.md b/themes/research/archetypes/default.md new file mode 100644 index 0000000..8706b92 --- /dev/null +++ b/themes/research/archetypes/default.md @@ -0,0 +1,10 @@ +--- +date: {{ now.Format "2006-01-02T15:04:05Z07:00" }} +toc: true +id: +slug: /{{ .Name }} +tags: + - Go +title: {{ .Name }} +draft: true +--- \ No newline at end of file diff --git a/themes/research/layouts/_default/_markup/render-image.html b/themes/research/layouts/_default/_markup/render-image.html new file mode 100644 index 0000000..41008ca --- /dev/null +++ b/themes/research/layouts/_default/_markup/render-image.html @@ -0,0 +1,11 @@ +{{ if .Title }} +
+ {{ .Text }} +
{{ .Title }}
+
+{{ else }} +
+ {{ .Text }} +
+{{ end }} + diff --git a/themes/research/layouts/_default/baseof.html b/themes/research/layouts/_default/baseof.html new file mode 100644 index 0000000..529ac10 --- /dev/null +++ b/themes/research/layouts/_default/baseof.html @@ -0,0 +1,32 @@ + + + + + + + + + + + {{ .Title }} + {{ with .Site.Params.description }}{{ end }} + {{ with .Site.Params.author }}{{ end }} + + {{ range .Site.Params.customCSS -}} + + {{- end }} + {{ with .OutputFormats.Get "RSS" -}} + {{ printf `` .Rel .MediaType.Type .RelPermalink $.Site.Title | safeHTML }} + {{- end }} + + + {{ partial "header" . }} + {{ block "main" . }}{{ end }} + {{ partial "footer" . }} + + diff --git a/themes/research/layouts/_default/list.html b/themes/research/layouts/_default/list.html new file mode 100644 index 0000000..1a1abce --- /dev/null +++ b/themes/research/layouts/_default/list.html @@ -0,0 +1,26 @@ +{{ define "main" }} +
+ {{ $listtitle := .Title }} + {{ if or .Title .Content }} +
+ {{ with .Title }}

{{ . }}

{{ end }} + {{ with .Content }}
{{ . }}
{{ end }} +
+ {{ end }} + + + {{ partial "pagination.html" . }} +
+{{ end }} diff --git a/themes/research/layouts/_default/single.html b/themes/research/layouts/_default/single.html new file mode 100644 index 0000000..673e26c --- /dev/null +++ b/themes/research/layouts/_default/single.html @@ -0,0 +1,15 @@ +{{ define "main" }} +
+
+

{{ .Title }}

+ + {{ range .Params.tags }} + #{{ . }} + {{ end }} +
+ {{ .Content }} +
+
+
+{{ partial "sidebar.html" . }} +{{ end }} diff --git a/themes/research/layouts/_default/summary.html b/themes/research/layouts/_default/summary.html new file mode 100644 index 0000000..3105e31 --- /dev/null +++ b/themes/research/layouts/_default/summary.html @@ -0,0 +1,13 @@ +
+

{{ .Title }}

+ + {{ range .Params.tags }} + #{{ . }} + {{ end }} +
+ {{ .Summary }} + {{ if .Truncated }} + Read more... + {{ end }} +
+
diff --git a/themes/research/layouts/index.html b/themes/research/layouts/index.html new file mode 100644 index 0000000..cd86013 --- /dev/null +++ b/themes/research/layouts/index.html @@ -0,0 +1,9 @@ +{{ define "main" }} +
+ {{ $paginator := .Paginate (where .Site.RegularPages "Type" "in" .Site.Params.mainSections) }} + {{ range $paginator.Pages }} + {{ .Render "summary" }} + {{ end }} + {{ partial "pagination.html" . }} +
+{{ end }} diff --git a/themes/research/layouts/partials/footer.html b/themes/research/layouts/partials/footer.html new file mode 100644 index 0000000..a3db252 --- /dev/null +++ b/themes/research/layouts/partials/footer.html @@ -0,0 +1,8 @@ + diff --git a/themes/research/layouts/partials/header.html b/themes/research/layouts/partials/header.html new file mode 100644 index 0000000..225d04f --- /dev/null +++ b/themes/research/layouts/partials/header.html @@ -0,0 +1,18 @@ +
+
+ ┏{{ strings.Repeat ( .Site.Title | len | add 2 ) "━" }}┓
+ ┇
+ ┗{{ strings.Repeat ( .Site.Title | len | add 2 ) "━" }}┛ +
+
{{ .Site.Params.subtitle }}

+

+

+

+ {{ end }} +
diff --git a/themes/research/layouts/partials/pagination.html b/themes/research/layouts/partials/pagination.html new file mode 100644 index 0000000..ffdbaab --- /dev/null +++ b/themes/research/layouts/partials/pagination.html @@ -0,0 +1,9 @@ +
+{{ if .Paginator.HasPrev }} + Previous Page +{{ end }} +Page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }} +{{ if .Paginator.HasNext }} + Next Page +{{ end }} +
diff --git a/themes/research/layouts/partials/sidebar.html b/themes/research/layouts/partials/sidebar.html new file mode 100644 index 0000000..92bbd80 --- /dev/null +++ b/themes/research/layouts/partials/sidebar.html @@ -0,0 +1,14 @@ + diff --git a/themes/research/static/css/style.css b/themes/research/static/css/style.css new file mode 100644 index 0000000..2b73525 --- /dev/null +++ b/themes/research/static/css/style.css @@ -0,0 +1,85 @@ +html { + overflow-y: scroll; +} +body { + max-width: 800px; + margin: 40px auto; + padding: 0 10px; + font: 14px/1.5 monospace; + color: #444; +} +h1, +h2, +h3 { + line-height: 1.2; +} +p > code { + padding: 2px 4px; + color: #555; + background: #eee; + padding: 2px; + border-radius: 4px; +} +pre { + color: #ffffff; + background: #000000; + padding: 24px; + overflow-x: auto; +} +article { + padding: 24px 0; +} +.center { + display: block; + margin-left: auto; + margin-right: auto; + width: 100%; +} +img { + display: block; + max-width: 100%; + height: auto; +} +figcaption { + color: #888; + font: 12px/1.5 monospace; + text-align: center; +} +figure { + margin: auto; +} +a { + color: #0091e6; + text-decoration: none; +} +.title { + color: black; +} +.logo { + color: black; + font-style: italic; + font-weight: bold; +} +.footer-link { + color: #333; +} +@media (prefers-color-scheme: dark) { + body { + color: white; + background: #444; + } + a:link { + color: #5bf; + text-decoration: none; + } + a:visited { + color: #5bf; + text-decoration: none; + } + .title { + color: white !important; + } + .logo { + color: white !important; + } +} \ No newline at end of file