diff --git a/README.md b/README.md
index 7703b24..d3fdbb8 100644
--- a/README.md
+++ b/README.md
@@ -20,23 +20,27 @@ Plugs into your dock — external monitors turn on, built-in turns off. Unplug
## How it works
-```
- ┌─ Hyprland: socket2 .socket2.sock ──────┐
- compositor ───┤ ├──▶ monitor-lets-go daemon
- └─ Sway: i3 IPC $SWAYSOCK ────────────┘ │
- hotplug events │
- ┌───────────────────────────────
- │ debounce 1200ms
- │ determine state (portable/docked)
- │ apply layout
- │ run hooks
- └──────────────┬───────────────
- │
- ┌────────▼────────┐
- │ systemd │
- │ watchdog 30s │
- │ restart 1s │
- └──────────────────┘
+```mermaid
+flowchart LR
+ subgraph WM["Compositor"]
+ HYPR["Hyprland
socket2 .socket2.sock"]
+ SWAY["Sway
i3 IPC $SWAYSOCK"]
+ end
+
+ HYPR -->|hotplug events| DAEMON["monitor-lets-go daemon"]
+ SWAY -->|hotplug events| DAEMON
+
+ subgraph LOOP["Event loop"]
+ DAEMON --> DEBOUNCE["debounce 1200ms"]
+ DEBOUNCE --> STATE["determine state
(portable / docked)"]
+ STATE --> APPLY["apply layout"]
+ APPLY --> HOOKS["run hooks"]
+ end
+
+ APPLY -->|Hyprland: monitors.lua + hyprctl reload
Sway: swaymsg batch| WM
+
+ SYSTEMD["systemd
watchdog 30s / restart 1s"] --> DAEMON
+ POLL["fallback polling 5s"] --> STATE
```
1. **Startup** — daemon queries connected monitors, determines portable/docked, applies layout