Merge remote-tracking branch 'origin/master'

This commit is contained in:
Daniel Flanagan 2024-06-06 17:05:27 -05:00
commit 4b67ef3b9d
22 changed files with 180 additions and 139 deletions

View file

@ -19,7 +19,7 @@ markup:
# post: /blog/:title
params:
Description: "Hi! I'm Daniel. I live in Kansas City where I help run a small Christian church, raise two kids with my awesome wife, and write software for Divvy."
Description: "Hi! I'm Daniel. I live in Kansas City where I help run a small Christian church, raise three boys with my awesome wife, and write software."
outputs:
home: [html]
@ -35,10 +35,10 @@ menu:
name: blog
url: /blog/
weight: 20
- identifier: tips
name: tips
url: /tips/
weight: 30
# - identifier: tips
# name: tips
# url: /tips/
# weight: 30
- identifier: contact
name: contact
url: /contact/

View file

@ -7,19 +7,22 @@
<!-- updates here must be mirrored in site config for meta description-->
I live in Kansas City where I help run <a target="_blank"
href="https://kcrising.church">a small Christian church</a>, raise two kids
href="https://kcrising.church">a small Christian church</a>, raise three boys
with my <a target="_blank"
href="https://www.instagram.com/valerielauren93">awesome wife</a>, and write
software for <a target="_blank" href="https://getdivvy.com">Divvy</a>.
software for <a target="_blank" href="https://getdivvy.com">Divvy (bought by
Bill.com)</a>.
I run a ton of self-hosted software here at home on some machines that sit on
I run a lot of self-hosted software here at home on some machines that sit on
[an unnecessarily large server rack in my basement][rack]. I love building
[keyboards][kb], too. [I heavily customize my workflow][wf] and you can
sift through my [dotfiles][df] if you like.
see how I set everything up with [Nix][nix] if you like (or even my old
[dotfiles](df)).
Occasionally, I post technical articles here.
Occasionally, I post technical articles (of varying length and complexity) here.
[rack]: //files.lyte.dev/images/server-rack.jpg
[rack]: //files.lyte.dev/images/server-rack-angle-2023-07.jpg
[kb]: //files.lyte.dev/keyboards
[wf]: //files.lyte.dev/images/desktop-screenshot.png
[wf]: //files.lyte.dev/images/desktop-screenshot-busy-2023-07.png
[nix]: //git.lyte.dev/lytedev/nix
[df]: //git.lyte.dev/lytedev/dotfiles

View file

@ -35,7 +35,7 @@ can either use [`Ecto.Changeset.change/2`][Ecto.Changeset.change/2] to handle
the results of an admin user submitting those forms or implement some sort of
protocol that lets you specify an admin-specific changeset.
## Getting That Sweet, Sweet Metadata
# Getting That Sweet, Sweet Metadata
My first issue was figuring out how to get the metadata that I knew Ecto already
had about my schemas. Y'know, which fields are which types, so that I could use
@ -301,7 +301,7 @@ single schema you have, too! Ahh, simplicity.
Here's all the code jumbled together (and perhaps slightly different):
## All Together Now!
# All Together Now!
```elixir
# router.ex

View file

@ -22,7 +22,7 @@ Check it out in context on
<a href="https://ellie-app.com/53ypTnnFykXa1" target="_blank">Ellie</a>,
the Elm playground!
## How Did I Get Here?
# How Did I Get Here?
To preface this, I'm going to be writing a *lot* of forms with a *lot* of
fields, all of which will pretty much work exactly the same, so creating a layer
@ -42,7 +42,7 @@ of copying code from it, I'm just going to roll my own, which is generally
a really good way to learn something anyways. So, while frustrated, I was also
eager to tackle the problem.
## Code Already!
# Code Already!
Since the Elm compiler is so awesome, I've taken to what I'm calling
"compiler-driven development", which is where I write out what I expect to work
@ -248,7 +248,7 @@ do (computers, amirite?) before I made it to this point.
Now, I'm confident Elm is a tool that can do everything I need it to do. I look
forward to using it more in the future!
## Full Source
# Full Source
Check it out in context on
<a href="https://ellie-app.com/53ypTnnFykXa1" target="_blank">Ellie</a>,

View file

@ -1,12 +1,15 @@
---
title: "Fetching Go Modules via `goproxy` Inside VPN"
date: "2023-06-22"
date: "2024-02-29"
toc: false
---
I think I finally setup the holy grail of universally being able to
fetch-by-proxy go modules through a firewall using
https://github.com/goproxy/goproxy
<!--more-->
On your internal host (such as your work machine), run the following:
```shell_session

View file

@ -1,11 +1,14 @@
---
title: "iex and dbg/1 without pry prompts"
date: "2023-06-22"
toc: false
---
I love `iex -S mix ...` but I usually don't like when `dbg` asks me to `pry`.
Just show me my data! Well, today I learned about `iex --no-pry`:
<!--more-->
```console
$ iex --help
Usage: iex [options] [.exs file] [data]
@ -15,4 +18,4 @@ Usage: iex [options] [.exs file] [data]
Now I can `iex --no-pry -S mix ...` and just see output instead of dealing with
the prompts for `pry`ing! Not sure if anybody else felt this pain, but there
ya go.
ya go.

View file

@ -5,6 +5,14 @@ draft: true
toc: false
---
For the longest time, my backup setup has been [a script I run manually that
was quite dumb][backupify] that had no features other than encryption. After
getting my feet wet with `btrfs` somewhat recently and seeing the magic of
deduplication, compression, and snapshots, I was all-in on these features and
also wanted them for my backups.
<!--more-->
# TL;DR
- Install `restic` on both machines (may only be needed on the backupper?)
@ -14,18 +22,6 @@ toc: false
password in a secret place accessible only to the backupper user
- `for d in $DIRS; do RESTIC_PASSWORD_COMMAND="load secret restic-key" restic -r sftp:restic@backuppee:/backups "$d"; done`
<!--more-->
# Intro
For the longest time, my backup setup has been [a script I run manually that
was quite dumb][backupify] that had no features other than encryption. After
getting my feet wet with `btrfs` somewhat recently and seeing the magic of
deduplication, compression, and snapshots, I was all-in on these features and
also wanted them for my backups.
I also had a friend that had been using `btrfs` snapshots for sometime and I was super impressed with the simplicity of his setup. It made me want to improve mine!
# Planning
The most important thing to think about when it comes to backups is to think

View file

@ -23,13 +23,13 @@ https://git.faceless.lyte.dev/lytedev/weechat-matrix-encryption-guide.git
/tmp/wmeg && $EDITOR /tmp/wmeg/easy-script.bash && /tmp/wmeg/easy-script.bash`
+ [Configure](#configuration) as needed
## Python Versions
# Python Versions
We need to establish which version of Python your WeeChat is using. You can find
this out in WeeChat with `/python version`. In my case, my `python` binary is
3.7.2 (`python -V`) while my WeeChat Python version is 2.7.15.
## Dependencies
# Dependencies
There are a number of dependencies we can go ahead and start grabbing. The main
repository lists a number of them in the `README`, so we will grab those. We
@ -44,7 +44,7 @@ Notice that we left out the [`matrix-nio`][matrix-nio] dependency. It's not in
PyPi, so we can't just `pip2 install matrix-nio` (yet!) and PyPi's `nio` package
is something probably unrelated, so we'll need to install it manually.
## Installing `matrix-nio`
# Installing `matrix-nio`
Let's go ahead and clone down the repository and get ready to do some stuff:
@ -98,7 +98,7 @@ package:
sudo python2 ./setup.py install
```
## Weechat Plugin Installation
# Weechat Plugin Installation
Once we've done that, we should have all the dependencies for `weechat-matrix`,
so let's go ahead and clone that and install it!
@ -111,7 +111,7 @@ make install
Done!
## Configuration
# Configuration
The rest is up to you! You'll need to [configure your Matrix servers within
WeeChat][weechat-matrix-config] and then verify keys. Verifying keys isn't

View file

@ -29,7 +29,7 @@ function checkMinecraftServerStatus() {
loading.style.display = "inherit";
servers.style.display = "none";
try {
fetch("https://api.lyte.dev/minecraft-server-status").then(res => {
fetch("https://deno-deploy-private.deno.dev/minecraft-server-status").then(res => {
res.json().then(statuses => {
console.log(statuses)
loading.style.display = "none";

View file

@ -1,5 +0,0 @@
---
title: Blog
---
## Latest Tips ([RSS](/tips/index.xml))

View file

@ -11,6 +11,12 @@ description: "About my tools, workflow, and other things I use as a software dev
This page lists the tools (both physical and otherwise) that I use to do my job
as a software developer along with some thoughts on them.
While this page is likely to be out of date when you're reading it, since I am
usually trying a few small changes here and there at any given point to try and
improve things, I try to update it regularly. You can follow those updates by
looking at [the history of the source code for this page
specifically][uses-history].
For other pages like this from other folks, check out this repository:
https://github.com/wesbos/awesome-uses
@ -22,7 +28,8 @@ for simplicity, but everything listed here should be searchable. If not, let
me know! I'll try to link to anything free, though, such as software.
I'll break stuff up by topic as things come up so you can skip things that are
not interesting to you.
not interesting to you. There is also a Table of Contents at the top to help
you navigate.
I also think that in general sharing this much information about yourself isn't
the _best_ idea. However, since I'm confident the bots can't know much more
@ -32,14 +39,15 @@ new stuff! Better yet, I hope you recommend me better stuff! I'm always wanting
to try new tools and discover something new that's good at something.
Regarding the configuration of my machines and the software referenced below,
[please refer to my dotfiles repo](https://git.lyte.dev/lytedev/dotfiles)!
[please refer to my Nix repo](https://git.lyte.dev/lytedev/nix)! It may also
be useful to look through my old [dotfiles
repo](https://git.lyte.dev/lytedev/dotfiles).
# Good morning!
I wake up when my kids do out of a Purple mattress.
I slip on my PineTime wrist watch, grab my Android smartphone and backpack, put
on my prescription glasses, and usually make some tea.
I wake up when my kids do out of a Purple mattress. I slip on my PineTime wrist
watch, grab my flashlight, Android smartphone and backpack, put on my prescription glasses,
and usually make some tea.
## Mattress: Purple King Size
@ -58,15 +66,31 @@ keeps improving! I get about two weeks of battery with light use and bluetooth
off. I get about 5 days if I've got notifications on full blast, but they
recently improved the firmware and claim this may now be more than double!
## Smart Phone: ASUS ROG Phone 5S
## Flashlight: Emisar DW4
I bought the phone that I can get root access to with the biggest battery,
nicest display, and a headphone jack. That's pretty much all I want in a phone.
The speakers are a great bonus. The two USB-C ports is actually a super nice
feature since I can connect peripherals while charging without a dock or crazy
dongle. I've also used the video mirroring on the side port to good effect a few
times in a pinch. I love this device so much I've bought it twice. I'm not sure
I've done that for anything else...
I have a phone with a flashlight. And even my watch can be enough of a
flashlight to navigate in pitch black, but I've taken to carrying an actual
flashlight. Specifically, an Emisar DW4. It has a magnetic tailcap so it can
attach near or directly to many work surfaces. It can get hilariously bright or
dim enough to be suitable for use around sleeping family members in the dark.
And it has fun RGB LEDs that can flash, show you the battery level, and just
look cool. It's not a game-changer, but at times it is incredibly convenient to
have on hand.
## Smart Phone: ASUS Zenfone 10
I've enjoyed ASUS's phones and have previously used the ROG Phone 5S. I bought
this since it maintained most of the important features of the ROG Phone while
being cheaper and my old ROG Phone started having bluetooth and phone call
issues. To be fair, I bought the international Chinese version off ebay to try
and save a buck.
The Zenfone 10 does everything I need. Lots of battery life, nice display for
reading on, good speakers, blah blah blah. Phone's get less interesting all the
time and most of them are good enough these days.
I hope a real Linux phone comes around!
### Android-Specific Software & Applications
@ -75,12 +99,14 @@ with my laptops/desktops) now in no particular order. I have no idea if any of
these have iOS equivalents, but here ya go.
- [Firefox](https://github.com/mozilla-mobile/fenix) as my web browser
- Firefox supports extensions even on Android! I use the following:
- Firefox supports (some) extensions even on Android! I use the following:
- [Dark Reader](https://addons.mozilla.org/en-US/firefox/addon/darkreader/) for keeping things easy on my eyes
- [uBlock Origin](https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/) for blocking ads
- [F-Droid](https://f-droid.org) as an awesome resource for applications
- [Termux](https://github.com/termux/termux-app) for doing Linux-y and
terminal-y things on my phone
- There's also [Nix-on-Droid](https://github.com/nix-community/nix-on-droid)
which I've started using more and more
- [OpenKeychain](https://github.com/open-keychain/open-keychain) for mobile GPG
key management
- [Password Store](https://github.com/android-password-store/Android-Password-Store)
@ -97,10 +123,8 @@ these have iOS equivalents, but here ya go.
- [Obsidian](https://play.google.com/store/apps/details?id=md.obsidian) for
reading and writing my notes (sync'd via `git`)
- [Fedilab](https://codeberg.org/tom79/Fedilab) as my mobile fediverse client
- [Weechat-Android](https://github.com/ubergeek42/weechat-android) as my mobile
IRC relay interface
- [Tailscale](https://github.com/tailscale/tailscale-android) for accessing
my VPN
- [Goguma](https://git.sr.ht/~emersion/goguma) as my mobile IRC client (connected to my IRC bouncer, (Soju)[https://git.sr.ht/~emersion/soju])
- [Tailscale](https://github.com/tailscale/tailscale-android) for my VPN
- Google Wallet for NFC payments (tap-to-pay or contactless) because getting
cards out of a wallet is _so_ pre-COVID
- Google Messages for SMS, MMS, and RCS
@ -146,6 +170,9 @@ problems immensely and makes port forwarding stuff a breeze. I'm roughly
familiar with its workings, which makes troubleshooting network problems that
much easier for me.
This is the last bastion for Arch Linux in my network and I'm excited to move.
Not because I hate Arch, but I'm _really_ loving NixOS.
## WiFi Access Point: Unifi AP-Pro
Fantastic access point that plays nicely with my very DIY home router. Not
@ -164,47 +191,45 @@ _Share the load_.
## Server(s)
I have a lot of servers, but the main server is just an ASUS Chromebox 3 that I
flashed Arch Linux to. It pretty much just runs a big ol' Docker Compose setup
with a sprinkling of other non-Docker'd services. It can do the hardware
transcoding for Jellyfin, my home media server, and just generally does not
break a sweat.
I recently was given a Dell R720xd with 20 hyperthreaded CPU cores (40 threads),
256GB RAM, and 44TB of raw disk space, which I am _very_ excited about, so I'll
probably be moving most stuff to that bad boy, though I expect the power bill to
go up _just a tad_.
I was given a Dell R720xd with dual Xeon E5-2580 CPUs (10c/20t),
256GB RAM, and 12x4TB (48TB) of raw disk space. It runs my own, my servers, and
hosts onsite backups for all my stuff and serves as an offsite encrypted backup
for some friends.
I have a few other cheap machines with larger disks at friends and family's
houses for off-site, encrypted backups of important data. I should
_really_ take the time to validate and automate my backup setup, because right
now, I do a completely garbage job of it.
houses for off-site, encrypted backups of important data. They all run NixOS and
use [its built-in restic backup setup][backups-nix].
Any paid client workloads are served via redundant mechanisms via cloud
services, generally Digital Ocean, and backed up with whatever the relevant
cloud offering is.
I run the following applications for my home:
I run the following main applications:
- [Traefik](https://traefik.io/traefik/) to reverse proxy all the things
- Though I use Caddy for most things, Traefik does work nicely with my
convoluted Docker Compose setup
- [Caddy](https://traefik.io/traefik/) to reverse proxy, TLS-terminate all
the things, and serve static, public files
- A homemade chat bot for various things
- Various game servers (Minecraft, Factorio, Valheim, etc.)
- [A small service that multiplexes audio and video feeds](https://git.lyte.dev/lytedev/tcplexer) mainly for combining a couple audio feeds from DIY IP baby monitors into a single stream for listening
- [Gitea](https://about.gitea.com/) for https://git.lyte.dev 💜💛💙
- [NGINX](https://www.nginx.com/) to serve static files for https://files.lyte.dev
- [Jellyfin](https://jellyfin.org/) for streaming my video media to approved users (family, friends, etc.)
- [Plausible](https://plausible.io/) for web analytics
- [PostgreSQL](https://www.postgresql.org/) as the great database for anything that needs one
- [MariaDB](https://mariadb.org/) for anything too lame to use Postgres
- [Jellyfin](https://jellyfin.org/) for streaming my video media to approved
users (family, friends, etc.)
- [PostgreSQL](https://www.postgresql.org/) as the great database for anything
that needs one
- [Vaultwarden](https://github.com/dani-garcia/vaultwarden) for sharing and
managing passwords
- [Atuin](https://atuin.sh) for sync'ing shell histories across my machines
- Samba file shares
Other details can be found in [the Nix config for the `beefcake` host][beefnix].
I run a few services from the cloud as well:
- [A small DDNS application](https://github.com/lytedev/deno-netlify-ddns) that machines report to so I have relatively up-to-date public IP information on most of my devices (this can't run from home for
fairly obvious reasons 😉)
- [A small DDNS application](https://github.com/lytedev/deno-netlify-ddns) that
machines report to so I have relatively up-to-date public IP information on
most of my devices (this can't run from home for fairly obvious reasons 😉)
- Each machine runs [the accompanying client](https://github.com/lytedev/deno-netlify-ddns-client) with unique credentials
- Various monitoring scripts for specific things (also can't run from home - who would monitor the monitors?)
- Various monitoring scripts for specific things (also can't run from home - who
would monitor the monitors?)
# Starting Work
@ -234,7 +259,7 @@ around with Pipewire.
Like a mattress, very subjective. Get your chairs secondhand for way cheap and
you can get some heckin' nice chairs. I spend about 8 hours a day in my chair,
so having a good chair is well worth it, even if the price tag is 1,500USD. 😬
so having a good chair is well worth it, even if the price tag is $1,500 USD. 😬
## Desk: Custom
@ -624,3 +649,7 @@ Ah, we have a couple tablets for Khan Academy Kids, white noise (and other
sleep-inducing ambience), and podcasts (like Base Camp Adventures!) and a
Google Home Mini or two, mostly for playing loud and obnoxious music or setting
timers.
[uses-history]: https://git.lyte.dev/lytedev/site.lyte.dev/commits/branch/master/content/uses.md
[backups-nix]: https://git.lyte.dev/lytedev/nix/src/commit/fafd242e461620aaa48a669b3623614cc6829700/nixos/beefcake.nix#L528-L573
[beefnix]: https://git.lyte.dev/lytedev/nix/src/branch/main/nixos/beefcake.nix

View file

@ -12,7 +12,7 @@
<link rel="shortcut icon" href="/icon.png" />
<link defer rel="stylesheet" href="/styles.css" />
<script defer type="module" src="/global.mjs"></script>
<script async defer data-domain="lyte.dev" src="https://a.lyte.dev/js/plausible.js"></script>
<script async defer data-domain="lyte.dev" src="https://a.lyte.dev/js/script.js"></script>
</head>
<body class="system-theme nojs">
<noscript>

View file

@ -10,7 +10,7 @@
</p>
{{ end }}
{{ if not (isset .Params "toc") }}
<details style="margin-bottom: 2.5em;">
<details class="left-border" style="margin-bottom: 2.5em;">
<summary>
<h3>Table of Contents</h3>
</summary>

View file

@ -1,8 +1,10 @@
<h3>
<a style="flex-shrink: 1; margin-right: auto;" href="{{ .Permalink }}">
{{ .Title }}
</a>
<br />
<small>Posted on {{ dateFormat "Jan 2 2006" (cond .Date.IsZero .Lastmod .Date) }}</small>
</h3>
{{ .Summary }}
<div class="left-border">
<h3>
<a style="flex-shrink: 1; margin-right: auto;" href="{{ .Permalink }}">
{{ .Title }}
</a>
<br />
<small>Posted on {{ dateFormat "Jan 2 2006" (cond .Date.IsZero .Lastmod .Date) }}</small>
</h3>
{{ .Summary }}
</div>

View file

@ -16,18 +16,4 @@
{{ end }}
</details>
<details open>
<summary>
<h2 id="latest-tips">
Latest <a href="/tips">Tips</a> (<a target="_blank" href="/tips/index.xml">RSS</a>)
</h2>
</summary>
{{ range (where .Site.RegularPages "Section" "tips") }}
{{ .Render "li" }}
{{ else }}
<p>Looks like there's nothing here!... yet!</p>
{{ end }}
</details>
{{ end }}

View file

@ -1,6 +1,6 @@
<svg class="hide-in-align-center" width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25H12" />
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12H12m-8.25 5.25h16.5" />
</svg>
<svg class="hide-in-align-left" width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M7.75 12 h8.5 m-12.25 5.25 h16.5" />
</svg>

Before

Width:  |  Height:  |  Size: 556 B

After

Width:  |  Height:  |  Size: 559 B

View file

@ -5,5 +5,5 @@
<path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z" />
</svg>
<svg class="only-in-system-theme" height="24" width="24" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99" />
<path stroke-linecap="round" stroke-linejoin="round" d="M9.53 16.122a3 3 0 0 0-5.78 1.128 2.25 2.25 0 0 1-2.4 2.245 4.5 4.5 0 0 0 8.4-2.245c0-.399-.078-.78-.22-1.128Zm0 0a15.998 15.998 0 0 0 3.388-1.62m-5.043-.025a15.994 15.994 0 0 1 1.622-3.395m3.42 3.42a15.995 15.995 0 0 0 4.764-4.648l3.876-5.814a1.151 1.151 0 0 0-1.597-1.597L14.146 6.32a15.996 15.996 0 0 0-4.649 4.763m3.42 3.42a6.776 6.776 0 0 0-3.42-3.42" />
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -37,9 +37,14 @@ button.copy-code-button
img, embed, frame, iframe { max-width: 100vw }
details
position relative
details > summary
cursor pointer
list-style none
text-decoration underline
color var(--link-fg)
details > summary::-webkit-details-marker
display none
@ -47,17 +52,20 @@ details > summary::-webkit-details-marker
details > summary::after
position absolute
top 0
right 0
align-self center
content "+"
right -1em
background-image url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='currentColor' style='width: 1em; height: 1em;'><path stroke-linecap='round' stroke-linejoin='round' d='M12 9v6m3-3H9m12 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z' /></svg>")
details[open] > summary::after
content "-"
details
.left-border
position relative
padding-left 0.5em
border-left solid var(--syntax-bpx) var(--syntax-ledg)
transition 0.2s border-color
&:hover
border-color var(--syntax-ledgh)
html,body
min-height 100vh
@ -76,15 +84,21 @@ html,body
padding 0.5em
line-height 1.6em
main:first-child, footer:first-child { margin-top: 0 }
main:first-child, footer:first-child
margin-top 0
&> main, > footer
> main, > footer
.highlight
position relative
background-color var(--syntax-bg)
max-width 100vw
border-left solid var(--syntax-bpx) var(--syntax-ledg)
display flex
pre.chroma
position relative
background-color var(--syntax-bg)
max-width 100vw
border-left solid var(--syntax-bpx) var(--syntax-ledg)
display flex
transition 0.2s border-color
&:hover
border-color var(--syntax-ledgh)
li
margin-top 0.5em
@ -260,7 +274,7 @@ form
.hide-in-align-left { display: none }
.with-align { text-align: left }
body.align-center
body:not(.align-left)
.hide-in-align-center { display: none }
.with-align { text-align: center }
&> main, > footer
@ -280,24 +294,25 @@ form
margin-right auto
.highlight
border-left 0
pre.chroma
padding 0
display flex
flex-direction column
width auto
flex 1
justify-content center
align-content center
align-items center
// justify-content center
// align-content center
// align-items center
margin-left auto
margin-right auto
> code
width: 600px;
padding 0.25em 0.5em
border-left solid var(--syntax-bpx) var(--syntax-ledg)
width 600px
padding 0.25em 0.5em
border-left solid var(--syntax-bpx) var(--syntax-ledg)
transition border-color 0.2s
&:hover
border-color var(--syntax-ledgh)
img,
embed,

View file

@ -10,7 +10,7 @@ main .highlight pre.chroma
color var(--fg)
main > .highlight > pre.chroma > code > .line
margin-right 5em
// margin-right 5em
.chroma
.err

View file

@ -22,6 +22,7 @@ light-theme = {
--syntax-brd: rgba(255, 255, 255, 0.2),
--syntax-bg: #e6e9ef,
--syntax-ledg: rgba(0, 0, 0, 0.1),
--syntax-ledg: rgba(0, 0, 0, 0.3),
--syntax-sh: #6c6f85,
--syntax-name: latte['green'],
--syntax-mag: latte['red'],
@ -50,7 +51,8 @@ light-theme = {
dark-theme = {
--syntax-brd: rgba(255, 255, 255, 0.2),
--syntax-bg: #181825,
--syntax-ledg: #313244,
--syntax-ledg: alpha(mocha['sapphire'], 0.5),
--syntax-ledgh: mocha['sapphire'],
--syntax-sh: #6c7086,
--icon-shadow: #000,
--syntax-name: mocha['green'],

View file

@ -14,8 +14,8 @@ document.querySelectorAll(".theme-toggler").forEach((a) =>
const initAlign = () => {
const cur = localStorage.getItem("align");
const prev = cur == "center" ? "left" : "center";
document.body.classList.add("align-" + cur);
document.body.classList.remove("align-" + prev);
document.body.classList.add("align-" + cur);
};
if (localStorage.getItem("align") === null) {

View file

@ -54,6 +54,13 @@ export class Theme {
document.body.classList.remove(`dark-theme`)
document.body.classList.remove(`system-theme`)
document.body.classList.add(`${this.#theme}-theme`)
const toggler = document.getElementById("theme-toggler")
toggler.setAttribute("title", this.toggleTitle)
toggler.setAttribute("aria-label", "toggle theme")
}
get toggleTitle() {
return `toggle theme (current theme: ${this.theme})`
}
get theme() {