feat(desktop): polish composer pill toward reference look

Solid foreground-on-background send/voice-conversation circle (black-on-white
in light, white-on-black in dark) anchors the right edge as the primary CTA
instead of the orange theme primary. Bumps the primary control to 2.125rem so
it visually outranks the ghost mic/plus controls. Opens up the surface padding
(0.625rem x / 0.5rem y) so the input row breathes around its controls, and
nudges the corner radius from 20 to 24px for a slightly pill-ier silhouette.
LiquidGlass distortion is preserved.
This commit is contained in:
Brooklyn Nicholson
2026-05-06 18:41:37 -05:00
parent 81d4316b4a
commit 07e0bb8aae
5 changed files with 24 additions and 10 deletions
@@ -8,6 +8,15 @@ import type { ChatBarState, VoiceStatus } from './types'
export const ICON_BTN = 'size-(--composer-control-size) shrink-0 rounded-full'
export const GHOST_ICON_BTN = cn(ICON_BTN, 'text-muted-foreground hover:bg-accent hover:text-foreground')
// Send/voice-conversation primary: solid foreground-on-background circle
// (reads as black-on-white in light mode, white-on-black in dark mode) to
// match the reference composer's high-contrast CTA. Keeps the pill itself
// neutral and lets the action visually dominate the row.
export const PRIMARY_ICON_BTN = cn(
'size-(--composer-control-primary-size,var(--composer-control-size)) shrink-0 rounded-full p-0',
'bg-foreground text-background hover:bg-foreground/90',
'disabled:bg-foreground/30 disabled:text-background disabled:opacity-100'
)
interface ConversationProps {
active: boolean
@@ -51,7 +60,7 @@ export function ComposerControls({
{showVoicePrimary ? (
<Button
aria-label="Start voice conversation"
className={cn(ICON_BTN, 'p-0')}
className={PRIMARY_ICON_BTN}
disabled={disabled}
onClick={() => {
triggerHaptic('open')
@@ -66,7 +75,7 @@ export function ComposerControls({
) : (
<Button
aria-label={busy ? 'Stop' : 'Send'}
className={cn(ICON_BTN, 'p-0')}
className={PRIMARY_ICON_BTN}
disabled={disabled || !canSubmit}
type="submit"
>
@@ -20,13 +20,13 @@ const COMPOSER_GLASS_TWEAKS: ComposerGlassTweakOutputs = {
liquid: {
aberrationIntensity: 0.95,
blurAmount: 0.072,
cornerRadius: 20,
cornerRadius: 24,
displacementScale: 46,
elasticity: 0,
mode: 'standard',
saturation: 128
},
liquidKey: ['standard', '0.950', '0.072', '20', '46', '0.00', '128'].join(':'),
liquidKey: ['standard', '0.950', '0.072', '24', '46', '0.00', '128'].join(':'),
showLibraryRims: false
}
+2 -2
View File
@@ -951,7 +951,7 @@ export function ChatBar({
<div className="relative w-full">
<div
className={cn(
'composer-liquid-shell-wrap absolute inset-0 isolate overflow-hidden rounded-(--composer-glass-radius,20px) transition-opacity duration-200 ease-out',
'composer-liquid-shell-wrap absolute inset-0 isolate overflow-hidden rounded-(--composer-glass-radius,24px) transition-opacity duration-200 ease-out',
'group-has-data-[state=open]/composer:rounded-t-none',
scrolledUp ? COMPOSER_SCROLLED_DIM_CLASS : 'opacity-100'
)}
@@ -1044,7 +1044,7 @@ export function ChatBarFallback() {
<div
className={cn(COMPOSER_SHELL_CLASS, 'bg-linear-to-b from-transparent to-background/55')}
data-slot="composer-root"
style={{ '--composer-active-radius': '1.25rem' } as CSSProperties}
style={{ '--composer-active-radius': '1.5rem' } as CSSProperties}
>
<div className="relative isolate h-(--composer-fallback-height) w-full overflow-hidden rounded-(--composer-active-radius) border border-input/70 shadow-composer">
<div aria-hidden className={COMPOSER_FROST_CLASS} />
@@ -62,12 +62,12 @@
width: 100% !important;
height: 100% !important;
padding: 0 !important;
border-radius: var(--composer-glass-radius, 20px) !important;
border-radius: var(--composer-glass-radius, 24px) !important;
box-shadow: none !important;
}
.composer-liquid-shell > .glass > .glass__warp {
border-radius: var(--composer-glass-radius, 20px) !important;
border-radius: var(--composer-glass-radius, 24px) !important;
}
.composer-liquid-shell > .glass > div {
+7 -2
View File
@@ -125,10 +125,15 @@
--composer-target-width: 68%;
--composer-max-width: 56rem;
--composer-control-size: 2rem;
/* Send / voice-conversation circle is one notch larger than the ghost
* controls so the primary CTA visually anchors the right edge. */
--composer-control-primary-size: 2.125rem;
--composer-control-gap: 0.375rem;
--composer-row-gap: 0.375rem;
--composer-surface-pad-x: 0.5rem;
--composer-surface-pad-y: 0.375rem;
/* Reference-clean padding: enough breathing room around the input row
* that the pill no longer feels cramped against its controls. */
--composer-surface-pad-x: 0.625rem;
--composer-surface-pad-y: 0.5rem;
--composer-input-min-height: 2rem;
--composer-input-max-height: 9.375rem;
--composer-input-inline-min-width: 8rem;