From cd7ba25fe413ba86417acc71641a60e74b651518 Mon Sep 17 00:00:00 2001 From: Rhiannon Morris Date: Tue, 3 Dec 2024 03:22:34 +0100 Subject: [PATCH 1/4] buttons --- index.html | 5 +++++ media/buttons/blau.png | 3 +++ media/buttons/clip.png | 3 +++ media/buttons/gabu.png | 3 +++ media/buttons/hell-labs-still.png | 3 +++ media/buttons/hell-labs.gif | 3 +++ media/buttons/katja.png | 3 +++ media/buttons/lifning.png | 3 +++ media/buttons/mathie.png | 3 +++ media/buttons/odoben.png | 3 +++ media/buttons/therra.png | 3 +++ 11 files changed, 35 insertions(+) create mode 100644 media/buttons/blau.png create mode 100644 media/buttons/clip.png create mode 100644 media/buttons/gabu.png create mode 100644 media/buttons/hell-labs-still.png create mode 100644 media/buttons/hell-labs.gif create mode 100644 media/buttons/katja.png create mode 100644 media/buttons/lifning.png create mode 100644 media/buttons/mathie.png create mode 100644 media/buttons/odoben.png create mode 100644 media/buttons/therra.png diff --git a/index.html b/index.html index e3b5ea8..713c8dd 100644 --- a/index.html +++ b/index.html @@ -429,6 +429,11 @@ smolderg.xyz + +
  • + + blau's blog + diff --git a/media/buttons/blau.png b/media/buttons/blau.png new file mode 100644 index 0000000..0b9e0cb --- /dev/null +++ b/media/buttons/blau.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e18ee746676a2e3b31780c1603e0faecfac2be1b7a662ab9144a3dfb1e6b1079 +size 3011 diff --git a/media/buttons/clip.png b/media/buttons/clip.png new file mode 100644 index 0000000..c4d9443 --- /dev/null +++ b/media/buttons/clip.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa4a658acc9f0d9f2557bace361c9bc41acdf06eb2d8f4fda45365a658c9e8d3 +size 2098 diff --git a/media/buttons/gabu.png b/media/buttons/gabu.png new file mode 100644 index 0000000..9daf840 --- /dev/null +++ b/media/buttons/gabu.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:009b7fc831c0ff7ad57fe71979a0c45be3a4ccd0560e41d3fddc465a8c586ced +size 835 diff --git a/media/buttons/hell-labs-still.png b/media/buttons/hell-labs-still.png new file mode 100644 index 0000000..a23a3f2 --- /dev/null +++ b/media/buttons/hell-labs-still.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b23dbc5031f29fb0cb383eb3acda6e0dce805b34a570506a79cae333fa39b05d +size 2394 diff --git a/media/buttons/hell-labs.gif b/media/buttons/hell-labs.gif new file mode 100644 index 0000000..8692d9c --- /dev/null +++ b/media/buttons/hell-labs.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e5947ba3c94e3c584e12044a3b6326228aa5ec6fd350f8bdfec3c48d09a6e7c +size 12092 diff --git a/media/buttons/katja.png b/media/buttons/katja.png new file mode 100644 index 0000000..5f470b3 --- /dev/null +++ b/media/buttons/katja.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d17d6314c864556208031d7d1103fab509cc894b195db98a82685261c96c8299 +size 4027 diff --git a/media/buttons/lifning.png b/media/buttons/lifning.png new file mode 100644 index 0000000..807b50e --- /dev/null +++ b/media/buttons/lifning.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4260ff94fd4a16073c76b1d76ef041de85802f166872d24e4d8c723555a9b951 +size 1528 diff --git a/media/buttons/mathie.png b/media/buttons/mathie.png new file mode 100644 index 0000000..5e5f6a1 --- /dev/null +++ b/media/buttons/mathie.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3a76a9d2333fa62c75da7444c0c14218a1f58a2689efa0b2d2676c7ecf6b4ee +size 10046 diff --git a/media/buttons/odoben.png b/media/buttons/odoben.png new file mode 100644 index 0000000..5cc1928 --- /dev/null +++ b/media/buttons/odoben.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:200c2ced55ce39d5d395fdec14053938fc61c1a8679d18298a699a1c9538e3f5 +size 1209 diff --git a/media/buttons/therra.png b/media/buttons/therra.png new file mode 100644 index 0000000..a7d19aa --- /dev/null +++ b/media/buttons/therra.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f4471f97ace4b2365e6cfc02cafde7e666d31a8fbcf049441bfc008e4f8ac07 +size 882 From 1f433de1597e1b741e18a5443b80ce150572f24f Mon Sep 17 00:00:00 2001 From: Rhiannon Morris Date: Tue, 3 Dec 2024 03:22:43 +0100 Subject: [PATCH 2/4] lfs avif --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index 0644d84..bea3f3f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,5 @@ *.png filter=lfs diff=lfs merge=lfs -text *.gif filter=lfs diff=lfs merge=lfs -text *.webp filter=lfs diff=lfs merge=lfs -text +*.avif filter=lfs diff=lfs merge=lfs -text *.kra filter=lfs diff=lfs merge=lfs -text From 6681d2eefb14326dc2f8af6eac68d80eb18efc1c Mon Sep 17 00:00:00 2001 From: Rhiannon Morris Date: Tue, 3 Dec 2024 03:23:07 +0100 Subject: [PATCH 3/4] update build commands --- Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index b05d476..da95b7a 100644 --- a/Makefile +++ b/Makefile @@ -8,12 +8,11 @@ SCRIPTS = $(patsubst %.ts,%.js,$(wildcard script/*.ts)) MISC = $(shell find .well-known -type f) ALL = $(CSS) $(PAGES) $(MEDIA) $(SCRIPTS) $(MISC) -BUILDDIR ?= _build +BUILDDIR ?= /srv/www/yummy TMPDIR ?= _tmp HOST ?= yummy.cricket REMOTE_USER ?= www-data -IDFILE ?= ~/.ssh/xyz REMOTE_DIR ?= yummy all: build @@ -24,7 +23,7 @@ upload: build @rsync --recursive --partial --progress --copy-links \ --compress --human-readable --hard-links --size-only \ --delete --delete-after \ - --rsh='ssh -l $(REMOTE_USER) -i $(IDFILE)' \ + --rsh='ssh -l $(REMOTE_USER)' \ $(BUILDDIR)/ $(HOST):$(REMOTE_DIR)/ $(BUILDDIR)/%: % From da06033eedf285f7f3ac08e2f14f30cd31e24887 Mon Sep 17 00:00:00 2001 From: Rhiannon Morris Date: Tue, 3 Dec 2024 03:40:16 +0100 Subject: [PATCH 4/4] rainbow quox --- Makefile | 10 +- rainbow-quox/back/belly1.webp | 3 + rainbow-quox/back/belly2.webp | 3 + rainbow-quox/back/claws.webp | 3 + rainbow-quox/back/cuffs.webp | 3 + rainbow-quox/back/eyes.webp | 3 + rainbow-quox/back/fins1.webp | 3 + rainbow-quox/back/fins2.webp | 3 + rainbow-quox/back/fins3.webp | 3 + rainbow-quox/back/lines.webp | 3 + rainbow-quox/back/masks.webp | 3 + rainbow-quox/back/outer.webp | 3 + rainbow-quox/back/spines.webp | 3 + rainbow-quox/back/static.webp | 3 + rainbow-quox/back/stripes.webp | 3 + rainbow-quox/back/vitiligo1.webp | 3 + rainbow-quox/back/vitiligo2.webp | 3 + rainbow-quox/back/vitiligo3.webp | 3 + rainbow-quox/back/vitiligo4.webp | 3 + rainbow-quox/colour.ts | 290 ++++++++++++++++++++++++++++++ rainbow-quox/front/belly1.webp | 3 + rainbow-quox/front/belly2.webp | 3 + rainbow-quox/front/claws.webp | 3 + rainbow-quox/front/cuffs.webp | 3 + rainbow-quox/front/eyes.webp | 3 + rainbow-quox/front/fins1.webp | 3 + rainbow-quox/front/fins2.webp | 3 + rainbow-quox/front/fins3.webp | 3 + rainbow-quox/front/lines.webp | 3 + rainbow-quox/front/masks.webp | 3 + rainbow-quox/front/outer.webp | 3 + rainbow-quox/front/spines.webp | 3 + rainbow-quox/front/static.webp | 3 + rainbow-quox/front/stripes.webp | 3 + rainbow-quox/front/vitiligo1.webp | 3 + rainbow-quox/front/vitiligo2.webp | 3 + rainbow-quox/front/vitiligo3.webp | 3 + rainbow-quox/front/vitiligo4.webp | 3 + rainbow-quox/index.html | 63 +++++++ rainbow-quox/kra/back.kra | 3 + rainbow-quox/kra/compl1.png | 3 + rainbow-quox/kra/compl2.png | 3 + rainbow-quox/kra/front.kra | 3 + rainbow-quox/kra/triad.png | 3 + rainbow-quox/style.css | 164 +++++++++++++++++ 45 files changed, 646 insertions(+), 4 deletions(-) create mode 100644 rainbow-quox/back/belly1.webp create mode 100644 rainbow-quox/back/belly2.webp create mode 100644 rainbow-quox/back/claws.webp create mode 100644 rainbow-quox/back/cuffs.webp create mode 100644 rainbow-quox/back/eyes.webp create mode 100644 rainbow-quox/back/fins1.webp create mode 100644 rainbow-quox/back/fins2.webp create mode 100644 rainbow-quox/back/fins3.webp create mode 100644 rainbow-quox/back/lines.webp create mode 100644 rainbow-quox/back/masks.webp create mode 100644 rainbow-quox/back/outer.webp create mode 100644 rainbow-quox/back/spines.webp create mode 100644 rainbow-quox/back/static.webp create mode 100644 rainbow-quox/back/stripes.webp create mode 100644 rainbow-quox/back/vitiligo1.webp create mode 100644 rainbow-quox/back/vitiligo2.webp create mode 100644 rainbow-quox/back/vitiligo3.webp create mode 100644 rainbow-quox/back/vitiligo4.webp create mode 100644 rainbow-quox/colour.ts create mode 100644 rainbow-quox/front/belly1.webp create mode 100644 rainbow-quox/front/belly2.webp create mode 100644 rainbow-quox/front/claws.webp create mode 100644 rainbow-quox/front/cuffs.webp create mode 100644 rainbow-quox/front/eyes.webp create mode 100644 rainbow-quox/front/fins1.webp create mode 100644 rainbow-quox/front/fins2.webp create mode 100644 rainbow-quox/front/fins3.webp create mode 100644 rainbow-quox/front/lines.webp create mode 100644 rainbow-quox/front/masks.webp create mode 100644 rainbow-quox/front/outer.webp create mode 100644 rainbow-quox/front/spines.webp create mode 100644 rainbow-quox/front/static.webp create mode 100644 rainbow-quox/front/stripes.webp create mode 100644 rainbow-quox/front/vitiligo1.webp create mode 100644 rainbow-quox/front/vitiligo2.webp create mode 100644 rainbow-quox/front/vitiligo3.webp create mode 100644 rainbow-quox/front/vitiligo4.webp create mode 100644 rainbow-quox/index.html create mode 100644 rainbow-quox/kra/back.kra create mode 100644 rainbow-quox/kra/compl1.png create mode 100644 rainbow-quox/kra/compl2.png create mode 100644 rainbow-quox/kra/front.kra create mode 100644 rainbow-quox/kra/triad.png create mode 100644 rainbow-quox/style.css diff --git a/Makefile b/Makefile index da95b7a..d993c19 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,12 @@ -CSS = $(wildcard style/*.css) $(shell find fonts -type f) -PAGES = index.html pubkey.txt +CSS = $(wildcard style/*.css) $(shell find fonts -type f) \ + rainbow-quox/style.css +PAGES = index.html pubkey.txt rainbow-quox/index.html MEDIA = \ $(wildcard media/*.png) $(wildcard media/*.gif) $(wildcard media/*.webp) \ $(wildcard media/flags/*) $(wildcard media/buttons/*) \ - $(wildcard media/icons/*) $(wildcard media/bg/*) 8831.png 8831-quox.png -SCRIPTS = $(patsubst %.ts,%.js,$(wildcard script/*.ts)) + $(wildcard media/icons/*) $(wildcard media/bg/*) 8831.png 8831-quox.png \ + $(wildcard rainbow-quox/front/*) $(wildcard rainbow-quox/back/*) +SCRIPTS = $(patsubst %.ts,%.js,$(wildcard script/*.ts)) rainbow-quox/colour.js MISC = $(shell find .well-known -type f) ALL = $(CSS) $(PAGES) $(MEDIA) $(SCRIPTS) $(MISC) diff --git a/rainbow-quox/back/belly1.webp b/rainbow-quox/back/belly1.webp new file mode 100644 index 0000000..d1db413 --- /dev/null +++ b/rainbow-quox/back/belly1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7bffff72e5f1148e7f998dce53a6ec61cd5bd495f43000c5aa8d4d07c2e50fa3 +size 30778 diff --git a/rainbow-quox/back/belly2.webp b/rainbow-quox/back/belly2.webp new file mode 100644 index 0000000..789349f --- /dev/null +++ b/rainbow-quox/back/belly2.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a3020a8e4d0720721ba65601c1b9f7aa38ba2c7efd5d37d33fec38ede68ef5f +size 25104 diff --git a/rainbow-quox/back/claws.webp b/rainbow-quox/back/claws.webp new file mode 100644 index 0000000..6f1187d --- /dev/null +++ b/rainbow-quox/back/claws.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85675981f3a2590bc8ed6c7d4a9819dd7ec3dad64c7b6a9d762ef7818137f3a7 +size 21514 diff --git a/rainbow-quox/back/cuffs.webp b/rainbow-quox/back/cuffs.webp new file mode 100644 index 0000000..357c395 --- /dev/null +++ b/rainbow-quox/back/cuffs.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9f4b1dd9ec4a0ac0b68d58fbeab77155674f38795c7bdf7c5a1a439dda6d8c3 +size 16610 diff --git a/rainbow-quox/back/eyes.webp b/rainbow-quox/back/eyes.webp new file mode 100644 index 0000000..7715872 --- /dev/null +++ b/rainbow-quox/back/eyes.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53f1cb3f3273904b0cfcff7be1c04aac7f4291e783b6b5b872704bce5402adc1 +size 6724 diff --git a/rainbow-quox/back/fins1.webp b/rainbow-quox/back/fins1.webp new file mode 100644 index 0000000..f5b4a55 --- /dev/null +++ b/rainbow-quox/back/fins1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd447feb938240b6f3aaf5c719275ccc085426fbce6da555676eb12f382d386e +size 20576 diff --git a/rainbow-quox/back/fins2.webp b/rainbow-quox/back/fins2.webp new file mode 100644 index 0000000..56da277 --- /dev/null +++ b/rainbow-quox/back/fins2.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be2a469f0b785afc48d5723fe43d924342c5dc956aafc9b43848e59b4516da5c +size 21326 diff --git a/rainbow-quox/back/fins3.webp b/rainbow-quox/back/fins3.webp new file mode 100644 index 0000000..26604d2 --- /dev/null +++ b/rainbow-quox/back/fins3.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2dd85c26aa10c22ff34b0406fbe27f5a9694e64919d119e00c6e6efa5513eda5 +size 7922 diff --git a/rainbow-quox/back/lines.webp b/rainbow-quox/back/lines.webp new file mode 100644 index 0000000..5a0851b --- /dev/null +++ b/rainbow-quox/back/lines.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa2bb28145d83875af044e62a787bd67e34b4d3f8db7dd4bd538726e83031bbf +size 205184 diff --git a/rainbow-quox/back/masks.webp b/rainbow-quox/back/masks.webp new file mode 100644 index 0000000..c2d0a41 --- /dev/null +++ b/rainbow-quox/back/masks.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6942c6cd3182e027bf69c5a46c1f8dbbc49af4baf1f32a1f48ad57c55d143bd5 +size 11346 diff --git a/rainbow-quox/back/outer.webp b/rainbow-quox/back/outer.webp new file mode 100644 index 0000000..23ad25f --- /dev/null +++ b/rainbow-quox/back/outer.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51e7660d2bf26cd8c162abd872ecd07be7375b78917e5e6830651397cd9aef33 +size 54632 diff --git a/rainbow-quox/back/spines.webp b/rainbow-quox/back/spines.webp new file mode 100644 index 0000000..f42ef83 --- /dev/null +++ b/rainbow-quox/back/spines.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2958d56981dcf50d4c504ac695dcca1d87425837b41026371f36d5aa5ea1aebe +size 18330 diff --git a/rainbow-quox/back/static.webp b/rainbow-quox/back/static.webp new file mode 100644 index 0000000..8801a41 --- /dev/null +++ b/rainbow-quox/back/static.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9628e09947c9a87901c80ba08465301a277b72a6e4d0e8b188c5e1a8d3d57c54 +size 36238 diff --git a/rainbow-quox/back/stripes.webp b/rainbow-quox/back/stripes.webp new file mode 100644 index 0000000..3e71565 --- /dev/null +++ b/rainbow-quox/back/stripes.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79cd316e8329cc967147ab937a4169279338ef0b15d5b9ecfd3cd25f90997cae +size 38228 diff --git a/rainbow-quox/back/vitiligo1.webp b/rainbow-quox/back/vitiligo1.webp new file mode 100644 index 0000000..1194365 --- /dev/null +++ b/rainbow-quox/back/vitiligo1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0175ff974fa83dd08f0912e0a31dbfbaf7fd4ef3556338d4d25aad87f0f715b2 +size 30564 diff --git a/rainbow-quox/back/vitiligo2.webp b/rainbow-quox/back/vitiligo2.webp new file mode 100644 index 0000000..ceafc0b --- /dev/null +++ b/rainbow-quox/back/vitiligo2.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:393a7da7efcd74d476f72620cba80102cbfd309e2e4a2eeb86081eccdcd329c6 +size 6668 diff --git a/rainbow-quox/back/vitiligo3.webp b/rainbow-quox/back/vitiligo3.webp new file mode 100644 index 0000000..b3b1000 --- /dev/null +++ b/rainbow-quox/back/vitiligo3.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfe6882054b792e44fa4216ec58aa3a5918ad8d526ad878b7f1438a4838ee22f +size 6078 diff --git a/rainbow-quox/back/vitiligo4.webp b/rainbow-quox/back/vitiligo4.webp new file mode 100644 index 0000000..bfbdb63 --- /dev/null +++ b/rainbow-quox/back/vitiligo4.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa8ed23495929d2cf817377b653b3f68d80af0b0d6ae00704bb5ca8cc1a9bb6c +size 14358 diff --git a/rainbow-quox/colour.ts b/rainbow-quox/colour.ts new file mode 100644 index 0000000..6d489ce --- /dev/null +++ b/rainbow-quox/colour.ts @@ -0,0 +1,290 @@ +type Rand = () => number; + + +/* +let randomData = new Uint32Array(100); +let next: number = 0; +function reset() { self.crypto.getRandomValues(randomData); next = 0; } +function rand() { + if (next >= 100) { reset(); } + return randomData[next++] / 4_294_967_295; // u32 max +} +reset(); +*/ + +const rand: Rand = Math.random; // [todo] + +const max = Math.max; +const min = Math.min; + +type Oklch = { l: number, c: number, h: number }; + +type LD = 'light' | 'dark'; + +const MAXL = 0.9; +const MINL = 0.4; +const MINL_LIGHT = 0.7; +const MAXL_DARK = 0.65; + +const MINC_LIGHT = 0.08; +const MAXC_LIGHT = 0.125; +const MINC_DARK = 0.12; +const MAXC_DARK = 0.2; + +// max spread for a sequence of analogous colours. unless that would put them +// too close together +const MAXH_WIDTH = 80; + +// minimum distance between adjacent analogous colours +const MINH_SEP = 5; + +// how far away from 180° a "complementary" colour can be +const MAXH_COMPL = 40; + +// how far away from 120° a "triad" colour can be +const MAXH_TRIAD = 20; + +function randBetween(x: number, y: number): number { + const lo = min(x, y), hi = max(x, y); + return lo + rand() * (hi - lo); +} + +function oneOf(...xs: A[]): A { + return xs[Math.floor(rand() * xs.length)]!; +} + + +function isLight(l: number): boolean { return l >= MINL_LIGHT; } + +function baseLuma(ld?: LD): number { + if (ld == 'light') { + return randBetween(MINL_LIGHT, MAXL); + } else if (ld == 'dark') { + return randBetween(MINL, MAXL_DARK); + } else { + return randBetween(MINL, MAXL); + } +} + +function baseChroma(l: number): number { + if (l >= MINL_LIGHT) { + return randBetween(MINC_LIGHT, MAXC_LIGHT); + } else { + return randBetween(MINC_DARK, MAXC_DARK); + } +} + +function baseHue(): number { return rand() * 360; } + +function baseOklch(ld?: LD): Oklch { + const l = baseLuma(ld); + return {l, c: baseChroma(l), h: baseHue()}; +} + +function lightFor(baseL: number): number { + return randBetween(baseL, MAXL); +} +function darkFor(baseL: number): number { + return randBetween(MINL, baseL); +} + +function brightFor(l: number, baseC: number): number { + if (isLight(l)) { return randBetween(baseC, MAXC_LIGHT); } + else { return randBetween(baseC, MAXC_DARK); } +} + +function dullFor(l: number, baseC: number): number { + if (isLight(l)) { return randBetween(baseC, MINC_LIGHT); } + else { return randBetween(baseC, MINC_DARK); } +} + + +type Numbers = number[]; + +function upto(end: number): Numbers { + function* go(next: number): Iterable { + if (next < end) { yield next; yield* go(next+1) } + } + return Array.from(go(0)); +} + +function analogous(baseH: number, count: number): Numbers { + const minWidth = count * MINH_SEP; + const width = + MAXH_WIDTH < minWidth ? minWidth : randBetween(minWidth, MAXH_WIDTH); + const sep = width / (count - 1); + const start = baseH - (width / 2); + let numbers = Array.from(upto(count).map(i => start + i * sep)); + return rand() > 0.5 ? numbers : numbers.reverse(); +} + +function complementary(baseH: number, count: number): Numbers { + const angle = randBetween(180 - MAXH_COMPL, 180 + MAXH_COMPL); + return analogous(baseH + angle, count); +} + +function triad(baseH: number): [number, number] { + const angle = randBetween(120 - MAXH_TRIAD, 120 + MAXH_TRIAD); + return [baseH - angle, baseH + angle]; +} + +type Layer = + 'outer' | 'spines' | 'vitiligo1' | + 'stripes' | 'cuffs' | + 'fins1' | 'fins2' | 'fins3' | 'vitiligo4' | + 'belly1' | 'vitiligo3' | 'belly2' | 'vitiligo2' | + 'eyes' | 'masks' | 'claws' | 'lines'; + +type Colours = { [l in Layer]: Oklch }; + +function colours(): Colours { + let cols: Partial = {}; + + cols.outer = baseOklch('dark'); // [todo] + cols.spines = mkSpines(cols.outer); + cols.vitiligo1 = mkVitiligo(cols.outer); + + cols.stripes = mkStripes(); + cols.cuffs = mkCuffs(cols.stripes); + + // fins, belly + const whichBody = rand(); + if (whichBody > 0.85) { + // triad + const hs = triad(cols.outer.h); + fins(hs[0]); belly(hs[1]); + } else if (whichBody > 0.4) { + // fins like belly + const [f, b] = complementary(cols.outer.h, 2); + fins(f!); belly(b!); + } else { + // fins like outer + fins(analogous(cols.outer.h, 3)[2]!); + belly(complementary(cols.outer.h, 3)[2]!); + } + + cols.eyes = { + l: baseLuma('light'), + c: randBetween(0.28, MAXC_LIGHT), + h: oneOf(analogous, complementary)(cols.outer.h, 3)[2]! + }; + + cols.masks = { + l: randBetween(0.8, MAXL), + c: randBetween(0.01, 0.06), + h: analogous(oneOf(cols.outer, cols.belly1, cols.fins1)!.h, 3)[2]! + }; + cols.claws = { + l: min(MAXL, cols.masks!.l + randBetween(0.1, -0.1)), + c: randBetween(0.01, 0.06), + h: analogous(cols.masks!.h, 3)[2]! + }; + + cols.lines = { + l: randBetween(0.01, 0.06), + c: baseChroma(0), + h: analogous(cols.outer!.h, 3)[2]! + } + + return cols as Colours; + + + function fins(h: number) { + const [fin1Hue, fin2Hue, fin3Hue] = analogous(h, 3); + const d = direction(); + cols.fins1 = doDirection(cols.outer!, fin1Hue!, d); + cols.fins2 = doDirection(cols.fins1, fin2Hue!, d); + cols.fins3 = doDirection(cols.fins2, fin3Hue!, d); + cols.vitiligo4 = mkVitiligo(cols.fins1); + } + + function belly(h: number) { + const [belly1Hue, belly2Hue] = analogous(h, 2); + cols.belly1 = { + l: randBetween(0.7, MAXL), + c: baseChroma(1), + h: belly1Hue! + }; + cols.belly2 = { + l: min(MAXL, cols.belly1!.l * 1.1), + c: cols.belly1!.c * 0.9, + h: belly2Hue! + }; + cols.vitiligo3 = mkVitiligo(cols.belly1); // oops sorry + cols.vitiligo2 = mkVitiligo(cols.belly2); + } + + type LFun = (l: number) => number; + type CFun = (l: number, c: number) => number; + function direction(): [LFun, CFun] { + return oneOf([lightFor, dullFor], [darkFor, brightFor]); + } + function doDirection(col: Oklch, h: number, [ll, cc]: [LFun, CFun]) { + return { l: ll(col.l), c: cc(col.l, col.c), h }; + } +} + +function mkVitiligo(outer: Oklch): Oklch { + return { + l: randBetween(max(outer.l, 0.8), MAXL), + c: randBetween(min(outer.c, 0.1), MINC_LIGHT), + h: randBetween(outer.h + 20, outer.h - 20) + }; +} + +function mkSpines(outer: Oklch): Oklch { + return { + l: outer.l * 0.8, c: outer.c * 1.1, + h: randBetween(outer.h + 12, outer.h - 12) + }; +} + +function mkStripes(): Oklch { + return { + l: randBetween(0.8, MAXL), + c: randBetween(MINC_LIGHT, MAXC_LIGHT), + h: rand() * 360 + }; +} + +function mkCuffs(sock: Oklch): Oklch { + return { + l: sock.l * 0.7, + c: randBetween(sock.c, MAXC_LIGHT), + h: randBetween(sock.h + 8, sock.h - 8) + }; +} + + +function setColours(cols: Colours) { + for (const k in cols) { + const c = cols[k as keyof Colours]; + for (const elem of Array.from(document.getElementsByClassName(k))) { + (elem as HTMLElement).style.background = `oklch(${c.l} ${c.c} ${c.h})`; + } + } + document.documentElement.style.setProperty('--hue', `${cols.outer.h}deg`); +} + + +document.addEventListener('DOMContentLoaded', function() { + const reroll = document.getElementById('reroll')!; + const swap = document.getElementById('swap')!; + const pic = document.getElementById('pic')!; + + reroll.addEventListener('click', doReroll); + swap.addEventListener('click', doSwap); + + doReroll(); + setTimeout(setTransition); + + function doReroll() { setColours(colours()); } + function doSwap() { pic.classList.toggle('back'); } + function setTransition() { + document.documentElement.style.setProperty('--transition', + 'background 0.4s ease-in-out, color 0.4s ease-in-out'); + } +}); + + +export {} diff --git a/rainbow-quox/front/belly1.webp b/rainbow-quox/front/belly1.webp new file mode 100644 index 0000000..a30d9e1 --- /dev/null +++ b/rainbow-quox/front/belly1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f5515bcd8865df62a88f0dc246282a22aa6434fe82dc62a026a6530ede05b2f +size 33482 diff --git a/rainbow-quox/front/belly2.webp b/rainbow-quox/front/belly2.webp new file mode 100644 index 0000000..0c14054 --- /dev/null +++ b/rainbow-quox/front/belly2.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:643cfcceac30ccffb73b5038d88317c30c66c931f25ff8db3aaed9a3f47f9bd9 +size 34988 diff --git a/rainbow-quox/front/claws.webp b/rainbow-quox/front/claws.webp new file mode 100644 index 0000000..5a95d1a --- /dev/null +++ b/rainbow-quox/front/claws.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4a568b8f63b1e4ab8e2ffd10fb430990af4c62d4ab9fc1452f9c94a7fc2d017 +size 18770 diff --git a/rainbow-quox/front/cuffs.webp b/rainbow-quox/front/cuffs.webp new file mode 100644 index 0000000..b9df330 --- /dev/null +++ b/rainbow-quox/front/cuffs.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8bfd541943e0ba2a4b22e2cb388547a252570cf671d10f291e29d9f1201dc06 +size 19030 diff --git a/rainbow-quox/front/eyes.webp b/rainbow-quox/front/eyes.webp new file mode 100644 index 0000000..a427132 --- /dev/null +++ b/rainbow-quox/front/eyes.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:321341953d8afd71a7147019beac8852179454cd60d9e45b8d2d1d6924c70f23 +size 6874 diff --git a/rainbow-quox/front/fins1.webp b/rainbow-quox/front/fins1.webp new file mode 100644 index 0000000..6375bb2 --- /dev/null +++ b/rainbow-quox/front/fins1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39bdaee56915a8aed70c2cb772a3d389ce16a61e64540e34890d25c933aab8cd +size 14174 diff --git a/rainbow-quox/front/fins2.webp b/rainbow-quox/front/fins2.webp new file mode 100644 index 0000000..907f261 --- /dev/null +++ b/rainbow-quox/front/fins2.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:353fadde80ca1443681df10725c6dddf4670fec0671f79e117170dd84cd30a71 +size 13806 diff --git a/rainbow-quox/front/fins3.webp b/rainbow-quox/front/fins3.webp new file mode 100644 index 0000000..f01fe5d --- /dev/null +++ b/rainbow-quox/front/fins3.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3049390a7a2f844a24f08ebc3f6c29fb85193358a0237ab88608a827b3b35631 +size 5726 diff --git a/rainbow-quox/front/lines.webp b/rainbow-quox/front/lines.webp new file mode 100644 index 0000000..0b1a447 --- /dev/null +++ b/rainbow-quox/front/lines.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ae65212ecd5b68e9e03a5e5d9bcb3bc36492d311f0e86038469683fba94d285 +size 220226 diff --git a/rainbow-quox/front/masks.webp b/rainbow-quox/front/masks.webp new file mode 100644 index 0000000..afacfdd --- /dev/null +++ b/rainbow-quox/front/masks.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07707af55f8e41ab0156ecdc490f3ae7faf2ecb369df54a8fd696325594932ad +size 11180 diff --git a/rainbow-quox/front/outer.webp b/rainbow-quox/front/outer.webp new file mode 100644 index 0000000..3ef1531 --- /dev/null +++ b/rainbow-quox/front/outer.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6afb5783c828ce56e3f590a2015859f82e841411305b9eab5f2a5bc87f99fd83 +size 28322 diff --git a/rainbow-quox/front/spines.webp b/rainbow-quox/front/spines.webp new file mode 100644 index 0000000..36f4910 --- /dev/null +++ b/rainbow-quox/front/spines.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:213ca5194a9471eabd99e81d6438816dc91fe9fd037e59b8c7dd663cc0332151 +size 11778 diff --git a/rainbow-quox/front/static.webp b/rainbow-quox/front/static.webp new file mode 100644 index 0000000..7da6697 --- /dev/null +++ b/rainbow-quox/front/static.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:584d2500af71f04385c0c23e8ef07be759e28d1633e750944fccb7ec5910b25c +size 60422 diff --git a/rainbow-quox/front/stripes.webp b/rainbow-quox/front/stripes.webp new file mode 100644 index 0000000..12d8b9b --- /dev/null +++ b/rainbow-quox/front/stripes.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab005f96e30bc1c4616df9fb13b3e942e3c665f1ff97e10b3c46b2d158e6e2c9 +size 52846 diff --git a/rainbow-quox/front/vitiligo1.webp b/rainbow-quox/front/vitiligo1.webp new file mode 100644 index 0000000..a7481af --- /dev/null +++ b/rainbow-quox/front/vitiligo1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26b0af713721f8f8d324af2d5a4ce73b02614e57c36a33d7c11ac1f02cff95d4 +size 17448 diff --git a/rainbow-quox/front/vitiligo2.webp b/rainbow-quox/front/vitiligo2.webp new file mode 100644 index 0000000..6e70fd4 --- /dev/null +++ b/rainbow-quox/front/vitiligo2.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39072c20f657bb4c395e35f82e3e107c49f0a2a1e6de0cb1262e5b462fc9f59c +size 5342 diff --git a/rainbow-quox/front/vitiligo3.webp b/rainbow-quox/front/vitiligo3.webp new file mode 100644 index 0000000..5bbf21b --- /dev/null +++ b/rainbow-quox/front/vitiligo3.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af3434048fae9d2eac0c3d76342a32357020e729a020ae38a7ba3bcf1acaa7f2 +size 3098 diff --git a/rainbow-quox/front/vitiligo4.webp b/rainbow-quox/front/vitiligo4.webp new file mode 100644 index 0000000..0fafd49 --- /dev/null +++ b/rainbow-quox/front/vitiligo4.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:771f1ad3217fe3530fb7560220b0ac4a9eda375b00a1909ea9ac27a41d045b19 +size 4974 diff --git a/rainbow-quox/index.html b/rainbow-quox/index.html new file mode 100644 index 0000000..c6b08b2 --- /dev/null +++ b/rainbow-quox/index.html @@ -0,0 +1,63 @@ + + +rainbow quox + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + +
    diff --git a/rainbow-quox/kra/back.kra b/rainbow-quox/kra/back.kra new file mode 100644 index 0000000..54e67ce --- /dev/null +++ b/rainbow-quox/kra/back.kra @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:462a140e5301d5ed8cff14ec5b019ddad5207f5e4aaadd7de637fa3a4d7dcfbe +size 10079930 diff --git a/rainbow-quox/kra/compl1.png b/rainbow-quox/kra/compl1.png new file mode 100644 index 0000000..23687ea --- /dev/null +++ b/rainbow-quox/kra/compl1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52e46b628ed2026246eb7cc928bc026b7f269a91c9f980db6825353d6e688dee +size 561799 diff --git a/rainbow-quox/kra/compl2.png b/rainbow-quox/kra/compl2.png new file mode 100644 index 0000000..0fdf791 --- /dev/null +++ b/rainbow-quox/kra/compl2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c6e5426f8d94cb92dd0ca9b9c553e50e4ee2976adb988339a5009aed73fd887 +size 560816 diff --git a/rainbow-quox/kra/front.kra b/rainbow-quox/kra/front.kra new file mode 100644 index 0000000..7fd8554 --- /dev/null +++ b/rainbow-quox/kra/front.kra @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:579ca5af9a79a8577f62013418f58c729c646cfda9f2fd2bed54688b59de2ddd +size 11346742 diff --git a/rainbow-quox/kra/triad.png b/rainbow-quox/kra/triad.png new file mode 100644 index 0000000..eb2300a --- /dev/null +++ b/rainbow-quox/kra/triad.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b59f4c7198b8782bdc16dc9012a25af0979948630390df9b1865238c46e1a66 +size 554043 diff --git a/rainbow-quox/style.css b/rainbow-quox/style.css new file mode 100644 index 0000000..e05ef37 --- /dev/null +++ b/rainbow-quox/style.css @@ -0,0 +1,164 @@ +@import url(/fonts/muller/muller.css); + +@property --transition { + syntax: "*"; + inherits: true; + initial-value: none; +} + +* { + box-sizing: border-box; + transition: var(--transition); +} + +@media (prefers-reduced-motion: reduce) { + * { transition: none; } +} + +:root { + --hue: 300deg; + min-height: 100vh; display: flex; + align-items: center; justify-content: center; + + --font: Muller, sans-serif; + font-family: var(--font); + + color-scheme: light dark; + background: + light-dark(oklch(0.9 0.08 var(--hue)), + oklch(0.3 0.12 var(--hue))); + + overflow-x: hidden; +} + +#pic { + position: relative; + width: min(1000px, 75vw); + margin: auto; + aspect-ratio: 2000/1312; +} +#pic div { + position: absolute; inset: 0; + mask-size: contain; mask-repeat: no-repeat; +} + + +#front, #back { + transition: all 0.45s cubic-bezier(.23,-0.03,.68,1.11); +} + +.back > #front { translate: 125vw; } +:not(.back) > #back { translate: -125vw; } + +@media (prefers-reduced-motion: reduce) { + #front, #back { transition: none; } + + .back > #front { translate: none; rotate: none; display: none; } + :not(.back) > #back { translate: none; rotate: none; display: none; } +} + + +#front .static { background: url(front/static.webp) 0 0 / contain; } +#back .static { background: url(back/static.webp) 0 0 / contain; } + +.spines { background: oklch(30.77% 0.1306 298.19); } +#front .spines { mask-image: url(front/spines.webp); } +#back .spines { mask-image: url(back/spines.webp); } + +.stripes { background: oklch(88.2% 0.0613 209.07); } +#front .stripes { mask-image: url(front/stripes.webp); } +#back .stripes { mask-image: url(back/stripes.webp); } + +.cuffs { background: oklch(72.74% 0.1008 225.69); } +#front .cuffs { mask-image: url(front/cuffs.webp); } +#back .cuffs { mask-image: url(back/cuffs.webp); } + +.outer { background: oklch(38.37% 0.1437 306.27); } +#front .outer { mask-image: url(front/outer.webp); } +#back .outer { mask-image: url(back/outer.webp); } + +.fins1 { background: oklch(85.06% 0.0961 81.4); } +#front .fins1 { mask-image: url(front/fins1.webp); } +#back .fins1 { mask-image: url(back/fins1.webp); } + +.fins2 { background: oklch(79.59% 0.1208 73.56); } +#front .fins2 { mask-image: url(front/fins2.webp); } +#back .fins2 { mask-image: url(back/fins2.webp); } + +.fins3 { background: oklch(74.11% 0.1268 64.62); } +#front .fins3 { mask-image: url(front/fins3.webp); } +#back .fins3 { mask-image: url(back/fins3.webp); } + +.belly1 { background: oklch(87.26% 0.0699 80.94); } +#front .belly1 { mask-image: url(front/belly1.webp); } +#back .belly1 { mask-image: url(back/belly1.webp); } + +.belly2 { background: oklch(76.92% 0.0954 58.36); } +#front .belly2 { mask-image: url(front/belly2.webp); } +#back .belly2 { mask-image: url(back/belly2.webp); } + +.eyes { background: oklch(36.26% 0.1107 145.78); } +#front .eyes { mask-image: url(front/eyes.webp); } +#back .eyes { mask-image: url(back/eyes.webp); } + +.masks { background: oklch(77.1% 0.0243 317.12); } +#front .masks { mask-image: url(front/masks.webp); } +#back .masks { mask-image: url(back/masks.webp); } + +.claws { background: oklch(88.92% 0.0207 325.75); } +#front .claws { mask-image: url(front/claws.webp); } +#back .claws { mask-image: url(back/claws.webp); } + +.vitiligo1 { background: oklch(79.4% 0.0588 309.27); } +#front .vitiligo1 { mask-image: url(front/vitiligo1.webp); } +#back .vitiligo1 { mask-image: url(back/vitiligo1.webp); } + +.vitiligo2 { background: oklch(93.14% 0.0331 83.71); } +#front .vitiligo2 { mask-image: url(front/vitiligo2.webp); } +#back .vitiligo2 { mask-image: url(back/vitiligo2.webp); } + +.vitiligo3 { background: oklch(95.7% 0.0296 94.35); } +#front .vitiligo3 { mask-image: url(front/vitiligo3.webp); } +#back .vitiligo3 { mask-image: url(back/vitiligo3.webp); } + +.vitiligo4 { background: oklch(95.7% 0.0296 94.35); } +#front .vitiligo4 { mask-image: url(front/vitiligo4.webp); } +#back .vitiligo4 { mask-image: url(back/vitiligo4.webp); } + +.lines { background: oklch(21.96% 0.0661 296.36); } +#front .lines { mask-image: url(front/lines.webp); } +#back .lines { mask-image: url(back/lines.webp); } + +.eye-shine { mask: none; mix-blend-mode: luminosity; } +#front .eye-shine { background: url(front/eyes.webp) 0 0 / contain; } +#back .eye-shine { background: url(back/eyes.webp) 0 0 / contain; } + + +#buttons { + margin-top: 3rem; + display: flex; gap: 20px; + z-index: -1; +} + +button { + font: 700 25pt var(--font); + flex: 30%; + background: oklch(0.5 0.2 var(--hue)); + color: oklch(0.95 0.075 calc(180deg + var(--hue))); + border: 3px solid oklch(0.2 0.05 var(--hue)); + padding: 0.2em 0.5em; + filter: drop-shadow(0 0 10px oklch(0.4 0.2 var(--hue) / 0.45)); +} + +nav { + position: absolute; + bottom: 15px; left: 22px; +} + +nav a { + color: light-dark(oklch(0.4 0.15 calc(180deg + var(--hue))), + oklch(0.9 0.19 calc(180deg + var(--hue)))); + text-decoration: 3px solid underline; + text-decoration-color: + oklch(0.6 0.1 calc(180deg + var(--hue))); +}