Skip to main content

Critical P0 Components - Production Specifications

Enterprise-essential UI patterns

M12: Dropdown Menu

Purpose: Action menus, context menus, command lists

Test Criteria:

composition:
- trigger: button or link
- menu: floating panel
- items: clickable actions

behavior:
- click_open: show menu on trigger click
- click_outside: close on outside click
- esc_close: close on ESC key
- keyboard_nav: arrow keys navigate items
- position: auto-adjust to viewport

accessibility:
- role: menu
- aria_haspopup: true on trigger
- aria_expanded: true/false
- keyboard_navigable: arrow keys + enter

Variants:

<!-- Basic Dropdown -->
<div class="dropdown" data-testid="dropdown">
<button
class="dropdown__trigger button button--secondary"
aria-haspopup="true"
aria-expanded="false"
data-testid="dropdown-trigger"
>
Actions
<svg class="dropdown__chevron" width="16" height="16">
<path d="M4 6l4 4 4-4" stroke="currentColor" strokeWidth="2" fill="none"/>
</svg>
</button>

<div class="dropdown__menu" role="menu" data-testid="dropdown-menu">
<button class="dropdown__item" role="menuitem">
<svg class="dropdown__icon" width="16" height="16">
<path d="M11 4H4a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2V8l-5-4z" stroke="currentColor"/>
</svg>
Edit
</button>
<button class="dropdown__item" role="menuitem">
<svg class="dropdown__icon" width="16" height="16">
<path d="M8 2h6l4 4v14" stroke="currentColor"/>
</svg>
Duplicate
</button>
<div class="dropdown__divider" role="separator"></div>
<button class="dropdown__item dropdown__item--danger" role="menuitem">
<svg class="dropdown__icon" width="16" height="16">
<path d="M3 6h18M6 6V4a2 2 0 012-2h8a2 2 0 012 2v2" stroke="currentColor"/>
</svg>
Delete
</button>
</div>
</div>

<!-- With Submenu -->
<div class="dropdown">
<button class="dropdown__trigger button">
More Options
</button>
<div class="dropdown__menu">
<button class="dropdown__item">View</button>
<button class="dropdown__item dropdown__item--submenu">
Share
<svg class="dropdown__submenu-icon" width="12" height="12">
<path d="M4 6l4 4 4-4" stroke="currentColor"/>
</svg>

<div class="dropdown__submenu">
<button class="dropdown__item">Email</button>
<button class="dropdown__item">Link</button>
<button class="dropdown__item">Slack</button>
</div>
</button>
<button class="dropdown__item">Download</button>
</div>
</div>

<!-- Icon-only Trigger (3-dot menu) -->
<div class="dropdown">
<button
class="dropdown__trigger button button--ghost"
aria-label="More actions"
>
<svg width="20" height="20">
<circle cx="10" cy="5" r="1.5" fill="currentColor"/>
<circle cx="10" cy="10" r="1.5" fill="currentColor"/>
<circle cx="10" cy="15" r="1.5" fill="currentColor"/>
</svg>
</button>
<div class="dropdown__menu dropdown__menu--right">
<!-- Menu items -->
</div>
</div>

<!-- With Keyboard Shortcuts -->
<div class="dropdown">
<button class="dropdown__trigger button">File</button>
<div class="dropdown__menu">
<button class="dropdown__item">
<span>New File</span>
<kbd class="dropdown__shortcut">⌘N</kbd>
</button>
<button class="dropdown__item">
<span>Open</span>
<kbd class="dropdown__shortcut">⌘O</kbd>
</button>
<button class="dropdown__item">
<span>Save</span>
<kbd class="dropdown__shortcut">⌘S</kbd>
</button>
</div>
</div>

CSS:

.dropdown {
position: relative;
display: inline-block;
}

.dropdown__trigger {
display: inline-flex;
align-items: center;
gap: 6px;
}

.dropdown__chevron {
transition: transform 0.2s;
}

.dropdown__trigger[aria-expanded="true"] .dropdown__chevron {
transform: rotate(180deg);
}

.dropdown__menu {
position: absolute;
top: calc(100% + 4px);
left: 0;
min-width: 200px;
background: var(--white);
border: 1px solid var(--gray-200);
border-radius: 8px;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
0 4px 6px -2px rgba(0, 0, 0, 0.05);
padding: 4px;
z-index: 1000;
display: none;
animation: fadeIn 0.15s ease-out;
}

.dropdown__menu--right {
left: auto;
right: 0;
}

.dropdown--open .dropdown__menu {
display: block;
}

@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(-4px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

.dropdown__item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
width: 100%;
padding: 8px 12px;
border: none;
background: none;
text-align: left;
font-size: 14px;
color: var(--gray-900);
border-radius: 6px;
cursor: pointer;
transition: background-color 0.15s;
}

.dropdown__item:hover {
background: var(--gray-100);
}

.dropdown__item:focus {
outline: none;
background: var(--gray-100);
}

.dropdown__item--danger {
color: var(--red-600);
}

.dropdown__item--danger:hover {
background: var(--red-50);
}

.dropdown__icon {
flex-shrink: 0;
color: var(--gray-500);
}

.dropdown__divider {
height: 1px;
background: var(--gray-200);
margin: 4px 0;
}

.dropdown__shortcut {
font-size: 12px;
color: var(--gray-500);
font-family: monospace;
}

/* Submenu */
.dropdown__item--submenu {
position: relative;
}

.dropdown__submenu {
position: absolute;
top: 0;
left: 100%;
margin-left: 4px;
min-width: 160px;
background: var(--white);
border: 1px solid var(--gray-200);
border-radius: 8px;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
padding: 4px;
display: none;
}

.dropdown__item--submenu:hover .dropdown__submenu {
display: block;
}

M13: Tabs

Purpose: Content organization, navigation within a view

Test Criteria:

composition:
- tab_list: horizontal navigation
- tab_panels: content areas

behavior:
- click_switch: change active tab
- keyboard_nav: arrow keys navigate tabs
- active_indicator: underline or background

accessibility:
- role: tablist, tab, tabpanel
- aria_selected: true on active tab
- aria_controls: link tab to panel
- keyboard_nav: arrow keys + home/end

Variants:

<!-- Basic Tabs -->
<div class="tabs" data-testid="tabs">
<div class="tabs__list" role="tablist" aria-label="Account settings">
<button
class="tabs__tab tabs__tab--active"
role="tab"
aria-selected="true"
aria-controls="panel-profile"
id="tab-profile"
>
<svg class="tabs__icon" width="16" height="16">
<path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2" stroke="currentColor"/>
</svg>
Profile
</button>
<button
class="tabs__tab"
role="tab"
aria-selected="false"
aria-controls="panel-account"
id="tab-account"
>
<svg class="tabs__icon" width="16" height="16">
<path d="M12 15v2m-6 4h12a2 2 0 002-2v-6" stroke="currentColor"/>
</svg>
Account
</button>
<button
class="tabs__tab"
role="tab"
aria-selected="false"
aria-controls="panel-billing"
id="tab-billing"
>
<svg class="tabs__icon" width="16" height="16">
<rect x="1" y="4" width="22" height="16" rx="2" stroke="currentColor"/>
</svg>
Billing
</button>
</div>

<div class="tabs__panels">
<div
class="tabs__panel tabs__panel--active"
role="tabpanel"
id="panel-profile"
aria-labelledby="tab-profile"
>
<h3>Profile Settings</h3>
<p>Update your profile information here.</p>
</div>

<div
class="tabs__panel"
role="tabpanel"
id="panel-account"
aria-labelledby="tab-account"
hidden
>
<h3>Account Settings</h3>
<p>Manage your account preferences.</p>
</div>

<div
class="tabs__panel"
role="tabpanel"
id="panel-billing"
aria-labelledby="tab-billing"
hidden
>
<h3>Billing Settings</h3>
<p>View and update billing information.</p>
</div>
</div>
</div>

<!-- With Badge Counts -->
<div class="tabs__list" role="tablist">
<button class="tabs__tab tabs__tab--active" role="tab">
All Tasks
<span class="badge badge--sm">24</span>
</button>
<button class="tabs__tab" role="tab">
Active
<span class="badge badge--sm badge--primary">8</span>
</button>
<button class="tabs__tab" role="tab">
Completed
<span class="badge badge--sm badge--success">16</span>
</button>
</div>

<!-- Vertical Tabs (Sidebar Style) -->
<div class="tabs tabs--vertical">
<div class="tabs__list tabs__list--vertical" role="tablist">
<button class="tabs__tab tabs__tab--active" role="tab">General</button>
<button class="tabs__tab" role="tab">Security</button>
<button class="tabs__tab" role="tab">Notifications</button>
<button class="tabs__tab" role="tab">Integrations</button>
</div>
<div class="tabs__panels">
<!-- Panels here -->
</div>
</div>

<!-- Pill Style -->
<div class="tabs tabs--pills">
<div class="tabs__list" role="tablist">
<button class="tabs__tab tabs__tab--active" role="tab">Overview</button>
<button class="tabs__tab" role="tab">Details</button>
<button class="tabs__tab" role="tab">Activity</button>
</div>
</div>

CSS:

.tabs {
display: flex;
flex-direction: column;
}

.tabs__list {
display: flex;
gap: 4px;
border-bottom: 1px solid var(--gray-200);
padding: 0 4px;
}

.tabs__tab {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 12px 16px;
border: none;
background: none;
color: var(--gray-600);
font-size: 14px;
font-weight: 500;
cursor: pointer;
position: relative;
transition: color 0.2s;
border-bottom: 2px solid transparent;
margin-bottom: -1px;
}

.tabs__tab:hover {
color: var(--gray-900);
}

.tabs__tab--active {
color: var(--blue-600);
border-bottom-color: var(--blue-600);
}

.tabs__tab:focus-visible {
outline: 2px solid var(--blue-500);
outline-offset: -2px;
border-radius: 6px;
}

.tabs__icon {
flex-shrink: 0;
}

.tabs__panels {
padding: 24px 4px;
}

.tabs__panel {
display: none;
}

.tabs__panel--active {
display: block;
animation: fadeIn 0.2s ease-out;
}

@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

/* Vertical variant */
.tabs--vertical {
flex-direction: row;
gap: 24px;
}

.tabs__list--vertical {
flex-direction: column;
min-width: 200px;
border-bottom: none;
border-right: 1px solid var(--gray-200);
padding: 4px 4px 4px 0;
}

.tabs--vertical .tabs__tab {
justify-content: flex-start;
width: 100%;
border-bottom: none;
border-right: 2px solid transparent;
margin-bottom: 0;
margin-right: -1px;
}

.tabs--vertical .tabs__tab--active {
border-right-color: var(--blue-600);
border-bottom-color: transparent;
}

/* Pill variant */
.tabs--pills .tabs__list {
border-bottom: none;
background: var(--gray-100);
border-radius: 8px;
padding: 4px;
}

.tabs--pills .tabs__tab {
border-radius: 6px;
border-bottom: none;
margin-bottom: 0;
}

.tabs--pills .tabs__tab--active {
background: var(--white);
border-bottom-color: transparent;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

M14: Tooltip

Purpose: Contextual help text, additional information

Test Criteria:

composition:
- trigger: any element
- tooltip: floating text box

behavior:
- hover_show: display on hover (desktop)
- focus_show: display on focus (keyboard)
- auto_position: adjust to viewport
- delay: 500ms before show

accessibility:
- role: tooltip
- aria_describedby: link to tooltip
- keyboard_accessible: shows on focus

Variants:

<!-- Basic Tooltip -->
<button
class="button"
aria-describedby="tooltip-save"
data-tooltip="Save your changes"
>
Save
<div class="tooltip" role="tooltip" id="tooltip-save">
Save your changes
</div>
</button>

<!-- Icon with Tooltip -->
<button class="button button--ghost" aria-label="Help">
<svg width="16" height="16">
<circle cx="8" cy="8" r="7" stroke="currentColor" fill="none"/>
<path d="M8 11v1M8 5v4" stroke="currentColor" strokeWidth="2"/>
</svg>
<div class="tooltip tooltip--top">
Click for help documentation
</div>
</button>

<!-- Position Variants -->
<div class="tooltip-examples">
<!-- Top (default) -->
<span class="tooltip-trigger">
Hover me
<div class="tooltip tooltip--top">Tooltip on top</div>
</span>

<!-- Right -->
<span class="tooltip-trigger">
Hover me
<div class="tooltip tooltip--right">Tooltip on right</div>
</span>

<!-- Bottom -->
<span class="tooltip-trigger">
Hover me
<div class="tooltip tooltip--bottom">Tooltip on bottom</div>
</span>

<!-- Left -->
<span class="tooltip-trigger">
Hover me
<div class="tooltip tooltip--left">Tooltip on left</div>
</span>
</div>

<!-- Rich Content Tooltip -->
<button class="tooltip-trigger">
View details
<div class="tooltip tooltip--rich">
<div class="tooltip__header">
<strong>Project Status</strong>
</div>
<div class="tooltip__content">
<p>Progress: 75%</p>
<p>Due: Jan 25, 2026</p>
</div>
</div>
</button>

CSS:

.tooltip-trigger {
position: relative;
display: inline-block;
}

.tooltip {
position: absolute;
bottom: calc(100% + 8px);
left: 50%;
transform: translateX(-50%);
padding: 6px 12px;
background: var(--gray-900);
color: var(--white);
font-size: 13px;
line-height: 1.4;
border-radius: 6px;
white-space: nowrap;
max-width: 300px;
z-index: 9999;
pointer-events: none;
opacity: 0;
transition: opacity 0.2s;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

/* Arrow */
.tooltip::after {
content: '';
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-top-color: var(--gray-900);
}

.tooltip-trigger:hover .tooltip,
.tooltip-trigger:focus .tooltip {
opacity: 1;
transition-delay: 500ms;
}

/* Position variants */
.tooltip--top {
bottom: calc(100% + 8px);
left: 50%;
transform: translateX(-50%);
}

.tooltip--top::after {
top: 100%;
left: 50%;
transform: translateX(-50%);
border-top-color: var(--gray-900);
border-bottom-color: transparent;
}

.tooltip--right {
bottom: auto;
left: calc(100% + 8px);
top: 50%;
transform: translateY(-50%);
}

.tooltip--right::after {
top: 50%;
left: -12px;
transform: translateY(-50%);
border-right-color: var(--gray-900);
border-left-color: transparent;
border-top-color: transparent;
}

.tooltip--bottom {
top: calc(100% + 8px);
bottom: auto;
left: 50%;
transform: translateX(-50%);
}

.tooltip--bottom::after {
top: -12px;
bottom: auto;
border-bottom-color: var(--gray-900);
border-top-color: transparent;
}

.tooltip--left {
bottom: auto;
right: calc(100% + 8px);
left: auto;
top: 50%;
transform: translateY(-50%);
}

.tooltip--left::after {
top: 50%;
right: -12px;
left: auto;
transform: translateY(-50%);
border-left-color: var(--gray-900);
border-right-color: transparent;
border-top-color: transparent;
}

/* Rich tooltip */
.tooltip--rich {
white-space: normal;
max-width: 280px;
padding: 12px;
}

.tooltip__header {
margin-bottom: 8px;
font-weight: 600;
}

.tooltip__content p {
margin: 4px 0;
}

M15: Alert / Banner

Purpose: System messages, notifications, warnings

Test Criteria:

composition:
- icon: semantic indicator
- message: text content
- close_button: dismissible

behavior:
- closeable: optional dismiss
- auto_dismiss: optional timeout
- color_coded: semantic colors

accessibility:
- role: alert or status
- aria_live: polite or assertive
- focus_management: focus on close

Variants:

<!-- Info Alert -->
<div class="alert alert--info" role="status" aria-live="polite">
<svg class="alert__icon" width="20" height="20">
<circle cx="10" cy="10" r="9" stroke="currentColor" fill="none"/>
<path d="M10 6v4M10 14v1" stroke="currentColor" strokeWidth="2"/>
</svg>
<div class="alert__content">
<div class="alert__title">New features available</div>
<div class="alert__message">
Check out the latest updates to your dashboard.
</div>
</div>
<button class="alert__close" aria-label="Dismiss alert">
<svg width="16" height="16">
<path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" strokeWidth="2"/>
</svg>
</button>
</div>

<!-- Success Alert -->
<div class="alert alert--success" role="status">
<svg class="alert__icon" width="20" height="20">
<circle cx="10" cy="10" r="9" stroke="currentColor" fill="none"/>
<path d="M6 10l2 2 4-4" stroke="currentColor" strokeWidth="2"/>
</svg>
<div class="alert__content">
<div class="alert__message">Changes saved successfully!</div>
</div>
</div>

<!-- Warning Alert -->
<div class="alert alert--warning" role="alert" aria-live="polite">
<svg class="alert__icon" width="20" height="20">
<path d="M10 2L2 18h16L10 2z" stroke="currentColor" fill="none"/>
<path d="M10 8v4M10 16v1" stroke="currentColor" strokeWidth="2"/>
</svg>
<div class="alert__content">
<div class="alert__title">Your trial expires soon</div>
<div class="alert__message">
Upgrade to continue using premium features.
<button class="alert__action">Upgrade Now</button>
</div>
</div>
<button class="alert__close" aria-label="Dismiss alert">×</button>
</div>

<!-- Error Alert -->
<div class="alert alert--error" role="alert" aria-live="assertive">
<svg class="alert__icon" width="20" height="20">
<circle cx="10" cy="10" r="9" stroke="currentColor" fill="none"/>
<path d="M7 7l6 6M13 7l-6 6" stroke="currentColor" strokeWidth="2"/>
</svg>
<div class="alert__content">
<div class="alert__title">Error saving changes</div>
<div class="alert__message">
Unable to connect to server. Please try again.
</div>
</div>
</div>

<!-- Banner Style (Full Width) -->
<div class="alert alert--banner alert--info">
<div class="alert__container">
<svg class="alert__icon" width="20" height="20">...</svg>
<div class="alert__content">
<strong>Scheduled Maintenance:</strong> System will be down on Jan 20, 2026 from 2-4am UTC
</div>
<button class="alert__close" aria-label="Dismiss">×</button>
</div>
</div>

CSS:

.alert {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 16px;
border-radius: 8px;
border: 1px solid;
margin-bottom: 16px;
animation: slideIn 0.2s ease-out;
}

@keyframes slideIn {
from {
opacity: 0;
transform: translateY(-8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

.alert__icon {
flex-shrink: 0;
margin-top: 2px;
}

.alert__content {
flex: 1;
min-width: 0;
}

.alert__title {
font-weight: 600;
margin-bottom: 4px;
font-size: 14px;
}

.alert__message {
font-size: 14px;
line-height: 1.5;
}

.alert__action {
display: inline-block;
margin-top: 8px;
padding: 0;
border: none;
background: none;
color: inherit;
font-weight: 600;
text-decoration: underline;
cursor: pointer;
}

.alert__close {
flex-shrink: 0;
width: 24px;
height: 24px;
padding: 0;
border: none;
background: none;
color: currentColor;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s;
}

.alert__close:hover {
background: rgba(0, 0, 0, 0.05);
}

/* Semantic variants */
.alert--info {
background: var(--blue-50);
border-color: var(--blue-200);
color: var(--blue-900);
}

.alert--info .alert__icon {
color: var(--blue-600);
}

.alert--success {
background: var(--green-50);
border-color: var(--green-200);
color: var(--green-900);
}

.alert--success .alert__icon {
color: var(--green-600);
}

.alert--warning {
background: var(--yellow-50);
border-color: var(--yellow-200);
color: var(--yellow-900);
}

.alert--warning .alert__icon {
color: var(--yellow-600);
}

.alert--error {
background: var(--red-50);
border-color: var(--red-200);
color: var(--red-900);
}

.alert--error .alert__icon {
color: var(--red-600);
}

/* Banner variant */
.alert--banner {
border-radius: 0;
border-left: none;
border-right: none;
margin-bottom: 0;
}

.alert__container {
display: flex;
align-items: center;
gap: 12px;
max-width: 1400px;
margin: 0 auto;
}

.alert--banner .alert__content {
font-size: 14px;
}

M16: Select / Combobox

Purpose: Searchable dropdown selection

Test Criteria:

composition:
- trigger: button with selected value
- dropdown: searchable list
- options: selectable items

behavior:
- search: filter options by text
- keyboard_nav: arrow keys navigate
- clear: optional clear selection
- multi_select: optional multiple

accessibility:
- role: combobox
- aria_expanded: true/false
- aria_autocomplete: list
- aria_activedescendant: focused option

Variants:

<!-- Basic Select -->
<div class="select" data-testid="select">
<button
class="select__trigger"
aria-haspopup="listbox"
aria-expanded="false"
aria-labelledby="select-label"
>
<span class="select__label" id="select-label">Choose an option</span>
<span class="select__value">Select...</span>
<svg class="select__chevron" width="16" height="16">
<path d="M4 6l4 4 4-4" stroke="currentColor" strokeWidth="2"/>
</svg>
</button>

<div class="select__dropdown" role="listbox">
<div class="select__option" role="option" aria-selected="false">
Option 1
</div>
<div class="select__option" role="option" aria-selected="false">
Option 2
</div>
<div class="select__option" role="option" aria-selected="false">
Option 3
</div>
</div>
</div>

<!-- Searchable Combobox -->
<div class="select select--searchable">
<div class="select__trigger">
<input
type="text"
class="select__search"
placeholder="Search countries..."
role="combobox"
aria-autocomplete="list"
aria-expanded="false"
aria-controls="country-listbox"
/>
<svg class="select__icon" width="16" height="16">
<circle cx="8" cy="8" r="6" stroke="currentColor" fill="none"/>
<path d="M14 14l-4-4" stroke="currentColor" strokeWidth="2"/>
</svg>
</div>

<div class="select__dropdown" role="listbox" id="country-listbox">
<div class="select__option" role="option">
<img src="/flags/us.svg" alt="" class="select__option-icon" />
<span>United States</span>
</div>
<div class="select__option" role="option">
<img src="/flags/uk.svg" alt="" class="select__option-icon" />
<span>United Kingdom</span>
</div>
<div class="select__option" role="option">
<img src="/flags/ca.svg" alt="" class="select__option-icon" />
<span>Canada</span>
</div>
<div class="select__empty">No results found</div>
</div>
</div>

<!-- Multi-select -->
<div class="select select--multi">
<div class="select__trigger">
<div class="select__tags">
<span class="tag">Design</span>
<span class="tag">Frontend</span>
</div>
<input
type="text"
class="select__search select__search--inline"
placeholder="Add tags..."
/>
</div>

<div class="select__dropdown">
<div class="select__option select__option--selected">
<input type="checkbox" checked />
<span>Design</span>
</div>
<div class="select__option select__option--selected">
<input type="checkbox" checked />
<span>Frontend</span>
</div>
<div class="select__option">
<input type="checkbox" />
<span>Backend</span>
</div>
</div>
</div>

<!-- With Groups -->
<div class="select">
<button class="select__trigger">
<span class="select__value">Select role...</span>
</button>

<div class="select__dropdown">
<div class="select__group">
<div class="select__group-label">Engineering</div>
<div class="select__option">Frontend Developer</div>
<div class="select__option">Backend Developer</div>
</div>

<div class="select__group">
<div class="select__group-label">Design</div>
<div class="select__option">Product Designer</div>
<div class="select__option">UX Researcher</div>
</div>
</div>
</div>

CSS:

.select {
position: relative;
width: 100%;
}

.select__trigger {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
height: 44px;
padding: 0 12px;
border: 1px solid var(--gray-300);
border-radius: 8px;
background: var(--white);
font-size: 14px;
cursor: pointer;
transition: all 0.2s;
}

.select__trigger:hover {
border-color: var(--gray-400);
}

.select__trigger:focus-within {
border-color: var(--blue-500);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.select__label {
font-size: 12px;
color: var(--gray-600);
position: absolute;
top: -8px;
left: 8px;
padding: 0 4px;
background: var(--white);
}

.select__value {
flex: 1;
text-align: left;
color: var(--gray-900);
}

.select__value:empty::before {
content: attr(data-placeholder);
color: var(--gray-400);
}

.select__chevron {
flex-shrink: 0;
color: var(--gray-500);
transition: transform 0.2s;
}

.select--open .select__chevron {
transform: rotate(180deg);
}

.select__dropdown {
position: absolute;
top: calc(100% + 4px);
left: 0;
right: 0;
max-height: 300px;
background: var(--white);
border: 1px solid var(--gray-200);
border-radius: 8px;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
overflow-y: auto;
z-index: 1000;
display: none;
}

.select--open .select__dropdown {
display: block;
}

.select__search {
flex: 1;
border: none;
outline: none;
font-size: 14px;
background: none;
}

.select__option {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 12px;
cursor: pointer;
transition: background-color 0.15s;
}

.select__option:hover {
background: var(--gray-100);
}

.select__option--selected {
background: var(--blue-50);
color: var(--blue-700);
font-weight: 500;
}

.select__option-icon {
width: 20px;
height: 20px;
border-radius: 4px;
object-fit: cover;
}

.select__empty {
padding: 16px;
text-align: center;
color: var(--gray-500);
font-size: 14px;
}

.select__group {
padding: 8px 0;
}

.select__group-label {
padding: 4px 12px;
font-size: 12px;
font-weight: 600;
color: var(--gray-600);
text-transform: uppercase;
letter-spacing: 0.5px;
}

/* Multi-select */
.select--multi .select__trigger {
min-height: 44px;
height: auto;
flex-wrap: wrap;
gap: 6px;
padding: 6px 12px;
}

.select__tags {
display: flex;
flex-wrap: wrap;
gap: 6px;
}

.select__search--inline {
min-width: 120px;
padding: 0;
}

These 5 P0 components complete the critical enterprise UI patterns needed for production.