• UI accessibility — screen reader labels for NVDA / Narrator ([#1015](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/pull/1015) by @brightening-eyes, fixes [#916](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/issues/916)). \`accesskit\` در Cargo.toml از قبل فعال بود ولی هیچ widget label-association نداشت — وقتی focus به یک text input یا combobox می‌رفت، NVDA فقط نوع control رو می‌گفت (\"edit\", \"combobox\") نه نام field رو. حالا \`form_row\` پلامبینگ \`egui::Id\` رو به widget می‌فرسته و هر widget با \`.labelled_by(label_id)\` به label visible خود معرفی می‌شه. تست شد توسط کاربر نابینایی که issue رو گزارش داد. ۲۰۸ lib test همه pass. (also includes [c437598](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/commit/c437598) fix for exit_node Content-Encoding + Content-Length stripping — ChatGPT / Claude / Reddit through exit-node now work without Content Encoding Error.) --- • **UI accessibility — proper screen-reader labels for NVDA / Narrator** ([#1015](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/pull/1015) by @brightening-eyes, fixes [#916](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/issues/916)). The `accesskit` feature was already enabled in `Cargo.toml` via eframe, but no widget had an explicit label association — so when focus moved to a text input or combobox, NVDA / Narrator only announced the control type ("edit", "combobox") instead of the field name. The fix plumbs `egui::Id` through `form_row` so each widget can call `.labelled_by(label_id)` to associate with its visible label. Tested by the blind user who originally reported the issue with their actual NVDA setup. 208/208 lib tests still pass. `form_row`'s signature changes from `widget: impl FnOnce(&mut egui::Ui)` to `widget: impl FnOnce(&mut egui::Ui, egui::Id)`. Two existing call sites that don't need the label id (the `Mode` combobox, `Share on LAN` checkbox) bind it as `_label_id` — no functional change there. • Also rolling up the [exit_node Content-Encoding fix](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/commit/c437598) (#964): `fetch()` (Deno / Bun / Node) auto-decompresses gzip / br / deflate response bodies, but the destination's `Content-Encoding: gzip` header was forwarded verbatim — telling the browser the body was gzipped when it was already plain. Browsers raised `Content Encoding Error: invalid or unsupported form of compression`. Strip both `Content-Encoding` and `Content-Length` from the forwarded headers (the Apps Script + Rust transport reframes the wire body anyway, so neither is meaningful end-to-end). Affects every compressed-response destination through exit-node: ChatGPT, Claude, Reddit, X, etc. **Action for exit-node users**: pull the latest [`assets/exit_node/exit_node.ts`](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/blob/main/assets/exit_node/exit_node.ts) and redeploy your Deno Deploy / VPS exit-node. The Rust binary side has nothing new for this fix — it's purely on the exit-node script.