diff --git a/.gitignore b/.gitignore
index 249e7db..90a9bfe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,3 +28,10 @@ Thumbs.db
*.zip
.env
.claude/
+
+# Local runtime config copies
+/public/configuration/renderer-config.json
+/public/configuration/ui-config.json
+/public/configuration/client-mode.json
+/public/configuration/adsense.json
+/public/configuration/hotlooks.json
diff --git a/README.md b/README.md
index a733fba..bc91d90 100644
--- a/README.md
+++ b/README.md
@@ -20,12 +20,13 @@
- `yarn install`
- `yarn link "@nitrots/nitro-renderer"` <== This will link the renderer in the project
- Rename a few files
- - Rename `public/renderer-config.json.example` to `public/renderer-config.json`
- - Rename `public/ui-config.json.example` to `public/ui-config.json`
-- Set your links
- - Open `public/renderer-config.json`
+ - Copy `public/configuration/renderer-config.example` to `public/configuration/renderer-config.json`
+ - Copy `public/configuration/ui-config.example` to `public/configuration/ui-config.json`
+ - Copy `public/configuration/client-mode.example` to `public/configuration/client-mode.json`
+ - Set your links
+ - Open `public/configuration/renderer-config.json`
- Update `socket.url, asset.url, image.library.url, & hof.furni.url`
- - Open `public/ui-config.json`
+ - Open `public/configuration/ui-config.json`
- Update `camera.url, thumbnails.url, url.prefix, habbopages.url`
- `yarn build` <== the final step to build the DIST folder this is where your browser needs to point / or upload this to your /client if you do the compile on a other machine (preferd)
- You can override any variable by passing it to `NitroConfig` in the index.html
diff --git a/docs/local-development-setup.en.md b/docs/local-development-setup.en.md
new file mode 100644
index 0000000..b873850
--- /dev/null
+++ b/docs/local-development-setup.en.md
@@ -0,0 +1,279 @@
+# Local Development Setup with `yarn start`
+
+This guide explains how to run Nitro locally with Vite, using:
+
+- local UI on `http://localhost:5173`;
+- local API/emulator on `http://localhost:2096`;
+- local WebSocket on `ws://localhost:2096`;
+- remote plain assets and gamedata, so you do not need to copy the full `client/nitro` folder locally.
+
+## 1. Start the emulator
+
+Inside `Arcturus-Morningstar-Extended/Emulator`, start the emulator with WebSocket enabled.
+
+Recommended local `config.ini` values:
+
+```ini
+ws.enabled=true
+ws.host=0.0.0.0
+ws.port=2096
+ws.whitelist=*
+ws.ip.header=
+
+crypto.ws.enabled=0
+
+nitro.secure.assets.enabled=false
+nitro.secure.api.enabled=false
+```
+
+For local development, it is easier to disable:
+
+- `crypto.ws.enabled`;
+- `nitro.secure.assets.enabled`;
+- `nitro.secure.api.enabled`.
+
+This keeps debugging simple and avoids the secure runtime layer.
+
+## 2. `public/configuration/client-mode.json`
+
+File:
+
+```txt
+Nitro-V3/public/configuration/client-mode.json
+```
+
+Recommended local config:
+
+```json
+{
+ "distObfuscationEnabled": true,
+ "secureAssetsEnabled": false,
+ "secureApiEnabled": false,
+ "apiBaseUrl": "http://localhost:2096",
+ "plainConfigBaseUrl": "http://localhost:5173/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+Notes:
+
+- `secureAssetsEnabled=false` avoids `/nitro-sec/file`.
+- `secureApiEnabled=false` avoids encrypted `/api/*` requests.
+- `apiBaseUrl` must point to your local emulator.
+- `plainGamedataBaseUrl` can stay remote if you do not have gamedata copied locally.
+
+If you want everything local, use:
+
+```json
+"plainGamedataBaseUrl": "http://localhost:5173/client/nitro/gamedata/"
+```
+
+but the files must really exist under:
+
+```txt
+Nitro-V3/public/client/nitro/gamedata/
+```
+
+## 3. `public/configuration/renderer-config.json`
+
+File:
+
+```txt
+Nitro-V3/public/configuration/renderer-config.json
+```
+
+Minimum local values:
+
+```json
+{
+ "socket.url": "ws://localhost:2096",
+ "api.url": "http://localhost:2096",
+ "crypto.ws.enabled": false,
+ "gamedata.url": "https://hotel.example.com/client/nitro/gamedata",
+ "external.texts.url": [
+ "${gamedata.url}/ExternalTexts.json",
+ "${gamedata.url}/UITexts.json"
+ ],
+ "furnidata.url": "${gamedata.url}/FurnitureData.json?t=%timestamp%",
+ "productdata.url": "${gamedata.url}/ProductData.json?t=%timestamp%",
+ "avatar.actions.url": "${gamedata.url}/HabboAvatarActions.json?t=%timestamp%",
+ "avatar.figuredata.url": "${gamedata.url}/FigureData.json?t=%timestamp%",
+ "avatar.figuremap.url": "${gamedata.url}/FigureMap.json?t=%timestamp%",
+ "avatar.effectmap.url": "${gamedata.url}/EffectMap.json?t=%timestamp%",
+ "login.endpoint": "${api.url}/api/auth/login",
+ "login.register.endpoint": "${api.url}/api/auth/register",
+ "login.forgot.endpoint": "${api.url}/api/auth/forgot-password",
+ "login.logout.endpoint": "${api.url}/api/auth/logout",
+ "login.remember.endpoint": "${api.url}/api/auth/remember",
+ "login.health.endpoint": "${api.url}/api/health",
+ "login.health.method": "GET",
+ "login.check-email.endpoint": "${api.url}/api/auth/check-email",
+ "login.check-username.endpoint": "${api.url}/api/auth/check-username",
+ "login.register.imaging.url": "${api.url}/api/avatar/imaging",
+ "login.news.url": "${api.url}/api/auth/news",
+ "badges.custom.list.endpoint": "${api.url}/api/badges/custom",
+ "badges.custom.create.endpoint": "${api.url}/api/badges/custom",
+ "badges.custom.update.endpoint": "${api.url}/api/badges/custom/%badgeId%",
+ "badges.custom.delete.endpoint": "${api.url}/api/badges/custom/%badgeId%",
+ "badges.custom.texts.endpoint": "${api.url}/api/badges/custom/texts"
+}
+```
+
+Important:
+
+- Do not use `https://localhost:2096/nitro-sec/file` locally if `secureAssetsEnabled=false`.
+- Do not use `ws://192.168.x.x/:2096`; it is malformed. Use `ws://localhost:2096` or `ws://192.168.x.x:2096`.
+
+## 4. `public/configuration/ui-config.json`
+
+File:
+
+```txt
+Nitro-V3/public/configuration/ui-config.json
+```
+
+For the login view, you can use remote plain images:
+
+```json
+{
+ "loginview": {
+ "images": {
+ "background": "https://hotel.example.com/client/nitro/images/reception/background_gradient_apr25.png",
+ "background.colour": "#6eadc8",
+ "drape": "https://hotel.example.com/client/nitro/images/reception/drape.png",
+ "left": "https://hotel.example.com/client/nitro/images/reception/mute_reception_backdrop_left.png",
+ "right": "https://hotel.example.com/client/nitro/images/reception/background_right.png"
+ }
+ }
+}
+```
+
+If you see `ERR_NAME_NOT_RESOLVED`, the configured domain does not exist or is not reachable.
+
+## 5. Database-backed news
+
+Login news should come from the database through the emulator.
+
+In renderer config use:
+
+```json
+"login.news.url": "${api.url}/api/auth/news"
+```
+
+The emulator reads from:
+
+```txt
+ui_news
+```
+
+Reference SQL:
+
+```txt
+Arcturus-Morningstar-Extended/Database Updates/013_UI_Client_News.sql
+```
+
+Main columns:
+
+- `title`
+- `body`
+- `image`
+- `link_text`
+- `link_url`
+- `enabled`
+- `sort_order`
+
+`public/configuration/news.json` can stay as a mock/fallback only, but it is not the correct production flow.
+
+## 6. Start Nitro
+
+Inside `Nitro-V3`:
+
+```bash
+yarn start
+```
+
+Open:
+
+```txt
+http://localhost:5173
+```
+
+Recommendation: use `localhost`, not `192.168.x.x`, because cookies and API sessions are host-based and can otherwise cause `401 Unauthorized`.
+
+## 7. Common errors
+
+### `Unable to load renderer-config.json`
+
+Check:
+
+```txt
+public/configuration/client-mode.json
+```
+
+It must contain:
+
+```json
+"secureAssetsEnabled": false
+```
+
+### `Invalid JSON ... Unexpected token '<'`
+
+The client requested JSON, but Vite returned HTML.
+
+This happens when a URL points to a file that does not exist, for example:
+
+```txt
+http://localhost:5173/client/nitro/gamedata/ExternalTexts.json
+```
+
+Fix:
+
+- use remote plain gamedata;
+- or copy the gamedata files into `public/client/nitro/gamedata`.
+
+### WebSocket `1006`
+
+Check:
+
+```json
+"socket.url": "ws://localhost:2096"
+```
+
+and emulator config:
+
+```ini
+ws.enabled=true
+ws.port=2096
+```
+
+### Custom badges `401 Unauthorized`
+
+This is normal if you are not logged in or if you open Nitro from a different host.
+
+Use:
+
+```txt
+http://localhost:5173
+```
+
+and API:
+
+```txt
+http://localhost:2096
+```
+
+## 8. Difference from production
+
+Local `yarn start`:
+
+```html
+
+```
+
+Production build:
+
+```html
+
+```
+
+Do not mix the two flows.
diff --git a/docs/local-development-setup.md b/docs/local-development-setup.md
new file mode 100644
index 0000000..b788e2e
--- /dev/null
+++ b/docs/local-development-setup.md
@@ -0,0 +1,279 @@
+# Setup locale con `yarn start`
+
+Questa guida serve per avviare Nitro in locale con Vite, usando:
+
+- UI locale su `http://localhost:5173`;
+- API/emulatore locale su `http://localhost:2096`;
+- WebSocket locale su `ws://localhost:2096`;
+- asset e gamedata remoti plain, così non devi copiare tutta la cartella `client/nitro`.
+
+## 1. Avvia l'emulatore
+
+Nel repo `Arcturus-Morningstar-Extended/Emulator`, avvia l'emulatore con WebSocket attivo.
+
+Nel tuo `config.ini` locale usa valori tipo:
+
+```ini
+ws.enabled=true
+ws.host=0.0.0.0
+ws.port=2096
+ws.whitelist=*
+ws.ip.header=
+
+crypto.ws.enabled=0
+
+nitro.secure.assets.enabled=false
+nitro.secure.api.enabled=false
+```
+
+Per il locale è meglio tenere spenti:
+
+- `crypto.ws.enabled`;
+- `nitro.secure.assets.enabled`;
+- `nitro.secure.api.enabled`.
+
+Così puoi debuggare senza layer secure in mezzo.
+
+## 2. `public/configuration/client-mode.json`
+
+File:
+
+```txt
+Nitro-V3/public/configuration/client-mode.json
+```
+
+Config locale consigliato:
+
+```json
+{
+ "distObfuscationEnabled": true,
+ "secureAssetsEnabled": false,
+ "secureApiEnabled": false,
+ "apiBaseUrl": "http://localhost:2096",
+ "plainConfigBaseUrl": "http://localhost:5173/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+Note:
+
+- `secureAssetsEnabled=false` evita `/nitro-sec/file`.
+- `secureApiEnabled=false` evita cifratura `/api/*`.
+- `apiBaseUrl` deve puntare all'emulatore locale.
+- `plainGamedataBaseUrl` può rimanere remoto se non hai gamedata copiato in locale.
+
+Se vuoi tutto locale, usa:
+
+```json
+"plainGamedataBaseUrl": "http://localhost:5173/client/nitro/gamedata/"
+```
+
+ma devi avere davvero i file sotto:
+
+```txt
+Nitro-V3/public/client/nitro/gamedata/
+```
+
+## 3. `public/configuration/renderer-config.json`
+
+File:
+
+```txt
+Nitro-V3/public/configuration/renderer-config.json
+```
+
+Valori minimi locali:
+
+```json
+{
+ "socket.url": "ws://localhost:2096",
+ "api.url": "http://localhost:2096",
+ "crypto.ws.enabled": false,
+ "gamedata.url": "https://hotel.example.com/client/nitro/gamedata",
+ "external.texts.url": [
+ "${gamedata.url}/ExternalTexts.json",
+ "${gamedata.url}/UITexts.json"
+ ],
+ "furnidata.url": "${gamedata.url}/FurnitureData.json?t=%timestamp%",
+ "productdata.url": "${gamedata.url}/ProductData.json?t=%timestamp%",
+ "avatar.actions.url": "${gamedata.url}/HabboAvatarActions.json?t=%timestamp%",
+ "avatar.figuredata.url": "${gamedata.url}/FigureData.json?t=%timestamp%",
+ "avatar.figuremap.url": "${gamedata.url}/FigureMap.json?t=%timestamp%",
+ "avatar.effectmap.url": "${gamedata.url}/EffectMap.json?t=%timestamp%",
+ "login.endpoint": "${api.url}/api/auth/login",
+ "login.register.endpoint": "${api.url}/api/auth/register",
+ "login.forgot.endpoint": "${api.url}/api/auth/forgot-password",
+ "login.logout.endpoint": "${api.url}/api/auth/logout",
+ "login.remember.endpoint": "${api.url}/api/auth/remember",
+ "login.health.endpoint": "${api.url}/api/health",
+ "login.health.method": "GET",
+ "login.check-email.endpoint": "${api.url}/api/auth/check-email",
+ "login.check-username.endpoint": "${api.url}/api/auth/check-username",
+ "login.register.imaging.url": "${api.url}/api/avatar/imaging",
+ "login.news.url": "${api.url}/api/auth/news",
+ "badges.custom.list.endpoint": "${api.url}/api/badges/custom",
+ "badges.custom.create.endpoint": "${api.url}/api/badges/custom",
+ "badges.custom.update.endpoint": "${api.url}/api/badges/custom/%badgeId%",
+ "badges.custom.delete.endpoint": "${api.url}/api/badges/custom/%badgeId%",
+ "badges.custom.texts.endpoint": "${api.url}/api/badges/custom/texts"
+}
+```
+
+Importante:
+
+- Non usare `https://localhost:2096/nitro-sec/file` in locale se `secureAssetsEnabled=false`.
+- Non usare `ws://192.168.x.x/:2096`: è malformato. Usa `ws://localhost:2096` oppure `ws://192.168.x.x:2096`.
+
+## 4. `public/configuration/ui-config.json`
+
+File:
+
+```txt
+Nitro-V3/public/configuration/ui-config.json
+```
+
+Per la login view puoi usare immagini remote plain:
+
+```json
+{
+ "loginview": {
+ "images": {
+ "background": "https://hotel.example.com/client/nitro/images/reception/background_gradient_apr25.png",
+ "background.colour": "#6eadc8",
+ "drape": "https://hotel.example.com/client/nitro/images/reception/drape.png",
+ "left": "https://hotel.example.com/client/nitro/images/reception/mute_reception_backdrop_left.png",
+ "right": "https://hotel.example.com/client/nitro/images/reception/background_right.png"
+ }
+ }
+}
+```
+
+Se vedi `ERR_NAME_NOT_RESOLVED`, il dominio configurato non esiste o non è raggiungibile.
+
+## 5. News dal database
+
+Le news della login devono arrivare dal database tramite l'emulatore.
+
+Nel renderer config usa:
+
+```json
+"login.news.url": "${api.url}/api/auth/news"
+```
+
+L'emulatore legge dalla tabella:
+
+```txt
+ui_news
+```
+
+SQL di riferimento:
+
+```txt
+Arcturus-Morningstar-Extended/Database Updates/013_UI_Client_News.sql
+```
+
+Colonne principali:
+
+- `title`
+- `body`
+- `image`
+- `link_text`
+- `link_url`
+- `enabled`
+- `sort_order`
+
+`public/configuration/news.json` può rimanere solo come mock/fallback, ma non è il flow corretto.
+
+## 6. Avvio Nitro
+
+Nel repo `Nitro-V3`:
+
+```bash
+yarn start
+```
+
+Apri:
+
+```txt
+http://localhost:5173
+```
+
+Consiglio: usa `localhost`, non `192.168.x.x`, perché cookie e sessioni API possono cambiare host e causare `401 Unauthorized`.
+
+## 7. Errori comuni
+
+### `Unable to load renderer-config.json`
+
+Controlla:
+
+```txt
+public/configuration/client-mode.json
+```
+
+Deve avere:
+
+```json
+"secureAssetsEnabled": false
+```
+
+### `Invalid JSON ... Unexpected token '<'`
+
+Vuol dire che il client ha chiesto un JSON, ma Vite ha risposto HTML.
+
+Succede quando un URL punta a un file che non esiste, per esempio:
+
+```txt
+http://localhost:5173/client/nitro/gamedata/ExternalTexts.json
+```
+
+Soluzione:
+
+- usa gamedata remoto plain;
+- oppure copia davvero i gamedata in `public/client/nitro/gamedata`.
+
+### WebSocket `1006`
+
+Controlla:
+
+```json
+"socket.url": "ws://localhost:2096"
+```
+
+e nel config emulator:
+
+```ini
+ws.enabled=true
+ws.port=2096
+```
+
+### Custom badges `401 Unauthorized`
+
+È normale se non sei loggato o se apri Nitro da un host diverso.
+
+Usa:
+
+```txt
+http://localhost:5173
+```
+
+e API:
+
+```txt
+http://localhost:2096
+```
+
+## 8. Differenza con produzione
+
+Locale con `yarn start`:
+
+```html
+
+```
+
+Produzione buildata:
+
+```html
+
+```
+
+Non mischiare i due flow.
diff --git a/docs/secure-production-setup.en.md b/docs/secure-production-setup.en.md
new file mode 100644
index 0000000..ab86bfd
--- /dev/null
+++ b/docs/secure-production-setup.en.md
@@ -0,0 +1,365 @@
+# Secure Runtime Production Setup
+
+Quick setup guide for running Nitro with:
+
+- configuration and gamedata served through `/nitro-sec/file`;
+- encrypted runtime `/api/*` calls;
+- obfuscated production bundles loaded as `.dat`.
+
+Replace the example domains with your real domains:
+
+- `https://hotel.example.com`
+- `https://nitro.example.com:2096`
+
+## 1. Build Nitro
+
+Inside the `Nitro-V3` repository:
+
+```bash
+yarn build
+```
+
+Then publish the `dist` folder to your web server, for example:
+
+```txt
+C:/inetpub/wwwroot/hotel/nitro
+```
+
+The deployed folder should contain at least:
+
+```txt
+configuration/
+assets/
+asset-loader.js
+index.html
+src/
+```
+
+## 2. `configuration/client-mode.json`
+
+File:
+
+```txt
+Nitro-V3/dist/configuration/client-mode.json
+```
+
+Secure production configuration:
+
+```json
+{
+ "distObfuscationEnabled": true,
+ "secureAssetsEnabled": true,
+ "secureApiEnabled": true,
+ "apiBaseUrl": "https://nitro.example.com:2096",
+ "plainConfigBaseUrl": "https://hotel.example.com/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+Meaning:
+
+- `distObfuscationEnabled: true` loads `app.js.dat` and `app.css.dat`.
+- `secureAssetsEnabled: true` loads `renderer-config.json`, `ui-config.json`, and gamedata through `/nitro-sec/file`.
+- `secureApiEnabled: true` automatically encrypts `/api/*` requests.
+- `apiBaseUrl` must point to the emulator/API.
+- `plainConfigBaseUrl` and `plainGamedataBaseUrl` are fallbacks when secure assets are disabled.
+
+## 3. `configuration/renderer-config.json`
+
+File:
+
+```txt
+Nitro-V3/dist/configuration/renderer-config.json
+```
+
+Important values:
+
+```json
+{
+ "socket.url": "wss://nitro.example.com:2096",
+ "api.url": "https://nitro.example.com:2096",
+ "gamedata.url": "https://nitro.example.com:2096/nitro-sec/file?kind=gamedata&file=",
+ "external.texts.url": [
+ "${gamedata.url}/ExternalTexts.json",
+ "${gamedata.url}/UITexts.json"
+ ],
+ "furnidata.url": "${gamedata.url}/FurnitureData.json?t=%timestamp%",
+ "productdata.url": "${gamedata.url}/ProductData.json?t=%timestamp%",
+ "avatar.actions.url": "${gamedata.url}/HabboAvatarActions.json?t=%timestamp%",
+ "avatar.figuredata.url": "${gamedata.url}/FigureData.json?t=%timestamp%",
+ "avatar.figuremap.url": "${gamedata.url}/FigureMap.json?t=%timestamp%",
+ "avatar.effectmap.url": "${gamedata.url}/EffectMap.json?t=%timestamp%",
+ "crypto.ws.enabled": true
+}
+```
+
+If you are not using WebSocket crypto yet, use:
+
+```json
+"crypto.ws.enabled": false
+```
+
+## 4. `configuration/ui-config.json`
+
+File:
+
+```txt
+Nitro-V3/dist/configuration/ui-config.json
+```
+
+Static image and camera URLs can remain plain:
+
+```json
+{
+ "camera.url": "https://hotel.example.com/client/camera/",
+ "thumbnails.url": "https://hotel.example.com/client/camera/thumbnail/%thumbnail%.png"
+}
+```
+
+Non-sensitive images can stay static. JSON configuration and gamedata should go through the secure endpoint.
+
+## 5. Emulator `config.ini`
+
+Inside `Arcturus-Morningstar-Extended`, edit the emulator config:
+
+```txt
+Emulator/config.ini
+```
+
+Production example:
+
+```ini
+ws.enabled=true
+ws.host=0.0.0.0
+ws.port=2096
+ws.whitelist=https://hotel.example.com
+ws.ip.header=CF-Connecting-IP
+
+crypto.ws.enabled=1
+
+nitro.secure.assets.enabled=true
+nitro.secure.api.enabled=true
+nitro.secure.config.root=C:/inetpub/wwwroot/hotel/nitro/configuration
+nitro.secure.gamedata.root=C:/inetpub/wwwroot/hotel/nitro/client/nitro/gamedata
+nitro.secure.master_key=change-this-to-a-long-random-secret
+
+login.remember.enabled=true
+login.remember.duration.days=30
+login.remember.jwt.secret=change-this-too-if-you-use-remember-me
+```
+
+Notes:
+
+- `nitro.secure.config.root` must point to the folder containing `renderer-config.json`, `ui-config.json`, and `client-mode.json`.
+- `nitro.secure.gamedata.root` must point to the live gamedata folder.
+- Files are read live from disk: if you update a JSON file, a new browser refresh reads the new version.
+- `nitro.secure.master_key` must be secret and stable. Never put it in public files.
+
+## 6. Cloudflare
+
+If you use Cloudflare:
+
+1. Keep the proxy enabled for the website domain `hotel.example.com`.
+2. Make sure Cloudflare supports/proxies the port used by `nitro.example.com:2096`.
+3. Always use HTTPS/WSS in the browser:
+
+```json
+"api.url": "https://nitro.example.com:2096",
+"socket.url": "wss://nitro.example.com:2096"
+```
+
+If you get CORS errors, check:
+
+```ini
+ws.whitelist=https://hotel.example.com
+```
+
+## 7. IIS / `.dat` MIME type
+
+If obfuscated `.dat` assets are enabled, IIS must serve them correctly.
+
+Add this MIME type:
+
+```txt
+Extension: .dat
+MIME type: application/octet-stream
+```
+
+Without it, the browser can receive 404 even when the file exists.
+
+## 8. Final checklist
+
+- `client-mode.json` has `secureAssetsEnabled=true`.
+- `client-mode.json` has `secureApiEnabled=true`.
+- `renderer-config.json` uses `/nitro-sec/file?kind=gamedata&file=`.
+- `api.url` points to `https://nitro.example.com:2096`.
+- `socket.url` points to `wss://nitro.example.com:2096`.
+- `config.ini` has the correct `nitro.secure.config.root`.
+- `config.ini` has the correct `nitro.secure.gamedata.root`.
+- `config.ini` has a stable `nitro.secure.master_key`.
+- IIS knows the `.dat` MIME type.
+- Restart the emulator after changing `config.ini`.
+- Refresh the browser after changing JSON files in `configuration` or `gamedata`.
+
+## 9. Temporarily disable secure mode
+
+For quick debugging, only change `client-mode.json`:
+
+```json
+{
+ "distObfuscationEnabled": false,
+ "secureAssetsEnabled": false,
+ "secureApiEnabled": false,
+ "apiBaseUrl": "https://nitro.example.com:2096",
+ "plainConfigBaseUrl": "https://hotel.example.com/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+Then hard refresh the browser.
+
+## 10. `configuration/bootstrap.js`
+
+File:
+
+```txt
+Nitro-V3/dist/configuration/bootstrap.js
+```
+
+This is the first loader when you use the external secure mode.
+
+It does three things:
+
+1. opens an ECDH session with the emulator through `/nitro-sec/bootstrap`;
+2. downloads encrypted `client-mode.json` through `/nitro-sec/file?kind=config`;
+3. downloads encrypted `asset-loader.js` and imports it as a JavaScript module.
+
+### Value to check
+
+Inside `bootstrap.js` there is:
+
+```js
+const API_BASE = "https://nitro.example.com:2096";
+```
+
+It must point to your public emulator/API URL.
+
+In production:
+
+```js
+const API_BASE = "https://nitro.example.com:2096";
+```
+
+In local development:
+
+```js
+const API_BASE = "http://localhost:2096";
+```
+
+If `bootstrap.js` fails, it automatically falls back to the plain loader:
+
+```txt
+configuration/asset-loader.js
+```
+
+So `asset-loader.js` must always exist inside the `configuration` folder.
+
+## 11. `configuration/asset-loader.js`
+
+File:
+
+```txt
+Nitro-V3/dist/configuration/asset-loader.js
+```
+
+This loader loads the actual bundle:
+
+- if `distObfuscationEnabled=true`
+ - it loads `app.css.dat`;
+ - it loads `app.js.dat`;
+ - it decodes, decompresses, and imports the bundle from a blob.
+
+- if `distObfuscationEnabled=false`
+ - it loads `assets/app.css`;
+ - it loads `assets/app.js`.
+
+### Required files in production
+
+With obfuscation enabled, these files must exist:
+
+```txt
+assets/app.css.dat
+assets/app.js.dat
+configuration/asset-loader.js
+configuration/bootstrap.js
+configuration/client-mode.json
+```
+
+With obfuscation disabled, these files must exist:
+
+```txt
+assets/app.css
+assets/app.js
+configuration/asset-loader.js
+configuration/client-mode.json
+```
+
+## 12. `index.html`
+
+`index.html` should stay minimal.
+
+Secure production example:
+
+```html
+
+
+```
+
+Vite development example:
+
+```html
+
+
+```
+
+Do not mix the two flows:
+
+- production build: use `configuration/bootstrap.js`;
+- `yarn start` development: use `/src/bootstrap.ts`.
+
+## 13. Files inside `/configuration`
+
+The `configuration` folder should contain:
+
+```txt
+asset-loader.js
+bootstrap.js
+client-mode.json
+renderer-config.json
+ui-config.json
+adsense.json optional
+hotlooks.json if register hot looks are enabled
+UITexts.json if separate UI texts are enabled
+```
+
+Login news should not live in `news.json` in production. They come from the database through:
+
+```json
+"login.news.url": "${api.url}/api/auth/news"
+```
+
+The emulator reads from the `ui_news` table.
+
+With `secureAssetsEnabled=true`, client-loaded files go through:
+
+```txt
+https://nitro.example.com:2096/nitro-sec/file?kind=config&file=...
+```
+
+The emulator reads them from:
+
+```ini
+nitro.secure.config.root=C:/inetpub/wwwroot/hotel/nitro/configuration
+```
+
+If you add new JSON/JS files inside `configuration` and want to protect them, they must be requested through the secure endpoint or loaded through `bootstrap.js`.
diff --git a/docs/secure-production-setup.md b/docs/secure-production-setup.md
new file mode 100644
index 0000000..eb76a6a
--- /dev/null
+++ b/docs/secure-production-setup.md
@@ -0,0 +1,365 @@
+# Setup Secure Runtime in produzione
+
+Guida rapida per avviare Nitro con:
+
+- configurazioni e gamedata serviti da `/nitro-sec/file`;
+- API `/api/*` cifrate dal wrapper runtime;
+- bundle buildati offuscati come `.dat`.
+
+Negli esempi usa i tuoi domini reali al posto di:
+
+- `https://hotel.example.com`
+- `https://nitro.example.com:2096`
+
+## 1. Build Nitro
+
+Nel repo `Nitro-V3`:
+
+```bash
+yarn build
+```
+
+Poi pubblica la cartella `dist` nel web server del sito, ad esempio:
+
+```txt
+C:/inetpub/wwwroot/hotel/nitro
+```
+
+La struttura pubblicata deve contenere almeno:
+
+```txt
+configuration/
+assets/
+asset-loader.js
+index.html
+src/
+```
+
+## 2. `configuration/client-mode.json`
+
+File:
+
+```txt
+Nitro-V3/dist/configuration/client-mode.json
+```
+
+Configurazione produzione secure:
+
+```json
+{
+ "distObfuscationEnabled": true,
+ "secureAssetsEnabled": true,
+ "secureApiEnabled": true,
+ "apiBaseUrl": "https://nitro.example.com:2096",
+ "plainConfigBaseUrl": "https://hotel.example.com/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+Significato:
+
+- `distObfuscationEnabled: true` carica `app.js.dat` e `app.css.dat`.
+- `secureAssetsEnabled: true` carica `renderer-config.json`, `ui-config.json` e gamedata da `/nitro-sec/file`.
+- `secureApiEnabled: true` cifra automaticamente le chiamate `/api/*`.
+- `apiBaseUrl` deve puntare all'emulatore/API.
+- `plainConfigBaseUrl` e `plainGamedataBaseUrl` restano fallback quando spegni secure assets.
+
+## 3. `configuration/renderer-config.json`
+
+File:
+
+```txt
+Nitro-V3/dist/configuration/renderer-config.json
+```
+
+Valori importanti:
+
+```json
+{
+ "socket.url": "wss://nitro.example.com:2096",
+ "api.url": "https://nitro.example.com:2096",
+ "gamedata.url": "https://nitro.example.com:2096/nitro-sec/file?kind=gamedata&file=",
+ "external.texts.url": [
+ "${gamedata.url}/ExternalTexts.json",
+ "${gamedata.url}/UITexts.json"
+ ],
+ "furnidata.url": "${gamedata.url}/FurnitureData.json?t=%timestamp%",
+ "productdata.url": "${gamedata.url}/ProductData.json?t=%timestamp%",
+ "avatar.actions.url": "${gamedata.url}/HabboAvatarActions.json?t=%timestamp%",
+ "avatar.figuredata.url": "${gamedata.url}/FigureData.json?t=%timestamp%",
+ "avatar.figuremap.url": "${gamedata.url}/FigureMap.json?t=%timestamp%",
+ "avatar.effectmap.url": "${gamedata.url}/EffectMap.json?t=%timestamp%",
+ "crypto.ws.enabled": true
+}
+```
+
+Se non usi ancora WebSocket crypto, metti:
+
+```json
+"crypto.ws.enabled": false
+```
+
+## 4. `configuration/ui-config.json`
+
+File:
+
+```txt
+Nitro-V3/dist/configuration/ui-config.json
+```
+
+Qui puoi lasciare immagini e camera su URL statici normali:
+
+```json
+{
+ "camera.url": "https://hotel.example.com/client/camera/",
+ "thumbnails.url": "https://hotel.example.com/client/camera/thumbnail/%thumbnail%.png"
+}
+```
+
+Le immagini non sensibili possono rimanere statiche. I JSON/gamedata invece passano dal secure endpoint.
+
+## 5. `config.ini` dell'emulatore
+
+Nel repo `Arcturus-Morningstar-Extended`, file usato dall'emulatore:
+
+```txt
+Emulator/config.ini
+```
+
+Esempio produzione:
+
+```ini
+ws.enabled=true
+ws.host=0.0.0.0
+ws.port=2096
+ws.whitelist=https://hotel.example.com
+ws.ip.header=CF-Connecting-IP
+
+crypto.ws.enabled=1
+
+nitro.secure.assets.enabled=true
+nitro.secure.api.enabled=true
+nitro.secure.config.root=C:/inetpub/wwwroot/hotel/nitro/configuration
+nitro.secure.gamedata.root=C:/inetpub/wwwroot/hotel/nitro/client/nitro/gamedata
+nitro.secure.master_key=change-this-to-a-long-random-secret
+
+login.remember.enabled=true
+login.remember.duration.days=30
+login.remember.jwt.secret=change-this-too-if-you-use-remember-me
+```
+
+Note:
+
+- `nitro.secure.config.root` deve puntare alla cartella dove ci sono `renderer-config.json`, `ui-config.json`, `client-mode.json`.
+- `nitro.secure.gamedata.root` deve puntare alla cartella live dei gamedata.
+- I file vengono letti live da disco: se cambi un JSON, un nuovo refresh pagina legge la nuova versione.
+- `nitro.secure.master_key` deve restare segreta e stabile. Non metterla nei file pubblici.
+
+## 6. Cloudflare
+
+Se usi Cloudflare:
+
+1. Lascia la nuvoletta attiva sul dominio web `hotel.example.com`.
+2. Per `nitro.example.com:2096`, assicurati che Cloudflare supporti/proxy il traffico sulla porta usata.
+3. Usa sempre HTTPS/WSS lato browser:
+
+```json
+"api.url": "https://nitro.example.com:2096",
+"socket.url": "wss://nitro.example.com:2096"
+```
+
+Se vedi errori CORS, controlla:
+
+```ini
+ws.whitelist=https://hotel.example.com
+```
+
+## 7. IIS / MIME `.dat`
+
+Se usi gli asset offuscati `.dat`, IIS deve servirli.
+
+Aggiungi MIME type:
+
+```txt
+Extension: .dat
+MIME type: application/octet-stream
+```
+
+Senza questo, il browser può dare 404 anche se il file esiste davvero.
+
+## 8. Checklist finale
+
+- `client-mode.json` ha `secureAssetsEnabled=true`.
+- `client-mode.json` ha `secureApiEnabled=true`.
+- `renderer-config.json` usa `/nitro-sec/file?kind=gamedata&file=`.
+- `api.url` punta a `https://nitro.example.com:2096`.
+- `socket.url` punta a `wss://nitro.example.com:2096`.
+- `config.ini` ha `nitro.secure.config.root` corretto.
+- `config.ini` ha `nitro.secure.gamedata.root` corretto.
+- `config.ini` ha `nitro.secure.master_key` stabile.
+- IIS conosce il MIME `.dat`.
+- Dopo modifiche a `config.ini`, riavvia l'emulatore.
+- Dopo modifiche ai JSON in `configuration` o `gamedata`, basta refresh pagina.
+
+## 9. Spegnere temporaneamente secure
+
+Per debug rapido, cambia solo `client-mode.json`:
+
+```json
+{
+ "distObfuscationEnabled": false,
+ "secureAssetsEnabled": false,
+ "secureApiEnabled": false,
+ "apiBaseUrl": "https://nitro.example.com:2096",
+ "plainConfigBaseUrl": "https://hotel.example.com/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+Poi fai hard refresh.
+
+## 10. `configuration/bootstrap.js`
+
+File:
+
+```txt
+Nitro-V3/dist/configuration/bootstrap.js
+```
+
+Questo è il primo loader quando usi la modalità secure esterna.
+
+Fa tre cose:
+
+1. apre una sessione ECDH con l'emulatore tramite `/nitro-sec/bootstrap`;
+2. scarica `client-mode.json` cifrato da `/nitro-sec/file?kind=config`;
+3. scarica `asset-loader.js` cifrato e lo importa come modulo JavaScript.
+
+### Valore da controllare
+
+Dentro `bootstrap.js` esiste:
+
+```js
+const API_BASE = "https://nitro.example.com:2096";
+```
+
+Deve puntare all'emulatore/API pubblico.
+
+In produzione:
+
+```js
+const API_BASE = "https://nitro.example.com:2096";
+```
+
+In locale:
+
+```js
+const API_BASE = "http://localhost:2096";
+```
+
+Se `bootstrap.js` fallisce, prova automaticamente fallback plain su:
+
+```txt
+configuration/asset-loader.js
+```
+
+Quindi `asset-loader.js` deve esistere sempre nella cartella `configuration`.
+
+## 11. `configuration/asset-loader.js`
+
+File:
+
+```txt
+Nitro-V3/dist/configuration/asset-loader.js
+```
+
+Questo loader carica il bundle vero:
+
+- se `distObfuscationEnabled=true`
+ - carica `app.css.dat`;
+ - carica `app.js.dat`;
+ - decodifica, decomprime e importa il bundle da blob.
+
+- se `distObfuscationEnabled=false`
+ - carica `assets/app.css`;
+ - carica `assets/app.js`.
+
+### File richiesti in produzione
+
+Con offuscamento attivo devono esistere:
+
+```txt
+assets/app.css.dat
+assets/app.js.dat
+configuration/asset-loader.js
+configuration/bootstrap.js
+configuration/client-mode.json
+```
+
+Con offuscamento spento devono esistere:
+
+```txt
+assets/app.css
+assets/app.js
+configuration/asset-loader.js
+configuration/client-mode.json
+```
+
+## 12. `index.html`
+
+Il file `index.html` deve rimanere minimale.
+
+Esempio secure:
+
+```html
+
+
+```
+
+Esempio dev Vite:
+
+```html
+
+
+```
+
+Non mischiare i due flow:
+
+- produzione buildata: usa `configuration/bootstrap.js`;
+- sviluppo con `yarn start`: usa `/src/bootstrap.ts`.
+
+## 13. File dentro `/configuration`
+
+La cartella `configuration` deve contenere:
+
+```txt
+asset-loader.js
+bootstrap.js
+client-mode.json
+renderer-config.json
+ui-config.json
+adsense.json opzionale
+hotlooks.json se usi register hot looks
+UITexts.json se usi testi UI separati
+```
+
+Le news login non devono stare in `news.json` in produzione: arrivano dal database tramite:
+
+```json
+"login.news.url": "${api.url}/api/auth/news"
+```
+
+L'emulatore legge dalla tabella `ui_news`.
+
+Con `secureAssetsEnabled=true`, i file letti dal client passano da:
+
+```txt
+https://nitro.example.com:2096/nitro-sec/file?kind=config&file=...
+```
+
+Quindi l'emulatore li legge da:
+
+```ini
+nitro.secure.config.root=C:/inetpub/wwwroot/hotel/nitro/configuration
+```
+
+Se aggiungi nuovi file JSON/JS in `configuration` e vuoi proteggerli, devono essere richiesti passando dal secure endpoint o caricati tramite `bootstrap.js`.
diff --git a/docs/secure-runtime-modes.en.html b/docs/secure-runtime-modes.en.html
new file mode 100644
index 0000000..491608d
--- /dev/null
+++ b/docs/secure-runtime-modes.en.html
@@ -0,0 +1,236 @@
+
+
+
+
+
+ Nitro Secure Runtime Modes
+
+
+
+
+
+
+ Nitro V3
+ Secure Runtime
+
+
Runtime configuration guide
+
+ This page gives you a cleaner, readable overview of runtime toggles, example files and the values that belong in config files
+ rather than hardcoded inside src.
+
+
+
+
+
+
+
+
+
Overview
+
+
+
Dist Obfuscation
+
Chooses whether the client loads app.js/app.css or the obfuscated .dat versions.
+
+
+
Secure Assets
+
Controls whether renderer-config, ui-config and gamedata go through /nitro-sec/file.
+
+
+
Secure API
+
Enables or disables runtime encryption for /api/* requests.
+
+
+
+
+
+
Files to use
+
+
+
+
+
File
+
Purpose
+
Note
+
+
+
+
+
public/configuration/client-mode.example
+
Template for runtime toggles
+
Copy it into a real configuration/client-mode.json in deployment; that real file stays ignored by Git
+
+
+
public/configuration/renderer-config.example
+
Clean renderer config template
+
Does not touch your local configuration/renderer-config.json
+
+
+
public/configuration/ui-config.example
+
UI config reference template
+
Use it as the source of truth for UI URLs and widgets
+
+
+
Latest_Compiled_Version/config.ini.example
+
Backend secure flags
+
Defines the emulator-side runtime settings
+
+
+
+
+
+
+
+
client-mode.example
+
This is the main runtime switchboard. You can enable or disable behavior without editing client source code.
Secure assets, secure API and dist obfuscation all enabled.
+
+
+
Only .dat
+
Uses obfuscated assets but leaves config/API in plain mode.
+
+
+
Everything plain
+
Complete fallback mode for local testing or debugging.
+
+
+
+
+
+
Final checklist
+
+
You created real files from client-mode.example, renderer-config.example and ui-config.example
+
Public URLs live in config files, not in React components
+
Both plain files and .dat files are deployed
+
Your server exposes a proper MIME type for .dat
+
You set nitro.secure.master_key on the emulator side
+
+
+
+
+
+
+
+
+
diff --git a/docs/secure-runtime-modes.en.md b/docs/secure-runtime-modes.en.md
new file mode 100644
index 0000000..3bac47f
--- /dev/null
+++ b/docs/secure-runtime-modes.en.md
@@ -0,0 +1,309 @@
+# Secure runtime modes
+
+This document summarizes all values you may need to configure for:
+
+- `dist` bundle obfuscation (`app.js` / `app.css` → `.dat`)
+- secure runtime assets (`configuration/renderer-config.json`, `configuration/ui-config.json`, `gamedata`)
+- secure runtime API (`/api/*`)
+- plain fallbacks when you want to disable the secure layer without removing the code
+
+## 1. `Nitro-V3/public/configuration/client-mode.json`
+
+This file controls everything at runtime.
+
+```json
+{
+ "distObfuscationEnabled": true,
+ "secureAssetsEnabled": true,
+ "secureApiEnabled": true,
+ "apiBaseUrl": "https://nitro.example.com:2096",
+ "plainConfigBaseUrl": "https://hotel.example.com/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+### Fields
+
+- `distObfuscationEnabled`
+ - `true`: `asset-loader.js` loads `app.css.dat` and `app.js.dat`
+ - `false`: it loads plain `assets/app.css` and `assets/app.js`
+
+- `secureAssetsEnabled`
+ - `true`: `bootstrap.ts` and `secure-assets.ts` use `/nitro-sec/file`
+ - `false`: `configuration/renderer-config.json`, `configuration/ui-config.json`, and gamedata are loaded in plain mode
+
+- `secureApiEnabled`
+ - `true`: the `fetch` wrapper encrypts `/api/*` requests
+ - `false`: `/api/*` requests stay plain
+
+- `apiBaseUrl`
+ - Nitro emulator / API base URL
+ - example: `https://nitro.example.com:2096`
+ - it is best to always set this explicitly, so you do not depend on the hardcoded fallback
+
+- `plainConfigBaseUrl`
+ - base URL for plain config files
+ - usually: `https://hotel.example.com/configuration/`
+
+- `plainGamedataBaseUrl`
+ - base URL for plain gamedata files
+ - usually: `https://hotel.example.com/client/nitro/gamedata/`
+
+## 2. `Nitro-V3/src/bootstrap.ts`
+
+`bootstrap.ts`:
+
+- installs the secure fetch wrapper
+- reads `window.__nitroClientMode`
+- builds `NitroConfig['config.urls']`
+
+### Current behavior
+
+- if `secureAssetsEnabled=true`
+ - it uses `secureUrl('config', 'renderer-config.json', true)`
+ - it uses `secureUrl('config', 'ui-config.json', true)`
+
+- if `secureAssetsEnabled=false`
+ - it uses plain files with cache busting (`?v=...`)
+
+### Important note
+
+The current fallback is:
+
+```ts
+(window as any).NitroSecureApiUrl = clientMode.apiBaseUrl || 'https://nitro.example.com:2096/';
+```
+
+So in production it is better to always set `apiBaseUrl` inside `configuration/client-mode.json`.
+
+## 3. `Nitro-V3/src/secure-assets.ts`
+
+This file contains the runtime logic for:
+
+- ECDH bootstrap
+- asset decrypt/encrypt
+- secure `/api/*`
+- plain fallback when the toggles are disabled
+
+### In practice
+
+- it reads flags from `window.__nitroClientMode`
+- if `secureAssetsEnabled=false`
+ - it automatically rewrites `/nitro-sec/file?...` into plain URLs
+- if `secureApiEnabled=false`
+ - it does not encrypt `/api/*`
+
+Normally you should not need to touch it unless you want to change the secure protocol itself.
+
+## 4. `Nitro-V3/public/configuration/renderer-config.json`
+
+This file still defines the paths used by the renderer.
+
+### Things to check
+
+- `api.url`
+- `socket.url`
+- `gamedata.url`
+- `external.texts.url`
+- `external.texts.translation.url`
+- `furnidata.url`
+- `furnidata.translation.url`
+
+### With secure assets enabled
+
+You can use:
+
+```json
+"gamedata.url": "https://nitro.example.com:2096/nitro-sec/file?kind=gamedata&file="
+```
+
+and the equivalent secure URLs for the other gamedata resources.
+
+### With secure assets disabled
+
+You can use plain classic paths, for example:
+
+```json
+"gamedata.url": "https://hotel.example.com/client/nitro/gamedata"
+```
+
+or you can keep the renderer config as-is and let `secure-assets.ts` handle the fallback conversion.
+
+## 5. `Nitro-V3/public/configuration/ui-config.json`
+
+There is no secure logic here, but it is one of the files loaded through `config.urls`.
+
+If `secureAssetsEnabled=true`, it is served from `/nitro-sec/file`.
+If `secureAssetsEnabled=false`, it is loaded from the static file with `?v=...`.
+
+So you only need to maintain the content itself correctly.
+
+## 6. `Nitro-V3/scripts/write-asset-loader.mjs`
+
+This script generates `public/configuration/asset-loader.js`.
+
+### What it does now
+
+- renders the initial shell
+- reads `configuration/client-mode.json`
+- decides whether to load:
+ - `app.css.dat` / `app.js.dat`
+ - or `assets/app.css` / `assets/app.js`
+
+### Important
+
+If you modify this script, the updated loader is regenerated on the next:
+
+```bash
+yarn build
+```
+
+because `package.json` already contains:
+
+```json
+"prebuild": "node scripts/write-asset-loader.mjs"
+```
+
+## 7. `Nitro-V3/scripts/minify-dist.mjs`
+
+This script now:
+
+- generates the `.dat` files
+- keeps the original `app.css` and `app.js` files too
+
+This is required, otherwise `distObfuscationEnabled=false` would not have a working fallback.
+
+## 8. `Arcturus-Morningstar-Extended/Latest_Compiled_Version/config.ini.example`
+
+The current backend flags are:
+
+```ini
+nitro.secure.assets.enabled=true
+nitro.secure.api.enabled=true
+nitro.secure.config.root=
+nitro.secure.gamedata.root=
+nitro.secure.master_key=change-me-to-a-long-random-secret
+```
+
+### Meaning
+
+- `nitro.secure.assets.enabled`
+ - enables `/nitro-sec/bootstrap` and `/nitro-sec/file`
+
+- `nitro.secure.api.enabled`
+ - enables the secure layer for `/api/*`
+
+- `nitro.secure.config.root`
+ - folder used to read `configuration/renderer-config.json` and `configuration/ui-config.json`
+
+- `nitro.secure.gamedata.root`
+ - folder used to read live gamedata
+
+- `nitro.secure.master_key`
+ - persistent server-side secret
+ - especially important when running behind Cloudflare / multiple backend requests
+
+## 9. Example setups
+
+### Everything enabled
+
+`configuration/client-mode.json`
+
+```json
+{
+ "distObfuscationEnabled": true,
+ "secureAssetsEnabled": true,
+ "secureApiEnabled": true,
+ "apiBaseUrl": "https://nitro.example.com:2096",
+ "plainConfigBaseUrl": "https://hotel.example.com/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+`config.ini`
+
+```ini
+nitro.secure.assets.enabled=true
+nitro.secure.api.enabled=true
+nitro.secure.config.root=C:/inetpub/wwwroot/paxxo/nitro
+nitro.secure.gamedata.root=C:/inetpub/wwwroot/paxxo/nitro/client/nitro/gamedata
+nitro.secure.master_key=a-long-random-secret
+```
+
+### `.dat` only, no secure assets/API
+
+`configuration/client-mode.json`
+
+```json
+{
+ "distObfuscationEnabled": true,
+ "secureAssetsEnabled": false,
+ "secureApiEnabled": false,
+ "apiBaseUrl": "https://nitro.example.com:2096",
+ "plainConfigBaseUrl": "https://hotel.example.com/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+`config.ini`
+
+```ini
+nitro.secure.assets.enabled=false
+nitro.secure.api.enabled=false
+```
+
+### Everything plain
+
+`configuration/client-mode.json`
+
+```json
+{
+ "distObfuscationEnabled": false,
+ "secureAssetsEnabled": false,
+ "secureApiEnabled": false,
+ "apiBaseUrl": "https://nitro.example.com:2096",
+ "plainConfigBaseUrl": "https://hotel.example.com/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+## 10. When rebuild is required
+
+### No rebuild required
+
+For changes to:
+
+- `configuration/client-mode.json`
+- `configuration/renderer-config.json`
+- `configuration/ui-config.json`
+- live gamedata
+- `config.ini`
+
+### Rebuild required
+
+For changes to:
+
+- `src/bootstrap.ts`
+- `src/secure-assets.ts`
+- `scripts/write-asset-loader.mjs`
+- `scripts/minify-dist.mjs`
+
+## 11. Deployment note
+
+To make the toggles work properly:
+
+- always deploy both plain files and `.dat` files
+- make sure IIS / your host serves the `.dat` MIME type
+- if you disable secure mode on the client, disable it on the backend too for consistency
+
+## 12. Quick checklist
+
+- `configuration/client-mode.json` configured
+- `apiBaseUrl` correct
+- `nitro.secure.master_key` set
+- `nitro.secure.config.root` correct
+- `nitro.secure.gamedata.root` correct
+- both `.dat` and plain files deployed
+- `.dat` MIME type configured on the web server
+
+
diff --git a/docs/secure-runtime-modes.html b/docs/secure-runtime-modes.html
new file mode 100644
index 0000000..d54c635
--- /dev/null
+++ b/docs/secure-runtime-modes.html
@@ -0,0 +1,236 @@
+
+
+
+
+
+ Nitro Secure Runtime Modes
+
+
+
+
+
+
+ Nitro V3
+ Secure Runtime
+
+
Documentazione configurazione runtime
+
+ Questa pagina riassume in modo ordinato come configurare i toggle runtime, i file example e i parametri lato client / emulatore
+ senza sporcare i componenti in src.
+
+
+
+
+
+
+
+
+
Overview
+
+
+
Dist Obfuscation
+
Sceglie se caricare app.js/app.css oppure .dat.
+
+
+
Secure Assets
+
Controlla se renderer-config, ui-config e gamedata passano da /nitro-sec/file.
+
+
+
Secure API
+
Attiva o disattiva la cifratura runtime automatica su /api/*.
+
+
+
+
+
+
File da usare
+
+
+
+
+
File
+
Scopo
+
Nota
+
+
+
+
+
public/configuration/client-mode.example
+
Template per i toggle runtime
+
Da copiare in configuration/client-mode.json nel deploy reale, che resta ignorato da Git
+
+
+
public/configuration/renderer-config.example
+
Template sicuro del renderer config
+
Non tocca il tuo configuration/renderer-config.json locale
+
+
+
public/configuration/ui-config.example
+
Template UI config
+
Da mantenere come riferimento pulito
+
+
+
Latest_Compiled_Version/config.ini.example
+
Flag backend secure
+
Specifica la parte lato emulatore
+
+
+
+
+
+
+
+
client-mode.example
+
È il punto centrale per attivare o disattivare il comportamento runtime senza dover modificare il codice.
Secure assets, secure API e dist obfuscation tutti attivi.
+
+
+
Solo .dat
+
Usi i .dat, ma lasci config/API in plain.
+
+
+
Tutto plain
+
Modalità fallback completa per debug o test locali.
+
+
+
+
+
+
Checklist finale
+
+
Hai creato i file reali partendo da client-mode.example, renderer-config.example e ui-config.example
+
Gli URL pubblici stanno nei file config, non nei componenti React
+
Hai deployato sia i file plain sia i .dat
+
Il server espone correttamente il MIME type per .dat
+
Hai impostato nitro.secure.master_key lato emulatore
+
+
+
+
+
+
+
+
+
diff --git a/docs/secure-runtime-modes.md b/docs/secure-runtime-modes.md
new file mode 100644
index 0000000..4a9d311
--- /dev/null
+++ b/docs/secure-runtime-modes.md
@@ -0,0 +1,309 @@
+# Secure runtime modes
+
+Questa doc riassume tutti i dati da impostare per:
+
+- offuscamento bundle `dist` (`app.js` / `app.css` → `.dat`)
+- secure assets runtime (`configuration/renderer-config.json`, `configuration/ui-config.json`, `gamedata`)
+- secure API runtime (`/api/*`)
+- fallback plain quando vuoi spegnere tutto senza togliere il codice
+
+## 1. `Nitro-V3/public/configuration/client-mode.json`
+
+Questo file controlla tutto a runtime.
+
+```json
+{
+ "distObfuscationEnabled": true,
+ "secureAssetsEnabled": true,
+ "secureApiEnabled": true,
+ "apiBaseUrl": "https://nitro.example.com:2096",
+ "plainConfigBaseUrl": "https://hotel.example.com/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+### Campi
+
+- `distObfuscationEnabled`
+ - `true`: `asset-loader.js` carica `app.css.dat` e `app.js.dat`
+ - `false`: carica i file normali `assets/app.css` e `assets/app.js`
+
+- `secureAssetsEnabled`
+ - `true`: `bootstrap.ts` e `secure-assets.ts` usano `/nitro-sec/file`
+ - `false`: `configuration/renderer-config.json`, `configuration/ui-config.json` e gamedata vengono letti in plain
+
+- `secureApiEnabled`
+ - `true`: il wrapper `fetch` cifra le chiamate `/api/*`
+ - `false`: le chiamate `/api/*` restano normali
+
+- `apiBaseUrl`
+ - base URL dell’emulatore / API Nitro
+ - esempio: `https://nitro.example.com:2096`
+ - meglio valorizzarlo sempre, così non dipendi dal fallback hardcoded
+
+- `plainConfigBaseUrl`
+ - base URL dei file config plain
+ - normalmente: `https://hotel.example.com/configuration/`
+
+- `plainGamedataBaseUrl`
+ - base URL del gamedata plain
+ - normalmente: `https://hotel.example.com/client/nitro/gamedata/`
+
+## 2. `Nitro-V3/src/bootstrap.ts`
+
+`bootstrap.ts`:
+
+- installa il secure fetch wrapper
+- legge `window.__nitroClientMode`
+- costruisce `NitroConfig['config.urls']`
+
+### Comportamento attuale
+
+- se `secureAssetsEnabled=true`
+ - usa `secureUrl('config', 'renderer-config.json', true)`
+ - usa `secureUrl('config', 'ui-config.json', true)`
+
+- se `secureAssetsEnabled=false`
+ - usa i file plain con cache bust (`?v=...`)
+
+### Nota importante
+
+Il fallback attuale è:
+
+```ts
+(window as any).NitroSecureApiUrl = clientMode.apiBaseUrl || 'https://nitro.example.com:2096/';
+```
+
+Quindi in produzione conviene sempre valorizzare `apiBaseUrl` dentro `configuration/client-mode.json`.
+
+## 3. `Nitro-V3/src/secure-assets.ts`
+
+Qui vive tutta la logica runtime:
+
+- bootstrap ECDH
+- decrypt/encrypt assets
+- secure `/api/*`
+- fallback plain quando i toggle sono spenti
+
+### In pratica
+
+- legge i flag da `window.__nitroClientMode`
+- se `secureAssetsEnabled=false`
+ - converte automaticamente `/nitro-sec/file?...` in URL plain
+- se `secureApiEnabled=false`
+ - non cifra `/api/*`
+
+Normalmente non serve toccarlo, a meno che tu non voglia cambiare il protocollo secure.
+
+## 4. `Nitro-V3/public/configuration/renderer-config.json`
+
+Questo file continua a definire i path usati dal renderer.
+
+### Da controllare
+
+- `api.url`
+- `socket.url`
+- `gamedata.url`
+- `external.texts.url`
+- `external.texts.translation.url`
+- `furnidata.url`
+- `furnidata.translation.url`
+
+### Con secure assets attivo
+
+Puoi usare:
+
+```json
+"gamedata.url": "https://nitro.example.com:2096/nitro-sec/file?kind=gamedata&file="
+```
+
+e gli altri URL secure equivalenti.
+
+### Con secure assets disattivo
+
+Conviene usare i path plain classici, per esempio:
+
+```json
+"gamedata.url": "https://hotel.example.com/client/nitro/gamedata"
+```
+
+oppure lasciare il renderer configurato com’è e demandare il fallback a `secure-assets.ts`.
+
+## 5. `Nitro-V3/public/configuration/ui-config.json`
+
+Qui non c’è logica secure, ma è uno dei file caricati da `config.urls`.
+
+Se `secureAssetsEnabled=true`, arriva da `/nitro-sec/file`.
+Se `secureAssetsEnabled=false`, arriva dal file statico con `?v=...`.
+
+Quindi basta mantenerlo corretto come contenuto, non serve altro.
+
+## 6. `Nitro-V3/scripts/write-asset-loader.mjs`
+
+Questo script genera `public/configuration/asset-loader.js`.
+
+### Cosa fa ora
+
+- mostra la shell iniziale
+- legge `configuration/client-mode.json`
+- decide se caricare:
+ - `app.css.dat` / `app.js.dat`
+ - oppure `assets/app.css` / `assets/app.js`
+
+### Importante
+
+Se modifichi questo script, il loader aggiornato viene rigenerato al prossimo:
+
+```bash
+yarn build
+```
+
+perché in `package.json` c’è:
+
+```json
+"prebuild": "node scripts/write-asset-loader.mjs"
+```
+
+## 7. `Nitro-V3/scripts/minify-dist.mjs`
+
+Adesso questo script:
+
+- genera i `.dat`
+- lascia anche i file originali `app.css` e `app.js`
+
+Questa parte è fondamentale, altrimenti il toggle `distObfuscationEnabled=false` non avrebbe fallback.
+
+## 8. `Arcturus-Morningstar-Extended/Latest_Compiled_Version/config.ini.example`
+
+I flag backend attuali sono:
+
+```ini
+nitro.secure.assets.enabled=true
+nitro.secure.api.enabled=true
+nitro.secure.config.root=
+nitro.secure.gamedata.root=
+nitro.secure.master_key=change-me-to-a-long-random-secret
+```
+
+### Significato
+
+- `nitro.secure.assets.enabled`
+ - abilita `/nitro-sec/bootstrap` e `/nitro-sec/file`
+
+- `nitro.secure.api.enabled`
+ - abilita il layer secure per `/api/*`
+
+- `nitro.secure.config.root`
+ - cartella dove leggere `configuration/renderer-config.json` e `configuration/ui-config.json`
+
+- `nitro.secure.gamedata.root`
+ - cartella dove leggere il gamedata live
+
+- `nitro.secure.master_key`
+ - segreto persistente lato server
+ - necessario soprattutto con Cloudflare / richieste multiple
+
+## 9. Esempi di configurazione
+
+### Tutto attivo
+
+`configuration/client-mode.json`
+
+```json
+{
+ "distObfuscationEnabled": true,
+ "secureAssetsEnabled": true,
+ "secureApiEnabled": true,
+ "apiBaseUrl": "https://nitro.example.com:2096",
+ "plainConfigBaseUrl": "https://hotel.example.com/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+`config.ini`
+
+```ini
+nitro.secure.assets.enabled=true
+nitro.secure.api.enabled=true
+nitro.secure.config.root=C:/inetpub/wwwroot/paxxo/nitro
+nitro.secure.gamedata.root=C:/inetpub/wwwroot/paxxo/nitro/client/nitro/gamedata
+nitro.secure.master_key=una-chiave-lunga-random
+```
+
+### Solo `.dat`, senza secure assets/api
+
+`configuration/client-mode.json`
+
+```json
+{
+ "distObfuscationEnabled": true,
+ "secureAssetsEnabled": false,
+ "secureApiEnabled": false,
+ "apiBaseUrl": "https://nitro.example.com:2096",
+ "plainConfigBaseUrl": "https://hotel.example.com/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+`config.ini`
+
+```ini
+nitro.secure.assets.enabled=false
+nitro.secure.api.enabled=false
+```
+
+### Tutto plain
+
+`configuration/client-mode.json`
+
+```json
+{
+ "distObfuscationEnabled": false,
+ "secureAssetsEnabled": false,
+ "secureApiEnabled": false,
+ "apiBaseUrl": "https://nitro.example.com:2096",
+ "plainConfigBaseUrl": "https://hotel.example.com/configuration/",
+ "plainGamedataBaseUrl": "https://hotel.example.com/client/nitro/gamedata/"
+}
+```
+
+## 10. Quando serve rebuild
+
+### Non serve rebuild
+
+Per cambiare:
+
+- `configuration/client-mode.json`
+- `configuration/renderer-config.json`
+- `configuration/ui-config.json`
+- gamedata live
+- `config.ini`
+
+### Serve rebuild
+
+Per cambiare:
+
+- `src/bootstrap.ts`
+- `src/secure-assets.ts`
+- `scripts/write-asset-loader.mjs`
+- `scripts/minify-dist.mjs`
+
+## 11. Nota pratica deployment
+
+Per usare bene i toggle:
+
+- pubblica sempre sia i file plain sia i `.dat`
+- assicurati che IIS/host serva il MIME type per `.dat`
+- se spegni il secure mode nel client, spegnilo anche nel backend per coerenza
+
+## 12. Checklist veloce
+
+- `configuration/client-mode.json` configurato
+- `apiBaseUrl` corretto
+- `nitro.secure.master_key` valorizzata
+- `nitro.secure.config.root` corretto
+- `nitro.secure.gamedata.root` corretto
+- `.dat` e file plain entrambi deployati
+- MIME `.dat` presente sul web server
+
+
diff --git a/index.html b/index.html
index e735f16..1c4fa2e 100644
--- a/index.html
+++ b/index.html
@@ -1,35 +1 @@
-
-
-
- Nitro
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/localization/badge-texts-en.json b/localization/badge-texts-en.json
deleted file mode 100644
index a8ab19a..0000000
--- a/localization/badge-texts-en.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "notification.badge.received": "New Badge!"
-}
diff --git a/localization/badge-texts-it.json b/localization/badge-texts-it.json
deleted file mode 100644
index 10c1271..0000000
--- a/localization/badge-texts-it.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "notification.badge.received": "Nuovo Distintivo!"
-}
diff --git a/mockup/assets/README.md b/mockup/assets/README.md
deleted file mode 100644
index f902c1b..0000000
--- a/mockup/assets/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Mockup Assets
-
-Questa cartella e' pronta per immagini o sprite dedicate ai mockup HTML.
-
-Uso previsto:
-- copiare qui versioni statiche di asset che vuoi testare fuori dal progetto
-- collegarle da `mockup/index.html`
-- tenere separati i file di esperimento dagli asset reali di `src/assets`
-
-Percorso base:
-- `Nitro-V3/mockup/index.html`
-- `Nitro-V3/mockup/assets/`
diff --git a/mockup/index.html b/mockup/index.html
deleted file mode 100644
index 8a08573..0000000
--- a/mockup/index.html
+++ /dev/null
@@ -1,623 +0,0 @@
-
-
-
-
-
- Nitro V3 Mockup Lab
-
-
-
-
Nitro V3 Mockup Lab
-
Mockup HTML standalone dei componenti principali attuali. La resa è pensata per darti una base visiva da modificare rapidamente fuori dal progetto reale.
-
-
-
-
-
NitroCard
-
Base card attuale con header blu, tabs grigie e content chiaro.
-
-
-
-
-
-
Navigator
-
-
-
-
Hotel
-
Rooms
-
+
-
-
- Contenuto card attuale, usato come base da vari componenti.
-