Which component do I reach for?
A handful of pairs (and one trio) in the component list read as the same thing at a skim. They aren't. Each entry below covers one pair, verified against both components' sources, not just their names.
Card vs. layout
Both read as "a box with a header, a middle and a footer," and nothing in the names tells them apart. They solve different problems.
Card is a flat vertical stack. <oblyx-card> is a column flexbox; whichever of <oblyx-card-header>,<oblyx-card-body> and <oblyx-card-footer> you include become its flex items, in DOM order, with no side panels, no independent scrolling per region, and no divider default that cascades from the parent. Reach for it for a single self-contained unit: a pricing tier, a settings panel, one row in a list of similar items.
A card
<oblyx-card>
<oblyx-card-header>Plan: Pro</oblyx-card-header>
<oblyx-card-body>Billed monthly. Cancel anytime.</oblyx-card-body>
<oblyx-card-footer>
<oblyx-button variant="primary">Manage plan</oblyx-button>
</oblyx-card-footer>
</oblyx-card>oblyxCard {
oblyxCardHeader { +"Plan: Pro" }
oblyxCardBody { +"Billed monthly. Cancel anytime." }
oblyxCardFooter {
oblyxButton(variant = OblyxButtonVariant.PRIMARY) { +"Manage plan" }
}
}Layout is two-dimensional. <oblyx-layout> is a CSS Grid with named areas for header, footer, and a start/content/end row between them; a <oblyx-layout-panel area="start"> or area="end"> is a real side panel, <oblyx-layout-content> and each panel scroll their own overflow independently by default, and setting default-has-dividers on the layout cascades a divider onto every header and footer inside it unless one opts out explicitly. None of that exists on card. Reach for layout to structure a whole page or a whole panel: an app shell, a dashboard with a side nav, anything with regions that scroll independently of each other.
A layout with a side panel
<oblyx-layout height="auto">
<oblyx-layout-header>Dashboard</oblyx-layout-header>
<oblyx-layout-panel area="start">Sidebar nav</oblyx-layout-panel>
<oblyx-layout-content>Main content, scrolls independently.</oblyx-layout-content>
<oblyx-layout-footer>Status bar</oblyx-layout-footer>
</oblyx-layout>oblyxLayout(height = OblyxLayoutHeight.AUTO) {
oblyxLayoutHeader { +"Dashboard" }
oblyxLayoutPanel(area = OblyxLayoutPanelArea.START) { +"Sidebar nav" }
oblyxLayoutContent { +"Main content, scrolls independently." }
oblyxLayoutFooter { +"Status bar" }
}The two nest without conflict. A card sitting inside a layout's content region, or a small layout used inside a card's body, share no CSS and don't interfere with each other.
Popover vs. tooltip vs. menu
All three are anchored surfaces built on the same positioning mechanism, and all three pop up next to a trigger. What they're for, and how they behave once open, differs enough that picking the wrong one is a real accessibility bug, not just a style mismatch.
Tooltip is advisory text, nothing else. It opens on hover or keyboard focus, never on click, and it never traps focus or becomes interactive: it exists purely to add a description to whatever it's anchored to, the same role a native title attribute plays but visible and stylable. Content is plain content text, not arbitrary markup.
Popover is arbitrary interactive content: a form, a list of options with their own controls, anything more than a sentence of description. It opens on click, and while open it traps focus, the one surface of the three that does, because it's meant to be a self-contained interactive region a keyboard user tabs around inside before dismissing.
Menu is a list of actions, opened by a trigger button. It has its own keyboard model instead of a focus trap: arrow keys move a roving highlight between <oblyx-menu-item> entries, and Tab closes the menu and moves focus onward rather than cycling inside it, matching how a native <select> or a desktop application's menu bar behaves. Reach for it when the content is exclusively a list of things to click, and for a form or richer content, popover.
Dialog vs. drawer
These two are closer to genuinely being the same component than the pairs above: both sit on the same shared base (native <dialog> plus showModal()), get identical focus trapping, scroll locking and dismiss handling, and compose with the same <oblyx-dialog-header>/-body/-footer children. The difference is purely positional. Dialog is centered on the viewport, sized by width/max-height. Drawer is anchored to a viewport edge (edge="start", "end", "top" or "bottom") and slides in from it. Reach for dialog for a centered confirmation or form; reach for drawer for a slide-in panel, such as a mobile navigation menu or a filter sidebar that shouldn't take over the whole screen.