* fix(theme-color): emit media-scoped dark variant for iOS Safari (#7606)
The theme-color meta only had a single light value rendered server-side;
dark mode was applied purely by JS (skin_variants.ts) after page load.
iOS Safari colors the address bar at parse time and does not reliably
repaint when JS mutates the meta later, so dark-mode iPhone users kept a
white address bar above a dark toolbar (the green Chromium Playwright test
masked this because Chrome does honor the dynamic update).
Emit a prefers-color-scheme media-scoped pair server-side so the correct
color is chosen at first paint without JS:
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#485365" media="(prefers-color-scheme: dark)">
- Add SkinColors.darkToolbarColor() (reuses toolbarColorForTokens).
- Expose enableDarkMode via getPublicSettings so the templates can gate the
dark variant on it (no dark variant when dark mode can't be reached).
- Apply to both pad.html and timeslider.html.
- updateThemeColorMeta now updates every theme-color meta so a manual
#options-darkmode toggle still wins over the media scoping on
desktop/Android.
- Backend + frontend tests updated to assert the media-scoped pair and the
enableDarkMode-off case.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(theme-color): prevent the light-mode flash on dark-OS load (#7606)
The theme-color meta fix corrects the address-bar tint, but dark-OS users
still saw the whole page painted light before the JS bundle ran and applied
the dark skin classes in postAceInit — a visible flash on every browser,
not just the mobile address bar.
Add a tiny blocking inline script in <head>, before the stylesheet, that
applies the dark skin classes to <html> synchronously during parse when the
client is in dark mode (matchMedia + no localStorage white-mode override).
The condition mirrors pad.ts's auto-switch, which still runs on init to wire
up the #options-darkmode toggle and theme the editor iframes (those don't
exist yet at parse time). Gated on the same enableDarkMode + colibris check
as the dark theme-color variant. Applied to pad.html and timeslider.html.
Verified in Chromium: at domcontentloaded a dark-OS client's <html> already
carries super-dark-editor/dark-background/super-dark-toolbar (no flash), and
a light-OS client is unaffected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(changelog): note the dark-mode address-bar + flash fix (#7606)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(theme-color): guard pre-paint script on #skinvariantsbuilder; ignore updater state
Address PR review:
- Copilot: the inline pre-paint dark-mode script must skip the auto-dark
switch on the #skinvariantsbuilder hash, matching pad.ts — otherwise it
forces super-dark classes on a dark-OS client and fights the variants
builder UI. Added the guard to pad.html and timeslider.html and a backend
assertion so it can't regress.
- Qodo: ignore var/update-state.json (runtime updater cache) so the server
run that regenerates it can't dirty the tree or be committed accidentally.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Added plugin live view.
* Implemented PoC for managing plugins with live-plugin-manager
* Add migration for plugins installed in node_modules and load plugins on start
* Create installed_plugins.json even if no plugin is installed
* Reload plugins and hooks after all (un)installs are done
* Add installed_plugins.json to gitignore
* Only write plugins to json file in Dockerfile
* Install live-plugin-manager
* Also persist plugin version
* Do not call hooks during migration of plugins
* Fix install of plugins in Dockerfile
* Revert Dockerfile changes
* Fixed package-lock.json
---------
Co-authored-by: SamTV12345 <40429738+samtv12345@users.noreply.github.com>
Co-authored-by: Hossein M <marzban98@gmail.com>