Three replacements for the black stroke the search field gets when it's focused. Each one is shown light and dark, with the recent-searches menu open underneath.
ComboField · ui/input/ComboField.vue — the field; the focus rule lives in its scoped styleQuickSearch · ui/components/QuickSearch.vue — passes class="quick-search" onto the ComboField rootSearchSidebar / SearchTopbar · ui/blocks/ — the two places the field renders/* ui/input/ComboField.vue — scoped <style>, line 511 */
&:focus-within,
&.active {
border-color: var(--c-bordertertiary);
}
/* the field's rest state, for reference */
.combo-field {
border: 2px solid transparent;
border-radius: 1.2rem;
background: var(--c-input-primary); /* metal-50 / metal-900 */
transition: border-color .2s ease;
}
ComboField · ui/input/ComboField.vue — scoped CSS change only, no template or propsIconButton · ui/buttons/IconButton.vue — the magnifier in the append slot, recoloured by the parent--c-icon-green · ui/css/colors.css — green-600 light / green-500 dark, no new token/* ui/input/ComboField.vue — scoped <style> */
/* 1. add the two new properties to the existing transition
on `.combo-field` (it only animates border-color today) */
transition:
border-color .2s ease,
background-color .2s ease,
box-shadow .2s ease;
/* 2. the focus rule. Drop `&.quick-search` from both selectors to
give every field in the app the same treatment. */
&.quick-search:focus-within,
&.quick-search.active {
border-color: var(--c-icon-green); /* green-600 / green-500 */
box-shadow: 0 0 0 4px color-mix(in srgb, var(--c-icon-green) 16%, transparent);
}
/* 3. the magnifier picks up the same green */
&.quick-search:focus-within .append button,
&.quick-search.active .append button {
color: var(--c-icon-green);
}
ComboField · ui/input/ComboField.vue — scoped CSS change only, no template or propsIconButton · ui/buttons/IconButton.vue — the magnifier in the append slot, recoloured by the parent--c-icon-green / --c-input-primary · ui/css/colors.css — the two tokens the tint is mixed from, no new token/* ui/input/ComboField.vue — scoped <style> */
/* 1. add background-color to the existing transition on
`.combo-field` (it only animates border-color today) */
transition:
border-color .2s ease,
background-color .2s ease;
/* 2. the focus rule — the colour goes into the well, not onto an
edge. One line, and it resolves for both schemes because both
inputs are theme-aware. Drop `&.quick-search` from both
selectors to give every field in the app the same treatment. */
&.quick-search:focus-within,
&.quick-search.active {
background: color-mix(in srgb, var(--c-icon-green) 12%, var(--c-input-primary));
}
/* 3. the magnifier goes green with it */
&.quick-search:focus-within .append button,
&.quick-search.active .append button {
color: var(--c-icon-green);
}
ComboField · ui/input/ComboField.vue — scoped CSS: focus fill + squared bottom cornersMenuSurface · ui/menus/MenuSurface.vue — variant:search-menu gets squared top corners and drops its top borderQuickSearch · ui/components/QuickSearch.vue — menu width, and the popper offset that closes the 6px gapPopMenu offset override · ui/components/pop/PopMenu.vue — needs a way to pass offset: [0, 0] if it doesn't take one yet/* ui/input/ComboField.vue — scoped <style> */
/* 1. add the two new properties to the existing transition
on `.combo-field` (it only animates border-color today) */
transition:
border-color .2s ease,
background-color .2s ease,
box-shadow .2s ease;
/* 2. the field becomes the top of the panel: dropdown fill, no
stroke, bottom corners squared off. 14px keeps the inner
curve concentric with the wrapper's 16px minus its 1px
border and the field's 2px (transparent) border. */
&.quick-search:focus-within,
&.quick-search.active {
background: var(--c-surface-dropdown);
border-color: transparent;
border-radius: 14px 14px 0 0;
}
&.quick-search:focus-within .append button,
&.quick-search.active .append button {
color: var(--c-icon-dark-gray);
}
/* ui/menus/MenuSurface.vue — scoped <style> */
.menu-surface.variant\:search-menu {
gap: 0;
padding: 4px;
/* joined to the field above: square the top, keep the bottom,
and let the hairline read as a divider rather than a border */
border-radius: 0 0 var(--br) var(--br);
border-top-color: var(--c-border-secondary);
box-shadow: 0 1.6rem 7.2rem 0 #171A571F;
}
<!-- 1. the popper currently offsets the menu 6px below the field.
Joined means 0. ComboField.vue sets it for its own
SelectMenu; the search menu comes from PopMenu, so the
override goes there (or PopMenu takes an `offset` prop). -->
popper = createPopper($inputText.value, $menu.value.$el, {
placement: props.placement,
modifiers: [{
name: 'offset',
options: {
offset: [0, 0], /* was [0, 6] */
}
}]
});
<!-- 2. the menu has to be exactly as wide as the field or the
seam shows. Sidebar already matches at 304px; the topbar
menu is viewport-width today and needs the field's width. -->
<MenuSurface
:width="props.menuId === 'sidebar' ? '304px' : 'calc(100vw - 32px)'"
variant="search-menu"
class="search-menu-surface">