Actions & HUD
Import these components from @static-bloom/vue. Each example is a separate client:visible island with its own SbProvider; Vue setup covers the shared stylesheet and provider.
The tables list Static Bloom’s additions and overrides. Every component accepts class (HTMLAttributes['class'], unset), merged with the theme. Components wrapping Reka forward the remaining props and declared emits of the named primitive; components built from native elements do not acquire a Reka model or keyboard behavior.
Here, Intent means 'primary' | 'secondary' | 'neutral' | 'info' | 'success' | 'warning' | 'danger'. Boolean flags default to false unless stated otherwise; optional labels default to unset. Defaults below include theme defaults.
SbButton + SbButtonGroup
Section titled “SbButton + SbButtonGroup”SbButton renders Reka Primitive as a native button by default. SbButtonGroup is a labelled div with role="group", joining adjacent buttons without introducing roving focus.
<script setup lang="ts">import { ref } from 'vue'import { SbButton, SbButtonGroup, SbProvider } from '@static-bloom/vue'const accepted = ref(false)</script>
<template> <SbProvider> <div class="flex flex-wrap items-center gap-4"> <SbButton @click="accepted = !accepted">Accept job</SbButton> <SbButtonGroup label="Route actions"> <SbButton variant="outline">Preview</SbButton> <SbButton variant="outline" disabled>Archive</SbButton> </SbButtonGroup> <span role="status" class="text-sm text-fg-muted">{{ accepted ? 'Job accepted' : 'No active job' }}</span> </div> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbButtonGroup> <SbButton /> <SbButton /></SbButtonGroup>| Component / prop | Type | Default | Effect |
|---|---|---|---|
Button variant |
'solid' | 'soft' | 'outline' | 'ghost' | 'link' |
'solid' |
Surface treatment |
Button intent |
Intent | 'primary' |
Semantic color |
Button size |
'xs' | 'sm' | 'md' | 'lg' |
'md' |
Control height |
Button icon, block |
boolean |
false |
Square icon control / full width |
Button loading |
boolean |
false |
Disables, sets aria-busy, overlays a spinner while retaining the label |
Button disabled |
boolean |
false |
Native disabled state; aria-disabled for other elements |
Button as |
PrimitiveProps['as'] |
'button' |
Rendered element |
Button type |
'button' | 'submit' | 'reset' |
'button' |
Native button type |
Group orientation |
'horizontal' | 'vertical' |
'horizontal' |
Attached-button direction |
Group label |
string |
unset | Accessible group name |
Tab reaches each enabled button; Enter and Space activate native buttons. Icon-only buttons need an accessible name. With as="a" or as-child, preserve the child’s semantics and handle disabled activation in consumer code; aria-disabled alone is not native disabling.
SbToggle + SbToggleGroup
Section titled “SbToggle + SbToggleGroup”SbToggle wraps Reka Toggle for a pressed state. SbToggleGroup wraps ToggleGroupRoot; its items inherit the group’s style and size.
<script setup lang="ts">import { ref } from 'vue'import { SbProvider, SbToggle, SbToggleGroup, SbToggleGroupItem } from '@static-bloom/vue'const muted = ref(false)const view = ref('map')</script>
<template> <SbProvider> <div class="flex flex-wrap gap-4"> <SbToggle v-model="muted" aria-label="Mute radio">Mute radio</SbToggle> <SbToggleGroup v-model="view" type="single" variant="outline" aria-label="Route view"> <SbToggleGroupItem value="map">Map</SbToggleGroupItem> <SbToggleGroupItem value="list">List</SbToggleGroupItem> </SbToggleGroup> </div> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbToggle /><SbToggleGroup> <SbToggleGroupItem value="map" /></SbToggleGroup>| Component / prop | Type | Default | Effect |
|---|---|---|---|
Toggle / Group variant |
'default' | 'outline' |
'default' |
Toggle surface |
Toggle / Group size |
'sm' | 'md' | 'lg' |
'md' |
Item dimensions |
Toggle modelValue |
boolean | null |
unset | v-model; emits update:modelValue |
Group type |
'single' | 'multiple' |
inferred from value, otherwise 'single' |
Selection mode; set explicitly for an initially empty group |
Group modelValue |
ToggleGroupRootProps['modelValue'] |
uncontrolled; initialized from defaultValue |
Selected item value(s); emits update:modelValue |
Space toggles aria-pressed; disabled items do not activate. Group arrow keys move roving focus between items. Give the group an accessible name and each item visible text or aria-label.
SbToolbar
Section titled “SbToolbar”SbToolbar wraps Reka ToolbarRoot to group related commands into one tab stop. Use its own button, link and toggle parts so arrow navigation can find them.
<script setup lang="ts">import { SbProvider, SbToolbar, SbToolbarButton, SbToolbarLink, SbToolbarSeparator, SbToolbarToggleGroup, SbToolbarToggleItem,} from '@static-bloom/vue'</script>
<template> <SbProvider> <SbToolbar aria-label="Dispatch tools" class="flex-wrap"> <SbToolbarToggleGroup type="single" default-value="local" aria-label="Channel"> <SbToolbarToggleItem value="local">Local</SbToolbarToggleItem> <SbToolbarToggleItem value="crew">Crew</SbToolbarToggleItem> </SbToolbarToggleGroup> <SbToolbarSeparator /> <SbToolbarButton>Save</SbToolbarButton> <SbToolbarLink href="/vue/">Guide</SbToolbarLink> </SbToolbar> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbToolbar> <SbToolbarToggleGroup> <SbToolbarToggleItem value="local" /> </SbToolbarToggleGroup> <SbToolbarSeparator /> <SbToolbarButton /> <SbToolbarLink /></SbToolbar>| Component / prop | Type | Default | Effect |
|---|---|---|---|
Toolbar class |
HTMLAttributes['class'] |
unset | Merged root styling; other props are ToolbarRootProps |
ToolbarButton variant, intent, size |
Button variants above | 'ghost', 'neutral', 'sm' |
Command appearance |
ToolbarButton icon |
boolean |
false |
Square command |
ToolbarToggleGroup variant, size |
Toggle variants above | 'default', 'sm' |
Inherited toggle appearance |
The root exposes role="toolbar". Tab enters its roving focus group; arrows move between commands, and Enter activates a button. Separators orient across the toolbar’s flow. Set aria-label on the toolbar.
SbBadge
Section titled “SbBadge”SbBadge uses Reka Primitive as a span for a status or category. It has no interaction or live announcement by itself.
<script setup lang="ts">import { SbBadge, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider> <div class="flex flex-wrap gap-3"> <SbBadge intent="success" dot>Available</SbBadge> <SbBadge intent="warning" variant="outline">Awaiting crew</SbBadge> <SbBadge accent="orchid">Courier</SbBadge> </div> </SbProvider></template>| Prop | Type | Default | Effect |
|---|---|---|---|
variant |
'solid' | 'soft' | 'outline' |
'soft' |
Surface |
intent |
Intent | 'primary' |
Semantic tone |
accent |
'plasma' | 'laser' | 'ember' | 'sodium' | 'halogen' | 'acid' | 'coolant' | 'frost' | 'ion' | 'ultraviolet' | 'orchid' | 'chrome' |
unset | Overrides intent |
size |
'sm' | 'md' | 'lg' |
'md' |
Badge size |
dot |
boolean |
false |
Leading color dot |
as |
PrimitiveProps['as'] |
'span' |
Rendered element |
Keep the status in text; the dot alone does not convey its meaning to a screen reader.
SbKbd + SbKeyHint
Section titled “SbKbd + SbKeyHint”SbKbd is a native kbd. SbKeyHint composes keycaps and an action label in a span; neither registers a shortcut or wraps an interactive Reka primitive.
<script setup lang="ts">import { SbKbd, SbKeyHint, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider> <div class="flex flex-wrap items-center gap-4"> <span class="text-sm text-fg-muted">Confirm with <SbKbd>Enter</SbKbd></span> <SbKeyHint :keys="['Ctrl', 'K']" label="Search" /> </div> </SbProvider></template>| Component / prop | Type | Default | Effect |
|---|---|---|---|
Both size |
'sm' | 'md' | 'lg' |
'md' |
Keycap dimensions |
Both highlight |
boolean |
false |
Active key treatment |
KeyHint keys |
readonly string[] |
required | Key combination |
KeyHint label |
string |
unset | Action text; default slot can replace it |
KeyHint disabled |
boolean |
false |
Muted state and aria-disabled |
Bind the actual shortcut in the app. In OPEN//77, Escape may be consumed by the platform unless keep-input is enabled; do not promise an Escape action without checking that page’s input configuration.
SbCard
Section titled “SbCard”SbCard and its parts use Reka Primitive for a composed content surface. The default card is a div, not a button.
Harbor delivery
Courier contract
<script setup lang="ts">import { SbButton, SbCard, SbCardHeader, SbCardTitle, SbCardDescription, SbCardContent, SbCardFooter, SbProvider,} from '@static-bloom/vue'</script>
<template> <SbProvider> <SbCard class="w-full max-w-sm"> <SbCardHeader> <SbCardTitle as="p">Harbor delivery</SbCardTitle> <SbCardDescription>Courier contract</SbCardDescription> </SbCardHeader> <SbCardContent>Collect the sealed parcel at the south depot.</SbCardContent> <SbCardFooter><SbButton variant="soft">View route</SbButton></SbCardFooter> </SbCard> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbCard> <SbCardHeader> <SbCardTitle /> <SbCardDescription /> </SbCardHeader> <SbCardContent /> <SbCardFooter /></SbCard>| Prop | Type | Default | Effect |
|---|---|---|---|
variant |
'default' | 'flat' | 'glass' | 'interactive' |
'default' |
Surface and interaction styling |
selected |
boolean |
false |
Selected appearance and data-selected |
as |
PrimitiveProps['as'] |
'div' |
Root element |
SbCardTitle defaults to h3; choose as to fit the document outline. variant="interactive" only changes styling: use a real button or link when the whole card is actionable, and avoid nested interactive controls in that case.
SbSeparator
Section titled “SbSeparator”SbSeparator wraps Reka Separator for horizontal or vertical division, optionally with a centered label.
<script setup lang="ts">import { SbProvider, SbSeparator } from '@static-bloom/vue'</script>
<template> <SbProvider> <div class="w-full text-sm text-fg-muted"> Dispatch channel <SbSeparator label="Crew channel" /> Private crew messages </div> </SbProvider></template>| Prop | Type | Default | Effect |
|---|---|---|---|
label |
string |
unset | Text in a horizontal separator |
neon |
boolean |
false |
Gradient tube treatment |
Reka’s remaining separator props pass through. It is decorative by default; set :decorative="false" when the separator needs a semantic role. A vertical separator needs a parent with height.
SbAvatar + SbAvatarGroup
Section titled “SbAvatar + SbAvatarGroup”SbAvatar wraps Reka AvatarRoot, with image and fallback parts. SbAvatarGroup is a labelled native group that caps visible children and adds a +N overflow avatar.
<script setup lang="ts">import { SbAvatar, SbAvatarFallback, SbAvatarGroup, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider> <SbAvatarGroup :max="2" label="Delivery crew"> <SbAvatar status="online" ><SbAvatarFallback>AL<span class="sr-only">Alex</span></SbAvatarFallback></SbAvatar > <SbAvatar ><SbAvatarFallback>RN<span class="sr-only">Ren</span></SbAvatarFallback></SbAvatar > <SbAvatar ><SbAvatarFallback>SM<span class="sr-only">Sam</span></SbAvatarFallback></SbAvatar > </SbAvatarGroup> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbAvatarGroup> <SbAvatar> <SbAvatarImage /> <SbAvatarFallback /> </SbAvatar></SbAvatarGroup>| Component / prop | Type | Default | Effect |
|---|---|---|---|
Avatar / Group size |
'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' |
'md' |
Group size is inherited unless overridden |
Avatar square |
boolean |
false |
Rounded square |
Avatar status |
'online' | 'away' | 'busy' | 'offline' |
unset | Status dot and screen-reader status text |
Group max |
number |
unset | Maximum avatars before overflow count |
Group label |
string |
unset | Accessible group name |
The fallback displays when the image cannot load. Supply meaningful alt to SbAvatarImage (its default is empty) and accessible fallback text. For offline game pages, bundle images locally; a group count does not expose hidden members’ names.
SbAspectRatio
Section titled “SbAspectRatio”SbAspectRatio wraps Reka AspectRatio to reserve media space. It adds only the shared class prop; ratio and the remaining props pass through to Reka.
<script setup lang="ts">import { SbAspectRatio, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider> <div class="w-full max-w-sm"> <SbAspectRatio :ratio="16 / 9"> <div class="grid size-full place-items-center bg-panel text-sm text-fg-muted"> Route preview · 16:9 </div> </SbAspectRatio> </div> </SbProvider></template>| Prop | Type | Default | Effect |
|---|---|---|---|
class |
HTMLAttributes['class'] |
unset | Merged surface styling |
Set ratio explicitly, as the example does. The wrapper does not replace an image’s alt text and adds no keyboard stop.
SbSkeleton + SbSpinner
Section titled “SbSkeleton + SbSpinner”SbSkeleton uses Reka Primitive for an aria-hidden placeholder. SbSpinner uses a native span with a status label, or a decorative span when another control owns the announcement.
<script setup lang="ts">import { SbProvider, SbSkeleton, SbSpinner } from '@static-bloom/vue'</script>
<template> <SbProvider> <div class="flex w-full max-w-sm items-center gap-4"> <SbSkeleton shape="circle" /> <div class="min-w-0 flex-1 space-y-2"> <SbSkeleton shape="text" /><SbSkeleton shape="text" class="w-2/3" /> </div> <SbSpinner label="Loading crew roster" /> </div> </SbProvider></template>| Component / prop | Type | Default | Effect |
|---|---|---|---|
Skeleton shape |
'block' | 'text' | 'circle' | 'rect' |
'block' |
Placeholder shape |
Skeleton static |
boolean |
false |
Disables shimmer |
Skeleton as |
PrimitiveProps['as'] |
'div' |
Placeholder element |
Spinner size |
'xs' | 'sm' | 'md' | 'lg' | 'xl' |
'md' |
Spinner dimensions |
Spinner intent |
Intent or 'current' |
'current' |
Spinner color |
Spinner label |
string |
'Loading' |
Screen-reader status text |
Spinner decorative |
boolean |
false |
Removes status role and hides from assistive technology |
Neither takes focus. Keep placeholders close to the eventual content dimensions; name the operation on a non-decorative spinner rather than adding multiple identical status announcements.
SbAlert
Section titled “SbAlert”SbAlert is a native feedback surface, with title and description parts. It selects role="alert" for warning/danger and role="status" for other intents; it does not wrap a Reka alert dialog.
Dispatch connected
New contracts will appear in the job board.
<script setup lang="ts">import { ref } from 'vue'import { SbAlert, SbAlertTitle, SbAlertDescription, SbButton, SbProvider } from '@static-bloom/vue'const visible = ref(true)</script>
<template> <SbProvider> <SbAlert v-if="visible" dismissible class="w-full" @dismiss="visible = false"> <SbAlertTitle>Dispatch connected</SbAlertTitle> <SbAlertDescription>New contracts will appear in the job board.</SbAlertDescription> </SbAlert> <SbButton v-else variant="outline" @click="visible = true">Restore notice</SbButton> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbAlert> <SbAlertTitle /> <SbAlertDescription /></SbAlert>| Prop | Type | Default | Effect |
|---|---|---|---|
variant |
'soft' | 'solid' | 'outline' |
'soft' |
Surface |
intent |
Intent | 'info' |
Tone, icon and announcement role |
hideIcon |
boolean |
false |
Hides the default leading icon |
dismissible |
boolean |
false |
Adds a native dismiss button |
dismissLabel |
string |
'Dismiss' |
Dismiss button name |
The dismiss button emits dismiss without removing the alert; the consumer controls visibility. Tab and Enter/Space operate that button. An alert does not trap focus or replace a confirmation dialog.
SbLink
Section titled “SbLink”SbLink uses Reka Primitive as an anchor. External links add an arrow, a screen-reader hint and safe new-tab attributes.
<script setup lang="ts">import { SbLink, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider> <div class="flex flex-wrap gap-4"> <SbLink href="/vue/">Vue setup</SbLink> <SbLink href="/open77/in-game/" variant="muted">In-game guide</SbLink> <SbLink disabled>Archived route</SbLink> </div> </SbProvider></template>| Prop | Type | Default | Effect |
|---|---|---|---|
variant |
'default' | 'muted' | 'subtle' |
'default' |
Link appearance |
href |
string |
unset | Destination |
external |
boolean |
false |
_blank plus noopener noreferrer |
externalLabel |
string |
'(opens in a new tab)' |
Hidden external-link hint |
disabled |
boolean |
false |
Removes href, adds aria-disabled |
as |
PrimitiveProps['as'] |
'a' |
Rendered element |
Native links activate with Enter. In-game pages should use app navigation or an explicit bridge action when a browser tab is not meaningful. With as-child, the child owns its content and external hint.
SbProgress
Section titled “SbProgress”SbProgress wraps Reka ProgressRoot and supplies ProgressIndicator. Pass null or omit modelValue for an indeterminate operation.
<script setup lang="ts">import { SbProgress, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider> <div class="w-full max-w-sm space-y-4"> <SbProgress :model-value="64" label="Download progress" /> <SbProgress :model-value="null" label="Connecting to dispatch" /> </div> </SbProvider></template>| Prop | Type | Default | Effect |
|---|---|---|---|
intent |
Intent | 'primary' |
Indicator tone |
size |
'xs' | 'sm' | 'md' | 'lg' |
'md' |
Track height |
glow |
boolean |
false |
Track bloom |
label |
string |
unset | aria-label |
The remaining ProgressRootProps and emits pass through. The indicator uses max or 100 for its visual scale. Determinate progress exposes aria-valuenow; indeterminate progress omits it. This display takes no keyboard input.
SbRating
Section titled “SbRating”SbRating composes Reka RatingRoot, RatingItem and RatingItemIndicator. Readonly mode instead renders a single labelled image role and allows fractional display values.
<script setup lang="ts">import { ref } from 'vue'import { SbProvider, SbRating } from '@static-bloom/vue'const rating = ref(3)</script>
<template> <SbProvider> <div class="flex flex-wrap items-center gap-4"> <SbRating v-model="rating" label="Rate this route" /> <span class="text-sm text-fg-muted">{{ rating }} of 5</span> </div> </SbProvider></template>| Prop | Type | Default | Effect |
|---|---|---|---|
size |
'sm' | 'md' | 'lg' |
'md' |
Star dimensions |
readonly |
boolean |
false |
Display-only role="img" |
label |
string |
unset (interactive fallback 'Rating') |
Accessible name |
length |
number |
5 |
Number of stars |
step |
RatingRootProps['step'] |
1 |
Selection step |
Remaining Reka rating props/emits pass through, except as and asChild. v-model receives update:modelValue. Arrow keys move between ratings and Space selects; readonly mode has no interactive star stops. Supply a label describing what is rated.
SbTable
Section titled “SbTable”SbTable and its parts use Reka Primitive with native table elements. The root supplies a horizontal scroll wrapper, not a grid keyboard model or a sorting engine.
| Route | Status |
|---|---|
| Harbor | Open |
| North depot | Assigned |
| Two contracts | |
<script setup lang="ts">import { SbProvider, SbTable, SbTableCaption, SbTableHeader, SbTableHead, SbTableBody, SbTableRow, SbTableCell, SbTableFooter,} from '@static-bloom/vue'</script>
<template> <SbProvider> <SbTable striped hover> <SbTableCaption>Available contracts</SbTableCaption> <SbTableHeader ><SbTableRow ><SbTableHead>Route</SbTableHead><SbTableHead>Status</SbTableHead></SbTableRow ></SbTableHeader > <SbTableBody> <SbTableRow><SbTableCell>Harbor</SbTableCell><SbTableCell>Open</SbTableCell></SbTableRow> <SbTableRow ><SbTableCell>North depot</SbTableCell><SbTableCell>Assigned</SbTableCell></SbTableRow > </SbTableBody> <SbTableFooter ><SbTableRow ><SbTableCell colspan="2">Two contracts</SbTableCell></SbTableRow ></SbTableFooter > </SbTable> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbTable> <SbTableCaption /> <SbTableHeader><SbTableRow><SbTableHead /></SbTableRow></SbTableHeader> <SbTableBody><SbTableRow><SbTableCell /></SbTableRow></SbTableBody> <SbTableFooter><SbTableRow><SbTableCell /></SbTableRow></SbTableFooter></SbTable>| Component / prop | Type | Default | Effect |
|---|---|---|---|
Table striped, hover, compact |
boolean |
false |
Alternate rows, hover fill, reduced padding |
Table as |
PrimitiveProps['as'] |
'table' |
Table element |
TableHead sort |
'ascending' | 'descending' | 'none' |
unset | aria-sort and direction icon |
TableRow selected |
boolean |
false |
Selected styling and aria-selected |
Keep a caption and column headings. Sorting and row selection require consumer state and keyboard-accessible controls; sort only describes the direction. Avoid turning a clickable row into the only way to open a record.
SbHudPanel + SbStatBar + SbNeonText
Section titled “SbHudPanel + SbStatBar + SbNeonText”SbHudPanel uses Reka Primitive as a section; SbNeonText uses it as a span. SbStatBar is a native, labelled role="meter" display with segmented fill. This demo uses the game backdrop to check panel legibility.
Vehicle telemetry
<script setup lang="ts">import { SbHudPanel, SbNeonText, SbProvider, SbStatBar } from '@static-bloom/vue'</script>
<template> <SbProvider> <SbHudPanel title="Vehicle telemetry" title-as="p" status class="w-full max-w-sm"> <div class="space-y-4"> <SbNeonText intent="success">Engine online</SbNeonText> <SbStatBar label="Hull" :value="78" intent="success" /> <SbStatBar label="Fuel" :value="42" intent="warning" :segments="20" value-text="42 percent fuel remaining" /> </div> </SbHudPanel> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbHudPanel> <template #header /> <template #actions /> <SbNeonText /> <SbStatBar><template #icon /></SbStatBar></SbHudPanel>For HudPanel and StatBar, HUD intent is Intent as defined above. NeonText accepts the same values except 'neutral'.
| Component / prop | Type | Default | Effect |
|---|---|---|---|
HudPanel intent |
HUD intent | 'primary' |
Header and frame tone |
HudPanel as |
PrimitiveProps['as'] |
'section' |
Root element |
HudPanel title |
string |
unset | Optional header title |
HudPanel titleAs |
'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' |
'h3' |
Title element |
HudPanel status |
boolean |
false |
Decorative status dot |
HudPanel brackets |
boolean |
true |
Corner brackets |
HudPanel scanlines, solid |
boolean |
false |
Scanlines / opaque sunken surface instead of glass |
StatBar label, value |
string, number |
required | Meter name and current value |
StatBar max, segments |
number |
100, 10 |
Maximum value and segment count |
StatBar intent, size |
HUD intent, 'sm' | 'md' | 'lg' |
'primary', 'md' |
Tone and dimensions |
StatBar glow, critical, hideValue |
boolean |
false |
Numeric glow, critical pulse, hidden numeric readout |
StatBar valueText |
string |
unset | aria-valuetext |
NeonText intent |
HUD intent | unset | Intent ink and glow |
NeonText glow |
'text' | 'bloom' | 'none' |
'text' |
Glow treatment |
NeonText gradient, flicker |
boolean |
false |
Bloom gradient / tube flicker |
NeonText as |
PrimitiveProps['as'] |
'span' |
Text element |
The meter clamps value between zero and max, and exposes its minimum, maximum and current value. These displays do not take focus or announce every telemetry update. The panel’s status dot is decorative; include status text when it matters.
For OPEN//77, put HUD widgets on one WebUI page, keep the document transparent and use sufficiently opaque panel surfaces over game imagery. Use solid when the scene makes glass hard to read. Interactive HUD controls still need page focus from the game client. In-game UIs covers input and bridge setup.