I just made a change to the surface widget that makes theming really really easy should you want a custom widget theme.
<vexi xmlns:ui="vexi://ui" xmlns="vexi.widget">
<ui:box theme=".path.to.custom.theme" />
// your app starts here
vexi.ui.frame = thisbox;
If you omit the box declaring your theme, vexi.widget.surface will apply a default theme for you. Nice and simple and no hardcoding - and it even opens the door for individual themes per surface with some more clever updates to vexi.widget.surface and the core.
For the curious, the way vexi.widget.surface automatically handles the theming is rather straightforward. If the theme attribute is defined, it applies to as a trap to the namespace vexi.theme, if not it just applies a default theme to that namespace:
// no theme has been specified by the user
if (thisbox.theme == null)
theme = vexi..org.vexi.theme.win2k;
// set up the theme
vexi..vexi.theme ++= theme;
// apply the theme surface template
Fairly easy, eh? The downside is that you must apply vexi.widget.surface for theming to work but the reality is that few (if any) of the widgets will work without it being applied to the root boxes of your applications.