I ended up writing my own layout system. There were enough changes I wanted to make to justify it. I'm still developing and testing, but here's what it looks like so far.
In Panorama each element name has to match a control. I got rid of that. If an element doesn't match a control it creates a normal blank panel. That way you don't have to create classes for everything, you can style via the element. They're also case insensitive now.
I made it so you can have inner text, and that'll be used for the content of the control if appropriate. This means you don't have to html encode special characters because they're not in an attribute, making things a bit more readable. This obviously doesn't account for localization right now - but I'm going to do something similar to what we do for Rust there.
If you look at the layout, you can see that it has "@text=" as one of the properties. This binds it to the value on the context object (which is by default the panel that applied the layout). So what this means is that if "InformationText" changes on that instance, it automatically updates that property.
You can also see that we have onclick/onmouseover etc functions. These are calling the c# function on the panel.