Harden the theme flag check and gate the .box scroll rule on :has()
Both from review findings on #6125.
The flag comparison only treated the exact string "false" as disabling, so an
external openboxes-config.properties setting the value as "FALSE", "False" or
with surrounding whitespace would silently leave the theme on. Since reading the
value as a string is the whole reason that branch exists, compare it trimmed and
case-insensitively instead.
The .box opt-out list is written entirely in :has() selectors. A selector list is
invalidated by any unsupported selector in it, so an engine without :has() drops
that rule wholesale and every .box gets overflow-x: auto -- including form
panels, whose Chosen and Select2 dropdowns would then be clipped. Wrapping the
rule that creates the overflow in @supports selector(:has(*)) means such an
engine keeps the pre-theme overflow behaviour rather than a broken hybrid.
This is the one deviation from the stylesheet as it stands in #6073; noted in
the file header.
Apply the unified design theme to legacy GSP pages
Takes openboxes-theme.css from PR #6073 by @christianallen and links it from
custom.gsp behind the same openboxes.layout.unified.enabled flag, without that
PR's layout-substitution machinery.
#6073 adds layouts/default.gsp (760 lines) plus UnifiedLayoutFinder, a bean
post-processor and a LayoutInterceptor so SiteMesh can resolve pages declaring
"custom" to the themed twin instead. But default.gsp differs from custom.gsp by
only nine lines, and the only one that carries the design is a single <link>.
A <g:if> in custom.gsp does the same job, so none of that machinery is needed.
The stylesheet is self-contained: every asset in it is an inline SVG data URI,
and it references none of #6073's new markup classes, so it needs no changes to
the 254 page GSPs. Its own :root block supersedes the older partial copy of the
design tokens in openboxes.css, since it loads later.
Default is on here rather than off, so the legacy pages match the React pages
out of the box; instances that want the original design set the flag to false.
The predicate treats the string "false" as false too, because external
openboxes-config.properties overrides arrive as strings and a plain truthiness
check would silently ignore them.
Scope is the desktop legacy pages only. #6073's mobile stylesheet, React-side
footer and dashboard changes, and its bundled bug fixes are not included here.