exlab_wizard.ui.theme#

Theme registration for NiceGUI / Quasar.

Per Frontend Spec §2.1.1, this module is the single place that injects the canonical :root { ... } CSS block (DESIGN.md §07). Component CSS uses var(--color-*) / var(--sp-*) / var(--text-*) / var(--radius-*) / var(--shadow-*) references instead of inline literals.

The block is generated from exlab_wizard.ui.design so DESIGN.md and design.py cannot drift.

Functions

build_root_css()

Render the canonical ``:root { .

mdi_font_head_html()

Return the <link> that loads the vendored MDI webfont from /assets.

register_static_assets()

Mount the project's assets/ directory at /assets.

register_theme()

Register the design tokens with NiceGUI / Quasar at app start.

resolve_assets_dir()

Return the absolute path to the bundled assets/ directory.

exlab_wizard.ui.theme.build_root_css()[source]#

Render the canonical :root { ... } CSS block from design tokens.

The string is intentionally derived from constants in exlab_wizard.ui.design so a token change automatically lands in the generated CSS without per-call-site updates.

Return type:

str

exlab_wizard.ui.theme.mdi_font_head_html()[source]#

Return the <link> that loads the vendored MDI webfont from /assets.

Served by register_static_assets() (mounted before register_theme() in mount_ui) and bundled offline under assets/fonts/mdi/ so the frozen desktop app renders MDI glyphs with no network access. Quasar already understands mdi-* icon names once this stylesheet is present.

Return type:

str

exlab_wizard.ui.theme.register_static_assets()[source]#

Mount the project’s assets/ directory at /assets.

Idempotent: a module-level guard prevents double-mounting on import cycles. Returns the resolved assets directory.

Return type:

Path

exlab_wizard.ui.theme.register_theme()[source]#

Register the design tokens with NiceGUI / Quasar at app start.

Imports NiceGUI lazily so unit tests can exercise this module without NiceGUI’s import side effects (the package opens browser channels at import time in some configurations).

The :root block is injected with shared=True so it lands in the document head of every page rather than only the page being rendered at call time – this is invoked once at app setup (from mount_ui), before any client connects, so a per-client (shared=False) head injection would have nothing to attach to and the design tokens would never reach the browser.

Returns the CSS string that was registered (handy for tests and for the static-asset bundler).

Return type:

str

exlab_wizard.ui.theme.resolve_assets_dir()[source]#

Return the absolute path to the bundled assets/ directory.

Resolves both in source layout (<repo>/assets/) and in a PyInstaller-frozen layout (sys._MEIPASS/assets/).

Source-layout walk: this file lives at <repo>/src/exlab_wizard/ui/theme.py so the four .parent hops are ui -> exlab_wizard -> src -> <repo>.

Return type:

Path