diff --git a/.gitattributes b/.gitattributes index 90fc636..213e0cb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,2 @@ *.jpg filter=lfs diff=lfs merge=lfs -text *.jpeg filter=lfs diff=lfs merge=lfs -text -*.pxm filter=lfs diff=lfs merge=lfs -text -*.mov filter=lfs diff=lfs merge=lfs -text -*.mp4 filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index 2073fc6..dc1c02a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,6 @@ -LightroomExports/ -node_modules/ public/ -/documentation/mirrors/ /resources/ .hugo_build.lock *.log *.orig *~ - -# Backup files for Markdown files processed in-place with sed -*.md-e diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 6563459..0000000 --- a/.gitmodules +++ /dev/null @@ -1,18 +0,0 @@ -[submodule "themes/platters"] - path = themes/platters - url = nutmeg:git/hugo-theme-platters.git -[submodule "themes/termlite"] - path = themes/termlite - url = git@github.com:erynofwales/hugo-theme-termlite.git -[submodule "themes/resource-builders"] - path = themes/resource-builders - url = git@github.com:erynofwales/hugo-resource-builders.git -[submodule "themes/image-utils"] - path = themes/image-utils - url = git@github.com:erynofwales/hugo-image-utilities.git -[submodule "themes/photostream"] - path = themes/photostream - url = git@github.com:erynofwales/hugo-theme-photostream.git -[submodule "themes/feeds"] - path = themes/feeds - url = git@github.com:erynofwales/hugo-theme-feeds.git diff --git a/.nvim/UltiSnips/markdown.snippets b/.nvim/UltiSnips/markdown.snippets deleted file mode 100644 index 9edc36e..0000000 --- a/.nvim/UltiSnips/markdown.snippets +++ /dev/null @@ -1,15 +0,0 @@ -snippet jp "lang jp shortcode" w -{{< lang jp >}}$1{{< /lang >}} -endsnippet - -snippet jpp "lang jp shortcode with expansion" w -{{% lang jp %}}$1{{% /lang %}} -endsnippet - -snippet tess "tess shortcode" w -{{< tess >}} -endsnippet - -snippet ruby "ruby shortcode" w -{{< ruby "$1" >}}$2{{< /ruby >}} -endsnippet diff --git a/.nvim/after/ftplugin/css.lua b/.nvim/after/ftplugin/css.lua deleted file mode 100644 index 886a868..0000000 --- a/.nvim/after/ftplugin/css.lua +++ /dev/null @@ -1,4 +0,0 @@ --- Eryn Wells - -vim.bo.shiftwidth = 2 -vim.bo.softtabstop = 2 diff --git a/.nvim/after/ftplugin/html.lua b/.nvim/after/ftplugin/html.lua deleted file mode 100644 index e4e10d2..0000000 --- a/.nvim/after/ftplugin/html.lua +++ /dev/null @@ -1,6 +0,0 @@ --- Eryn Wells - -local root = gitTopLevelDirectory() -vim.opt_local.path:prepend(root .. "/assets/scripts/**") -vim.opt_local.path:prepend(root .. "/assets/styles/**") -vim.opt_local.path:prepend(root .. "/layouts/**") diff --git a/.nvim/after/ftplugin/javascript.lua b/.nvim/after/ftplugin/javascript.lua deleted file mode 100644 index 441fb56..0000000 --- a/.nvim/after/ftplugin/javascript.lua +++ /dev/null @@ -1,4 +0,0 @@ --- Eryn Wells - -local root = gitTopLevelDirectory() -vim.opt_local.path:prepend(root .. "/assets/scripts/**") diff --git a/.nvim/after/ftplugin/markdown.lua b/.nvim/after/ftplugin/markdown.lua deleted file mode 100644 index 06282ba..0000000 --- a/.nvim/after/ftplugin/markdown.lua +++ /dev/null @@ -1,11 +0,0 @@ --- Eryn Wells - -vim.bo.textwidth = 80 - -vim.cmd [[ - iabbrev tokyo Tōkyō - iabbrev Tokyo Tōkyō - iabbrev kyoto Kyōto - iabbrev Kyoto Kyōto - iabbrev xx × -]] diff --git a/.nvim/ftdetect/html.lua b/.nvim/ftdetect/html.lua deleted file mode 100644 index 1c8cf86..0000000 --- a/.nvim/ftdetect/html.lua +++ /dev/null @@ -1,8 +0,0 @@ --- Eryn Wells - -local filetypedetectGroup = vim.api.nvim_create_augroup("HugoHTMLTemplates", {clear = true}) -vim.api.nvim_create_autocmd({"BufRead", "BufNewFile"}, { - pattern = {"**/layouts/**/*.html"}, - group = filetypedetectGroup, - command = "set ft=gohtmltmpl", -}) diff --git a/Makefile b/Makefile index fea5233..f65a034 100644 --- a/Makefile +++ b/Makefile @@ -1,44 +1,9 @@ # Eryn Wells -BUILD_DIR=public +DEPLOY_LOCATION=eryn@nutmeg.erynwells.me:/srv/www/erynwells.me/html -CONTENT_PATH=content +.PHONY: deploy +deploy: + hugo + rsync -avz --no-times --no-perms --delete public/ $(DEPLOY_LOCATION) -DEPLOY_USER=eryn -DEPLOY_HOSTNAME=nutmeg.erynwells.me -DEPLOY_PATH=/srv/www/erynwells.me/html -DEPLOY_LOCATION=$(DEPLOY_USER)@$(DEPLOY_HOSTNAME):$(DEPLOY_PATH) - -HOSTNAME=$(shell hostname -s) - -NETHACK_LOGFILE=$(shell command nethack --showpaths | grep scoredir | sed 's/.*"\(.*\)".*/\1/g')/logfile -NETHACK_LOGFILE_DATA_FILE=data/nethack/logfile/$(HOSTNAME).json - -.PHONY: site deploy clean - -site: - @echo "Building site" - hugo --buildFuture --enableGitInfo --destination "$(BUILD_DIR)" - -deploy: site - @echo "Removing .DS_Store files from $(DEPLOY_LOCATION)" - find "$(BUILD_DIR)" -name .DS_Store -print -delete - @echo "Deploying to $(DEPLOY_LOCATION)" - rsync -avz --no-times --no-perms --delete "$(BUILD_DIR)/" "$(DEPLOY_LOCATION)" - git tag -f $(shell ./scripts/website deployment next-tag) - -deployall: nethack deploy - -nethack: nethack-logfile nethack-commit - -nethack-logfile: $(NETHACK_LOGFILE) -ifeq (,$(wildcard $<)) - @echo "Importing Nethack logfile from $(NETHACK_LOGFILE)" - scripts/import-nethack-logfile.py -o $(NETHACK_LOGFILE_DATA_FILE) $< -endif - -nethack-commit: $(NETHACK_LOGFILE_DATA_FILE) - if ! git diff --quiet $<; then git commit -m "Update Nethack logfile for $(HOSTNAME)" -- $<; fi - -clean: - rm -rf "$(BUILD_DIR)/" diff --git a/archetypes/link.md b/archetypes/link.md deleted file mode 100644 index 5a8d835..0000000 --- a/archetypes/link.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: "{{ replace .Name "-" " " | title }}" -slug: link-{{ .Name }} -date: {{ .Date }} -categories: links -draft: true -tags: [] ---- - diff --git a/scripts/erynwells_me/__init__.py b/archetypes/other.md similarity index 100% rename from scripts/erynwells_me/__init__.py rename to archetypes/other.md diff --git a/archetypes/sketch/index.md b/archetypes/sketch/index.md deleted file mode 100644 index dee4e18..0000000 --- a/archetypes/sketch/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: "{{ replace .Name "-" " " | title }}" -date: {{ .Date }} -draft: true ---- - -{{< figures/p5 id="sketch" >}} diff --git a/archetypes/sketch/sketch.js b/archetypes/sketch/sketch.js deleted file mode 100644 index 54d2b7d..0000000 --- a/archetypes/sketch/sketch.js +++ /dev/null @@ -1,20 +0,0 @@ -const sketch = p => { - p.setup = () => { - const sketchContainer = document.querySelector('#sketch'); - const canvasWidth = parseFloat(getComputedStyle(sketchContainer).width); - let canvas = p.createCanvas(canvasWidth, canvasWidth); - canvas.canvas.removeAttribute('style'); - sketchContainer.appendChild(canvas.canvas); - - p.pixelDensity(p.displayDensity()); - }; - - p.draw = () => { - p.background(255); - p.strokeWeight(4); - p.stroke(0, 0, 255); - p.circle(100, 100, 100); - }; -}; - -new p5(sketch, 'sketch'); diff --git a/archetypes/weeknotes.md b/archetypes/weeknotes.md deleted file mode 100644 index 1bae5a0..0000000 --- a/archetypes/weeknotes.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: "Notes on {{ time.Now.Format "2006" }}W%%WEEK_NUMBER%%" -slug: weeknotes-{{ time.Now.Format "2006" }}w%%WEEK_NUMBER%% -date: {{ .Date | time.Format "2006-01-02" }} -categories: weeknotes -tags: - - Weeknotes -draft: true ---- - diff --git a/assets/css/099_format_tweaks.css b/assets/css/099_format_tweaks.css deleted file mode 100644 index 453f2cc..0000000 --- a/assets/css/099_format_tweaks.css +++ /dev/null @@ -1,18 +0,0 @@ - - - - - -/************************ - * PARAGRAPH-SPACED LIST - ************************/ - -p + .paragraph-spaced-list { - margin-block-start: var(--space-paragraph); -} - -.paragraph-spaced-list { - li + li { - margin-block-start: var(--space-paragraph); - } -} diff --git a/assets/css/099_home_latest.css b/assets/css/099_home_latest.css deleted file mode 100644 index 7fb9e44..0000000 --- a/assets/css/099_home_latest.css +++ /dev/null @@ -1,42 +0,0 @@ -.home-latest { - display: grid; - grid-column: main-start / main-end; - grid-template-columns: 1fr 1fr 1fr 1fr; - grid-template-rows: min-content min-content; - grid-template-areas: - "blog1 blog1 blog2 blog2" - "photo1 photo2 photo3 photo4"; - - .home-latest__blog { - margin-block-end: var(--space-m); - } - - .home-latest__blog:nth-of-type(1) { - grid-area: blog1; - border-right: 2px dashed var(--gray6); - padding-inline-end: var(--space-s); - } - - .home-latest__blog:nth-of-type(2) { - grid-area: blog2; - padding-inline-start: var(--space-s); - } - - .home-latest__photo { - } -} - -@media screen and (max-width: 480px) { - .home-latest { - grid-template-columns: 1fr 1fr; - grid-template-rows: repeat(min-content, 4); - grid-template-areas: - "blog1 blog2" - "photo1 photo2" - "photo3 photo4"; - } -} - -p + .home-latest { - margin-block-start: var(--space-paragraph); -} diff --git a/assets/css/099_nethack.css b/assets/css/099_nethack.css deleted file mode 100644 index 3667e30..0000000 --- a/assets/css/099_nethack.css +++ /dev/null @@ -1,100 +0,0 @@ - - - - - -/****************** - * NETHACK LOGFILE - ******************/ - -#dungeon-background { - width: 100vw; - height: 100vh; - position: fixed; - top: 0; - left: 0; - z-index: -1; - filter: brightness(0.3); -} - -.nethack-logfile { - margin-inline-start: 0; - padding-inline-start: 0; - - .nethack-logentry { - align-items: first baseline; - display: grid; - grid-template-columns: min-content min-content auto min-content; - grid-template-areas: - "list-marker entry-marker entry-date entry-character-descriptor" - ". . entry-description entry-description" - ". . entry-stats entry-stats"; - gap: var(--space-xs); - margin-inline-start: 0; - } -} - - -.nethack-logentry { - &:not(:last-child) { - margin-block-end: var(--space-l); - } - - &::before { - grid-area: list-marker; - } - - .nethack-logentry__marker { - grid-area: entry-marker; - } - - .nethack-logentry__date { - grid-area: entry-date; - line-height: 1; - margin: 0; - padding: 0; - } - - .nethack-logentry__character-descriptor { - font-family: var(--font-family-monospace); - font-size: var(--text-s); - grid-area: entry-character-descriptor; - line-height: 1; - white-space: nowrap; - } - - .nethack-logentry__description { - grid-area: entry-description; - margin: 0; - } - - .nethack-logentry__stats { - border: 0; - color: var(--text-color-secondary); - font-family: var(--font-family-monospace); - font-size: var(--text-s); - grid-area: entry-stats; - margin-block: 0; - width: 100%; - -webkit-border-horizontal-spacing: 0; - -webkit-border-vertical-spacing: 0; - } - - .nethack-logentry__stats { - padding: 0; - text-transform: uppercase; - vertical-align: bottom; - white-space: nowrap; - - thead { - font-weight: bolder; - } - - .nethack-logentry__score, - .nethack-logentry__hp, - .nethack-logentry__level { - width: 16rem; - text-align: right; - } - } -} diff --git a/assets/images/memes/not-doing-it.png b/assets/images/memes/not-doing-it.png deleted file mode 100644 index 0dd9974..0000000 Binary files a/assets/images/memes/not-doing-it.png and /dev/null differ diff --git a/assets/scripts/nethack/dungeon.js b/assets/scripts/nethack/dungeon.js deleted file mode 100644 index 6203f94..0000000 --- a/assets/scripts/nethack/dungeon.js +++ /dev/null @@ -1,758 +0,0 @@ -const NUMBER_OF_ROOMS = 12; -const TUNNEL_PASSES = 3; - -class Cell { - static CORRIDOR = "#"; - static DOOR_CLOSED = "+"; - - character; - characterColor; - backgroundColor; - - constructor(char, charColor) { - this.character = char; - } - - empty() { this.character = " "; } - floor() { this.character = "."; } - upStair() { this.character = "<"; } - downStair() { this.character = ">"; } - corridor() { this.character = Cell.CORRIDOR; } - topLeftWall() { this.character = "┌"; } - topRightWall() { this.character = "┐"; } - bottomLeftWall() { this.character = "└"; } - bottomRightWall() { this.character = "┘"; } - horizontalWall() { this.character = "─"; } - verticalWall() { this.character = "│"; } - doorClosed() { this.character = Cell.DOOR_CLOSED; } - - isEmpty() { return !this.character || this.character === " "; } - isDoor() { return this.character === Cell.DOOR_CLOSED; } - isCorridor() { return this.character === Cell.CORRIDOR; } - - canBecomeDoor() { return this.character === "─" || this.character === "│" } -} - -class Point { - x = 0; - y = 0; - - constructor(x, y) { - if (x) { this.x = x; } - if (y) { this.y = y; } - } - - *neighbors() { - const x = this.x; - const y = this.y; - - yield new Point(x - 1, y - 1); - yield new Point(x, y - 1); - yield new Point(x + 1, y - 1); - yield new Point(x - 1, y); - yield new Point(x + 1, y); - yield new Point(x - 1, y + 1); - yield new Point(x, y + 1); - yield new Point(x + 1, y + 1); - } - - equalsPoint(other) { return this.x === other.x && this.y === other.y; } -} - -class Size { - width = 0; - height = 0; - - constructor(width, height) { - this.width = width; - this.height = height; - } -} - -class Rect { - origin = new Point(); - size = new Size(); - - static fromCoordinates(x, y, w, h) { - return new Rect(new Point(x, y), new Size(w, h)); - } - - constructor(origin, size) { - this.origin = origin; - this.size = size; - } - - get minX() { return this.origin.x; } - get minY() { return this.origin.y; } - get maxX() { return this.origin.x + this.size.width; } - get maxY() { return this.origin.y + this.size.height; } - - get width() { return this.size.width; } - get height() { return this.size.height; } - get area() { return this.size.width * this.size.height; } - - *xCoordinates() { - for (let x = this.minX; x <= this.maxX; x++) { - yield x; - } - } - - *yCoordinates() { - for (let y = this.minY; y <= this.maxY; y++) { - yield y; - } - } - - insetRect(inset) { - const twiceInset = 2 * inset; - - return Rect.fromCoordinates( - this.origin.x + inset, - this.origin.y + inset, - this.size.width - twiceInset, - this.size.height - twiceInset - ); - } - - intersects(otherRect) { - if (otherRect.minX > this.maxX) - return false; - - if (otherRect.maxX < this.minX) - return false; - - if (otherRect.minY > this.maxY) - return false; - - if (otherRect.maxY < this.minY) - return false; - - return true; - } -} - -class Grid { - #size; - #cells = []; - #rooms = []; - - constructor(width, height) { - this.#size = new Size(width, height); - - this.#cells = new Array(width * height); - for (let i = 0; i < this.#cells.length; i++) { - this.#cells[i] = new Cell(" "); - } - } - - get bounds() { return new Rect(new Point(), this.#size); } - get width() { return this.#size.width; } - get height() { return this.#size.height; } - get rooms() { return this.#rooms; } - - generate(p, roomGeneratorClass, tunnelGeneratorClass) { - this.#generateRooms(p, new roomGeneratorClass(this, NUMBER_OF_ROOMS)); - this.#placeStairs(); - this.#digCorridors(p, new tunnelGeneratorClass(this, TUNNEL_PASSES)); - } - - #generateRooms(p, generator) { - generator.generate(p); - this.#rooms = generator.rooms; - } - - #placeStairs() { - const indexOfRoomWithUpStairs = randomInt(this.#rooms.length); - const coordinateOfUpStair = this.#rooms[indexOfRoomWithUpStairs].randomPoint(); - this.cellAt(coordinateOfUpStair.x, coordinateOfUpStair.y).upStair(); - - while (true) { - let indexOfRoomForDownStair = randomInt(this.#rooms.length); - if (indexOfRoomForDownStair == indexOfRoomWithUpStairs) { - continue; - } - - const coordinateOfDownStair = this.#rooms[indexOfRoomForDownStair].randomPoint(); - this.cellAt(coordinateOfDownStair.x, coordinateOfDownStair.y).downStair(); - - break; - } - } - - #digCorridors(p, generator) { - generator.generate(p); - } - - pointIsInBounds(pt) { return pt.x >= 0 && pt.x < this.width && pt.y >= 0 && pt.y < this.height; } - - cellAt(x, y) { return this.#cells[y * this.width + x]; } -} - -class Room { - #rect; - - constructor(rect) { - this.#rect = rect; - } - - get bounds() { return this.#rect; } - - get minX() { return this.#rect.minX; } - get minY() { return this.#rect.minY; } - get maxX() { return this.#rect.maxX; } - get maxY() { return this.#rect.maxY; } - - randomPoint() { - return new Point( - this.#rect.minX + 1 + randomInt(this.#rect.size.width - 2), - this.#rect.minY + 1 + randomInt(this.#rect.size.height - 2) - ); - } - - transformCellAt(pt, cell) { - const minX = this.minX; - const minY = this.minY; - const maxX = this.maxX; - const maxY = this.maxY; - - const x = pt.x; - const y = pt.y; - - if (y === minY && x === minX) { cell.topLeftWall(); } - else if (y === minY && x === maxX) { cell.topRightWall(); } - else if (y === maxY && x === minX) { cell.bottomLeftWall(); } - else if (y === maxY && x === maxX) { cell.bottomRightWall(); } - else if (y === minY || y === maxY) { cell.horizontalWall(); } - else if (x === minX || x === maxX) { cell.verticalWall(); } - else if ((x > minX && x < maxX) && (y > minY && y < maxY)) { return cell.floor(); } - } -} - -class NRandomRoomsGenerator { - static MIN_ROOM_DIMENSION = 7; - static MAX_ROOM_DIMENSION = 12; - - #numberOfRooms = 12; - #rooms; - #grid; - - constructor(grid, numberOfRooms) { - this.#grid = grid; - - if (numberOfRooms) { - this.#numberOfRooms = numberOfRooms; - } - } - - get rooms() { - if (!this.#rooms) { - this.#generateRooms(); - } - - return this.#rooms; - } - - get #bounds() { return this.#grid.bounds; } - - generate(p) { - this.#generateRooms(); - - for (let i = 0; i < this.#rooms.length; i++) { - let room = this.#rooms[i]; - for (let y = room.minY; y <= room.maxY; y++) { - for (let x = room.minX; x <= room.maxX; x++) { - let point = new Point(x, y); - let cell = this.#grid.cellAt(x, y); - - room.transformCellAt(point, cell); - cell.characterColor = p.color(255); - } - } - } - } - - #generateRooms() { - let rects = new Array(); - - const sizeRange = NRandomRoomsGenerator.MAX_ROOM_DIMENSION - NRandomRoomsGenerator.MIN_ROOM_DIMENSION; - - while (rects.length < this.#numberOfRooms) { - const randomSize = new Size( - NRandomRoomsGenerator.MIN_ROOM_DIMENSION + randomInt(sizeRange), - NRandomRoomsGenerator.MIN_ROOM_DIMENSION + randomInt(sizeRange) - ); - - const randomOrigin = new Point( - this.#bounds.minX + randomInt(this.#bounds.maxX - randomSize.width), - this.#bounds.minY + randomInt(this.#bounds.maxY - randomSize.height) - ); - - const proposedRoomRect = new Rect(randomOrigin, randomSize); - - // Check that the rect doesn't intersect with any other rects. - if (rects.some(e => e.intersects(proposedRoomRect))) { - continue; - } - - rects.push(proposedRoomRect); - } - - rects.sort((a, b) => { - if (a.origin.x < b.origin.x) { return -1; } - if (a.origin.x > b.origin.x) { return 1; } - if (a.origin.y < b.origin.y) { return -1; } - if (a.origin.y > b.origin.y) { return 1; } - return 0; - }); - - this.#rooms = rects.map(r => new Room(r.insetRect(1))); - } -} - -class TunnelGenerator { - static MAX_DOORS = 100; - - #grid; - #passes = 3; - #numberOfDoorsPlaced = 0; - - constructor(grid, passes) { - this.#grid = grid; - if (passes) { this.#passes = passes; } - } - - generate(p) { - console.group("Digging tunnels"); - - if (this.#passes >= 1) { - this.#doPassOne(p); - } - - if (this.#passes >= 2) { - this.#doPassTwo(p); - } - - if (this.#passes >= 3) { - this.#doPassThree(p); - } - - console.groupEnd(); - } - - #doPassOne(p) { - console.group("Pass 1"); - this.#iterateAndConnectRoomsWithOffset(p, 1); - console.groupEnd(); - } - - #doPassTwo(p) { - console.group("Pass 2"); - this.#iterateAndConnectRoomsWithOffset(p, 2); - console.groupEnd(); - } - - #doPassThree(p) { - console.group("Pass 3"); - this.#iterateAndConnectRoomsWithOffset(p, 3); - console.groupEnd(); - } - - #iterateAndConnectRoomsWithOffset(p, offset) { - let rooms = this.#grid.rooms; - const numberOfRooms = rooms.length; - for (let i = 0; i < numberOfRooms - offset; i++) { - let fromRoom = rooms[i]; - let toRoom = rooms[i + offset]; - - let [fromPoint, toPoint] = this.#findPointFromRoomToRoom(fromRoom, toRoom); - if (!fromPoint || !toPoint) { - continue; - } - - for (let neighbor of fromPoint.neighbors()) { - if (!this.#grid.pointIsInBounds(neighbor)) { - continue; - } - - let cell = this.#grid.cellAt(neighbor.x, neighbor.y); - if ((neighbor.x === fromPoint.x || neighbor.y === fromPoint.y) && cell.canBecomeDoor()) { - cell.doorClosed(); - this.#numberOfDoorsPlaced++; - break; - } - } - - const successfullyFoundTargetPoint = this.#digCorridorFromPointToPoint(p, fromPoint, toPoint); - - if (successfullyFoundTargetPoint) { - for (let neighbor of toPoint.neighbors()) { - if (!this.#grid.pointIsInBounds(neighbor)) { - continue; - } - - let cell = this.#grid.cellAt(neighbor.x, neighbor.y); - if ((neighbor.x === toPoint.x || neighbor.y === toPoint.y) && cell.canBecomeDoor()) { - cell.doorClosed(); - this.#numberOfDoorsPlaced++; - break; - } - } - } - } - } - - /** - * Dig a corridor from fromPoint to toPoint, assuming that both points are - * adjacent to valid locations for doors on the map. - * - * This is as close a copy of dig_corridor in the Nethack source as I could - * muster. It's not exactly pretty. This method assumed - */ - #digCorridorFromPointToPoint(p, fromPoint, toPoint) { - const MAX_STEPS = 500; - - if (!fromPoint || !toPoint) { - return; - } - - const fromX = fromPoint.x; - const toX = toPoint.x; - const fromY = fromPoint.y; - const toY = toPoint.y; - - let curX = fromX; - let curY = fromY; - - let dx = 0; - let dy = 0; - - // Set up the initial direction of the dig. - if (toX > curX) { - dx = 1; - } else if (toY > curY) { - dy = 1; - } else if (toX < curX) { - dx = -1; - } else { - dy = -1; - } - - curX -= dx; - curY -= dy; - - let steps = 0; - while (curX !== toX || curY !== toY) { - if (steps++ > MAX_STEPS) { - return false; - } - - curX += dx; - curY += dy; - - if (curX >= this.#grid.width - 1 || curX <= 0 || curY <= 0 || curY >= this.#grid.height - 1) { - return false; - } - - let cell = this.#grid.cellAt(curX, curY); - if (cell.isEmpty()) { - cell.corridor(); - } else if (!cell.isCorridor()) { - return false; - } - - let dix = Math.abs(curX - toX); - let diy = Math.abs(curY - toY); - - if (dix > diy && diy) { - const random = randomInt(dix - diy + 1); - if (!random) { - dix = 0; - } - } else if (diy > dix && dix) { - const random = randomInt(dix - diy + 1); - if (!random) { - diy = 0; - } - } - - if (dy && dix > diy) { - const ddx = curX > toX ? -1 : 1; - - let cell = this.#grid.cellAt(curX + ddx, curY); - if (cell.isEmpty() || cell.isCorridor()) { - dx = ddx; - dy = 0; - continue; - } - } else if (dx && diy > dix) { - const ddy = curY > toY ? -1 : 1; - - let cell = this.#grid.cellAt(curX, curY + ddy); - if (cell.isEmpty() || cell.isCorridor()) { - dy = ddy; - dx = 0; - continue; - } - } - - cell = this.#grid.cellAt(curX + dx, curY + dy); - if (cell.isEmpty() || cell.isCorridor()) { - continue; - } - - if (dx) { - dx = 0; - dy = toY < curY ? -1 : 1; - } else { - dy = 0; - dx = toX < curX ? -1 : 1; - } - - cell = this.#grid.cellAt(curX + dx, curY + dy); - if (cell.isEmpty() || cell.isCorridor()) { - continue; - } - - dy = -dy; - dx = -dx; - } - - return true; - } - - #findPointFromRoomToRoom(fromRoom, toRoom) { - const fromRoomBounds = fromRoom.bounds; - const toRoomBounds = toRoom.bounds; - - let foundFromPoint = false; - let foundToPoint = false; - - let fromPoint; - let toPoint; - if (fromRoomBounds.maxX < toRoomBounds.minX) { - // fromRoom is farther left than toRoom - - fromPoint = new Point(fromRoomBounds.maxX, fromRoomBounds.minY + 1 + randomInt(fromRoomBounds.height - 2)); - foundFromPoint = this.#canPlaceDoorAt(fromPoint); - - for (let y of fromRoomBounds.yCoordinates()) { - fromPoint.y = y; - foundFromPoint = this.#canPlaceDoorAt(fromPoint); - if (foundFromPoint) { - break; - } - } - - if (!foundFromPoint) { - return []; - } - - toPoint = new Point(toRoomBounds.minX, toRoomBounds.minY + 1 + randomInt(toRoomBounds.height - 2)); - foundToPoint = this.#canPlaceDoorAt(toPoint); - - for (let y of toRoomBounds.yCoordinates()) { - toPoint.y = y; - foundToPoint = this.#canPlaceDoorAt(toPoint); - if (foundToPoint) { - break; - } - } - - if (!foundToPoint) { - return []; - } - - fromPoint.x += 1; - toPoint.x -= 1; - } else if (fromRoomBounds.minX > toRoomBounds.maxX) { - // fromRoom is farther right than toRoomBounds. - - fromPoint = new Point(toRoomBounds.maxX, toRoomBounds.minY + 1 + randomInt(toRoomBounds.height - 2)); - foundFromPoint = this.#canPlaceDoorAt(fromPoint); - - for (let y of toRoomBounds.yCoordinates()) { - fromPoint.y = y; - foundFromPoint = this.#canPlaceDoorAt(fromPoint); - if (foundFromPoint) { - break; - } - } - - if (!foundFromPoint) { - return []; - } - - toPoint = new Point(fromRoomBounds.minX, fromRoomBounds.minY + 1 + randomInt(fromRoomBounds.height - 2)); - foundToPoint = this.#canPlaceDoorAt(toPoint); - - for (let y of fromRoomBounds.yCoordinates()) { - toPoint.y = y; - foundToPoint = this.#canPlaceDoorAt(toPoint); - if (foundToPoint) { - break; - } - } - - if (!foundToPoint) { - return []; - } - - fromPoint.x -= 1; - toPoint.x += 1; - } else if (fromRoomBounds.maxY < (toRoomBounds.minY - 1)) { - // fromRoom is above toRoom - - fromPoint = new Point(fromRoomBounds.minX + 1 + randomInt(fromRoomBounds.width - 2), fromRoomBounds.maxY); - foundFromPoint = this.#canPlaceDoorAt(fromPoint); - - for (let x of fromRoomBounds.xCoordinates()) { - fromPoint.x = x; - foundFromPoint = this.#canPlaceDoorAt(fromPoint); - if (foundFromPoint) { - break; - } - } - - if (!foundFromPoint) { - return []; - } - - toPoint = new Point(toRoomBounds.minX + 1 + randomInt(toRoomBounds.width - 2), toRoomBounds.minY); - foundToPoint = this.#canPlaceDoorAt(toPoint); - - for (let x of toRoomBounds.xCoordinates()) { - toPoint.x = x; - foundToPoint = this.#canPlaceDoorAt(toPoint); - if (foundToPoint) { - break; - } - } - - if (!foundToPoint) { - return []; - } - - fromPoint.y += 1; - toPoint.y -= 1; - } else if (fromRoomBounds.minY > (toRoomBounds.maxY + 1)) { - // fromRoom is below toRoom - - fromPoint = new Point(toRoomBounds.minX + 1 + randomInt(toRoomBounds.width - 2), toRoomBounds.maxY); - foundFromPoint = this.#canPlaceDoorAt(fromPoint); - - for (let x of toRoomBounds.xCoordinates()) { - fromPoint.x = x; - foundFromPoint = this.#canPlaceDoorAt(fromPoint); - if (foundFromPoint) { - break; - } - } - - if (!foundFromPoint) { - return []; - } - - toPoint = new Point(fromRoomBounds.minX + 1 + randomInt(fromRoomBounds.width - 2), fromRoomBounds.minY); - foundToPoint = this.#canPlaceDoorAt(toPoint); - - for (let x of fromRoomBounds.xCoordinates()) { - toPoint.x = x; - foundToPoint = this.#canPlaceDoorAt(toPoint); - if (foundToPoint) { - break; - } - } - - if (!foundToPoint) { - return []; - } - - fromPoint.y += 1; - toPoint.y -= 1; - } - - return [fromPoint, toPoint]; - } - - #canPlaceDoorAt(pt) { - if (this.#numberOfDoorsPlaced > TunnelGenerator.MAX_DOORS) { - return false; - } - - if (!this.#grid.cellAt(pt.x, pt.y).canBecomeDoor()) { - return false; - } - - for (let neighbor of pt.neighbors()) { - if (!this.#grid.pointIsInBounds(neighbor)) { - continue; - } - - let cell = this.#grid.cellAt(neighbor.x, neighbor.y); - if (cell.isDoor()) { - return false; - } - } - - return true; - } -} - -function randomInt(n) { - max = Math.floor(n); - return Math.floor(Math.random() * max); -} - -let grid; - -new p5(p => { - const CELL_WIDTH = 20; - const CELL_HEIGHT = Math.floor(CELL_WIDTH * 1.3); - - p.setup = () => { - const container = document.querySelector('#dungeon-background'); - console.assert(container, "Missing #dungeon-background element"); - - canvasWidth = parseFloat(getComputedStyle(container).width); - canvasHeight = parseFloat(getComputedStyle(container).height); - - let canvas = p.createCanvas(canvasWidth, canvasHeight); - canvas.canvas.removeAttribute('style'); - container.appendChild(canvas.canvas); - - p.pixelDensity(p.displayDensity()); - p.textFont("Courier"); - - const gridBounds = Rect.fromCoordinates( - 0, 0, - Math.max(80, Math.ceil(canvasWidth / CELL_WIDTH) - 1), - Math.max(24, Math.ceil(canvasHeight / CELL_HEIGHT) - 1) - ); - - console.log(`Generating grid with size ${gridBounds.size.width} x ${gridBounds.size.height}`); - - grid = new Grid(gridBounds.size.width, gridBounds.size.height); - grid.generate(p, NRandomRoomsGenerator, TunnelGenerator); - }; - - p.draw = () => { - console.log("Drawing"); - - p.textSize(CELL_HEIGHT); - - for (let y = 0; y < grid.height; y++) { - for (let x = 0; x < grid.width; x++) { - let cell = grid.cellAt(x, y); - - let fillColor = cell.characterColor ? cell.characterColor : p.color(255); - p.fill(fillColor); - - p.textAlign(p.CENTER, p.CENTER); - p.text(cell.character, x * CELL_WIDTH, y * CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT); - } - } - - p.noLoop(); - }; - -}, '#dungeon-background'); diff --git a/assets/scripts/railroad-utils.js b/assets/scripts/railroad-utils.js index d57777d..79b60e9 100644 --- a/assets/scripts/railroad-utils.js +++ b/assets/scripts/railroad-utils.js @@ -1,4 +1,8 @@ -import rr from "scripts/lib/railroad.js"; +{{ with resources.Get "scripts/lib/railroad.js" | fingerprint "sha512" }} +import rr from "{{ .RelPermalink }}"; +{{ else }} + {{ errorf "Unable to get railroad.js resource" }} +{{ end }} class RailroadDiagramManager { constructor() { diff --git a/assets/scripts/rubiks/scrambler.js b/assets/scripts/rubiks/scrambler.js deleted file mode 100644 index 10a03c3..0000000 --- a/assets/scripts/rubiks/scrambler.js +++ /dev/null @@ -1,123 +0,0 @@ -class RubiksCubeScrambler extends HTMLElement { - static #RandomMoveHysteresisMaxLength = 2; - - #shadowRoot; - #movesListElement; - - #numberOfMovesToGenerate = 25; - - constructor() { - super(); - this.#shadowRoot = this.attachShadow({ mode: "open" }); - } - - scramble() { - console.log("Randomizing Rubik's cube..."); - - const movesList = this.#movesListElement; - - while (movesList.childElementCount > this.#numberOfMovesToGenerate) { - movesList.removeChild(movesList.lastChild); - } - - let randomMoveHysteresis = []; - - for (let i = 0; i < this.#numberOfMovesToGenerate; i++) { - const randomMove = this.#randomMove(randomMoveHysteresis); - - let moveItem; - if (i < movesList.childElementCount) { - moveItem = movesList.children[i]; - } else { - moveItem = document.createElement("li"); - movesList.appendChild(moveItem); - } - - moveItem.classList.add("scrambler__move"); - moveItem.classList.remove("scrambler__move--start", "scrambler__move--end"); - - if (randomMove.includes("2")) { - moveItem.classList.add("scrambler__move--start"); - } else if (randomMove.includes("'")) { - moveItem.classList.add("scrambler__move--end"); - } - - moveItem.innerText = randomMove; - } - } - - #randomMove(hysteresis) { - const faces = "FBLRUD"; - - let move; - do { - move = faces.charAt(Math.floor(Math.random() * faces.length)); - } while (hysteresis && hysteresis.includes(move)); - - if (hysteresis) { - hysteresis.unshift(move); - while (hysteresis.length > RubiksCubeScrambler.#RandomMoveHysteresisMaxLength) { - hysteresis.pop(); - } - } - - const modifierFactor = Math.random(); - if (modifierFactor < 0.33333) { - move = "2" + move; - } else if (modifierFactor < 0.666666) { - move = move + "'"; - } - - return move; - } - - #removeAllMoves() { - const element = this.#movesListElement; - while (element.hasChildNodes()) { - element.removeChild(element.lastChild); - } - } - - // MARK: Custom Element - - connectedCallback() { - let template = document.getElementById("rubiks-cube-scrambler-template"); - console.assert(template, "Couldn't find RubiksCubeScrambler component template in the document"); - - const shadowRoot = this.#shadowRoot; - shadowRoot.appendChild(template.content.cloneNode(true)); - - this.#movesListElement = shadowRoot.querySelector(".scrambler__move-list"); - - shadowRoot - .querySelector("button[name='scramble']") - .addEventListener("click", () => this.scramble()); - - const patternLengthInputElement = shadowRoot.querySelector(".scrambler__pattern-length > input"); - patternLengthInputElement.value = this.#numberOfMovesToGenerate; - patternLengthInputElement.addEventListener("input", event => { - try { - const integerValue = parseInt(event.target.value); - this.#numberOfMovesToGenerate = integerValue; - } catch (e) { - console.error("Non-integer value of pattern length field", e); - } - }); - - this.scramble(); - } - - attributeChangedCallback(name, oldValue, newValue) { - console.debug("RubiksCubeScrambler attribute changed", name, oldValue, newValue); - if (name === "count") { - try { - let newIntValue = parseInt(newValue); - this.#numberOfMovesToGenerate = newIntValue; - } catch (e) { - console.error("`count` attribute should have an integer value.", e); - } - } - } -} - -window.customElements.define("rubiks-cube-scrambler", RubiksCubeScrambler); diff --git a/assets/scripts/ruby_switch.js b/assets/scripts/ruby_switch.js deleted file mode 100644 index 4556eb7..0000000 --- a/assets/scripts/ruby_switch.js +++ /dev/null @@ -1,169 +0,0 @@ -// Eryn Wells - -class RubySwitch extends HTMLElement { - static controlSizeInPixels = 32; - static thumbTransitionDuration = 0.1; - - static settings = [ - { - id: "ruby-switch-none", - value: "none", - label: "あ" - }, - { - id: "ruby-switch-both", - value: "both", - label: "a", - default: true - }, - { - id: "ruby-switch-hidden", - value: "hidden", - label: "ab" - }, - ]; - - #root; - #thumb; - - constructor() { - super(); - - this.#updateValue(RubySwitch.settings.find(obj => obj.default).value); - this.addEventListener("RubyStyleChanged", event => { - this.#updateValue(event.detail.style); - }); - - this.#root = this.attachShadow({ mode: "closed" }); - this.#buildShadowDOM(); - - this.#updateThumbPosition(this.#root.querySelector(".control[data-default]")); - } - - #updateValue(style) { - this.setAttribute("value", style); - } - - get #stylesheet() { - const controlSize = RubySwitch.controlSizeInPixels; - const halfControlSize = controlSize / 2; - - return ` - #ruby-controls { - box-sizing: border-box; - display: inline-block; - position: relative; - } - - #controls { - border: none; - box-sizing: border-box; - display: inline grid; - grid-template-columns: repeat(3, ${controlSize}px); - margin: 0; - overflow: none; - padding: 0; - } - - #thumb { - box-sizing: border-box; - box-shadow: 2px 2px 6px #ccc; - border: 0.5px solid #aaa; - border-radius: ${halfControlSize}px; - position: absolute; - top: 0; - height: ${controlSize}px; - width: ${controlSize}px; - z-index: 50; - transition: left ${RubySwitch.thumbTransitionDuration}s; - } - - .control { - aspect-ratio: 1; - display: flex; - justify-content: center; - align-items: center; - height: ${controlSize}px; - width: ${controlSize}px; - } - - b { - font-weight: normal; - cursor: pointer; - } - - label { - z-index: 2; - text-align: center; - } - - #ruby-switch-both { - } - `; - } - - #buildShadowDOM() { - const root = this.#root; - - const style = document.createElement("style"); - style.textContent = this.#stylesheet; - root.appendChild(style); - - let container = document.createElement("div"); - container.id = "ruby-controls"; - root.appendChild(container); - - let controls = document.createElement("div"); - controls.id = "controls"; - container.appendChild(controls); - - for (const desc of RubySwitch.settings) { - let control = document.createElement("div"); - control.classList.add("control") - control.id = desc.id; - - control.dataset.value = desc.value; - if (desc.default) { - control.dataset.default = ""; - } - - controls.appendChild(control); - - control.addEventListener("click", event => { - event.stopPropagation(); - event.preventDefault(); - - this.#updateThumbPosition(event.currentTarget); - - this.#root.dispatchEvent(new CustomEvent("RubyStyleChanged", { - bubbles: true, - composed: true, - detail: { - style: control.dataset.value, - }, - })); - }, { capture: true }); - - const label = document.createElement("b"); - label.innerHTML = desc.label; - control.appendChild(label); - } - - const thumb = document.createElement("div"); - this.#thumb = thumb; - thumb.id = "thumb"; - container.appendChild(thumb); - } - - #updateThumbPosition(selectedControl) { - const controls = this.#root.querySelector("#controls"); - - const trackBoundingRect = controls.getBoundingClientRect(); - const controlBoundingRect = selectedControl.getBoundingClientRect(); - - const offset = controlBoundingRect.left - trackBoundingRect.left; - this.#thumb.style.left = `${offset}px`; - } -} - -customElements.define("ruby-switch", RubySwitch); diff --git a/assets/scripts/site.js b/assets/scripts/site.js index b2ef2b1..5ba8b4a 100644 --- a/assets/scripts/site.js +++ b/assets/scripts/site.js @@ -3,4 +3,23 @@ */ window.addEventListener("DOMContentLoaded", () => { + const siteHeader = document.querySelector("header.site"); + if (!siteHeader) { + return; + } + siteHeader.classList.add("visible"); + + siteHeader.addEventListener("animationend", () => { + console.log("Animation ended"); + siteHeader.classList.add("sticky"); + }, false); + + try { + const documentReferrer = new URL(document.referrer); + if (documentReferrer.pathname === "/") { + siteHeader.classList.add("animated"); + } else { + siteHeader.classList.add("sticky"); + } + } catch { } }); diff --git a/assets/styles/blog.css b/assets/styles/blog.css new file mode 100644 index 0000000..1512c63 --- /dev/null +++ b/assets/styles/blog.css @@ -0,0 +1,82 @@ +:root { + --post-item-highlight-color: #efefef; +} +@media (prefers-color-scheme: dark) { + :root { + --post-item-highlight-color: #121212; + } +} + +.blog > .highlight { margin-block-end: var(--body-item-spacing); } + +.post-nav { + align-items: baseline; + display: flex; + margin-top: 3.5rem; +} + +.post-nav .next { + margin-left: auto; +} + +.post-single footer { + margin-block-start: var(--body-item-spacing); +} + +.blog.list > ul { + list-style: none; +} +.blog.list > ul > li { + align-items: baseline; + border-radius: 6px; + display: grid; + gap: 1rem; + grid-template-columns: minmax(min-content, 10vh) minmax(min-content, 3vh) auto max-content; + margin-block-end: 0.25rem; + transition: background-color 0.25s; +} +.blog.list > ul > li:hover { + background-color: var(--post-item-highlight-color); +} +.blog.list > ul > li > a { + color: inherit; +} +.blog.list > ul > li > a:hover { + text-decoration: none; +} +.blog.list > ul > li > .draft { + align-self: center; +} + +@supports (grid-template-columns: subgrid) { + .blog.list { + display: grid; + gap: 1rem; + grid-template-columns: minmax(min-content, 10vh) minmax(min-content, 3vh) auto max-content; + } + .blog.list > ul { + display: grid; + row-gap: 0.25rem; + grid-column: 1 / -1; + grid-template-columns: subgrid; + list-style: none; + } + .blog.list > ul > li { + display: grid; + grid-column: 1 / -1; + grid-template-columns: subgrid; + margin-block-end: 0; + } + + .blog.list > h5 { + grid-column: 1 / -1; + margin-block: 1rem 0; + } + .blog.list > h5:first-child { + margin-block-start: 0; + } +} + +.blog.list > ul > li > :first-child { + text-align: end; +} diff --git a/assets/styles/development.css b/assets/styles/development.css new file mode 100644 index 0000000..f27c5dd --- /dev/null +++ b/assets/styles/development.css @@ -0,0 +1,67 @@ +/* development.css + * Some styles for development UI. + * Eryn Wells + */ + +details:has(.photo-params.debug) { + margin-block-end: var(--body-item-spacing); +} + +.draft { + color: red; + display: inline-block; + font-family: 'SF Pro', sans-serif; + font-size: 1.5rem; + font-weight: bold; + letter-spacing: 3px; + text-transform: uppercase; +} + +.draft:before { + content: "["; +} + +.draft:after { + content: "]"; +} + +#debug-page-info { + background-color: var(--background-color); + border: 1px solid var(--separator-color); + border-radius: 6px; + box-shadow: 4px 5px 5px var(--box-shadow-color); + font-size: 1.75rem; + padding: 0.5rem; + position: fixed; + left: 2rem; + bottom: 2rem; + width: max-content; +} + +#debug-page-info > details { + margin: 0.5rem; +} + +#debug-page-info > summary { + font-family: var(--font-family-heading); +} + +#debug-page-info > details > table { + border-collapse: collapse; + display: block; + margin-block-start: 0.5em; + margin-inline-start: 1em; +} + +#debug-page-info > details > table > tbody > tr > td { + border: 1px solid rgb(var(--dk-gray)); + padding: 0.3em; +} + +#debug-page-info > details > table > tbody > tr:nth-child(even) { + background-color: var(--separator-color); +} + +.photo-params.debug { + width: 100%; +} diff --git a/assets/styles/home.css b/assets/styles/home.css new file mode 100644 index 0000000..c658264 --- /dev/null +++ b/assets/styles/home.css @@ -0,0 +1,170 @@ +:root { + --animation-offset: 6px; + --font-size-max: 12px; +} + +body { + display: flex; + flex-direction: column; + font-size: 2rem; + justify-content: center; + margin: auto; +} + +h1 { + font-size: 5rem; + line-height: 1.3; + margin: 0; + padding: 0; +} +@media (max-width: 599px) { + h1 { font-size: 4.25rem; } +} + +html { + font-size: clamp(var(--font-size-min), 2.5vw, var(--font-size-max)); +} + +main { + margin-block-start: 10vh; + width: inherit; +} + +main .grid { + align-items: baseline; + display: grid; + gap: 0 2rem; + grid-template-columns: minmax(min-content, 1fr) minmax(min-content, 2fr); + grid-template-rows: repeat(2, max-content); + grid-template-areas: + "title blurb" + "title nav"; + padding-inline: 1em; + width: min-content; +} +@media (max-width: 599px) { + main .grid { + gap: 1rem 0; + grid-template-columns: 1fr; + grid-template-rows: repeat(3, max-content); + grid-template-areas: + "title" + "blurb" + "nav"; + text-align: center; + } +} + +main h1 { + letter-spacing: 0.025em; + text-align: end; +} +@media (max-width: 599px) { + main h1 { text-align: center; } +} + +nav { + align-items: baseline; + display: flex; + list-style: none; + text-transform: lowercase; +} + +nav > li { + margin-inline-start: 0.5em; +} + +nav > li:first-of-type { + margin-inline-start: 0; +} + +p { + margin: 0; +} + +h1 { grid-area: title; } +#content { grid-area: blurb } +nav { grid-area: nav } + +h1, #content > p, nav { position: relative; } + +h1 { + animation: left-fade-in var(--transition-duration) ease-in-out; +} +@media (max-width: 599px) { + h1 { + animation: top-fade-in var(--transition-duration) ease-in-out; + } +} +#content > p, nav { + animation: right-fade-in var(--transition-duration) ease-in-out; +} +@media (max-width: 599px) { + #content > p, nav { + animation: bottom-fade-in var(--transition-duration) ease-in-out; + } +} + +@keyframes left-fade-in { + from { + opacity: 0%; + left: var(--animation-offset); + } + 33% { + opacity: 0%; + left: var(--animation-offset); + } + to { + opacity: 100%; + left: 0; + } +} + +@keyframes right-fade-in { + from { + opacity: 0%; + left: calc(-1 * var(--animation-offset)); + } + 33% { + opacity: 0%; + left: calc(-1 * var(--animation-offset)); + } + to { + opacity: 100%; + left: 0; + } +} + +@keyframes top-fade-in { + from { + opacity: 0%; + bottom: calc(-1 * var(--animation-offset)); + } + 33% { + opacity: 0%; + bottom: calc(-1 * var(--animation-offset)); + } + to { + opacity: 100%; + bottom: 0; + } +} + +@keyframes bottom-fade-in { + from { + opacity: 0%; + bottom: var(--animation-offset); + } + 33% { + opacity: 0%; + bottom: var(--animation-offset); + } + to { + opacity: 100%; + bottom: 0; + } +} + +.platter { + padding: 1.5rem 3rem; +} diff --git a/assets/styles/monokai.css b/assets/styles/monokai.css new file mode 100644 index 0000000..523390e --- /dev/null +++ b/assets/styles/monokai.css @@ -0,0 +1,192 @@ +:root { + --highlight-background-color: rgb(var(--super-lt-gray)); + --highlight-foreground-color: var(--foreground-body-color); +} +@media (prefers-color-scheme: dark) { + :root { + } +} + +.chroma { + line-height: var(--body-line-height); +} + +.bg { + color: var(--highlight-foreground-color); + background-color: var(--highlight-background-color); +} + +.chroma { + color: var(--highlight-foreground-color); + background-color: var(--highlight-background-color); +} + +/* Other */ .chroma .x { } +/* Error */ .chroma .err { color: #960050; background-color: #1e0010 } +/* CodeLine */ .chroma .cl { } +/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } +/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } +/* LineHighlight */ .chroma .hl { background-color: #ffffcc } +/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } +/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } +/* Keyword */ .chroma .k { color: #00a8c8 } +/* KeywordConstant */ .chroma .kc { color: #00a8c8 } +/* KeywordDeclaration */ .chroma .kd { color: #00a8c8 } +/* KeywordNamespace */ .chroma .kn { color: #f92672 } +/* KeywordPseudo */ .chroma .kp { color: #00a8c8 } +/* KeywordReserved */ .chroma .kr { color: #00a8c8 } +/* KeywordType */ .chroma .kt { color: #00a8c8 } +/* Name */ .chroma .n { color: #111111 } +/* NameAttribute */ .chroma .na { color: #75af00 } +/* NameBuiltin */ .chroma .nb { color: #111111 } +/* NameBuiltinPseudo */ .chroma .bp { color: #111111 } +/* NameClass */ .chroma .nc { color: #75af00 } +/* NameConstant */ .chroma .no { color: #00a8c8 } +/* NameDecorator */ .chroma .nd { color: #75af00 } +/* NameEntity */ .chroma .ni { color: #111111 } +/* NameException */ .chroma .ne { color: #75af00 } +/* NameFunction */ .chroma .nf { color: #75af00 } +/* NameFunctionMagic */ .chroma .fm { color: #111111 } +/* NameLabel */ .chroma .nl { color: #111111 } +/* NameNamespace */ .chroma .nn { color: #111111 } +/* NameOther */ .chroma .nx { color: #75af00 } +/* NameProperty */ .chroma .py { color: #111111 } +/* NameTag */ .chroma .nt { color: #f92672 } +/* NameVariable */ .chroma .nv { color: #111111 } +/* NameVariableClass */ .chroma .vc { color: #111111 } +/* NameVariableGlobal */ .chroma .vg { color: #111111 } +/* NameVariableInstance */ .chroma .vi { color: #111111 } +/* NameVariableMagic */ .chroma .vm { color: #111111 } +/* Literal */ .chroma .l { color: #ae81ff } +/* LiteralDate */ .chroma .ld { color: #d88200 } +/* LiteralString */ .chroma .s { color: #d88200 } +/* LiteralStringAffix */ .chroma .sa { color: #d88200 } +/* LiteralStringBacktick */ .chroma .sb { color: #d88200 } +/* LiteralStringChar */ .chroma .sc { color: #d88200 } +/* LiteralStringDelimiter */ .chroma .dl { color: #d88200 } +/* LiteralStringDoc */ .chroma .sd { color: #d88200 } +/* LiteralStringDouble */ .chroma .s2 { color: #d88200 } +/* LiteralStringEscape */ .chroma .se { color: #8045ff } +/* LiteralStringHeredoc */ .chroma .sh { color: #d88200 } +/* LiteralStringInterpol */ .chroma .si { color: #d88200 } +/* LiteralStringOther */ .chroma .sx { color: #d88200 } +/* LiteralStringRegex */ .chroma .sr { color: #d88200 } +/* LiteralStringSingle */ .chroma .s1 { color: #d88200 } +/* LiteralStringSymbol */ .chroma .ss { color: #d88200 } +/* LiteralNumber */ .chroma .m { color: #ae81ff } +/* LiteralNumberBin */ .chroma .mb { color: #ae81ff } +/* LiteralNumberFloat */ .chroma .mf { color: #ae81ff } +/* LiteralNumberHex */ .chroma .mh { color: #ae81ff } +/* LiteralNumberInteger */ .chroma .mi { color: #ae81ff } +/* LiteralNumberIntegerLong */ .chroma .il { color: #ae81ff } +/* LiteralNumberOct */ .chroma .mo { color: #ae81ff } +/* Operator */ .chroma .o { color: #f92672 } +/* OperatorWord */ .chroma .ow { color: #f92672 } +/* Punctuation */ .chroma .p { color: #111111 } +/* Comment */ .chroma .c { color: #75715e } +/* CommentHashbang */ .chroma .ch { color: #75715e } +/* CommentMultiline */ .chroma .cm { color: #75715e } +/* CommentSingle */ .chroma .c1 { color: #75715e } +/* CommentSpecial */ .chroma .cs { color: #75715e } +/* CommentPreproc */ .chroma .cp { color: #75715e } +/* CommentPreprocFile */ .chroma .cpf { color: #75715e } +/* Generic */ .chroma .g { } +/* GenericDeleted */ .chroma .gd { } +/* GenericEmph */ .chroma .ge { font-style: italic } +/* GenericError */ .chroma .gr { } +/* GenericHeading */ .chroma .gh { } +/* GenericInserted */ .chroma .gi { } +/* GenericOutput */ .chroma .go { } +/* GenericPrompt */ .chroma .gp { } +/* GenericStrong */ .chroma .gs { font-weight: bold } +/* GenericSubheading */ .chroma .gu { } +/* GenericTraceback */ .chroma .gt { } +/* GenericUnderline */ .chroma .gl { } +/* TextWhitespace */ .chroma .w { } + +@media (prefers-color-scheme: dark) { + /* Background */ .bg { color: #f8f8f2; background-color: #272822 } + /* PreWrapper */ .chroma { color: #f8f8f2; background-color: #272822; } + /* Other */ .chroma .x { } + /* Error */ .chroma .err { color: #960050; background-color: #1e0010 } + /* CodeLine */ .chroma .cl { } + /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } + /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } + /* LineHighlight */ .chroma .hl { background-color: #ffffcc } + /* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } + /* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } + /* Keyword */ .chroma .k { color: #66d9ef } + /* KeywordConstant */ .chroma .kc { color: #66d9ef } + /* KeywordDeclaration */ .chroma .kd { color: #66d9ef } + /* KeywordNamespace */ .chroma .kn { color: #f92672 } + /* KeywordPseudo */ .chroma .kp { color: #66d9ef } + /* KeywordReserved */ .chroma .kr { color: #66d9ef } + /* KeywordType */ .chroma .kt { color: #66d9ef } + /* Name */ .chroma .n { } + /* NameAttribute */ .chroma .na { color: #a6e22e } + /* NameBuiltin */ .chroma .nb { color: inherit; } + /* NameBuiltinPseudo */ .chroma .bp { } + /* NameClass */ .chroma .nc { color: #a6e22e } + /* NameConstant */ .chroma .no { color: #66d9ef } + /* NameDecorator */ .chroma .nd { color: #a6e22e } + /* NameEntity */ .chroma .ni { } + /* NameException */ .chroma .ne { color: #a6e22e } + /* NameFunction */ .chroma .nf { color: #a6e22e } + /* NameFunctionMagic */ .chroma .fm { } + /* NameLabel */ .chroma .nl { } + /* NameNamespace */ .chroma .nn { } + /* NameOther */ .chroma .nx { color: #a6e22e } + /* NameProperty */ .chroma .py { } + /* NameTag */ .chroma .nt { color: #f92672 } + /* NameVariable */ .chroma .nv { color: inherit; } + /* NameVariableClass */ .chroma .vc { } + /* NameVariableGlobal */ .chroma .vg { } + /* NameVariableInstance */ .chroma .vi { } + /* NameVariableMagic */ .chroma .vm { } + /* Literal */ .chroma .l { color: #ae81ff } + /* LiteralDate */ .chroma .ld { color: #e6db74 } + /* LiteralString */ .chroma .s { color: #e6db74 } + /* LiteralStringAffix */ .chroma .sa { color: #e6db74 } + /* LiteralStringBacktick */ .chroma .sb { color: #e6db74 } + /* LiteralStringChar */ .chroma .sc { color: #e6db74 } + /* LiteralStringDelimiter */ .chroma .dl { color: #e6db74 } + /* LiteralStringDoc */ .chroma .sd { color: #e6db74 } + /* LiteralStringDouble */ .chroma .s2 { color: #e6db74 } + /* LiteralStringEscape */ .chroma .se { color: #ae81ff } + /* LiteralStringHeredoc */ .chroma .sh { color: #e6db74 } + /* LiteralStringInterpol */ .chroma .si { color: #e6db74 } + /* LiteralStringOther */ .chroma .sx { color: #e6db74 } + /* LiteralStringRegex */ .chroma .sr { color: #e6db74 } + /* LiteralStringSingle */ .chroma .s1 { color: #e6db74 } + /* LiteralStringSymbol */ .chroma .ss { color: #e6db74 } + /* LiteralNumber */ .chroma .m { color: #ae81ff } + /* LiteralNumberBin */ .chroma .mb { color: #ae81ff } + /* LiteralNumberFloat */ .chroma .mf { color: #ae81ff } + /* LiteralNumberHex */ .chroma .mh { color: #ae81ff } + /* LiteralNumberInteger */ .chroma .mi { color: #ae81ff } + /* LiteralNumberIntegerLong */ .chroma .il { color: #ae81ff } + /* LiteralNumberOct */ .chroma .mo { color: #ae81ff } + /* Operator */ .chroma .o { color: #f92672 } + /* OperatorWord */ .chroma .ow { color: #f92672 } + /* Punctuation */ .chroma .p { color: inherit; } + /* Comment */ .chroma .c { color: #75715e } + /* CommentHashbang */ .chroma .ch { color: #75715e } + /* CommentMultiline */ .chroma .cm { color: #75715e } + /* CommentSingle */ .chroma .c1 { color: #75715e } + /* CommentSpecial */ .chroma .cs { color: #75715e } + /* CommentPreproc */ .chroma .cp { color: #75715e } + /* CommentPreprocFile */ .chroma .cpf { color: #75715e } + /* Generic */ .chroma .g { } + /* GenericDeleted */ .chroma .gd { color: #f92672 } + /* GenericEmph */ .chroma .ge { font-style: italic } + /* GenericError */ .chroma .gr { } + /* GenericHeading */ .chroma .gh { } + /* GenericInserted */ .chroma .gi { color: #a6e22e } + /* GenericOutput */ .chroma .go { } + /* GenericPrompt */ .chroma .gp { } + /* GenericStrong */ .chroma .gs { font-weight: bold } + /* GenericSubheading */ .chroma .gu { color: #75715e } + /* GenericTraceback */ .chroma .gt { } + /* GenericUnderline */ .chroma .gl { } + /* TextWhitespace */ .chroma .w { } +} diff --git a/assets/styles/photos.css b/assets/styles/photos.css new file mode 100644 index 0000000..59d7dbc --- /dev/null +++ b/assets/styles/photos.css @@ -0,0 +1,166 @@ +:root { + --date-item-background-color: rgb(var(--lt-gray)); + + --photo-params-background-color: rgb(var(--lt-gray)); + --photo-params-container-background-color: rgb(var(--super-lt-gray)); + --photo-params-color: rgb(var(--sub-dk-gray)); + --photo-params-border-color: rgb(var(--super-lt-gray)); +} +@media (prefers-color-scheme: dark) { + :root { + --date-item-background-color: rgb(var(--dk-gray)); + + --photo-params-background-color: rgb(var(--dk-gray)); + --photo-params-container-background-color: rgb(var(--sub-dk-gray)); + --photo-params-color: rgb(var(--super-lt-gray)); + --photo-params-border-color: rgb(var(--sub-dk-gray)); + } +} + +.photos.list { + box-sizing: border-box; + max-width: none; + padding: 0 var(--body-item-spacing); + width: 100%; +} + +.photos.list { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 4px; +} + +.photos.page > nav { + margin-block-end: var(--body-item-spacing); +} + +.photos.list > a { + display: block; + line-height: 0; +} + +.photos.list > a > img { + border-radius: 3px; + image-orientation: from-image; +} + +.photos.list > div { + background-color: var(--date-item-background-color); + border-radius: 3px; + width: 100%; + height: 100%; + display: flex; + align-items: center; +} + +.photos.list > div > h6 { + display: block; + font-size: 5rem; + margin: 0 auto; + letter-spacing: 0; +} + +.photos.list > div > h6 > span { + text-align: end; + width: min-content; + position: relative; + display: inline-block; + padding-inline-end: 20px; +} + +.photos.list > div > h6 > span::after { + top: 6px; + right: 0px; + position: absolute; + display: block; + content: "⏵︎"; + font-size: 80%; +} +@media (max-width: calc(24px + 400px + 4px)) { + .photos.list > div > h6 > span { + width: max-content; + padding-block: calc(0.25 * var(--body-item-spacing)); + } + .photos.list > div > h6 > span::after { + content: ""; + } +} + +.photo-params { + width: 100%; +} + +.photo-params .container { + display: block; + background-color: var(--photo-params-container-background-color); + border-radius: 10px; + margin: var(--body-item-spacing) auto; + padding: calc(var(--body-item-spacing) / 2); + width: 66%; +} + +.photo-params table { + background-color: var(--photo-params-background-color); + color: var(--photo-params-color); + border-collapse: collapse; + border-radius: 6px; + table-layout: fixed; + text-align: center; + width: 100%; +} + +.photo-params thead td { + border-bottom: 1px solid var(--photo-params-border-color); + font-size: 80%; + font-weight: bold; +} + +.photo-params tr.exposure-attributes td { + border-top: 1px solid var(--photo-params-border-color); + border-left: 1px solid var(--photo-params-border-color); +} + +.photo-params tr.exposure-attributes td:first-child { + border-left: none; +} + +.photo-params td { + font-size: 75%; + padding: 1rem; +} + +.photo-params td:last-child { + text-align: end; +} + +.photo-params td:first-child { + text-align: start; +} + +.photo-params .make-model { + font-weight: bold; +} + +.photo-params .size { + border-left: 0; +} + +.photo-params .location { + border-right: 0; +} + +.photo-params.debug thead { + font-size: 2rem; + font-weight: bold; + border-bottom: 2px solid rgb(var(--dk-gray)); +} + +.photo-params.debug { + width: 100%; +} + +.photo-params.debug td { + border: 1px solid var(--photo-params-border-color); + overflow: scroll; + vertical-align: top; +} diff --git a/assets/styles/railroad.css b/assets/styles/railroad.css new file mode 100644 index 0000000..da649ad --- /dev/null +++ b/assets/styles/railroad.css @@ -0,0 +1,64 @@ +:root { + --rect-fill: rgba(var(--mid-blue), 0.1); +} +@media (prefers-color-scheme: dark) { + :root { + --rect-fill: rgb(var(--mid-blue), 0.9); + } +} + +svg.railroad-diagram path { + stroke-width: 2; + stroke: var(--html-color); + fill: none; +} + +svg.railroad-diagram text { + font-family: var(--font-family-monospace); + text-anchor: middle; + white-space: pre; + fill: var(--html-color); +} + +svg.railroad-diagram text.diagram-text { + font-size: 11px; +} + +svg.railroad-diagram text.diagram-arrow { + font-size: 16px; +} + +svg.railroad-diagram text.label { + text-anchor: start; +} + +svg.railroad-diagram text.comment { + font: italic 12px var(--font-family-monospace); +} + +svg.railroad-diagram g.non-terminal text { + /*font-style: italic;*/ +} + +svg.railroad-diagram rect { + stroke-width: 2; + stroke: var(--html-color); + fill: var(--rect-fill); +} + +svg.railroad-diagram rect.group-box { + stroke: gray; + stroke-dasharray: 10 5; + fill: none; +} + +svg.railroad-diagram path.diagram-text { + stroke-width: 2; + stroke: var(--html-color); + fill: var(--html-background-color); + cursor: help; +} + +svg.railroad-diagram g.diagram-text:hover path.diagram-text { + fill: var(--rect-fill); +} diff --git a/assets/styles/root.css b/assets/styles/root.css new file mode 100644 index 0000000..735310e --- /dev/null +++ b/assets/styles/root.css @@ -0,0 +1,619 @@ +@layer reset, root, template, page; + +:root { + --black: 0, 0, 0; + --sub-dk-gray: 16, 16, 16; + --dk-gray: 32, 32, 32; + --super-dk-gray: 80, 80, 80; + --mid-gray: 128, 128, 128; + --sub-lt-gray: 175, 175, 175; + --lt-gray: 223, 223, 223; + --super-lt-gray: 240, 240, 240; + --white: 255, 255, 255; + + --lt-blue: 69, 212, 243; + --mid-blue: 26, 169, 239; + --dk-blue: 63, 46, 231; + --purple: 161, 49, 232; + --lilac: 187, 121, 245; + + --site-nav-link-color: rgb(var(--mid-blue)); + + --separator-color: rgb(var(--lt-gray)); + --header-border-color: var(--separator-color); + --footer-border-color: var(--separator-color); + + --box-shadow-color: rgba(var(--lt-gray), 0.8); + --header-box-shadow-color: var(--box-shadow-color); + + --font-family-body: Verdana, Helvetica, sans-serif; + --font-family-monospace: "Courier New", Courier, monospace; + --font-family-heading: Museo_Slab, Tahoma, sans-serif; + --font-family-site-heading: Museo_Slab, Tahoma, sans-serif; + --font-size-min: 6px; + --font-size-max: 8px; + + --body-font-size: 2rem; + --body-item-spacing: 1em; + --body-line-height: 1.5; + --body-header-line-height: 1.1; + --body-code-background-color: rgb(var(--super-lt-gray)); + + --heading-color: rgb(var(--black)); + --header-series-arrow-foreground-color: rgb(var(--sub-dk-gray)); + + --html-background-color: rgb(var(--white)); + --html-color: rgba(var(--black), 0.8); + + --platter-background-color: rgba(var(--white), var(--platter-background-opacity)); + --platter-background-opacity: 0.6; + --platter-backdrop-filter: blur(10px); + + --content-width: 80rem; + + --tag-foreground-color: rgb(var(--super-dk-gray)); + --tag-background-color: rgb(var(--super-lt-gray)); + --tag-spacer-foreground-color: rgb(var(--super-dk-gray)); + --tag-hover-background-color: rgb(var(--sub-lt-gray)); + + --transition-duration: 0.7s; + + --social-menu-padding: 1rem; + --menu-icon-size: 20px; + --twitter-icon: url(/icons/twitter.svg); + --github-icon: url(/icons/github.svg); + --instagram-icon: url(/icons/instagram.svg); + --feed-icon: url(/icons/rss.svg); +} +@media (prefers-color-scheme: dark) { + :root { + --separator-color: rgb(var(--dk-gray)); + --box-shadow-color: rgba(var(--dk-gray), 0.8); + --body-code-background-color: rgb(var(--dk-gray)); + + --heading-color: rgb(var(--white)); + --header-series-arrow-foreground-color: rgb(var(--super-dk-gray)); + + --html-background-color: rgb(var(--black)); + --html-color: rgba(var(--white), 0.8); + + --platter-background-color: rgba(var(--black), var(--platter-background-opacity)); + --platter-backdrop-filter: brightness(0.66) blur(10px); + + --tag-foreground-color: rgb(var(--sub-lt-gray)); + --tag-background-color: rgb(var(--dk-gray)); + --tag-spacer-foreground-color: rgb(var(--super-dk-gray)); + --tag-hover-background-color: rgb(var(--super-dk-gray)); + --tag-hover-foreground-color: rgb(var(--mid-gray)); + + --twitter-icon: url(/icons/twitter-dark.svg); + --github-icon: url(/icons/github-dark.svg); + --instagram-icon: url(/icons/instagram-dark.svg); + --feed-icon: url(/icons/rss-dark.svg); + } +} + +@font-face { + font-family: "Museo_Slab"; + src: url("{{ `/fonts/Museo_Slab_500.woff2` | relURL }}") format("woff2"), + url("{{ `/fonts/Museo_Slab_500.woff` | relURL }}") format("woff"); + font-weight: normal; + font-style: normal; +} + +@layer reset { + body, button, h1, h2, h3, h4, h5, h6, input, ol, ul, p, pre, textarea { + padding: 0; margin: 0; + } +} + +a { + color: rgb(var(--mid-blue)); + text-decoration: none; +} +a:hover { + text-decoration: underline; + text-underline-offset: 0.12em; +} +a:visited { color: none; } + +blockquote { + border-inline-start: 4px solid var(--separator-color); + padding-inline-start: 2rem; + margin-inline-start: 2rem; +} + +body { + font-size: var(--body-font-size); + line-height: var(--body-line-height); +} + +code { + background-color: var(--body-code-background-color); + border-radius: 0.25rem; + font-family: var(--font-family-monospace); + display: inline-block; + padding-inline: 0.6rem; +} + +figcaption { + font-size: 75%; + line-height: var(--body-line-height); + margin-block-start: 0.2em; + text-align: center; +} + +figure { + border-radius: 6px; + display: inline-block; + line-height: 1; + margin: 0; + margin-block: 0 var(--body-item-spacing); + margin-inline: 0; + overflow: hidden; + max-width: var(--content-width); + width: 100%; +} + +figure.bordered { + padding: 0.5rem; + border: 2px solid #eee; +} + +figure a, +figure a:hover { + border: 0; +} + +figure img { + border-radius: 6px; + height: auto; + max-width: var(--content-width); + width: 100%; +} + +figure svg { + width: 100%; + height: auto; +} + +figure .youtube { + border-radius: 6px; + line-height: 1; + overflow: hidden; + max-width: var(--content-width); + width: 100%; +} + +footer.site { + align-items: center; + display: flex; + flex-direction: column; + font-size: 1.6rem; + margin-block: var(--body-item-spacing); + text-align: center; +} + +footer.site > ul { + align-items: center; + display: flex; + flex-wrap: wrap; + justify-content: center; + list-style: none; +} + +footer.site > .slogans > li { + margin-inline-start: 0.5em; +} + +footer.site > p { + margin: 0; +} + +footer.site p + p { + margin-top: 0.25rem; +} + +@media (max-width: 740px) { + footer.site .slogans span { + white-space: nowrap; + } +} + +h1 { font-size: 1.6em; } +h2 { font-size: 1.5em; } +h3 { font-size: 1.4em; } +h4 { font-size: 1.3em; } +h5 { font-size: 1.3em; } +h6 { font-size: var(--body-font-size); } +h5, h6 { font-family: var(--font-family-body); } + +h1, h2, h3, h4, h5, h6 { + color: var(--heading-color); + font-family: var(--font-family-heading); + font-weight: 600; + margin-block: 3.5rem 1rem; + letter-spacing: 0.08em; + line-height: var(--body-header-line-height); +} + +h1.site { + color: rgb(var(--mid-blue)); + font-size: 2.5em; +} +@supports (background-clip: text) { + h1.site { + background: + radial-gradient(circle at 20% 70%, rgb(var(--purple)), transparent 40%), + radial-gradient(circle at 30% 30%, rgb(var(--lt-blue)), rgb(var(--mid-blue)) 20%, transparent 80%), + radial-gradient(ellipse at 95% 20%, rgb(var(--dk-blue)), rgb(var(--mid-blue)) 70%, transparent 80%), + radial-gradient(circle at 100% 100%, rgb(var(--purple)), rgb(var(--lilac)) 100%), + radial-gradient(circle at 45% 100%, rgb(var(--lilac)), rgb(var(--purple)) 60%), + radial-gradient(ellipse at 50% 50%, rgb(var(--dk-blue)), transparent 80%); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + } +} + +h1.site > a { color: inherit; } +h1.site > a:hover { text-decoration: none; } + +header.site { + display: flex; + left: 0; + position: fixed; + top: 0; + visibility: hidden; + width: 100%; + z-index: 10000; +} +header.site.visible { visibility: visible; } +header.site.sticky { position: sticky; } +header.site.animated { + animation: site-header-slide-in var(--transition-duration) ease-out; +} +@keyframes site-header-slide-in { + from { + top: -200px; + } + to { + top: 0; + } +} + +header.site > .grid > h1 { + font-family: var(--font-family-site-heading); + font-size: 2em; + margin: 0; + order: 1; + white-space: nowrap; +} + +header.site > .grid { + align-items: baseline; + display: flex; + flex-wrap: wrap; + gap: 0 0.5em; + margin: 0 auto; + max-width: var(--content-width); + padding: 1.5rem 3rem; + width: 100%; +} + +header.site > .grid > nav:first-of-type { + justify-content: start; + order: 2; +} + +header.site > .grid > nav:last-of-type { + justify-content: end; + order: 3; +} + +@media (max-width: 516px) { + header.site > .platter { + border-left: none; + border-radius: 0; + border-right: none; + border-top: none; + } + header.site > .grid { + max-width: none; + } +} + +@media (max-width: 435px) { + header.site > .grid > nav:first-of-type { + order: 5; + } +} + +html { + background-color: var(--html-background-color); + color: var(--html-color); + font-family: var(--font-family-body); + font-size: clamp(var(--font-size-min), 1vw, var(--font-size-max)); +} + +img { + height: auto; + max-width: 100%; +} + +img.circular { + shape-outside: circle(50%); + -webkit-clip-path: circle(50%); + clip-path: circle(50%); +} + +main { + box-sizing: border-box; + max-width: var(--content-width); + margin: var(--body-item-spacing) auto; + padding-inline: var(--body-item-spacing); + width: 100%; +} + +main > header { + margin-bottom: var(--body-item-spacing); +} + +main > :first-child { margin-block-start: 0; } +main > :last-child { margin-block-end: 0; } + +header.site > .grid > nav { + align-items: center; + display: flex; + font-size: max(1.5rem, 80%); + justify-content: start; + letter-spacing: 0.12em; + list-style: none; + text-transform: lowercase; +} + +header.site > .grid > nav > li { + color: var(--site-nav-link-color); + display: block; + margin-inline-end: 0.5em; +} + +header.site > .grid > nav > .active { font-weight: bold; } + +nav.bulleted > li:first-child::before { + color: var(--html-color); + content: ""; + margin-inline-end: 0; +} + +nav.bulleted > li::before { + color: var(--heading-color); + content: "•"; + font-size: 60%; + font-weight: normal; + opacity: 80%; + margin-inline-end: 0.5em; +} + +p { + letter-spacing: 0.025em; + line-height: var(--body-line-height); + margin-block-end: var(--body-item-spacing); +} + +ul ul, +ul ol, +ol ul, +ol ol { + margin-inline-start: var(--body-item-spacing); +} + +header > span.series { + font-size: 1.75rem; + letter-spacing: 1px; + margin-inline-start: 0.5em; +} + +header > span.series::before { + color: var(--header-series-arrow-foreground-color); + content: "↳"; + margin-inline-end: 0.25em; +} + +.post-list { + list-style: none; + margin: 0; + padding: 0; +} +@supports (display: subgrid) { + .post-list { + align-items: baseline; + display: grid; + gap: 1em; + grid-template-columns: + minmax(150px, max-content) minmax(20px, max-content) 3px auto; + grid-template-areas: "month day line title"; + } +} + +.post-list li { + align-items: baseline; + border-radius: 6px; + display: grid; + gap: 1em; + padding: 0.1em; +} + +.post-title { + align-items: baseline; + display: flex; + flex-wrap: wrap; + gap: 0 4rem; +} + +.post-title h1 { + flex-grow: 1; + font-size: 1.8em; + margin-block: 0; + padding-bottom: 0; +} + +.post-title > .post-date { + color: var(--light-dim); + display: inline-block; + font-size: 1.75rem; + inline-size: min-content; + letter-spacing: 1px; + margin-block-start: 0.5rem; + white-space: nowrap; +} + +.p5-sketch { + display: block; + position: relative; + width: 100%; +} + +.social { + display: block; + letter-spacing: 2px; + margin-left: auto; + order: 2; +} + +.social > li > a { + background-image: var(--url); + background-repeat: no-repeat; + background-size: var(--menu-icon-size); + display: block; + height: var(--menu-icon-size); + width: var(--menu-icon-size); +} + +.social > li > a > span { + display: none; +} + +.social > li + li:before { + color: var(--dark); + padding: 0 0.5rem; +} + +footer > .tags { + display: flex; + padding-inline-start: 0; +} + +footer > .tags > li { + background-color: var(--tag-background-color); + color: var(--tag-foreground-color); + border-radius: 4px; + display: inline-block; + font-size: 75%; + letter-spacing: 1px; +} + +footer > .tags > li:hover { + background-color: var(--tag-hover-background-color); +} + +footer > .tags > li > a { + color: inherit; + display: block; + height: 100%; + width: 100%; + padding: 0.6rem 1rem; +} + +footer > .tags > li > a:hover { + color: var(--tag-hover-foreground-color); + text-decoration: none; +} + +footer > .tags > li + li { margin-inline-start: 1rem; } +footer > .tags > li.chevron + li { margin-inline-start: 0 } + +footer > .tags > .chevron { + align-items: center; + border: 0; + border-radius: 0; + color: var(--tag-spacer-foreground-color); + background-color: inherit; + display: flex; + justify-content: center; + margin-inline-start: 0; + padding-inline-start: 1px; + width: 2rem; +} + +footer > .tags > .chevron:hover { + color: var(--tag-spacer-foreground-color); + background-color: inherit; +} + +table { + border: 1px solid var(--separator-color); + border-collapse: collapse; + margin-block-end: var(--body-item-spacing); + margin-inline: auto; + width: 50%; +} + +td, th { + border: 1px solid var(--separator-color); + padding-inline: 1rem; +} + +.youtube iframe { + aspect-ratio: 16 / 9; + margin-bottom: -3px; + width: 100%; +} + +/** SYNTAX HIGHLIGHTING **/ + +.highlight code { + background-color: inherit; + margin-block: 0.5em; +} + +.highlight .line { + display: grid; + grid-template-columns: max-content auto; +} + +.highlight .ln a { + -webkit-user-select: none; + -moz-use-select: none; + -ms-user-select: none; + user-select: none; +} + +.highlight .cl { + white-space: pre-wrap; +} + +/** HELPER CLASSES **/ + +.centered { text-align: center; } +.float-right { float: right; } + +.nobreak { white-space: nowrap; } +.noselect { + cursor: default; + -webkit-user-select: none; + -moz-use-select: none; + -ms-user-select: none; + user-select: none; +} + +.platter { + -webkit-backdrop-filter: var(--platter-backdrop-filter); + backdrop-filter: var(--platter-backdrop-filter); + background-color: var(--platter-background-color); + border: 1px solid var(--header-border-color); + border-radius: 12px; + box-shadow: 3px 4px 4px var(--header-box-shadow-color); +} + +.visible { visibility: visible; } diff --git a/config/_default/author.yaml b/config/_default/author.yaml new file mode 100644 index 0000000..145eed7 --- /dev/null +++ b/config/_default/author.yaml @@ -0,0 +1,2 @@ +name: Eryn Wells +email: eryn@erynwells.me diff --git a/config/_default/config.yaml b/config/_default/config.yaml index 950d2f1..4159747 100644 --- a/config/_default/config.yaml +++ b/config/_default/config.yaml @@ -1,6 +1,4 @@ baseURL: https://erynwells.me/ languageCode: en-US -title: ~eryn -copyright: Copyright © 2020—2024 Eryn Wells +title: Erynwells.me defaultContentLanguage: en -enableEmoji: true diff --git a/config/_default/languages.yaml b/config/_default/languages.yaml index b450ec4..7b9bc90 100644 --- a/config/_default/languages.yaml +++ b/config/_default/languages.yaml @@ -1,12 +1,4 @@ en: - languageName: English weight: 1 es: - languageName: Español weight: 2 -jp: - languageName: 日本語 - weight: 3 -tok: - languageName: toki pona - weight: 4 diff --git a/config/_default/markup.yaml b/config/_default/markup.yaml index 0a8cb53..34bc211 100644 --- a/config/_default/markup.yaml +++ b/config/_default/markup.yaml @@ -1,12 +1,5 @@ -goldmark: - renderer: - unsafe: true - parser: - attribute: - block: true - title: true highlight: anchorLineNos: true - lineNos: false + lineNos: true lineNumbersInTable: false noClasses: false diff --git a/config/_default/menu.yaml b/config/_default/menu.yaml index e9bf573..717cf31 100644 --- a/config/_default/menu.yaml +++ b/config/_default/menu.yaml @@ -11,19 +11,13 @@ main: name: About url: /about/ weight: 30 - - identifier: feed - name: feed - url: /feed.atom - weight: 40 - params: - style: file social: - - identifier: mastodon - name: Mastodon - url: https://mastodon.social/@erynofwales + - identifier: twitter + name: Twitter + url: https://twitter.com/erynofwales weight: 10 params: - shortName: mst + shortName: tw - identifier: github name: Github url: https://github.com/erynofwales @@ -34,19 +28,12 @@ social: name: Instagram url: https://instagram.com/erynofwales weight: 30 - params: + params: shortName: ig - identifier: feed - name: feed + name: Feed url: /feed.atom weight: 40 params: shortName: feed targetBlank: false -about: - - identifier: resume - name: Résumé - url: /resume/ - - identifier: whereAmI - name: Where Am I - url: /where-am-i/ diff --git a/config/_default/module.yaml b/config/_default/module.yaml deleted file mode 100644 index df1ab3b..0000000 --- a/config/_default/module.yaml +++ /dev/null @@ -1,15 +0,0 @@ -hugoVersion: - extended: false - min: "0.116.0" -replacements: >- - github.com/erynofwales/hugo-theme-feeds/v2 -> feeds, - github.com/erynofwales/hugo-theme-termlite/v2 -> termlite, - github.com/erynofwales/hugo-theme-photostream/v2 -> photostream, - github.com/erynofwales/hugo-resource-builders/v2 -> resource-builders, - github.com/erynofwales/hugo-image-utilities/v2 -> image-utils -imports: - - path: github.com/erynofwales/hugo-theme-termlite/v2 - - path: github.com/erynofwales/hugo-theme-feeds/v2 - - path: github.com/erynofwales/hugo-theme-photostream/v2 - - path: github.com/erynofwales/hugo-resource-builders/v2 - - path: github.com/erynofwales/hugo-image-utilities/v2 diff --git a/config/_default/outputs.yaml b/config/_default/outputs.yaml index 5dec102..f788268 100644 --- a/config/_default/outputs.yaml +++ b/config/_default/outputs.yaml @@ -1,4 +1,3 @@ -home: [HTML, Atom] -section: [HTML, Atom] -taxonomy: [HTML] -term: [HTML] +home: [HTML, Atom, RSS] +page: [HTML, JSON] +section: [HTML, Atom, RSS] diff --git a/config/_default/params.yaml b/config/_default/params.yaml index ca8f50f..cbaec88 100644 --- a/config/_default/params.yaml +++ b/config/_default/params.yaml @@ -1,20 +1,4 @@ -author: - name: Eryn Wells - email: eryn@erynwells.me - -shortTitle: Eryn Wells - twitter: erynofwales github: erynofwales instagram: erynofwales description: Home page of Eryn Rachel Wells - -blog: - yearLimit: 3 - -photostream: - yearLimit: 3 - -photos: - gridSize: 200 - thumbnailSize: 600 diff --git a/config/_default/permalinks.yaml b/config/_default/permalinks.yaml index 7d4b0bc..8efe757 100644 --- a/config/_default/permalinks.yaml +++ b/config/_default/permalinks.yaml @@ -1,3 +1,2 @@ blog: blog/:year/:month/:slug/ photos: photos/:year/:month/:slug/ -twitter: twitter/:year/:month/:slug/ diff --git a/config/_default/privacy.yaml b/config/_default/privacy.yaml index ad42382..86268a6 100644 --- a/config/_default/privacy.yaml +++ b/config/_default/privacy.yaml @@ -1,2 +1,2 @@ -x: +twitter: enableDNT: true diff --git a/config/_default/services.yaml b/config/_default/services.yaml index 4738995..4ad50c5 100644 --- a/config/_default/services.yaml +++ b/config/_default/services.yaml @@ -1,2 +1,2 @@ -x: +twitter: disableInlineCSS: true diff --git a/content/_index.es.md b/content/_index.es.md index dec3a59..b09db21 100644 --- a/content/_index.es.md +++ b/content/_index.es.md @@ -1,20 +1,5 @@ --- -layout: single -draft: true -params: - renderHeadingAnchors: false +title: Eryn Rachel Wells --- -¡Hola! Me llamo Eryn Wells. Este es mi sitio web. ¡Bienvenidos! - - -## Personal - -Soy mujer queer, - - -## Profesional - -Desde 2011, he trabajado como ingeniera de software en varios companías alrededor del área -del Bahía de San Francisco. En 2016, me uní a [Apple][]. Hoy, trabajo en -tecnologías que +Este es un poco de texto sobre Eryn: quién es, qué le gusta, y por qué existe este sitio. diff --git a/content/_index.md b/content/_index.md index e4ca8ce..b8b596b 100644 --- a/content/_index.md +++ b/content/_index.md @@ -1,66 +1,5 @@ --- -layout: single -params: - renderHeadingAnchors: false +title: Eryn Rachel Wells --- -Hi, I'm Eryn Wells. This is my website. Welcome! - - -## Latest - -Here are some of my most recent posts. - -{{< home/latest >}} - - -## Personal - -I'm a queer woman, {{< tess >}}' partner, and mom of [two cats][cats]. I -was born in Seattle, {{< abbr Washington >}}WA{{< /abbr >}} and grew up in -Phoenix, {{< abbr Arizona >}}AZ{{< /abbr >}}. I attended [Oberlin College][] -where I got a degree in Computer Science. My pronouns are [she/her][pronouns]. - -You can read more about me on my [about][ab] page, or [get in touch][where-am-i]. - - -## Professional - -I've worked as a software engineer since 2011 for a variety of companies around -the San Francisco Bay Area. I joined [Apple][] in 2016, where I currently work -on password management and authentication technologies. - -My [résumé][r] has all the details. - - -## Hobbies - -When I'm not working, you can reliably find me hacking on this website or [some -other coding project][src]. I'm also a musician: I play piano, Irish tin -whistle, and modular synthesizer. Occasionally I [record things][sc] or offer -them [for sale][sc]. I love outer space and astronomy; I will always get excited -to look at the moon with you, or check out anything through a telescope. I enjoy -[photograhy][p], mostly as a travel hobby. And I've been practicing -[iaidō][mjer], a traditional Japanese sword art, at [Nishi Kaigan Iaidō -Dōjō][nkid] since early 2024. Other things I've been into include: bread baking, -bicycling, calligraphy, ceramics, and knitting. - - -[Apple]: https://apple.com -[ab]: {{< ref "/about" >}} -[b]: {{< ref "/blog" >}} -[bc]: https://erynwells.bandcamp.com/releases -[cats]: {{< ref "/cats" >}} -[eml]: mailto:Eryn%20Wells -[src]: https://source.erynwells.me/eryn -[ig]: https://www.instagram.com/erynofwales -[m]: https://mastodon.social/@erynofwales -[n]: {{< ref "/now" >}} -[Oberlin College]: https://www.oberlin.edu -[p]: {{< ref "/photos" >}} -[pronouns]: http://pronoun.is/she -[r]: {{< ref "/resume" >}} -[sc]: https://soundcloud.com/purlsnbeeps -[where-am-i]: {{< ref "/about/where-am-i" >}} -[mjer]: https://en.wikipedia.org/wiki/Mus%C5%8D_Jikiden_Eishin-ry%C5%AB -[nkid]: https://iaido.org +Software engineer, potter, musician, and overall nerd. This is my website. diff --git a/content/about/_index.es.md b/content/about/index.es.md similarity index 71% rename from content/about/_index.es.md rename to content/about/index.es.md index 5f528ed..0253dde 100644 --- a/content/about/_index.es.md +++ b/content/about/index.es.md @@ -1,24 +1,13 @@ --- title: "Hola! 👋🏻" draft: false -slug: sobre -resources: - - name: me - src: me.jpeg --- -{{< circular_image id=me name=me class="float-right" width=200 - alt="Una foto de me, con sombrero, sentando en frente de un fondo de piedra">}} +Me llamo Eryn. Mis pronombres son [ella/ella][p]. Esta es me página personal. Bienvenide. -Me llamo Eryn. Mis pronombres son [ella/ella][p]. Esta es me página personal. -Bienvenide. +Soy una mujer trans y queer. Vivo en San Francisco con mis [dos gatos][cats]. Nací en Seattle, WA, y crecía en Phoenix, AZ. Asistí [Oberlin College][ob] donde obtuve un títolo en informática. {{< tess >}} es mi novia. -Soy una mujer trans y queer. Vivo en San Francisco con mis [dos gatos][cats]. -Nací en Seattle, WA, y crecía en Phoenix, AZ. Asistí [Oberlin College][ob] donde -obtuve un títolo en informática. {{< tess >}} es mi novia. - -Mi lengua nativa es inglés, y también hablo español pero siempre necesito -practicar más. +Mi lengua nativa es inglés, y también hablo español pero siempre necesito practicar más. ## Pasatiempos @@ -47,15 +36,14 @@ Echa un vistazo a mi [resumen][r] para más detalles. ## Decirme Hola -Puedes [encontrarme en muchos rincones del Internet][where-am-i]. Estoy más -activa en [Twitter][t] y [Instagram][i]. Publico música en [SoundCloud][sc] y +Puedes encontrarme en muchos rincones del Internet. Estoy más activa en +[Twitter][t] y [Instagram][i]. Publico música en [SoundCloud][sc] y [Bandcamp][bc]. Y para los proyectos de software, estoy en [GitHub][gh]. [p]: http://pronoun.is/she [cats]: {{< ref "/cats" >}} [ob]: https://www.oberlin.edu -[r]: {{< ref path="/resume" >}} -[where-am-i]: {{< ref path="about/where-am-i" lang="es" >}} +[r]: {{< ref "/resume" >}} [t]: https://twitter.com/erynofwales [i]: https://www.instagram.com/erynofwales/ [sc]: https://soundcloud.com/purlsnbeeps diff --git a/content/about/_index.md b/content/about/index.md similarity index 80% rename from content/about/_index.md rename to content/about/index.md index 5c1da98..ed28084 100644 --- a/content/about/_index.md +++ b/content/about/index.md @@ -1,16 +1,14 @@ --- title: "Hi! 👋🏻" -layout: single +date: 2022-09-03T12:14:32-07:00 +draft: false resources: - name: me src: me.jpeg - params: - alt: > - Me, wearing a hat and smiling slightly, standing in front of a stone - background. --- -{{% section class=content--small-right-column %}} +{{< circular_image id=me name=me class="float-right" width=200 + alt="A photo of me, wearing a hat, standing in front of a stone background">}} I'm Eryn. My pronouns are [she/her][p]. I'm a queer trans woman. I live in San Francisco, CA, on the unceded ancestral lands of the Ramaytush Ohlone people, @@ -20,10 +18,6 @@ I attended [Oberlin College][ob] where I got a degree in Computer Science. I speak English natively, and Spanish too, though I always need more practice. -{{< circular_image id=me name=me class="content--right-column" width=200 >}} - -{{% /section %}} - ## Hobbies I've been a musician for most of my life. I started on the piano at age seven, @@ -51,8 +45,8 @@ Check out my [résumé][r] for more details. ## Say Hello -You can find me in [lots of other corners of the Internet][where-am-i]. I'm most -active on [Twitter][t] and [Instagram][i]. I post music on [SoundCloud][sc] and +You can find me in lots of other corners of the Internet. I'm most active on +[Twitter][t] and [Instagram][i]. I post music on [SoundCloud][sc] and [Bandcamp][bc]. I'm on [GitHub][gh] for coding projects. You can also send me an [email][eml]. @@ -66,4 +60,3 @@ active on [Twitter][t] and [Instagram][i]. I post music on [SoundCloud][sc] and [bc]: https://erynwells.bandcamp.com/releases [gh]: https://github.com/erynofwales [eml]: mailto:Eryn%20Wells -[where-am-i]: {{< ref "/about/where-am-i" >}} diff --git a/content/about/style.css b/content/about/style.css index 45d6e31..b39c308 100644 --- a/content/about/style.css +++ b/content/about/style.css @@ -1,17 +1,4 @@ -@layer page { - main > section > p:not(:last-child) { - margin-bottom: var(--body-item-spacing); - } - p:has(img#me) { - display: inline; - grid-column: unset; - margin-bottom: 0; - } - - img#me { - margin: 0; - shape-outside: circle(55%); +img#me { width: min(200px, 25%); - } } diff --git a/content/about/where-am-i.es.md b/content/about/where-am-i.es.md deleted file mode 100644 index e2b7a2e..0000000 --- a/content/about/where-am-i.es.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "Dónde encontrarme" -date: 2022-11-11T08:35:26-08:00 -slug: donde-encontrarme ---- - -Aquí está una lista de dónde se puede encontrarme en línea. - -## Redes Sociales - -- Cohost: [@eryn](https://cohost.org/eryn) -- Instagram: [@erynofwales](https://instagram.com/erynofwales) -- Mastodon: [@erynofwales](https://mastodon.social/@erynofwales) -- Twitter: [@erynofwales](https://twitter.com/erynofwales) - -## Contenido - -- Bandcamp: [erynwells](https://erynwells.bandcamp.com/releases) -- Soundcloud: [purlsnbeeps](https://soundcloud.com/purlsnbeeps) -- YouTube: [Eryn Wells](https://www.youtube.com/channel/UCWb2pTDlC27R1PucyUPrypA) -- GitHub: [erynofwales](https://github.com/erynofwales) - -## La Manera Antigua - -- Email: [eryn@erynwells.me](mailto:Eryn%20Wells) diff --git a/content/about/where-am-i.md b/content/about/where-am-i.md deleted file mode 100644 index a033245..0000000 --- a/content/about/where-am-i.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: "Where to Find Me" -date: 2022-11-11T08:35:26-08:00 ---- - -Here's a list of places you can find me online. You can often find me on -services not listed here with the `erynofwales` or `erynrwells` handles. - -## Social Media - -I'm really only on Instagram and Mastodon these days. My Twitter account is -still live, as an archive, but I don't post on it or look at it. Ditto for -Facebook. - -- Facebook: [erynofwales](https://www.facebook.com/erynofwales) -- Instagram: [@erynofwales](https://instagram.com/erynofwales) -- Mastodon: [@erynofwales](https://mastodon.social/@erynofwales) -- Twitter: [@erynofwales](https://twitter.com/erynofwales) - -## Content - -- Bandcamp: [erynwells](https://erynwells.bandcamp.com/releases) -- GitHub: [erynofwales](https://github.com/erynofwales) -- Soundcloud: [purlsnbeeps](https://soundcloud.com/purlsnbeeps) -- StoryGraph: [erynrwells](https://app.thestorygraph.com/profile/erynrwells) -- YouTube: [Eryn Wells](https://www.youtube.com/channel/UCWb2pTDlC27R1PucyUPrypA) - -## The Old Fashioned Way - -- Email: [eryn@erynwells.me](mailto:Eryn%20Wells) diff --git a/content/blog/2020/10/boot-raspberry-pi-over-tftp.md b/content/blog/2020/10/boot-raspberry-pi-over-tftp.md index 3143677..8cfef8b 100644 --- a/content/blog/2020/10/boot-raspberry-pi-over-tftp.md +++ b/content/blog/2020/10/boot-raspberry-pi-over-tftp.md @@ -1,7 +1,7 @@ --- title: "Booting a Raspberry Pi Over TFTP" date: 2020-10-13T08:31:52-07:00 -description: A writeup of how I set up a Raspberry Pi to boot over TFTP to facilitate an operating system development project. +draft: false series: ["Raspberry Pi OS Development"] categories: ["Tech"] tags: ["Raspberry Pi", "Networking"] diff --git a/content/blog/2020/_index.md b/content/blog/2020/_index.md deleted file mode 100644 index 0539207..0000000 --- a/content/blog/2020/_index.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 2020 -date: 2020-01-01 ---- diff --git a/content/blog/2021/09/oskitone-scout/index.md b/content/blog/2021/09/oskitone-scout/index.md index 3b3012c..8d74247 100644 --- a/content/blog/2021/09/oskitone-scout/index.md +++ b/content/blog/2021/09/oskitone-scout/index.md @@ -7,7 +7,7 @@ categories: ["Music"] tags: ["Synthesizers", "Electronics", "DIY", "Compositions"] --- -{{< youtube id="gCSwWsxzy_c" title="A timelapse video of me building an Oskitone Scout, set to music produced using the Scout itself" >}} +{{< figures/youtube id="gCSwWsxzy_c" title="A timelapse video of me building an Oskitone Scout, set to music produced using the Scout itself">}} [Oskitone][oskitone] recently released a new synthesizer: the [Scout][scout]. It's a small monophonic keyboard synth built around an Arduino. It was a quick diff --git a/content/blog/2021/10/pnw-reunion-trip/index.md b/content/blog/2021/10/pnw-reunion-trip/index.md index c574098..07ec46e 100644 --- a/content/blog/2021/10/pnw-reunion-trip/index.md +++ b/content/blog/2021/10/pnw-reunion-trip/index.md @@ -41,4 +41,4 @@ I'm so grateful for every one of these people. We've been friends for years and even though our lives have taken us in so many different directions, we've found each other again and that is so wonderful. -{{< twitter user=erynofwales id=1447951049076056071 >}} +{{< twitter erynofwales 1447951049076056071 >}} diff --git a/content/blog/2021/_index.md b/content/blog/2021/_index.md deleted file mode 100644 index f27ca81..0000000 --- a/content/blog/2021/_index.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 2021 -date: 2021-01-01 ---- diff --git a/content/blog/2022/01/cmss-3modules/index.md b/content/blog/2022/01/cmss-3modules/index.md index f78c23a..96d8bac 100644 --- a/content/blog/2022/01/cmss-3modules/index.md +++ b/content/blog/2022/01/cmss-3modules/index.md @@ -7,7 +7,7 @@ categories: ["Music"] tags: ["Eurorack", "Synthesizers", "Recordings", "Performances", "Compositions"] --- -{{< youtube id="sqr7g4P85aM" title="A top-down video of me operating a small Eurorack system made of only three modules. Lights flash, an incorporeal hand turns knobs to sculpt the sound." >}} +{{< figures/youtube id="sqr7g4P85aM" title="A top-down video of me operating a small Eurorack system made of only three modules. Lights flash, an incorporeal hand turns knobs to sculpt the sound." >}} This is my submission to the [Three Module Challenge][3mc] show put on by Colorado Modular Synth Society in late January 2022. This is my first time diff --git a/content/blog/2022/04/nethack/index.es.md b/content/blog/2022/04/nethack/index.es.md index d2fbcbd..308e0a9 100644 --- a/content/blog/2022/04/nethack/index.es.md +++ b/content/blog/2022/04/nethack/index.es.md @@ -2,15 +2,14 @@ title: Ay, Ella Se Ha Vuelto Adicta a Nethack date: 2022-04-24T17:36:33-07:00 description: In which I get hooked on that one roguelike (God help me) -categories: ["Games"] +draft: false tags: ["Nethack", "Video Games"] --- Hace unas semanas que conecté a mi VPS para averiguar algo. Hay [un parte][list-tmux-sessions] de [mis dotfiles][zprofile] que ejecuta durante la iniciación de las sesiones de inicio de ZSH que imprime las sesiones existidos -de `tmux` asociados con mi cuenta. Me dio cuenta que había una sesión y me la -adjunté. +de `tmux` asociados con mi cuenta. Realizé que había una sesión y me la adjunté. En esa sesión encontré un juego de [Nethack][nethack] que empezaba en enero y nunca lo completé. Lo completé, me mató un duende, y, pues, el daño ya se me @@ -18,7 +17,7 @@ estuve hecho. Es posible que me entusiasme un poco. -{{< twitter user=erynofwales id=1510763278691016705 >}} +{{< twitter erynofwales 1510763278691016705 >}} He mejorado mucho en las últimas semanas. Mis puntajes han crecidos desde 1,000 hasta el mejor juego hasta ahora en que [obtuve 9401 puntos][over9000]. Quién @@ -35,4 +34,4 @@ web. Echa un vistazo a mi [logfile](/nethack) de Nethack para esa. [nethack]: https://www.nethack.org [nethackwiki]: https://nethackwiki.com/wiki/Main_Page [priceid]: https://nethackwiki.com/wiki/Price_identification -[over9000]: https://www.youtube.com/watch?v=ITWMoS2L1oo +[over9000]: https://www.youtube.com/watch?v=ITWMoS2L1oo \ No newline at end of file diff --git a/content/blog/2022/04/nethack/index.md b/content/blog/2022/04/nethack/index.md index 9eb2538..30e7ed1 100644 --- a/content/blog/2022/04/nethack/index.md +++ b/content/blog/2022/04/nethack/index.md @@ -2,6 +2,7 @@ title: Oh Dear, She Got Hooked on Nethack Again date: 2022-04-24T17:36:33-07:00 description: In which I get hooked on that one roguelike (God help me) +draft: false categories: ["Games"] tags: ["Nethack", "Roguelikes"] --- @@ -23,7 +24,7 @@ packed with [NetHackWiki][nethackwiki] tabs too, including a pinned one for the I may have gotten a little carried away a time or two. -{{< twitter user=erynofwales id=1510763278691016705 >}} +{{< twitter erynofwales 1510763278691016705 >}} I've gotten much better in that time. My scores have increased from the 1000-2000 range to my best game so far in which [I scored 9401 diff --git a/content/blog/2022/05/roguelikes-i-like/index.md b/content/blog/2022/05/roguelikes-i-like/index.md index c8bc0d4..305dbf5 100644 --- a/content/blog/2022/05/roguelikes-i-like/index.md +++ b/content/blog/2022/05/roguelikes-i-like/index.md @@ -1,7 +1,6 @@ --- title: "Roguelikes I Like" date: 2022-05-09T08:37:23-07:00 -description: Some roguelikes I’ve enjoyed recently. draft: false resources: - name: nethack diff --git a/content/blog/2022/08/audio-scope-with-p5js/diagram.svg b/content/blog/2022/08/audio-scope-with-p5js/diagram.svg deleted file mode 100644 index a4483cb..0000000 --- a/content/blog/2022/08/audio-scope-with-p5js/diagram.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - -<audio> - - - - - - - -Analyzer - - - - - - - -destination - - - - - - diff --git a/content/blog/2022/08/audio-scope-with-p5js/index.md b/content/blog/2022/08/audio-scope-with-p5js/index.md index 8db3abc..142398b 100644 --- a/content/blog/2022/08/audio-scope-with-p5js/index.md +++ b/content/blog/2022/08/audio-scope-with-p5js/index.md @@ -1,7 +1,7 @@ --- title: "Making an Audio Scope with P5.js" date: 2022-08-18T20:48:37-07:00 -description: A writeup of a small JavaScript waveform visualizer I made with P5.js. +draft: false categories: ["Tech"] tags: ["P5.js", "Programming", "Web", "Art"] resources: @@ -88,7 +88,22 @@ node to the input of the analyzer node, and the output of the analyzer node to the audio context's `destination` node that routes to the computer's speakers. Our audio processing graph looks like this: -![](diagram.svg) +{{< figures/railroad id="audioContextDiagram" >}} + {{< scripts/railroad >}} + return rr.Diagram( + rr.Sequence( + rr.Terminal("