diff --git a/IDEAS.md b/IDEAS.md
index d01d686..bcce436 100644
--- a/IDEAS.md
+++ b/IDEAS.md
@@ -37,6 +37,8 @@ Working scratch list. Same format as the NLOS post: vanilla JS, 2D canvas, scene
- **Garbage collection, three flavors.** Same heap, same allocation pattern, three collectors running in parallel panes: mark-sweep, copying, generational. Watch pause times and fragmentation diverge. Slider for allocation rate to find where each collector falls over.
- **Branch prediction history.** A loop with a data-dependent branch. Toggle between always-taken, two-bit saturating counter, and a small perceptron predictor. Mispredict rate and pipeline bubbles rendered as wasted clock ticks.
- **A load balancer at work.** Incoming requests, a pool of backends with varying response times. Switch between round robin, least connections, and consistent hashing. Kill a backend and watch the failure modes differ.
+- **Subnetting IPv4.** An address and a prefix length. Slider from /8 to /30. Bits light up in the network and host portions. Host count, usable range, broadcast address, and subnet mask all recompute live. Second scene: take a /22 and carve it into a /24 + /25 + /26 + /27 + /28 to fit a specific set of site sizes. Overlap and waste rendered visually so VLSM clicks. Third scene: two hosts with given addresses and masks; show whether they're on the same subnet and, if not, what the gateway decision looks like.
+- **Layer 2 and layer 3, side by side.** A small network: a few hosts, a switch, a router, two subnets. A packet leaves a host with a destination IP on the other subnet. Watch the ARP for the default gateway, the L2 frame addressed to the router's MAC, the router rewriting the L2 header and forwarding out a different interface, another ARP on the far side, final delivery. Toggle between a hub (collisions visible), a learning switch (MAC table filling in), and a router (routing table consulted per packet). Second scene introduces VLANs and trunking: the same switch logically split, a trunk port carrying tagged frames, the router-on-a-stick doing inter-VLAN routing. The phrase "broadcast domain" stops being abstract.
- **TCP in the weeds (follow-up to how-tcp-and-udp-work).** MSS negotiation, Path MTU Discovery, segmentation of a 10 KB write into 1460-byte segments, fast retransmit and SACK, delayed/accumulated ACKs, Nagle's algorithm, the PSH and URG flags, connection teardown with FIN/FIN-ACK and the TIME-WAIT state, keepalives and persist timers. One scene per mechanism with a small packet diagram each. Written for the reader who already understands the basics.
## Ham radio
diff --git a/content/blog/subnetting-ipv4.md b/content/blog/subnetting-ipv4.md
new file mode 100644
index 0000000..5d93318
--- /dev/null
+++ b/content/blog/subnetting-ipv4.md
@@ -0,0 +1,57 @@
++++
+title = "Subnetting IPv4: the bit-bending behind the slash"
+date = 2026-06-05
+draft = true
++++
+
+
+
+
+
+An [IPv4 address](https://en.wikipedia.org/wiki/IPv4) is 32 bits. That is the whole of it. Everything else you ever hear about subnets, masks, supernets, VLSM, CIDR, and the `/24` that turns up in every man page on Earth is just an elaborate argument about where to draw a line in those 32 bits and what the two halves mean.
+
+The address gets dressed up in dotted decimal for the benefit of humans who do not like reading binary, and it is easy to forget there are only ever bits underneath. The prefix length (the number after the slash) is the scoreboard: everything to the left is the network, everything to the right is a host within that network. Move the line, change the number of networks, change the number of hosts per network. The math is not complicated. It only feels that way because it is usually taught by somebody reading out a subnet mask table instead of letting you see the bits.
+
+Below, the same territory in three scenes. Start with the address and the mask, then carve a block into a mix of smaller blocks (VLSM), then do the one routing decision every host makes on every outbound packet: am I talking to you directly, or do I need to hand this to my gateway?
+
+## The address, the mask, and the slash
+
+
+
+Drag the prefix slider. The bits on the left are the network portion and will match across every address in the subnet. The bits on the right are the host portion and are free to be anything. The subnet mask is just a second 32-bit number with ones in the network portion and zeros in the host portion. There is no third thing. If you understand the bits and the mask, you understand [CIDR](https://datatracker.ietf.org/doc/html/rfc4632).
+
+Two host values are reserved in each subnet. The all-zeros host is the network address itself, used as a label for the subnet and legal nowhere else. The all-ones host is the directed broadcast address. Everything in between is usable for actual hosts, which is why a /24 holds 254 usable addresses even though it technically contains 256. The two you cannot use are not a waste so much as a tax, and the tax is fixed regardless of subnet size, which is why small subnets feel expensive. A /30 (two usable hosts out of four) is half overhead. A /31 is a special case that [RFC 3021](https://datatracker.ietf.org/doc/html/rfc3021) legalized for point-to-point links because losing half your addresses to ceremony on every link between two routers was getting embarrassing.
+
+A /32 is a single address with no room for anyone else, which is useful for loopbacks and host routes. A /0 is the whole internet, which is useful as a default route and for almost nothing else.
+
+## Carving a block with VLSM
+
+Early IPv4 had exactly three network sizes: /8, /16, /24, called Class A, B, and C. If you needed 500 addresses you got a /16 with 65,534 of them and threw 65,034 in the bin. [Classless Inter-Domain Routing](https://datatracker.ietf.org/doc/html/rfc4632) arrived in 1993 to stop doing that. With CIDR and its close cousin [Variable-Length Subnet Masking](https://en.wikipedia.org/wiki/Subnetwork#Variable-length_subnet_masking), you can take any block and carve it into smaller blocks of whatever sizes you actually need, and you can do this recursively until the block has nothing left to give.
+
+
+
+The parent block above is a /22: four /24s, 1022 usable hosts. The slider picks a VLSM strategy that allocates the largest subnet first, then the next, and so on until the parent is full or the remaining space is too small to honor the request. Each subnet gets drawn at its correct size, which makes it visible how fast the address space disappears when you start asking for /24s, and how much further you can stretch the block when the things on it actually fit in /27s.
+
+VLSM is greedy: largest first, then walk down. The rule is that every subnet must be aligned to its own size. A /24 has to start on a multiple of 256. A /26 has to start on a multiple of 64. You cannot hand out a /26 that starts at offset 32 any more than you can hand out a 64-byte block of memory that starts at a 32-byte boundary. If this feels familiar it is because IP address allocation and memory allocation are more or less the same problem, and in both cases the scheme that works is the one where everything lines up on powers of two and you do not argue with it.
+
+## Same subnet or gateway: the decision a host makes on every packet
+
+Every host that wants to send a packet asks itself one question first: is the destination on my local subnet, or not? If it is, the packet goes directly (ARP for the destination's MAC, send). If it is not, the packet goes to the [default gateway](https://en.wikipedia.org/wiki/Default_gateway), which is some router on the local subnet that has agreed to take packets off the host's hands and figure out where they belong. The host never thinks about where the router will send the packet next. That is the router's problem, and in exchange for that favor the router gets to charge you an extra MAC-layer frame rewrite on every packet that crosses it.
+
+
+
+Two hosts, two addresses, one shared mask. The bits under the network portion either match or they don't. Slide the mask to change where the line falls and watch the decision flip. A /24 might put both hosts on the same subnet; a /26, on the same underlying ethernet, might not, because the line has moved and now the network bits disagree.
+
+This is the reason a misconfigured subnet mask breaks connectivity in the exact pattern it does. If your mask is too long, you think your neighbors are on other networks and hand every packet to the gateway, which will either route them back out the same interface (wasteful but functional) or drop them on the floor (silent and infuriating). If your mask is too short, you think hosts on other networks are your neighbors, ARP for their MAC addresses, get no answer, and conclude that the network is down, when in fact the network is fine and you are the one who has misunderstood the map.
+
+## The bit that makes the rest make sense
+
+Subnetting is not a different skill from address arithmetic. It is address arithmetic, performed on 32-bit numbers, with the bits grouped into octets for dotted decimal only because humans are bad at binary. Every question about a subnet (what is the network address, what is the broadcast, what is the next subnet, can these two hosts talk directly) is answered by looking at the bits with the mask applied. Whole books have been written to avoid saying this. The books are longer than the idea.
+
+Once the bits are visible, the rest is geometry. A /24 is not smaller than a /16 because somebody said so; it is smaller because 24 is more than 16, and those extra 8 bits of network portion leave 8 fewer bits of host portion, and 2^8 is 256 instead of 65536. The whole of IPv4 subnetting is in that sentence, with a rounding error for the two addresses you can't use.
+
+IPv6 does the same thing with 128 bits instead of 32, which fixes the scarcity problem and changes essentially nothing about how the math works. Which is good, because having learned this once is plenty.
+
+