diff --git a/README.md b/README.md
index 3eded5c..72b3db3 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+
+
# Shade Engine
[](https://github.com/vfilby/shade-engine/actions/workflows/validate.yml)
@@ -223,6 +225,19 @@ disabled.)
data: { option: night }
```
+## Simulator
+
+[`docs/simulator.html`](docs/simulator.html) is a self-contained, single-page
+simulator (no build, no network — open it in any browser). Paste your zone
+YAML, pick a date, location, and sky, and it plays the whole stack through a
+day: the calculator's glare position (a direct port of `calculator.py`,
+eye-zone and reflected-glare constraints included), a lux/elevation policy
+ladder with editable thresholds, and the actuator's real semantics — deadband,
+rate limiting that defers, and manual-move holds (there's a control to inject
+a manual move and watch the hold start and expire). A room cross-section
+diagram shows the sun ray, eye zone, and reflector bounce at any scrubbed
+minute — useful for sanity-checking a zone's geometry before deploying it.
+
## Verifying your geometry
Run in shadow mode first: configure zones, restart, and graph
diff --git a/assets/README.md b/assets/README.md
new file mode 100644
index 0000000..24fb12f
--- /dev/null
+++ b/assets/README.md
@@ -0,0 +1,18 @@
+# Brand assets
+
+`icon.svg` is the source for the integration's brand images. The rasterized
+copies live at `custom_components/shade_engine/brand/icon.png` (256×256) and
+`icon@2x.png` (512×512): since Home Assistant 2026.3, brand images shipped in
+a `brand/` directory inside the integration are served locally and take
+priority over the brands CDN, so no submission to
+[home-assistant/brands](https://github.com/home-assistant/brands) is needed
+(that repo stopped accepting custom-integration PRs in early 2026).
+
+Regenerate the PNGs from the SVG with headless Chrome:
+
+```sh
+chrome --headless --default-background-color=00000000 \
+ --window-size=256,256 --screenshot=icon.png assets/icon.svg
+chrome --headless --default-background-color=00000000 \
+ --window-size=512,512 --screenshot=icon@2x.png assets/icon.svg
+```
diff --git a/assets/icon.svg b/assets/icon.svg
new file mode 100644
index 0000000..f918edf
--- /dev/null
+++ b/assets/icon.svg
@@ -0,0 +1,50 @@
+
diff --git a/custom_components/shade_engine/brand/icon.png b/custom_components/shade_engine/brand/icon.png
new file mode 100644
index 0000000..58163ef
Binary files /dev/null and b/custom_components/shade_engine/brand/icon.png differ
diff --git a/custom_components/shade_engine/brand/icon@2x.png b/custom_components/shade_engine/brand/icon@2x.png
new file mode 100644
index 0000000..2ac0d87
Binary files /dev/null and b/custom_components/shade_engine/brand/icon@2x.png differ
diff --git a/docs/simulator.html b/docs/simulator.html
new file mode 100644
index 0000000..5aae36a
--- /dev/null
+++ b/docs/simulator.html
@@ -0,0 +1,1333 @@
+
+
+
+ Paste a shade_engine zone configuration, set a day and a sky, and watch what the
+ engine would do: the calculator's glare position, the policy ladder switching modes, and the
+ actuator's actual cover commands — deadband, rate limiting, and manual-move holds included.
+ Times are shown in this browser's timezone; illuminance is a synthetic outdoor-sensor model.
+