Migrated to blog
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
This commit is contained in:
parent
1a6315fa5f
commit
6ef5248f4d
16
Dockerfile
16
Dockerfile
@ -1,16 +1,2 @@
|
||||
FROM debian:buster AS builder
|
||||
RUN apt-get -qq update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get -qq install -y --no-install-recommends libstdc++6 python-pygments git ca-certificates asciidoc curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
ENV HUGO_VERSION 0.74.3
|
||||
ENV HUGO_BINARY hugo_extended_${HUGO_VERSION}_Linux-64bit.deb
|
||||
RUN curl -sL -o /tmp/hugo.deb \
|
||||
https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/${HUGO_BINARY} && \
|
||||
dpkg -i /tmp/hugo.deb && \
|
||||
rm /tmp/hugo.deb
|
||||
WORKDIR /app
|
||||
ADD . .
|
||||
RUN hugo -d /usr/share/nginx/html/
|
||||
|
||||
FROM nginx:latest
|
||||
COPY --from=builder /usr/share/nginx/html/ /usr/share/nginx/html/
|
||||
COPY default.conf /etc/nginx/conf.d/default.conf
|
||||
|
@ -1,6 +1,8 @@
|
||||
# T.I.L.
|
||||
|
||||
> Repo containing the code for https://til.marcusnoble.co.uk where I record all small interesting things I learn.
|
||||
> Repo previously containing the code for https://til.marcusnoble.co.uk where I record all small interesting things I learn.
|
||||
|
||||
Content has been migrated to, and combined with, my blog at https://marcusnoble.co.uk
|
||||
|
||||
## Building from source
|
||||
|
||||
|
@ -1,7 +0,0 @@
|
||||
---
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
draft: true
|
||||
tags: [blah]
|
||||
---
|
||||
|
14
config.toml
14
config.toml
@ -1,14 +0,0 @@
|
||||
title = "T.I.L."
|
||||
baseURL = "https://til.marcusnoble.co.uk"
|
||||
languageCode = "en-gb"
|
||||
theme = "hello-friend-ng"
|
||||
enableGitInfo = true
|
||||
|
||||
[permalinks]
|
||||
posts = "/:title/"
|
||||
|
||||
[params]
|
||||
gitUrl = "https://git.cluster.fun/AverageMarcus/til/commit/"
|
||||
|
||||
[taxonomies]
|
||||
series = "series"
|
@ -1,12 +0,0 @@
|
||||
---
|
||||
title: "Don't Reuse API Keys"
|
||||
date: 2020-10-03T12:49:37+01:00
|
||||
draft: false
|
||||
tags:
|
||||
- cli
|
||||
- credentials
|
||||
images:
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=Don't%20Reuse%20API%20Keys&tags=cli%2Ccredentials&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
Not a technical post today, more of a reminder to myself not to reuse API keys for different purposes. In this instance I reset the credentials I had labelled "Terraform" which I just so happened to also be using In [Harbor](https://goharbor.io/) to connect to my S3 bucket. Que 2 hours of me later trying to figure out why I couldn't pull or push any images.
|
@ -1,21 +0,0 @@
|
||||
---
|
||||
title: "How to get the favicon of any site"
|
||||
date: 2020-11-10T09:49:37+01:00
|
||||
draft: false
|
||||
tags:
|
||||
-
|
||||
images:
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=How%20to%20get%20the%20favicon%20of%20any%20site&tags=favicon&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
If you ever find yourself needing to display a small icon for a 3rd party URL but don't want to have to crawl the site to pull out the favicon URL then you can make use of a Google CDN:
|
||||
|
||||
```
|
||||
https://s2.googleusercontent.com/s2/favicons?domain_url=https://www.bbc.co.uk/
|
||||
```
|
||||
|
||||
Example: 
|
||||
|
||||
You can even provide any page, not just the root URL.
|
||||
|
||||
e.g. `https://s2.googleusercontent.com/s2/favicons?domain_url=https://www.bbc.co.uk/news/newsbeat-54838856`: 
|
@ -1,42 +0,0 @@
|
||||
---
|
||||
title: "CLI flag handling in Bash using getopts"
|
||||
date: 2021-08-04T20:49:37+01:00
|
||||
draft: false
|
||||
tags:
|
||||
- bash
|
||||
images:
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=CLI%20flag%20handling%20in%20Bash%20using%20getopts&tags=bash&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
I'm not sure how I've never come across this before but while looking through the [Scaleway Kosmos](https://www.scaleway.com/en/betas/#kuberneteskosmos) multi-cloud init script I dicovered the [`getopts`](https://www.man7.org/linux/man-pages/man1/getopts.1p.html) utility.
|
||||
|
||||
`getopts` makes it easier to parse arguments passed to a shell script by defining which letters your script supports. It supports both boolean and string style arguments but only supports single letter flags. (e.g. `-h` and not `--help`)
|
||||
|
||||
Example usage:
|
||||
|
||||
```sh
|
||||
#!/bin/bash
|
||||
|
||||
NAME="World"
|
||||
FORCE=false
|
||||
|
||||
showHelp() {
|
||||
echo "Usage: example.sh [args]"
|
||||
exit 0
|
||||
}
|
||||
|
||||
while getopts 'hfn:' FLAG
|
||||
do
|
||||
case $FLAG in
|
||||
h) showHelp ;;
|
||||
f) FORCE=true ;;
|
||||
n) NAME=$OPTARG ;;
|
||||
*) echo "Unsupported argument flag passed" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "Hello, $NAME"
|
||||
|
||||
```
|
||||
|
||||
Notice the `:` following the `n`? That indicates that a value should follow the argument flag (`n` in this example) and will be made available as the `OPTARG` variable.
|
@ -1,36 +0,0 @@
|
||||
---
|
||||
title: "Named returns in Go functions"
|
||||
date: 2020-10-05T15:50:00
|
||||
draft: false
|
||||
tags:
|
||||
- golang
|
||||
images:
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=Named%20returns%20in%20Go%20functions&tags=golang%2Cprogramming&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
While debugging some issues I was having with the AWS Golang SDK I discovered it was possible to name your function return values (pointers) and then set them within your function body without needing to explicitly return them at the end.
|
||||
|
||||
E.g.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
var greeting = "Hello, world"
|
||||
|
||||
func main() {
|
||||
fmt.Println(*test())
|
||||
}
|
||||
|
||||
func test() (returnVal *string) {
|
||||
returnVal = &greeting
|
||||
return
|
||||
}
|
||||
```
|
||||
|
||||
Note the single `return` at the end of the function.
|
||||
|
||||
I'm not really sure if this is a useful feature, feels more like it'd make code harder to read and could lead to some pretty nasty unintended mistakes when someone unfamilure with the code comes to make changes. Interesting either way.
|
||||
|
||||
I'd be interested if anyone has any examples of where this kind of thing is beneficial.
|
@ -1,61 +0,0 @@
|
||||
---
|
||||
title: "Golang's append mutates the provided array"
|
||||
date: 2020-10-30T12:49:37+01:00
|
||||
draft: false
|
||||
tags:
|
||||
- golang
|
||||
images:
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=Golang's%20append%20mutates%20the%20provided%20array&tags=golang%2Cprogramming%2Carrays%2Cslices&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
A word of warning when using `append()` in Golang...
|
||||
|
||||
When using a slice of an array as the first parameter when calling `append` if the length of the resulting array is less than that of the initial array then the values in the initial array will be overridden by the new values being appended.
|
||||
|
||||
For example, if we use `append` to take the first two values from the array called `first` and all the values from the array called `second` we can see that `first` is being mutated unexpectedly.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
first := []int{0, 1, 2, 3, 4, 5, 6}
|
||||
second := []int{4, 5, 6}
|
||||
|
||||
fmt.Println(first)
|
||||
// -> [0 1 2 3 4 5 6]
|
||||
fmt.Println(append(first[:2], second...))
|
||||
// -> [0 1 4 5 6]
|
||||
fmt.Println(first)
|
||||
// -> [0 1 4 5 6 4 5 6]
|
||||
}
|
||||
```
|
||||
|
||||
This is _only_ an issue when the resulting array is shorter than the array passed in as the first parameter.
|
||||
|
||||
**Update:**
|
||||
It turns out this is expected behavior (see https://github.com/golang/go/issues/28780#issuecomment-438428780) and a side-effect of how slices work in Go.
|
||||
|
||||
A slice (what we're producing when using the `[:2]`) can be thought of as a view onto an array. So when making changes to a slice you're really just making changes to that part of the array it is pointed to. By default slices are dynamic in size so if you go past the end of the slice you still continue along the array if it has more entries.
|
||||
|
||||
To avoid this happening you can specify a third value in the slice that sets the fixed length of the slice. E.g.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
first := []int{0, 1, 2, 3, 4, 5, 6}
|
||||
second := []int{4, 5, 6}
|
||||
|
||||
fmt.Println(first)
|
||||
// -> [0 1 2 3 4 5 6]
|
||||
fmt.Println(append(first[:2:2], second...))
|
||||
// -> [0 1 4 5 6]
|
||||
fmt.Println(first)
|
||||
// -> [0 1 2 3 4 5 6]
|
||||
fmt.Println("Much better :)")
|
||||
}
|
||||
```
|
@ -1,29 +0,0 @@
|
||||
---
|
||||
title: "Split on spaces in Go"
|
||||
date: 2020-09-18
|
||||
draft: false
|
||||
tags:
|
||||
- go
|
||||
- golang
|
||||
images:
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=Split%20on%20spaces%20in%20Go&tags=golang%2Cprogramming%2Carrays&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
While looking to split a multiline and space separated string and not having any luck with `strings.Split()` I came across this somewhat oddly names function:
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
input := `This is
|
||||
a multiline, space
|
||||
separated string`
|
||||
|
||||
output := strings.Fields(input)
|
||||
|
||||
fmt.Println(output) // ["This", "is", "a", "multiline,", "space", "separated", "string"]
|
||||
}
|
||||
```
|
File diff suppressed because one or more lines are too long
@ -1,15 +0,0 @@
|
||||
---
|
||||
title: "Kubernetes label length"
|
||||
date: 2021-04-20T15:10:37+01:00
|
||||
draft: false
|
||||
tags:
|
||||
- kubernetes
|
||||
images:
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=Kubernetes%20label%20length&tags=kubernetes%2Clabels&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
It turns out that label _values_ in Kubernetes have a limit of 63 characters!
|
||||
|
||||
I discovered this today when none of my nodes seemed to be connecting to the control plane. Eventually discovered the hostname of the node was longer than 63 characters (mainly due to multiple subdomain levels) and so the `kubernetes.io/hostname` label being automtically added to the node was causing Kubernetes to reject it.
|
||||
|
||||
If you hit this like me, the hostname used for the label can be [overridden using the `--hostname-override` flag on kubelet](https://kubernetes.io/docs/reference/labels-annotations-taints/#kubernetesiohostname) or by setting the value of the label yourself with the `--node-labels` flag.
|
@ -1,59 +0,0 @@
|
||||
---
|
||||
title: "Tekton Multi-Arch Image Builds"
|
||||
date: 2020-09-13T01:49:37+01:00
|
||||
draft: false
|
||||
tags:
|
||||
- tekton
|
||||
- docker
|
||||
images:
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=Tekton%20Multi-Arch%20Image%20Builds&tags=tekton%2Cdocker%2Cci%2Ccd&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
Using Buildkit to build multi-arch compatible images without Docker daemon:
|
||||
|
||||
```yaml
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: Task
|
||||
metadata:
|
||||
name: docker-build-and-publish
|
||||
namespace: tekton-pipelines
|
||||
spec:
|
||||
- name: IMAGE
|
||||
type: string
|
||||
resources:
|
||||
inputs:
|
||||
- name: src
|
||||
type: git
|
||||
steps:
|
||||
- name: build-and-push
|
||||
workingDir: /workspace/src
|
||||
image: moby/buildkit:latest
|
||||
env:
|
||||
- name: DOCKER_CONFIG
|
||||
value: /root/.docker
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
buildctl-daemonless.sh --debug \
|
||||
build \
|
||||
--progress=plain \
|
||||
--frontend=dockerfile.v0 \
|
||||
--opt filename=Dockerfile \
|
||||
--opt platform=linux/amd64,linux/arm/7,linux/arm64 \
|
||||
--local context=. \
|
||||
--local dockerfile=. \
|
||||
--output type=image,name=$(params.IMAGE),push=true \
|
||||
--export-cache type=inline \
|
||||
--import-cache type=registry,ref=$(params.IMAGE)
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
- name: docker-config
|
||||
mountPath: /root/.docker/config.json
|
||||
subPath: config.json
|
||||
volumes:
|
||||
- name: docker-config
|
||||
secret:
|
||||
secretName: docker-config
|
||||
```
|
@ -1,79 +0,0 @@
|
||||
---
|
||||
title: "YAML keys allow for spaces in them"
|
||||
date: 2021-05-11
|
||||
draft: false
|
||||
tags:
|
||||
- yaml
|
||||
images:
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=YAML%20keys%20allow%20for%20spaces%20in%20them&tags=yaml&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
While browsing through some of [Frenck's](https://github.com/frenck) [Home Assistant Config](https://github.com/frenck/home-assistant-config) for ideas I came across [this interesting line of YAML](https://github.com/frenck/home-assistant-config/blob/a963e1cb3e2acf7beda2b466b334218ac27ee42f/config/integrations/automation.yaml#L7):
|
||||
|
||||
```yaml
|
||||
---
|
||||
# This handles the loading of my automations
|
||||
#
|
||||
# https://www.home-assistant.io/docs/automation/
|
||||
#
|
||||
automation: !include ../automations.yaml
|
||||
automation split: !include_dir_list ../automations # <--
|
||||
```
|
||||
|
||||
I found myself staring at this for a while, followed by searching the [Home Assistant](https://www.home-assistant.io/) documentation website to see if `split` was a special keyword I wasn't aware of.
|
||||
|
||||
And then it dawned on me! As all JSON is valid YAML, and JSON keys can be pretty much any string it makes sense that YAML supports it.
|
||||
|
||||
The above example converted to JSON using [json2yaml](https://www.json2yaml.com/convert-yaml-to-json) looks like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"automation": "../automations.yaml",
|
||||
"automation split": "../automations"
|
||||
}
|
||||
```
|
||||
|
||||
Knowing this, I decided to try out a few more variations to see what works...
|
||||
|
||||
YAML:
|
||||
```yaml
|
||||
---
|
||||
123: Valid
|
||||
---: also valid
|
||||
5.5: yup! this too
|
||||
#how about this?: nope, this is treated as a comment
|
||||
//: yeah, totally valid
|
||||
✨: yep!
|
||||
[1]: Works
|
||||
[1, 2]: Still works, treated as string
|
||||
{another}: This one is interesting
|
||||
```
|
||||
|
||||
JSON:
|
||||
```json
|
||||
{
|
||||
"123": "Valid",
|
||||
"---": "also valid",
|
||||
"5.5": "yup! this too",
|
||||
"//": "yeah, totally valid",
|
||||
"✨": "yep!",
|
||||
"[1]": "Works",
|
||||
"[1, 2]": "Still works, treated as string",
|
||||
"{\"another\"=>nil}": "This one is interesting"
|
||||
}
|
||||
```
|
||||
|
||||
Depending on the library used, varying results can be generated. For example, [yamlonline](https://yamlonline.com/) returns the following for the same input:
|
||||
|
||||
```json
|
||||
{
|
||||
"1": "Works",
|
||||
"123": "Valid",
|
||||
"---": "also valid",
|
||||
"5.5": "yup! this too",
|
||||
"//": "yeah, totally valid",
|
||||
"✨": "yep!",
|
||||
"1,2": "Still works, treated as string",
|
||||
"[object Object]": "This one is interesting"
|
||||
}
|
||||
```
|
@ -1,27 +0,0 @@
|
||||
---
|
||||
title: "YAML multiline values"
|
||||
date: 2020-09-17
|
||||
draft: false
|
||||
tags:
|
||||
- yaml
|
||||
images:
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=YAML%20multiline%20values&tags=yaml&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
After using YAML for a long time, for many, many Kubernetes manifest files, I have today learnt that it contains two multiline value types (called scalars):
|
||||
|
||||
```yaml
|
||||
scalarsExample:
|
||||
literalScalar: |
|
||||
Literal scalars use the pipe (`|`) to denote the start of the value with the scope indicated by indentation.
|
||||
All content here is used literally, with newlines preserved.
|
||||
<-- This is the start of the line, the spaces before this aren't included in the literal.
|
||||
This should be used when storing things like file contents (e.g. in a ConfigMap)
|
||||
foldedScalar: >
|
||||
Folded scalars use the greater-than symbol (`>`) to denote the start of the value with the scope indicated by indentation.
|
||||
Unlike literal scalars newlines aren't preserved and instead converted into spaces.
|
||||
<-- This is the start of the line, the spaces before this aren't included in the value.
|
||||
This should be used when you'd normally use a string but the contents are long and wrapping makes it easier to read.
|
||||
```
|
||||
|
||||
> More info: https://yaml.org/spec/1.2/spec.html#id2760844
|
19
default.conf
Normal file
19
default.conf
Normal file
@ -0,0 +1,19 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name localhost;
|
||||
|
||||
rewrite ^/dont-reuse-keys/?$ https://marcusnoble.co.uk/2020-10-03-t-i-l-don-t-reuse-api-keys/ permanent;
|
||||
rewrite ^/favicons/?$ https://marcusnoble.co.uk/2020-11-10-t-i-l-how-to-get-the-favicon-of-any-site/ permanent;
|
||||
rewrite ^/getopts/?$ https://marcusnoble.co.uk/2021-08-04-t-i-l-cli-flag-handling-in-bash-using-getopts/ permanent;
|
||||
rewrite ^/go-named-return-values/?$ https://marcusnoble.co.uk/2020-10-05-t-i-l-named-returns-in-go-functions/ permanent;
|
||||
rewrite ^/golang-append/?$ https://marcusnoble.co.uk/2020-10-30-t-i-l-golang-s-append-mutates-the-provided-array/ permanent;
|
||||
rewrite ^/golang-split-by-space/?$ https://marcusnoble.co.uk/2020-09-18-t-i-l-split-on-spaces-in-go/ permanent;
|
||||
rewrite ^/kubectl-replace/?$ https://marcusnoble.co.uk/2020-09-25-t-i-l-kubectl-replace/ permanent;
|
||||
rewrite ^/kubernetes-label-length/?$ https://marcusnoble.co.uk/2021-04-20-t-i-l-kubernetes-label-length/ permanent;
|
||||
rewrite ^/tekton-multi-arch-builds/?$ https://marcusnoble.co.uk/2020-09-13-t-i-l-tekton-multi-arch-image-builds/ permanent;
|
||||
rewrite ^/yaml-key-spaces/?$ https://marcusnoble.co.uk/2021-05-11-t-i-l-yaml-keys-allow-for-spaces-in-them/ permanent;
|
||||
rewrite ^/yaml-multiline/?$ https://marcusnoble.co.uk/2020-09-17-t-i-l-yaml-multiline-values/ permanent;
|
||||
rewrite ^/?$ https://marcusnoble.co.uk/ permanent;
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
---
|
||||
|
||||
env:
|
||||
es6: true
|
||||
|
||||
extends:
|
||||
# https://github.com/airbnb/javascript
|
||||
- airbnb
|
||||
- eslint:recommended
|
||||
- prettier
|
||||
|
||||
parser: babel-eslint
|
||||
|
||||
rules:
|
||||
# best practices
|
||||
arrow-parens:
|
||||
- 2
|
||||
- as-needed
|
||||
semi:
|
||||
- 2
|
||||
- never
|
||||
class-methods-use-this: 0
|
||||
comma-dangle:
|
||||
- 2
|
||||
- always-multiline
|
||||
no-console:
|
||||
- 2
|
||||
no-unused-expressions: 0
|
||||
no-param-reassign:
|
||||
- 2
|
||||
- props: false
|
||||
no-useless-escape: 0
|
||||
func-names: 0
|
||||
quotes:
|
||||
- 2
|
||||
- single
|
||||
- allowTemplateLiterals: true
|
||||
no-underscore-dangle: 0
|
||||
object-curly-newline: 0
|
||||
function-paren-newline: 0
|
||||
operator-linebreak:
|
||||
- 2
|
||||
- after
|
||||
no-unused-vars:
|
||||
- 2
|
||||
- argsIgnorePattern: "^_"
|
||||
# jsx a11y
|
||||
jsx-a11y/no-static-element-interactions: 0
|
||||
jsx-a11y/anchor-is-valid:
|
||||
- 2
|
||||
- specialLink:
|
||||
- to
|
||||
|
||||
globals:
|
||||
document: true
|
||||
requestAnimationFrame: true
|
||||
window: true
|
||||
self: true
|
||||
fetch: true
|
||||
Headers: true
|
35
themes/hello-friend-ng/.gitignore
vendored
35
themes/hello-friend-ng/.gitignore
vendored
@ -1,35 +0,0 @@
|
||||
|
||||
# Created by https://www.gitignore.io/api/macos
|
||||
# Edit at https://www.gitignore.io/?templates=macos
|
||||
|
||||
### macOS ###
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# End of https://www.gitignore.io/api/macos
|
||||
|
||||
.vscode
|
@ -1,14 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## 2020-05-13
|
||||
|
||||
### Added
|
||||
- Changelog
|
||||
|
||||
### Changed
|
||||
- In order to make the image handling more consistent, the `cover` tag does not force the image to live in `/img/` anymore. [!131](https://github.com/rhazdon/hugo-theme-hello-friend-ng/pull/131).
|
@ -1,4 +0,0 @@
|
||||
|
||||
# How to contribute
|
||||
|
||||
If you spot any bugs, please use [Issue Tracker](https://github.com/rhazdon/hugo-theme-hello-friend-ng/issues) or if you want to add a new feature directly please create a new [Pull Request](https://github.com/rhazdon/hugo-theme-hello-friend-ng/pulls).
|
@ -1,11 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Original work Copyright (c) 2018 Track3<br />
|
||||
Original work Copyright (c) 2019 panr<br />
|
||||
Modified work Copyright (c) 2019 Djordje Atlialp<br />
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -1,188 +0,0 @@
|
||||
# Hello Friend NG
|
||||
|
||||

|
||||
|
||||
## General informations
|
||||
|
||||
This theme was highly inspired by the [hello-friend](https://github.com/panr/hugo-theme-hello-friend) and [hermit](https://github.com/Track3/hermit). A lot of kudos for theier great work.
|
||||
|
||||
---
|
||||
## Table of Contents
|
||||
|
||||
- [Features](#features)
|
||||
- [How to start](#how-to-start)
|
||||
- [How to configure](#how-to-configure)
|
||||
- [More](#more-things)
|
||||
- [Built in shortcodes](#built-in-shortcodes)
|
||||
- [image](#image)
|
||||
- [Code highlighting](#code-highlighting)
|
||||
- [Favicon](#favicon)
|
||||
- [Social Icons](#social-icons)
|
||||
- [Known issues](#known-issues)
|
||||
- [How to edit the theme](#how-to-edit-the-theme)
|
||||
- [Changelog](CHANGELOG.md)
|
||||
- [Sponsoring](#sponsoring)
|
||||
- [Licence](#licence)
|
||||
|
||||
---
|
||||
## Features
|
||||
|
||||
- Theming: **dark/light mode**, depending on your preferences (dark is default, but you can change it)
|
||||
- Great reading experience thanks to [**Inter UI font**](https://rsms.me/inter/), made by [Rasmus Andersson](https://rsms.me/about/)
|
||||
- Nice code highlighting thanks to [**PrismJS**](https://prismjs.com)
|
||||
- An easy way to modify the theme with Hugo tooling
|
||||
- Fully responsive
|
||||
- Support for social icons
|
||||
- Support for sharing buttons
|
||||
|
||||
|
||||
## How to start
|
||||
|
||||
You can download the theme manually by going to [https://github.com/rhazdon/hugo-theme-hello-friend-ng.git](https://github.com/rhazdon/hugo-theme-hello-friend-ng.git) and pasting it to `themes/hello-friend-ng` in your root directory.
|
||||
|
||||
You can also clone it directly to your Hugo folder:
|
||||
|
||||
``` bash
|
||||
$ git clone https://github.com/rhazdon/hugo-theme-hello-friend-ng.git themes/hello-friend-ng
|
||||
```
|
||||
|
||||
If you don't want to make any radical changes, it's the best option, because you can get new updates when they are available. To do so, include it as a git submodule:
|
||||
|
||||
``` bash
|
||||
$ git submodule add https://github.com/rhazdon/hugo-theme-hello-friend-ng.git themes/hello-friend-ng
|
||||
```
|
||||
|
||||
## How to configure
|
||||
|
||||
The theme doesn't require any advanced configuration. Just copy the following config file.
|
||||
To see all possible configurations, [check the docs](docs/config.md).
|
||||
Note: There are more options to configure. Take a look into the `config.toml` in `exampleSite`.
|
||||
|
||||
``` toml
|
||||
baseurl = "localhost"
|
||||
title = "My Blog"
|
||||
languageCode = "en-us"
|
||||
theme = "hello-friend-ng"
|
||||
paginate = 10
|
||||
|
||||
[params]
|
||||
dateform = "Jan 2, 2006"
|
||||
dateformShort = "Jan 2"
|
||||
dateformNum = "2006-01-02"
|
||||
dateformNumTime = "2006-01-02 15:04"
|
||||
|
||||
# Subtitle for home
|
||||
homeSubtitle = "A simple and beautiful blog"
|
||||
|
||||
# Set disableReadOtherPosts to true in order to hide the links to other posts.
|
||||
disableReadOtherPosts = false
|
||||
|
||||
# Enable sharing buttons, if you linke
|
||||
enableSharingButtons = true
|
||||
|
||||
# Metadata mostly used in document's head
|
||||
description = "My new homepage or blog"
|
||||
keywords = "homepage, blog"
|
||||
images = [""]
|
||||
|
||||
# Default theme "light" or "dark"
|
||||
defaultTheme = "dark"
|
||||
|
||||
[taxonomies]
|
||||
category = "blog"
|
||||
tag = "tags"
|
||||
series = "series"
|
||||
|
||||
[languages]
|
||||
[languages.en]
|
||||
title = "Hello Friend NG"
|
||||
subtitle = "A simple theme for Hugo"
|
||||
keywords = ""
|
||||
copyright = '<a href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank" rel="noopener">CC BY-NC 4.0</a>'
|
||||
readOtherPosts = "Read other posts"
|
||||
|
||||
[languages.en.params.logo]
|
||||
logoText = "hello friend ng"
|
||||
logoHomeLink = "/"
|
||||
# or
|
||||
#
|
||||
# path = "/img/your-example-logo.svg"
|
||||
# alt = "Your example logo alt text"
|
||||
|
||||
# And you can even create generic menu
|
||||
[[menu.main]]
|
||||
identifier = "blog"
|
||||
name = "Blog"
|
||||
url = "/posts"
|
||||
```
|
||||
|
||||
## More things
|
||||
|
||||
### Built-in shortcodes
|
||||
|
||||
Of course you are able to use all default shortcodes from hugo (https://gohugo.io/content-management/shortcodes/).
|
||||
|
||||
#### image
|
||||
|
||||
Properties:
|
||||
|
||||
- `src` (required)
|
||||
- `alt` (optional)
|
||||
- `position` (optional, default: `left`, options: [`left`, `center`, `right`])
|
||||
- `style`
|
||||
|
||||
Example:
|
||||
|
||||
``` golang
|
||||
{{< image src="/img/hello.png" alt="Hello Friend" position="center" style="border-radius: 8px;" >}}
|
||||
```
|
||||
|
||||
### Code highlighting
|
||||
|
||||
Supported languages: [Take a look here](https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+abap+actionscript+ada+apacheconf+apl+applescript+c+arff+asciidoc+asm6502+csharp+autohotkey+autoit+bash+basic+batch+bison+brainfuck+bro+cpp+aspnet+arduino+cil+coffeescript+clojure+ruby+csp+css-extras+d+dart+diff+markup-templating+docker+eiffel+elixir+elm+lua+erb+erlang+fsharp+flow+fortran+gcode+gedcom+gherkin+git+glsl+gml+go+graphql+groovy+less+handlebars+haskell+haxe+hcl+http+hpkp+hsts+ichigojam+icon+inform7+ini+io+j+java+scala+php+javastacktrace+jolie+n4js+markdown+json+julia+keyman+kotlin+latex+crystal+scheme+liquid+lisp+livescript+lolcode+makefile+django+matlab+mel+mizar+monkey+n1ql+typescript+nand2tetris-hdl+nasm+nginx+nim+nix+nsis+objectivec+ocaml+opencl+oz+parigp+parser+pascal+perl+php-extras+sql+powershell+processing+prolog+properties+protobuf+scss+puppet+pure+python+q+qore+r+jsx+renpy+reason+vala+rest+rip+roboconf+textile+rust+plsql+sass+stylus+smalltalk+smarty+soy+sas+twig+swift+yaml+tcl+haml+toml+tt2+pug+tsx+visual-basic+vbnet+velocity+verilog+vhdl+vim+wasm+wiki+xeora+xojo+xquery+tap)
|
||||
|
||||
By default the theme is using PrismJS to color your code syntax. All you need to do is to wrap you code like this:
|
||||
|
||||
<pre>
|
||||
``` html
|
||||
// your code here
|
||||
```
|
||||
</pre>
|
||||
|
||||
### Favicon
|
||||
|
||||
Check the [docs](docs/favicons.md).
|
||||
|
||||
## Social Icons:
|
||||
|
||||
Take a look into this [list](docs/svgs.md)
|
||||
|
||||
If you need another one, just open an issue or create a pull request with your wished icon. :)
|
||||
|
||||
## Known issues
|
||||
|
||||
There is a bug in Hugo that sometimes causes the main page not to render correctly. The reason is an empty taxonomy part.
|
||||
Related issue tickets: [!14](https://github.com/rhazdon/hugo-theme-hello-friend-ng/issues/14) [!59](https://github.com/rhazdon/hugo-theme-hello-friend-ng/issues/59).
|
||||
|
||||
Either you comment it out completely or you write the following in
|
||||
|
||||
``` toml
|
||||
[taxonomies]
|
||||
tag = "tags"
|
||||
category = "categories"
|
||||
```
|
||||
|
||||
## How to edit the theme
|
||||
|
||||
Just edit it. You don't need any node stuff. ;)
|
||||
|
||||
## Sponsoring
|
||||
|
||||
If you like my work and if you think this project is worth to support it, just <br />
|
||||
<a href="https://www.buymeacoffee.com/djordjeatlialp" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-green.png" alt="Buy Me A Coffee" style="height: 51px !important;width: 217px !important;" ></a>
|
||||
|
||||
## Licence
|
||||
|
||||
Copyright © 2019-2020 Djordje Atlialp
|
||||
|
||||
The theme is released under the MIT License. Check the [original theme license](https://github.com/rhazdon/hugo-theme-hello-friend-ng/blob/master/LICENSE.md) for additional licensing information.
|
@ -1,8 +0,0 @@
|
||||
---
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
draft: true
|
||||
comments: false
|
||||
images:
|
||||
---
|
||||
|
@ -1,10 +0,0 @@
|
||||
---
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
draft: true
|
||||
toc: false
|
||||
images:
|
||||
tags:
|
||||
- untagged
|
||||
---
|
||||
|
@ -1 +0,0 @@
|
||||
// Some code could be here ...
|
@ -1,22 +0,0 @@
|
||||
// Mobile menu
|
||||
|
||||
const menuTrigger = document.querySelector(".menu-trigger");
|
||||
const menu = document.querySelector(".menu");
|
||||
const mobileQuery = getComputedStyle(document.body).getPropertyValue(
|
||||
"--phoneWidth"
|
||||
);
|
||||
const isMobile = () => window.matchMedia(mobileQuery).matches;
|
||||
const isMobileMenu = () => {
|
||||
menuTrigger && menuTrigger.classList.toggle("hidden", !isMobile());
|
||||
menu && menu.classList.toggle("hidden", isMobile());
|
||||
};
|
||||
|
||||
isMobileMenu();
|
||||
|
||||
menuTrigger &&
|
||||
menuTrigger.addEventListener(
|
||||
"click",
|
||||
() => menu && menu.classList.toggle("hidden")
|
||||
);
|
||||
|
||||
window.addEventListener("resize", isMobileMenu);
|
File diff suppressed because one or more lines are too long
@ -1,25 +0,0 @@
|
||||
// Toggle theme
|
||||
|
||||
const theme = window.localStorage && window.localStorage.getItem("theme");
|
||||
const themeToggle = document.querySelector(".theme-toggle");
|
||||
const isDark = theme === "dark";
|
||||
var metaThemeColor = document.querySelector("meta[name=theme-color]");
|
||||
|
||||
if (theme !== null) {
|
||||
document.body.classList.toggle("dark-theme", isDark);
|
||||
isDark
|
||||
? metaThemeColor.setAttribute("content", "#252627")
|
||||
: metaThemeColor.setAttribute("content", "#fafafa");
|
||||
}
|
||||
|
||||
themeToggle.addEventListener("click", () => {
|
||||
document.body.classList.toggle("dark-theme");
|
||||
window.localStorage &&
|
||||
window.localStorage.setItem(
|
||||
"theme",
|
||||
document.body.classList.contains("dark-theme") ? "dark" : "light"
|
||||
);
|
||||
document.body.classList.contains("dark-theme")
|
||||
? metaThemeColor.setAttribute("content", "#252627")
|
||||
: metaThemeColor.setAttribute("content", "#fafafa");
|
||||
});
|
@ -1,99 +0,0 @@
|
||||
.button-container {
|
||||
display: table;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
button,
|
||||
.button,
|
||||
a.button {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 8px 18px;
|
||||
margin-bottom: 5px;
|
||||
background: $light-background-secondary;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
|
||||
.dark-theme & {
|
||||
background: $dark-background-secondary;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* variants */
|
||||
|
||||
&.outline {
|
||||
background: transparent;
|
||||
border-color: $light-background-secondary;
|
||||
box-shadow: none;
|
||||
padding: 8px 18px;
|
||||
|
||||
.dark-theme & {
|
||||
border-color: $dark-background-secondary;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
:hover {
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.primary {
|
||||
box-shadow: 0 4px 6px rgba(50, 50, 93, .11), 0 1px 3px rgba(0, 0, 0, .08);
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 2px 6px rgba(50, 50, 93, .21), 0 1px 3px rgba(0, 0, 0, .08);
|
||||
}
|
||||
}
|
||||
|
||||
&.link {
|
||||
background: none;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
&.small {
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
&.wide {
|
||||
min-width: 200px;
|
||||
padding: 14px 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.code-toolbar {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.toolbar-item a {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3px 8px;
|
||||
margin-bottom: 5px;
|
||||
background: $light-background-secondary;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
|
||||
.dark-theme & {
|
||||
background: $dark-background-secondary;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'Inter UI';
|
||||
font-style: normal;
|
||||
font-display: auto;
|
||||
font-weight: 400;
|
||||
src: url("../fonts/Inter-UI-Regular.woff2") format("woff2"),
|
||||
url("../fonts/Inter-UI-Regular.woff") format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter UI';
|
||||
font-style: italic;
|
||||
font-display: auto;
|
||||
font-weight: 400;
|
||||
src: url("../fonts/Inter-UI-Italic.woff2") format("woff2"),
|
||||
url("../fonts/Inter-UI-Italic.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter UI';
|
||||
font-style: normal;
|
||||
font-display: auto;
|
||||
font-weight: 600;
|
||||
src: url("../fonts/Inter-UI-Medium.woff2") format("woff2"),
|
||||
url("../fonts/Inter-UI-Medium.woff") format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter UI';
|
||||
font-style: italic;
|
||||
font-display: auto;
|
||||
font-weight: 600;
|
||||
src: url("../fonts/Inter-UI-MediumItalic.woff2") format("woff2"),
|
||||
url("../fonts/Inter-UI-MediumItalic.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter UI';
|
||||
font-style: normal;
|
||||
font-display: auto;
|
||||
font-weight: 800;
|
||||
src: url("../fonts/Inter-UI-Bold.woff2") format("woff2"),
|
||||
url("../fonts/Inter-UI-Bold.woff") format("woff");
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter UI';
|
||||
font-style: italic;
|
||||
font-display: auto;
|
||||
font-weight: 800;
|
||||
src: url("../fonts/Inter-UI-BoldItalic.woff2") format("woff2"),
|
||||
url("../fonts/Inter-UI-BoldItalic.woff") format("woff");
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
.footer {
|
||||
padding: 40px 20px;
|
||||
flex-grow: 0;
|
||||
color: $light-color-secondary;
|
||||
font-size: 0.7em;
|
||||
|
||||
&__inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0 auto;
|
||||
width: 760px;
|
||||
max-width: 100%;
|
||||
|
||||
@media #{$media-size-tablet} {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
font-size: 0.6rem;
|
||||
color: $light-color-secondary;
|
||||
|
||||
@media #{$media-size-tablet} {
|
||||
flex-direction: column;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
& > *:not(:last-child)::after {
|
||||
content: "•";
|
||||
padding: 0 5px;
|
||||
|
||||
@media #{$media-size-tablet} {
|
||||
content: "";
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
& > *:last-child {
|
||||
padding: 0 5px;
|
||||
|
||||
@media #{$media-size-tablet} {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
.header {
|
||||
background: #fafafa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
padding: 20px;
|
||||
|
||||
.dark-theme & {
|
||||
background: #252627;
|
||||
}
|
||||
|
||||
&__right {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
@media #{$media-size-phone} {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
}
|
||||
|
||||
&__inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 0 auto;
|
||||
width: 760px;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.theme-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.theme-toggler {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.unselectable {
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
.rss-button {
|
||||
margin-right: 10px;
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
.posts {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
text-align: left;
|
||||
padding: 20px;
|
||||
margin: 20px auto;
|
||||
|
||||
@media #{$media-size-tablet} {
|
||||
max-width: 660px;
|
||||
}
|
||||
|
||||
&:not(:last-of-type) {
|
||||
border-bottom: 1px solid $light-border-color;
|
||||
|
||||
.dark-theme & {
|
||||
border-color: $dark-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-group {
|
||||
display: flex;
|
||||
margin-bottom: 1.9em;
|
||||
line-height: normal;
|
||||
|
||||
@media #{$media-size-tablet} {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&-list {
|
||||
flex-grow: 1;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.post {
|
||||
&-title {
|
||||
font-size: 1rem;
|
||||
margin: 5px 0 5px 0;
|
||||
}
|
||||
|
||||
&-year {
|
||||
padding-top: 6px;
|
||||
margin-right: 1.8em;
|
||||
font-size: 1.6em;
|
||||
@include dimmed;
|
||||
|
||||
@media #{$media-size-tablet} {
|
||||
margin: -6px 0 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&-item {
|
||||
border-bottom: 1px grey dashed;
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
padding: 12px 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-day {
|
||||
flex-shrink: 0;
|
||||
margin-left: 1em;
|
||||
@include dimmed;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
font-display: auto;
|
||||
font-family: monospace, monospace;
|
||||
|
||||
img {
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
&__mark {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
&__text {
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
&__cursor {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 1rem;
|
||||
background: #fe5186;
|
||||
margin-left: 5px;
|
||||
border-radius: 1px;
|
||||
animation: cursor 1s infinite;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
&__cursor {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@keyframes cursor {
|
||||
0% { opacity: 0; }
|
||||
50% { opacity: 1; }
|
||||
100% { opacity: 0; }
|
||||
}
|
@ -1,332 +0,0 @@
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
line-height: 1.6;
|
||||
letter-spacing: .06em;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Inter UI', -apple-system, BlinkMacSystemFont, "Roboto", "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
font-display: auto;
|
||||
font-size: 1rem;
|
||||
line-height: 1.54;
|
||||
background-color: $light-background;
|
||||
color: $light-color;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-feature-settings: "liga", "tnum", "case", "calt", "zero", "ss01", "locl";
|
||||
-webkit-overflow-scrolling: touch;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
flex-direction: column;
|
||||
|
||||
@media #{$media-size-phone} {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
&.dark-theme {
|
||||
background-color: $dark-background;
|
||||
color: $dark-color;
|
||||
}
|
||||
}
|
||||
|
||||
h2, h3, h4, h5, h6 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.625rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.625rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.375rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
@media #{$media-size-phone} {
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
|
||||
&.left {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
&.center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
&.right {
|
||||
margin-left: auto;
|
||||
}
|
||||
&.circle {
|
||||
border-radius: 50%;
|
||||
max-width: 25%;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
figure {
|
||||
display: table;
|
||||
max-width: 100%;
|
||||
margin: 25px 0;
|
||||
|
||||
&.left {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
&.left-floated {
|
||||
margin-right: auto;
|
||||
float: left;
|
||||
img {
|
||||
margin: 20px 20px 20px 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
&.right {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
&.right-floated {
|
||||
margin-left: auto;
|
||||
float: right;
|
||||
img {
|
||||
margin: 20px 0 20px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&.rounded {
|
||||
img {
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
figcaption {
|
||||
font-size: 14px;
|
||||
margin-top: 5px;
|
||||
opacity: .8;
|
||||
|
||||
&.left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;
|
||||
font-display: auto;
|
||||
font-feature-settings: normal;
|
||||
background: $light-background-secondary;
|
||||
padding: 1px 6px;
|
||||
margin: 0 2px;
|
||||
border-radius: 5px;
|
||||
font-size: .95rem;
|
||||
|
||||
.dark-theme & {
|
||||
background: $dark-background-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #212020;
|
||||
padding: 10px 10px 10px 20px;
|
||||
border-radius: 8px;
|
||||
font-size: .95rem;
|
||||
overflow: auto;
|
||||
|
||||
@media #{$media-size-phone} {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
code {
|
||||
background: none !important;
|
||||
color: #ccc;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: inherit;
|
||||
|
||||
.dark-theme & {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 2px solid;
|
||||
margin: 40px;
|
||||
padding: 10px 20px;
|
||||
|
||||
@media #{$media-size-phone} {
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: '”';
|
||||
font-family: Georgia, serif;
|
||||
font-display: auto;
|
||||
font-size: 3.875rem;
|
||||
position: absolute;
|
||||
left: -40px;
|
||||
top: -20px;
|
||||
}
|
||||
|
||||
p:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||