diff --git a/blog/zsa-moonlander-review-2020-11-06.markdown b/blog/zsa-moonlander-review-2020-11-06.markdown
new file mode 100644
index 0000000..ce30fde
--- /dev/null
+++ b/blog/zsa-moonlander-review-2020-11-06.markdown
@@ -0,0 +1,440 @@
+---
+title: ZSA Moonlander Review
+date: 2020-11-06
+series: keeb
+tags:
+ - moonlander
+ - keyboard
+ - nixos
+---
+
+# ZSA Moonlander Review
+
+I am nowhere near qualified to review things objectively. Therefore this
+blogpost will mostly be about what I like about this keyboard. I plan to go into
+a fair bit of detail, however please do keep in mind that this is subjective as
+all hell. Also keep in mind that this is partially also going to be a review of
+my own keyboard layout too. I'm going to tackle this in a few parts that I will
+label with headings.
+
+This review is NOT sponsored. I paid for this device with my own money. I have
+no influence pushing me either way on this keyboard.
+
+
+
+[That 3d printed brain is built from the 3D model that was made as a part of this
+blogpost.](conversation://Mara/hacker)
+
+## tl;dr
+
+I like the Moonlander. It gets out of my way and lets me focus on writing and
+code. I don't like how limited the Oryx configurator is, but the fact that I can
+build my own firmware from source and flash it to the keyboard on my own makes
+up for that. I think this was a purchase well worth making, but I can understand
+why others would disagree. I can easily see this device becoming a core part of
+my workflow for years to come.
+
+## Build Quality
+
+The Moonlander is a solid keyboard. Once you set it up with the tenting legs and
+adjust the key cluster, the keyboard is rock solid. The only give I've noticed
+is because my desk mat is made of a rubber-like material. The construction of
+the keyboard is all plastic but there isn't any deck flex that I can tell.
+Compare this to cheaper laptops where the entire keyboard bends if you so much
+as touch the keys too hard.
+
+The palmrests are detachable and when they are off it gives the keyboard a
+space-age vibe to it:
+
+
+
+The palmrests feel very solid and fold up into the back of the keyboard for
+travel. However folding up the palmrest does mess up the tenting stability, so
+you can't fold in the palmrest and type very comfortably. This makes sense
+though, the palmrest is made out of smooth plastic so it feels nicer on the
+hands.
+
+ZSA said that iPad compatibility is not guaranteed due to the fact that the iPad
+might not put out enough juice to run it, however in my testing with an iPad Pro
+2018 (12", 512 GB storage) it works fine. The battery drains a little faster,
+but the Moonlander is a much more active keyboard than the smart keyboard so I
+can forgive this.
+
+## Switches
+
+I've been using mechanical keyboards for years, but most of them have been
+clicky switches (such as cloned Cherry MX blues, actual legit Cherry MX blues
+and the awful Razer Green switches). This is my first real experience with
+Cherry MX brown switches. There are many other options when you are about to
+order a moonlander, but I figured Cherry MX browns would be a nice neutral
+choice.
+
+The keyswitches are hot-swappable (no disassembly or soldering required), and
+changing out keyswitches **DOES NOT** void your warranty. I plan to look into
+[Holy Pandas](https://www.youtube.com/watch?v=QLm8DNH5hJk) and [Zilents
+V2](https://youtu.be/uGVw85solnE) in the future. There is even a clever little
+tool in the box that makes it easy to change out keyswitches.
+
+Overall, this has been one of the best typing experiences I have ever had. The
+noise is a little louder than I would have liked (please note that I tend to
+bottom out the keycaps as I type, so this may end up factoring into the noise I
+experience); but overall I really like it. It is far better than I have ever had
+with clicky switches.
+
+## Typing Feel
+
+The Moonlander uses an ortholinear layout as opposed to the staggered layout
+that you find on most keyboards. This took some getting used to, but I have
+found that it is incredibly comfortable and
+
+## My Keymap
+
+Each side of the keyboard has the following:
+
+- 20 alphanumeric keys (some are used for `;`, `,`, `.` and `/` like normal
+ keyboards)
+- 12 freely assignable keys (useful for layer changes, arrow keys, symbols and
+ modifiers)
+- 4 thumb keys
+
+In total, this keyboard has 72 keys, making it about a 70% keyboard (assuming
+the math in my head is right).
+
+My keymap uses all but two of these keys. The two keys I haven't figured out how
+to best use yet are the ones that I currently have the `[` and `]` keycaps on.
+Right now they are mapped to the left and right arrow keys. This was the
+default.
+
+My keymap is organized into
+[layers](https://docs.qmk.fm/#/keymap?id=keymap-and-layers). In each of these
+subsections I will go into detail about what these layers are, what they do and
+how they help me. My keymap code is
+[here](https://tulpa.dev/cadey/kadis-layouts/src/branch/master/moonlander) and I
+have a limited view of it embedded below:
+
+
+
+
+
+If you want to flash my layout to your Moonlander for some reason, you can find
+the firmware binary
+[here](https://cdn.christine.website/file/christine-static/img/keeb/moonlander_kadis.bin).
+You can then flash this to your keyboard with
+[Wally](https://ergodox-ez.com/pages/wally).
+
+### Base Layers
+
+I have a few base layers that contain the main set of letters and numbers that I
+type. The main base layer is my Colemak layer. I have the keys arranged to a
+standard [Colemak](https://Colemak.com/) layout and it is currently the layer I
+type the fastest on. I have the RGB configured so that it is mostly pink with
+the homerow using a lighter shade of pink. The color codes come from my logo
+that you can see in the favicon [or here for a larger
+version](https://christine.website/static/img/avatar_large.png).
+
+I also have a qwerty layer for gaming. Most games expect qwerty keyboards and
+this is an excellent stopgap to avoid having to rebind every game that I want to
+play.
+
+Thanks to a friend of mine, I am also playing with Dvorak. I have not gotten far
+in Dvorak yet, but it is interesting to play with.
+
+I'll cover the leader key in the section below dedicated to it, but the other
+major thing that I have is a colon key on my right hand thumb cluster. This has
+been a huge boon for programming. The colon key is typed a lot. Having it on the
+thumb cluster means that I can just reach down and hit it when I need to. This
+makes writing code in Go and Rust so much easier.
+
+### Symbol/Number Layer
+
+If you look at the base layer keymap, you will see that I do not have square
+brackets mapped anywhere there. Yet I write code with it effortlessly. This is
+because of the symbol/number layer that I access with the lower right and lower
+left keys on the keyboard. I have it positioned there so I can roll my hand to
+the side and then unlock the symbols there. I have access to every major symbol
+needed for programming save `<` and `>` (which I can easily access on the base
+layer with the shift key). I also get a nav cluster and a number pad.
+
+I also have [dynamic macros](https://docs.qmk.fm/#/feature_dynamic_macros) on
+this layer which function kinda like vim macros. The only difference is that
+there's only two macros instead of many like vim. They are convenient though.
+
+### Media Layer
+
+One of the cooler parts of the Moonlander is that it can act as a mouse. It is a
+very terrible mouse (understandably, mostly because the digital inputs of
+keypresses cannot match the analog precision of a mouse). This layer has an
+arrow key cluster too. I normally use the arrow keys along the bottom of the
+keyboard with my thumbs, but sometimes it can help to have a dedicated inverse T
+arrow cluster for things like old MS-DOS games.
+
+I also have media control keys here. They aren't the most useful on my linux
+desktop, however when I plug it into my iPad they are amazing.
+
+### dwm Layer
+
+I use [dwm](/blog/why-i-use-suckless-tools-2020-06-05) as my main window manager
+in Linux. dwm is entirely controlled using the keyboard. I have a dedicated
+keyboard layer to control dwm and send out its keyboard shortcuts. It's really
+nice and lets me get all of the advantages of my tiling setup without needing to
+hit weird keycombos.
+
+### Leader Macros
+
+[Leader macros](https://docs.qmk.fm/#/feature_leader_key) are one of the killer
+features of my layout. I have a [huge
+bank](https://tulpa.dev/cadey/kadis-layouts/src/branch/master/doc/leader.md) of
+them and use them to do type out things that I type a lot. Most common git and
+Kubernetes commands are just a leader macro away.
+
+The Go `if err != nil` macro that got me on /r/programmingcirclejerk twice is
+one of my leader macros, but I may end up promoting it to its own key if I keep
+getting so much use out of it (maybe one of the keys I don't use can become my
+`if err != nil` key). I'm sad that the threads got deleted (I love it when my
+content gets on there, it's one of my favorite subreddits), but such is life.
+
+## NixOS, the Moonlander and Colemak
+
+When I got this keyboard, flashed the firmware and plugged it in, I noticed that
+my keyboard was sending weird inputs. It was rendering things that look like
+this:
+
+```
+The quick brown fox jumps over the lazy yellow dog.
+```
+
+into this:
+
+```
+Ghf qluce bpywk tyx nlm;r yvfp ghf iazj jfiiyw syd.
+```
+
+This is because I had configured my NixOS install to interpret the keyboard as
+if it was Colemak. However the keyboard is able to lie and sends out normal
+keycodes (even though I am typing them in Colemak) as if I was typing in qwerty.
+This double Colemak meant that a lot of messages and commands were completely
+unintelligible until I popped into my qwerty layer.
+
+I quickly found the culprit in my config:
+
+```nix
+console.useXkbConfig = true;
+services.xserver = {
+ layout = "us";
+ xkbVariant = "colemak";
+ xkbOptions = "caps:escape";
+};
+```
+
+This config told the X server to always interpret my keyboard as if it was
+Colemak, meaning that I needed to tell it not to. As a stopgap I commented this
+section of my config out and rebuilt my system.
+
+X11 allows you to specify keyboard configuration for keyboards individually by
+device product/vendor names. The easiest way I know to get this information is
+to open a terminal, run `dmesg -w` to get a constant stream of kernel logs,
+unplug and plug the keyboard back in and see what the kernel reports:
+
+```console
+[242718.024229] usb 1-2: USB disconnect, device number 8
+[242948.272824] usb 1-2: new full-speed USB device number 9 using xhci_hcd
+[242948.420895] usb 1-2: New USB device found, idVendor=3297, idProduct=1969, bcdDevice= 0.01
+[242948.420896] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
+[242948.420897] usb 1-2: Product: Moonlander Mark I
+[242948.420898] usb 1-2: Manufacturer: ZSA Technology Labs
+[242948.420898] usb 1-2: SerialNumber: 0
+```
+
+The product is named `Moonlander Mark I`, which means we can match for it and
+tell X11 to not colemakify the keycodes using something like this:
+
+```
+Section "InputClass"
+ Identifier "moonlander"
+ MatchIsKeyboard "on"
+ MatchProduct "Moonlander"
+ Option "XkbLayout" "us"
+ Option "XkbVariant" "basic"
+EndSection
+```
+
+[For more information on what you can do in an `InputClass` section, see here
+in the X11 documentation.](conversation://Mara/hacker)
+
+This configuration fragment can easily go in the normal X11 configuration
+folder, but doing it like this would mean that I would have to manually drop
+this file in on every system I want to colemakify. This does not scale and
+defeats the point of doing this in NixOS.
+
+Thankfully NixOS has [an
+option](https://search.nixos.org/options?channel=20.09&show=services.xserver.inputClassSections&from=0&size=30&sort=relevance&query=inputClassSections)
+to solve this very problem. Using this module we can write something like this:
+
+```nix
+services.xserver = {
+ layout = "us";
+ xkbVariant = "colemak";
+ xkbOptions = "caps:escape";
+
+ inputClassSections = [
+ ''
+ Identifier "yubikey"
+ MatchIsKeyboard "on"
+ MatchProduct "Yubikey"
+ Option "XkbLayout" "us"
+ Option "XkbVariant" "basic"
+ ''
+ ''
+ Identifier "moonlander"
+ MatchIsKeyboard "on"
+ MatchProduct "Moonlander"
+ Option "XkbLayout" "us"
+ Option "XkbVariant" "basic"
+ ''
+ ];
+};
+```
+
+But this is NixOS and that allows us to go one step further and make the
+identifier and product matching string configurable as will with our own [NixOS
+options](https://nixos.org/manual/nixos/stable/index.html#sec-writing-modules).
+Let's start by lifting all of that above config into its own module:
+
+```nix
+# Colemak.nix
+
+{ config, lib, ... }: with lib; {
+ options = {
+ cadey.colemak = {
+ enable = mkEnableOption "Enables colemak for the default X config";
+ };
+ };
+
+ config = mkIf config.cadey.Colemak.enable {
+ services.xserver = {
+ layout = "us";
+ xkbVariant = "colemak";
+ xkbOptions = "caps:escape";
+
+ inputClassSections = [
+ ''
+ Identifier "yubikey"
+ MatchIsKeyboard "on"
+ MatchProduct "Yubikey"
+ Option "XkbLayout" "us"
+ Option "XkbVariant" "basic"
+
+ ''
+ ''
+ Identifier "moonlander"
+ MatchIsKeyboard "on"
+ MatchProduct "Moonlander"
+ Option "XkbLayout" "us"
+ Option "XkbVariant" "basic"
+ ''
+ ];
+ };
+ };
+}
+```
+
+[This also has Yubikey inputs not get processed into Colemak so that Yubikey OTPs
+still work as expected. Keep in mind that a Yubikey in this mode pretends to be
+a keyboard, so without this configuration the OTP will be processed into
+Colemak. The Yubico verification service will not be able to understand OTPs
+that are typed out in Colemak.](conversation://Mara/hacker)
+
+Then we can turn the identifier and product values into options with
+[mkOption](https://nixos.org/manual/nixos/stable/index.html#sec-option-declarations)
+and string interpolation:
+
+```nix
+# ...
+ cadey.colemak = {
+ enable = mkEnableOption "Enables Colemak for the default X config";
+ ignore = {
+ identifier = mkOption {
+ type = types.str;
+ description = "Keyboard input identifier to send raw keycodes for";
+ default = "moonlander";
+ };
+ product = mkOption {
+ type = types.str;
+ description = "Keyboard input product to send raw keycodes for";
+ default = "Moonlander";
+ };
+ };
+ };
+# ...
+ ''
+ Identifier "${config.cadey.colemak.ignore.identifier}"
+ MatchIsKeyboard "on"
+ MatchProduct "${config.cadey.colemak.ignore.product}"
+ Option "XkbLayout" "us"
+ ''
+# ...
+```
+
+Adding this to the default load path and enabling it with `cadey.Colemak.enable
+= true;` in my tower's `configuration.nix`
+
+This section was made possible thanks to help from [Graham
+Christensen](https://twitter.com/grhmc) who seems to be in search of a job. If
+you are wanting someone on your team that is kind and more than willing to help
+make your team flourish, I highly suggest looking into putting him in your
+hiring pipeline. See
+[here](https://twitter.com/grhmc/status/1324765493534875650) for contact
+information.
+
+## Oryx
+
+[Oryx](https://configure.ergodox-ez.com) is the configurator that ZSA created to
+allow people to create keymaps without needing to compile your own firmware or
+install the [QMK](https://qmk.fm) toolchain.
+
+[QMK is the name of the firmware that the Moonlander (and a lot of other
+custom/split mechanical keyboards) use. It works on AVR and Arm
+processors.](conversation://Mara/hacker)
+
+For most people, Oryx should be sufficient. I actually started my keymap using
+Oryx and sorta outgrew it as I learned more about QMK. It would be nice if Oryx
+added leader key support, however this is more of an advanced feature so I
+understand why it doesn't have that.
+
+## Things I Don't Like
+
+This keyboard isn't flawless, but it gets so many things right that this is
+mostly petty bickering at this point. I had to look hard to find these.
+
+I would have liked having another thumb key for things like layer toggling. I
+can make do with what I have, but another key would have been nice. Maybe add a
+1u key under the red shaped key?
+
+At the point I ordered the Moonlander, I was unable to order a black keyboard
+with white keycaps. I am told that ZSA will be selling keycap sets as early as
+next year. When that happens I will be sure to order a white one so that I can
+have an orca vibe.
+
+ZSA ships with UPS. Normally UPS is fine for me, but the driver that was slated
+to deliver it one day just didn't deliver it. I was able to get the keyboard
+eventually though. Contrary to their claims, the UPS website does NOT update
+instantly and is NOT the most up to date source of information about your
+package.
+
+The cables aren't braided. I would have liked braided cables.
+
+Like I said, these are _really minor_ things, but it's all I can really come up
+with as far as downsides go.
+
+## Conclusion
+
+Overall this keyboard is amazing. I would really suggest it to anyone that wants
+to be able to have control over their main tool and craft it towards their
+desires instead of making do with what some product manager somewhere decided
+what keys should do what. It's expensive at USD$350, but for the right kind of
+person this will be worth every penny. Your mileage may vary, but I like it.