From 7a9a6779b00ba9d889d52d70f7ded834bbe2d73f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Mon, 20 Apr 2026 08:02:40 -0400 Subject: [PATCH] uodate --- .../crates/app_ui/src/app_root.rs | 38 +-- .../crates/app_ui/src/app_root/approvals.rs | 12 +- .../crates/app_ui/src/app_root/documents.rs | 8 +- .../crates/app_ui/src/app_root/inbox.rs | 2 +- .../crates/app_ui/src/app_root/messages.rs | 278 ++++++++++-------- .../app_ui/src/app_root/messages_parts.rs | 144 +++++---- .../crates/app_ui/src/app_root/onboarding.rs | 16 +- .../crates/app_ui/src/app_root/overview.rs | 259 ++++++++++++---- .../crates/app_ui/src/app_root/runs.rs | 63 ++-- .../crates/app_ui/src/app_root/settings.rs | 4 +- .../crates/app_ui/src/app_root/sidebar.rs | 105 +++---- .../crates/app_ui/src/app_root/workspaces.rs | 2 +- AgentCompany-Rust/crates/app_ui/src/theme.rs | 37 +++ AgentCompany-Rust/prd.json | 6 +- 14 files changed, 577 insertions(+), 397 deletions(-) diff --git a/AgentCompany-Rust/crates/app_ui/src/app_root.rs b/AgentCompany-Rust/crates/app_ui/src/app_root.rs index 0cf83bdc..afb64657 100644 --- a/AgentCompany-Rust/crates/app_ui/src/app_root.rs +++ b/AgentCompany-Rust/crates/app_ui/src/app_root.rs @@ -360,8 +360,10 @@ impl Render for AppRoot { .flex_col() .child( div() - .px_8() - .py_5() + .px_6() + .h(px(56.0)) + .flex() + .items_center() .border_b_1() .border_color(theme::panel_border()) .bg(theme::shell_header()) @@ -370,41 +372,25 @@ impl Render for AppRoot { .flex() .items_center() .justify_between() + .w_full() .child( div() - .child( - div() - .text_3xl() - .text_color(theme::text_primary()) - .child(self.state.section.label()), - ) - .child( - div() - .text_sm() - .text_color(theme::text_muted()) - .child(header), - ) - .child( - div() - .text_sm() - .text_color(theme::text_subtle()) - .child(self.state.status_line.clone().unwrap_or_else(|| { - "Native Rust shell is reading the shared local profile." - .to_string() - })), - ), + .text_size(px(14.0)) + .font_weight(gpui::FontWeight::MEDIUM) + .text_color(theme::text_primary()) + .child(self.state.section.label()), ) .child( div() .px_4() .py_3() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) - .text_sm() + .text_size(px(14.0)) .text_color(theme::text_secondary()) - .child("Show console"), + .child(header), ), ), ) diff --git a/AgentCompany-Rust/crates/app_ui/src/app_root/approvals.rs b/AgentCompany-Rust/crates/app_ui/src/app_root/approvals.rs index 3b6c48e1..b6871d6b 100644 --- a/AgentCompany-Rust/crates/app_ui/src/app_root/approvals.rs +++ b/AgentCompany-Rust/crates/app_ui/src/app_root/approvals.rs @@ -34,7 +34,7 @@ impl AppRoot { fn render_pending_approval_list(&self, cx: &mut Context) -> impl IntoElement + '_ { let pending = pending_approvals(&self.snapshot).collect::>(); div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -103,7 +103,7 @@ impl AppRoot { cx: &mut Context, ) -> impl IntoElement + '_ { div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -126,7 +126,7 @@ impl AppRoot { .child( div() .mt(px(10.0)) - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_inset_border()) .bg(theme::panel_inset()) @@ -140,7 +140,7 @@ impl AppRoot { inner.child( div() .mt(px(12.0)) - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -275,7 +275,7 @@ fn render_review_groups_panel(groups: &ReviewGroups<'_>) -> impl IntoElement { let has_rows = !(groups.board.is_empty() && groups.user.is_empty() && groups.manager.is_empty()); div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -337,7 +337,7 @@ fn review_group_section<'a>( div() .w(px(28.0)) .h(px(28.0)) - .rounded_lg() + .rounded(px(0.0)) .bg(theme::panel_muted()), ) .child( diff --git a/AgentCompany-Rust/crates/app_ui/src/app_root/documents.rs b/AgentCompany-Rust/crates/app_ui/src/app_root/documents.rs index d16eebb5..eb94d780 100644 --- a/AgentCompany-Rust/crates/app_ui/src/app_root/documents.rs +++ b/AgentCompany-Rust/crates/app_ui/src/app_root/documents.rs @@ -41,7 +41,7 @@ impl AppRoot { selected: Option<&domain::Document>, ) -> impl IntoElement + '_ { div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -117,7 +117,7 @@ impl AppRoot { selected: Option<&domain::Document>, ) -> impl IntoElement + '_ { div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -146,7 +146,7 @@ impl AppRoot { .child( div() .mt(px(16.0)) - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_inset_border()) .bg(theme::panel_inset()) @@ -209,7 +209,7 @@ fn document_section_label(label: &'static str) -> impl IntoElement { fn render_work_products<'a>(products: &'a [&'a domain::ArtifactRecord]) -> impl IntoElement + 'a { div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) diff --git a/AgentCompany-Rust/crates/app_ui/src/app_root/inbox.rs b/AgentCompany-Rust/crates/app_ui/src/app_root/inbox.rs index d1d42458..c202147a 100644 --- a/AgentCompany-Rust/crates/app_ui/src/app_root/inbox.rs +++ b/AgentCompany-Rust/crates/app_ui/src/app_root/inbox.rs @@ -186,7 +186,7 @@ impl InboxRow { .flex() .gap_3() .items_center() - .child(div().w(px(36.0)).h(px(36.0)).rounded_lg().bg(tile_bg)) + .child(div().w(px(36.0)).h(px(36.0)).rounded(px(0.0)).bg(tile_bg)) .child( div() .flex_1() diff --git a/AgentCompany-Rust/crates/app_ui/src/app_root/messages.rs b/AgentCompany-Rust/crates/app_ui/src/app_root/messages.rs index 413be346..7c2397bf 100644 --- a/AgentCompany-Rust/crates/app_ui/src/app_root/messages.rs +++ b/AgentCompany-Rust/crates/app_ui/src/app_root/messages.rs @@ -37,7 +37,6 @@ impl AppRoot { div() .flex() - .gap_3() .child(render_message_sidebar( &channel_groups, selected_channel.as_deref(), @@ -47,10 +46,8 @@ impl AppRoot { .child( div() .flex_1() - .border_1() - .rounded_md() - .border_color(theme::panel_border()) - .bg(theme::panel()) + .flex_col() + .bg(theme::card()) .child(render_message_header( self, selected_channel.as_deref(), @@ -61,8 +58,9 @@ impl AppRoot { div() .id("messages-stream") .flex_1() - .p_4() .overflow_scroll() + .px(px(8.0)) + .py(px(12.0)) .when(visible_messages.is_empty(), |container| { container.child(selected_message_card(None)) }) @@ -77,7 +75,7 @@ impl AppRoot { message.id ))) .cursor_pointer() - .hover(|style| style.bg(theme::panel_hover())) + .hover(|style| style.bg(theme::muted())) .on_click(cx.listener(move |this, _, _, cx| { this.state.selected_message_id = Some(message_id.clone()); @@ -225,101 +223,131 @@ fn render_message_sidebar<'a>( cx: &'a mut Context, ) -> impl IntoElement + 'a { div() - .w(px(292.0)) - .p_3() - .gap_3() - .border_1() - .rounded_md() - .border_color(theme::panel_border()) - .bg(theme::sidebar_bg()) - .children(groups.iter().map(|group| { + .w(px(260.0)) + .flex_col() + .overflow_hidden() + .border_r_1() + .border_color(theme::border()) + .bg(theme::card()) + .child( div() - .gap_2() - .child(message_section_label(group.label)) - .children(group.rows.iter().map(|channel| { - let active = active_channel == Some(channel.key.as_str()); - let next_message_id = channel - .rows - .first() - .cloned() - .or_else(|| selected_message_id.clone()) - .unwrap_or_default(); + .id("message-sidebar-scroll") + .flex_1() + .overflow_scroll() + .px(px(8.0)) + .py(px(12.0)) + .children(groups.iter().map(|group| { div() - .id(SharedString::from(format!( - "message-channel-{}", - channel.key - ))) - .cursor_pointer() - .hover(|style| style.bg(theme::panel_hover())) - .bg(if active { - theme::selection_fill() - } else { - theme::panel() - }) - .rounded_md() - .px_3() - .py_2() - .on_click(cx.listener(move |this, _, _, cx| { - if !next_message_id.is_empty() { - this.state.selected_message_id = Some(next_message_id.clone()); - } - cx.notify(); - })) - .child( + .mb_3() + .child(message_section_label(group.label)) + .children(group.rows.iter().map(|channel| { + let active = active_channel == Some(channel.key.as_str()); + let next_message_id = channel + .rows + .first() + .cloned() + .or_else(|| selected_message_id.clone()) + .unwrap_or_default(); div() - .flex() - .items_center() - .gap_3() + .id(SharedString::from(format!( + "message-channel-{}", + channel.key + ))) + .cursor_pointer() + .hover(|style| { + if active { + style + } else { + style.bg(theme::muted()) + } + }) + .bg(if active { + theme::accent() + } else { + theme::card() + }) + .px(px(12.0)) + .py(px(8.0)) + .on_click(cx.listener(move |this, _, _, cx| { + if !next_message_id.is_empty() { + this.state.selected_message_id = Some(next_message_id.clone()); + } + cx.notify(); + })) .child( div() - .w(px(28.0)) - .h(px(28.0)) - .rounded_md() - .bg(theme::panel_muted()), + .flex() + .items_center() + .gap(px(10.0)) + .child( + div() + .w(px(28.0)) + .h(px(28.0)) + .flex() + .items_center() + .justify_center() + .rounded(px(0.0)) + .bg(theme::muted()), + ) + .child( + div().flex_1().child( + div() + .text_size(px(13.0)) + .font_weight(if active || channel.count > 0 { + gpui::FontWeight::SEMIBOLD + } else { + gpui::FontWeight::MEDIUM + }) + .text_color(if active || channel.count > 0 { + theme::foreground() + } else { + theme::muted_foreground() + }) + .truncate() + .child(channel.label.clone()), + ), + ) + .when(channel.urgent, |container| { + container.child( + div() + .w(px(8.0)) + .h(px(8.0)) + .rounded_full() + .bg(theme::destructive()), + ) + }) + .when(channel.count > 0, |container| { + container.child( + div() + .h(px(18.0)) + .min_w(px(18.0)) + .flex() + .items_center() + .justify_center() + .rounded_full() + .bg(theme::primary()) + .px(px(4.0)) + .text_size(px(10.0)) + .font_weight(gpui::FontWeight::BOLD) + .text_color(theme::primary_foreground()) + .child(channel.count.to_string()), + ) + }), ) - .child( - div().flex_1().child( - div() - .text_sm() - .text_color(if active { - theme::sidebar_text_active() - } else { - theme::text_secondary() - }) - .truncate() - .child(channel.label.clone()), - ), - ) - .when(channel.urgent, |container| { - container.child( - div() - .w(px(8.0)) - .h(px(8.0)) - .rounded_full() - .bg(theme::danger()), - ) - }) - .when(channel.count > 0, |container| { - container.child( - div() - .px_2() - .py_1() - .rounded_full() - .bg(theme::primary_action()) - .text_xs() - .text_color(theme::primary_action_text()) - .child(channel.count.to_string()), - ) - }), - ) - })) - })) + })) + })), + ) .child( div() .flex() .justify_between() - .text_xs() - .text_color(theme::text_muted()) + .items_center() + .px(px(16.0)) + .py(px(8.0)) + .border_t_1() + .border_color(theme::border()) + .text_size(px(11.0)) + .text_color(theme::muted_foreground()) .child(format!( "{} channels", groups.iter().map(|group| group.rows.len()).sum::() @@ -338,23 +366,25 @@ fn render_message_header( .flex() .justify_between() .items_center() - .px_5() - .py_4() + .px(px(16.0)) + .py(px(10.0)) .border_b_1() - .border_color(theme::panel_border()) + .border_color(theme::border()) + .bg(theme::card()) .child( div() .child( div() - .text_lg() - .text_color(theme::text_primary()) + .text_size(px(13.0)) + .font_weight(gpui::FontWeight::SEMIBOLD) + .text_color(theme::foreground()) .child(active_channel.unwrap_or("Select a channel").to_string()), ) .child( div() .mt(px(4.0)) - .text_sm() - .text_color(theme::text_muted()) + .text_size(px(11.0)) + .text_color(theme::muted_foreground()) .child(format!("{} visible messages", visible_count)), ), ) @@ -374,11 +404,11 @@ fn render_message_composer<'a>( cx: &'a mut Context, ) -> impl IntoElement + 'a { div() - .px_4() - .py_3() + .px(px(16.0)) + .py(px(12.0)) .border_t_1() - .border_color(theme::panel_border()) - .bg(theme::panel()) + .border_color(theme::border()) + .bg(theme::card()) .child( div() .flex() @@ -390,10 +420,10 @@ fn render_message_composer<'a>( div() .mt(px(12.0)) .p_3() - .rounded_lg() - .bg(theme::panel_inset()) + .rounded(px(0.0)) + .bg(theme::muted()) .border_1() - .border_color(theme::panel_inset_border()) + .border_color(theme::border()) .child(root.message_input.clone()), ) .child( @@ -404,8 +434,8 @@ fn render_message_composer<'a>( .items_center() .child( div() - .text_xs() - .text_color(theme::text_muted()) + .text_size(px(11.0)) + .text_color(theme::muted_foreground()) .child("Reply, mention, or route an operational update."), ) .child( @@ -426,14 +456,15 @@ fn render_message_inspector(selected: Option<&domain::AgentMessage>) -> impl Int div() .w(px(320.0)) .border_1() - .rounded_lg() - .border_color(theme::panel_border()) - .bg(theme::panel()) - .p_5() + .rounded(px(0.0)) + .border_color(theme::border()) + .bg(theme::card()) + .p(px(20.0)) .child( div() - .text_lg() - .text_color(theme::text_primary()) + .text_size(px(13.0)) + .font_weight(gpui::FontWeight::SEMIBOLD) + .text_color(theme::foreground()) .child("Conversation details"), ) .child(selected_message_card(selected)) @@ -445,26 +476,27 @@ fn render_message_inspector(selected: Option<&domain::AgentMessage>) -> impl Int fn message_filter_toggle(unread_only: bool, cx: &mut Context) -> impl IntoElement { div() .id("message-filter-toggle") - .px_3() - .py_2() + .px(px(10.0)) + .py(px(6.0)) .rounded_full() .cursor_pointer() .bg(if unread_only { - theme::primary_action() + theme::primary() } else { - theme::panel_muted() + theme::muted() }) - .text_xs() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight::MEDIUM) .text_color(if unread_only { - theme::primary_action_text() + theme::primary_foreground() } else { - theme::text_secondary() + theme::muted_foreground() }) .hover(|style| { style.bg(if unread_only { - theme::primary_action_hover() + theme::primary() } else { - theme::panel_hover() + theme::muted() }) }) .on_click(cx.listener(move |this, _, _, cx| { diff --git a/AgentCompany-Rust/crates/app_ui/src/app_root/messages_parts.rs b/AgentCompany-Rust/crates/app_ui/src/app_root/messages_parts.rs index f5924b46..5d277bd9 100644 --- a/AgentCompany-Rust/crates/app_ui/src/app_root/messages_parts.rs +++ b/AgentCompany-Rust/crates/app_ui/src/app_root/messages_parts.rs @@ -1,7 +1,13 @@ use super::*; pub(super) fn message_section_label(label: &'static str) -> impl IntoElement { - div().text_xs().text_color(theme::text_muted()).child(label) + div() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight::SEMIBOLD) + .text_color(theme::muted_foreground()) + .mb(px(4.0)) + .px(px(8.0)) + .child(label) } pub(super) fn selected_message_card(message: Option<&domain::AgentMessage>) -> impl IntoElement { @@ -14,30 +20,31 @@ pub(super) fn selected_message_card(message: Option<&domain::AgentMessage>) -> i }); div() .p_4() - .rounded_md() + .rounded(px(0.0)) .border_1() - .border_color(theme::panel_border()) - .bg(theme::panel()) + .border_color(theme::border()) + .bg(theme::card()) .child(message_header(message, false)) .child( div() .mt(px(16.0)) - .text_lg() - .text_color(theme::text_primary()) + .text_size(px(14.0)) + .font_weight(gpui::FontWeight::SEMIBOLD) + .text_color(theme::foreground()) .child(subject), ) .child( div() .mt(px(12.0)) - .text_base() - .text_color(theme::text_secondary()) + .text_size(px(14.0)) + .text_color(theme::muted_foreground()) .child(body), ) .child( div() .mt(px(16.0)) - .text_sm() - .text_color(theme::text_muted()) + .text_size(px(14.0)) + .text_color(theme::muted_foreground()) .child("↩ Reply"), ) } @@ -45,24 +52,25 @@ pub(super) fn selected_message_card(message: Option<&domain::AgentMessage>) -> i pub(super) fn compact_message_card(message: &domain::AgentMessage) -> impl IntoElement { div() .mt(px(16.0)) - .p_5() - .rounded_lg() + .p(px(12.0)) + .rounded(px(0.0)) .border_1() - .border_color(theme::panel_border()) - .bg(theme::panel()) + .border_color(theme::border()) + .bg(theme::card()) .child(message_header(Some(message), true)) .child( div() .mt(px(12.0)) - .text_base() - .text_color(theme::text_primary()) + .text_size(px(14.0)) + .font_weight(gpui::FontWeight::SEMIBOLD) + .text_color(theme::foreground()) .child(message.subject.clone()), ) .child( div() .mt(px(8.0)) - .text_sm() - .text_color(theme::text_muted()) + .text_size(px(14.0)) + .text_color(theme::muted_foreground()) .line_clamp(2) .child(message.body.clone()), ) @@ -82,62 +90,75 @@ fn message_header(message: Option<&domain::AgentMessage>, urgent: bool) -> impl .gap_3() .child( div() - .w(px(40.0)) - .h(px(40.0)) + .w(px(36.0)) + .h(px(36.0)) .rounded_full() - .bg(theme::accent_orange_soft()) + .bg(theme::accent()) .border_1() - .border_color(theme::panel_border()) - .text_color(theme::accent_orange()) + .border_color(theme::border()) + .text_color(theme::foreground()) .flex() .items_center() .justify_center() + .text_size(px(14.0)) + .font_weight(gpui::FontWeight::MEDIUM) .child(sender.to_string()), ) .child( div() .flex() + .flex_1() .gap_2() .items_center() .child( - div().text_sm().text_color(theme::accent_orange()).child( - message - .map(|item| item.sender_kind.clone()) - .unwrap_or_else(|| "human".to_string()), - ), - ) - .child( - div().text_sm().text_color(theme::text_muted()).child( - message - .map(|item| item.channel.clone()) - .unwrap_or_else(|| "company".to_string()), - ), + div() + .text_size(px(14.0)) + .font_weight(gpui::FontWeight::MEDIUM) + .text_color(theme::foreground()) + .child( + message + .map(|item| item.sender_kind.clone()) + .unwrap_or_else(|| "human".to_string()), + ), ) .child( div() - .px_2() - .py_1() + .text_size(px(12.0)) + .text_color(theme::muted_foreground()) + .child( + message + .map(|item| item.channel.clone()) + .unwrap_or_else(|| "company".to_string()), + ), + ) + .child( + div() + .px(px(8.0)) + .py(px(2.0)) .rounded_full() - .bg(theme::accent_orange_soft()) - .text_xs() - .text_color(theme::accent_orange()) + .bg(theme::primary()) + .text_size(px(10.0)) + .font_weight(gpui::FontWeight::MEDIUM) + .text_color(theme::primary_foreground()) .child("OPERATIONS"), ) .child( div() - .text_sm() - .text_color(theme::text_muted()) + .flex_1() + .text_size(px(12.0)) + .text_color(theme::muted_foreground()) .child(timestamp), ) .when(urgent, |container| { container.child( div() - .px_2() - .py_1() + .px(px(8.0)) + .py(px(2.0)) .rounded_full() - .bg(theme::danger_bg()) - .text_xs() - .text_color(theme::danger()) + .bg(theme::destructive()) + .text_size(px(10.0)) + .font_weight(gpui::FontWeight::MEDIUM) + .text_color(theme::primary_foreground()) .child("URGENT"), ) }), @@ -156,28 +177,29 @@ fn trim_sender(sender: &str) -> &str { pub(super) fn composer_chip(label: &str) -> impl IntoElement { div() - .px_4() - .py_3() - .rounded_lg() + .px(px(12.0)) + .py(px(6.0)) + .rounded(px(0.0)) .border_1() - .border_color(theme::panel_border()) - .bg(theme::panel()) - .text_sm() - .text_color(theme::text_secondary()) + .border_color(theme::border()) + .bg(theme::muted()) + .text_size(px(12.0)) + .font_weight(gpui::FontWeight::MEDIUM) + .text_color(theme::muted_foreground()) .child(label.to_string()) } pub(super) fn composer_subject(message: Option<&domain::AgentMessage>) -> impl IntoElement { div() .flex_1() - .px_4() - .py_3() - .rounded_lg() + .px(px(12.0)) + .py(px(6.0)) + .rounded(px(0.0)) .border_1() - .border_color(theme::panel_border()) - .bg(theme::panel()) - .text_sm() - .text_color(theme::text_subtle()) + .border_color(theme::border()) + .bg(theme::card()) + .text_size(px(14.0)) + .text_color(theme::muted_foreground()) .child( message .map(|item| item.subject.clone()) diff --git a/AgentCompany-Rust/crates/app_ui/src/app_root/onboarding.rs b/AgentCompany-Rust/crates/app_ui/src/app_root/onboarding.rs index 8bd0e353..a118aeb1 100644 --- a/AgentCompany-Rust/crates/app_ui/src/app_root/onboarding.rs +++ b/AgentCompany-Rust/crates/app_ui/src/app_root/onboarding.rs @@ -193,7 +193,7 @@ impl AppRoot { )) .child( div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel_inset()) @@ -255,7 +255,7 @@ impl AppRoot { )) .child( div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel_inset()) @@ -383,7 +383,7 @@ impl AppRoot { )) .child( div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel_inset()) @@ -443,7 +443,7 @@ impl AppRoot { ) .child( div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel_inset()) @@ -484,7 +484,7 @@ impl AppRoot { .child(self.onboarding_goal_detail_input.clone()) .child( div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel_inset()) @@ -830,7 +830,7 @@ fn step_connector(active: bool) -> impl IntoElement { fn onboarding_metric_row(label: &'static str, value: String) -> impl IntoElement { div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel_inset()) @@ -892,7 +892,7 @@ fn onboarding_card() -> gpui::Div { div() .w_full() .p_8() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -1018,7 +1018,7 @@ fn summary_tile(label: &'static str, value: String) -> impl IntoElement { div() .min_h(px(92.0)) .p_5() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_inset_border()) .bg(theme::panel_inset()) diff --git a/AgentCompany-Rust/crates/app_ui/src/app_root/overview.rs b/AgentCompany-Rust/crates/app_ui/src/app_root/overview.rs index c3d2e4f0..51a9e54b 100644 --- a/AgentCompany-Rust/crates/app_ui/src/app_root/overview.rs +++ b/AgentCompany-Rust/crates/app_ui/src/app_root/overview.rs @@ -209,33 +209,59 @@ impl AppRoot { } fn recovery_banner(runs: &[&domain::Run]) -> impl IntoElement { + let danger_30 = gpui::Hsla { a: 0.3, ..theme::danger() }; div() - .rounded_lg() + .rounded(px(0.0)) .border_1() - .border_color(theme::danger()) - .bg(theme::danger_bg()) - .p_4() - .gap_3() - .child(div().text_sm().text_color(theme::danger()).child(format!( - "{} interrupted task(s) detected from the previous session", - runs.len() - ))) + .border_color(danger_30) + .bg(theme::warning_bg()) + .px_4() + .py_4() + .mb_4() + .child( + div() + .flex() + .gap_2() + .items_center() + .child( + div() + .w(px(16.0)) + .h(px(16.0)) + .rounded(px(4.0)) + .bg(theme::danger()) + .flex() + .items_center() + .justify_center() + .child(div().w(px(10.0)).h(px(10.0)).rounded_full().bg(theme::panel())), + ) + .child( + div() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight::MEDIUM) + .text_color(theme::text_primary()) + .child(format!( + "{} interrupted task(s) detected from the previous session", + runs.len() + )), + ), + ) .children(runs.iter().map(|run| { div() - .rounded_md() + .mt(px(8.0)) + .rounded(px(4.0)) .bg(theme::panel()) .px_4() .py_3() .child( div() - .text_sm() + .text_size(px(13.0)) .text_color(theme::text_primary()) .child(overview_run_title_from_run(run)), ) .child( div() .mt(px(4.0)) - .text_xs() + .text_size(px(11.0)) .text_color(theme::text_muted()) .child(run.id.get(..8).unwrap_or(run.id.as_str()).to_string()), ) @@ -243,13 +269,14 @@ fn recovery_banner(runs: &[&domain::Run]) -> impl IntoElement { } fn budget_alert_banner(agents: &[&domain::Agent], cx: &mut Context) -> impl IntoElement { + let danger_30 = gpui::Hsla { a: 0.3, ..theme::danger() }; div().gap_2().children(agents.iter().map(|agent| { div() .id(SharedString::from(format!("budget-alert-{}", agent.id))) - .rounded_lg() + .rounded(px(0.0)) .border_1() - .border_color(theme::danger()) - .bg(theme::accent_orange_soft()) + .border_color(danger_30) + .bg(theme::danger_bg()) .px_4() .py_3() .cursor_pointer() @@ -260,12 +287,30 @@ fn budget_alert_banner(agents: &[&domain::Agent], cx: &mut Context) -> })) .child( div() - .text_sm() - .text_color(theme::accent_orange()) - .child(format!( - "{} is at ${:.2} / ${:.2} monthly budget.", - agent.name, agent.spent_monthly_usd, agent.budget_monthly_usd - )), + .flex() + .gap_2() + .items_center() + .child( + div() + .w(px(16.0)) + .h(px(16.0)) + .rounded(px(4.0)) + .bg(theme::danger()) + .flex() + .items_center() + .justify_center() + .child(div().w(px(10.0)).h(px(10.0)).rounded_full().bg(theme::panel())), + ) + .child( + div() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight::MEDIUM) + .text_color(theme::text_primary()) + .child(format!( + "{} is at ${:.2} / ${:.2} monthly budget.", + agent.name, agent.spent_monthly_usd, agent.budget_monthly_usd + )), + ), ) })) } @@ -275,17 +320,25 @@ fn metric_card( value: String, subtitle: String, icon_bg: gpui::Hsla, - tone: gpui::Hsla, + _tone: gpui::Hsla, target_section: SectionId, cx: &mut Context, ) -> impl IntoElement { + let icon_letter = match label { + "ACTIVE TASKS" => "T", + "APPROVALS" => "A", + "RUNS" => "R", + "AGENTS" => "A", + _ => "•", + }; div() .id(SharedString::from(format!("overview-metric-{label}"))) - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) - .p_4() + .px_4() + .py_4() .cursor_pointer() .hover(|style| style.bg(theme::panel_hover())) .on_click(cx.listener(move |this, _, _, cx| { @@ -297,16 +350,45 @@ fn metric_card( .flex() .gap_4() .items_center() - .child(div().w(px(48.0)).h(px(48.0)).rounded_lg().bg(icon_bg)) + .child( + div() + .w(px(48.0)) + .h(px(48.0)) + .rounded(px(4.0)) + .bg(icon_bg) + .flex() + .items_center() + .justify_center() + .child( + div() + .text_size(px(18.0)) + .font_weight(gpui::FontWeight::BOLD) + .text_color(theme::text_muted()) + .child(icon_letter), + ), + ) .child( div() .flex_1() - .child(div().text_xs().text_color(theme::text_muted()).child(label)) - .child(div().text_3xl().text_color(tone).child(value)) + .child( + div() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight::SEMIBOLD) + .text_color(theme::text_muted()) + .child(label), + ) + .child( + div() + .text_size(px(28.0)) + .font_weight(gpui::FontWeight::BOLD) + .text_color(theme::text_primary()) + .child(value), + ) .child( div() .mt(px(6.0)) - .text_xs() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight::MEDIUM) .text_color(theme::text_muted()) .child(subtitle), ), @@ -315,7 +397,11 @@ fn metric_card( } fn eyebrow_label(label: &'static str) -> impl IntoElement { - div().text_xs().text_color(theme::text_muted()).child(label) + div() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight::SEMIBOLD) + .text_color(theme::text_muted()) + .child(label) } fn needs_attention_label() -> impl IntoElement { @@ -332,7 +418,8 @@ fn needs_attention_label() -> impl IntoElement { ) .child( div() - .text_xs() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight::SEMIBOLD) .text_color(theme::accent_orange()) .child("NEEDS ATTENTION"), ) @@ -350,7 +437,7 @@ fn attention_row( let selected_id = target_id.map(str::to_string); div() .id(SharedString::from(format!("overview-attention-{title}"))) - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -373,26 +460,48 @@ fn attention_row( .flex() .gap_3() .items_center() - .child(div().w(px(36.0)).h(px(36.0)).rounded_lg().bg(tile_bg)) + .child( + div() + .w(px(36.0)) + .h(px(36.0)) + .rounded(px(4.0)) + .bg(tile_bg) + .flex() + .items_center() + .justify_center() + .child( + div() + .w(px(8.0)) + .h(px(8.0)) + .rounded_full() + .bg(accent), + ), + ) .child( div() .flex_1() .child( div() - .text_sm() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight::MEDIUM) .text_color(theme::text_primary()) .child(title), ) .child( div() .mt(px(4.0)) - .text_xs() + .text_size(px(11.0)) .text_color(theme::text_muted()) .line_clamp(2) .child(subtitle), ), ) - .child(div().w(px(10.0)).h(px(10.0)).rounded_full().bg(accent)), + .child( + div() + .text_size(px(14.0)) + .text_color(theme::text_muted()) + .child(">"), + ), ) } @@ -440,21 +549,23 @@ fn success_rate_card(snapshot: &domain::ProfileSnapshot) -> impl IntoElement { completed as f32 / finished as f32 }; div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) .p_5() .child( div() - .text_xs() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight::SEMIBOLD) .text_color(theme::text_muted()) .child("SUCCESS RATE"), ) .child( div() .mt(px(10.0)) - .text_3xl() + .text_size(px(28.0)) + .font_weight(gpui::FontWeight::BOLD) .text_color(theme::accent_teal()) .child(format!("{:.0}%", rate * 100.0)), ) @@ -487,28 +598,30 @@ fn cost_trend_card(snapshot: &domain::ProfileSnapshot) -> impl IntoElement { total / costs.len() as f64 }; div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) .p_5() .child( div() - .text_xs() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight::SEMIBOLD) .text_color(theme::text_muted()) .child("COST TREND"), ) .child( div() .mt(px(10.0)) - .text_3xl() + .text_size(px(28.0)) + .font_weight(gpui::FontWeight::BOLD) .text_color(theme::text_primary()) .child(format!("${total:.2}")), ) .child( div() .mt(px(8.0)) - .text_xs() + .text_size(px(11.0)) .text_color(theme::text_muted()) .child(format!("Average ${average:.2} per metered run")), ) @@ -542,12 +655,18 @@ fn mini_chart_card( .unwrap_or(1) .max(1) as f32; div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) .p_5() - .child(div().text_xs().text_color(theme::text_muted()).child(label)) + .child( + div() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight::SEMIBOLD) + .text_color(theme::text_muted()) + .child(label), + ) .children(rows.into_iter().map(|(name, count)| { div() .mt(px(12.0)) @@ -557,13 +676,15 @@ fn mini_chart_card( .justify_between() .child( div() - .text_sm() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight::MEDIUM) .text_color(theme::text_primary()) .child(name), ) .child( div() - .text_xs() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight::MEDIUM) .text_color(theme::text_muted()) .child(count.to_string()), ), @@ -587,7 +708,7 @@ fn mini_chart_card( fn budget_utilization_card(snapshot: &domain::ProfileSnapshot) -> impl IntoElement { div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -609,16 +730,21 @@ fn budget_utilization_card(snapshot: &domain::ProfileSnapshot) -> impl IntoEleme .items_center() .child( div() - .text_sm() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight::MEDIUM) .text_color(theme::text_primary()) .child(agent.name.clone()), ) - .child(div().text_xs().text_color(theme::text_muted()).child( - format!( - "${:.2} / ${:.2}", - agent.spent_monthly_usd, agent.budget_monthly_usd - ), - )), + .child( + div() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight::MEDIUM) + .text_color(theme::text_muted()) + .child(format!( + "${:.2} / ${:.2}", + agent.spent_monthly_usd, agent.budget_monthly_usd + )), + ), ) .child( div() @@ -650,7 +776,8 @@ fn active_work_header(cx: &mut Context) -> impl IntoElement { div() .id("overview-all-runs") .cursor_pointer() - .text_xs() + .text_size(px(11.0)) + .font_weight(gpui::FontWeight::MEDIUM) .text_color(theme::accent_blue()) .hover(|style| style.text_color(theme::text_primary())) .on_click(cx.listener(|this, _, _, cx| { @@ -667,7 +794,7 @@ fn active_work_card<'a>( cx: &mut Context, ) -> impl IntoElement + 'a { div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -692,20 +819,21 @@ fn active_work_card<'a>( this.state.selected_run_id = Some(run_id.clone()); cx.notify(); })) - .px_5() - .py_4() + .px_4() + .py_3() .border_b_1() .border_color(theme::panel_border()) .child( div() - .text_base() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight::MEDIUM) .text_color(theme::text_primary()) .child(overview_run_title(snapshot, run)), ) .child( div() .mt(px(4.0)) - .text_sm() + .text_size(px(11.0)) .text_color(theme::text_muted()) .child(format!( "{} · {}", @@ -719,26 +847,27 @@ fn active_work_card<'a>( fn activity_feed_card(snapshot: &domain::ProfileSnapshot) -> impl IntoElement { div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) .children(snapshot.activity.iter().take(10).map(|item| { div() - .px_5() - .py_4() + .px_4() + .py_3() .border_b_1() .border_color(theme::panel_border()) .child( div() - .text_sm() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight::MEDIUM) .text_color(theme::text_primary()) .child(format!("{} {}", item.actor, item.action.replace('_', " "))), ) .child( div() .mt(px(4.0)) - .text_xs() + .text_size(px(11.0)) .text_color(theme::text_muted()) .child(item.detail.clone()), ) diff --git a/AgentCompany-Rust/crates/app_ui/src/app_root/runs.rs b/AgentCompany-Rust/crates/app_ui/src/app_root/runs.rs index d55156c4..cad3576c 100644 --- a/AgentCompany-Rust/crates/app_ui/src/app_root/runs.rs +++ b/AgentCompany-Rust/crates/app_ui/src/app_root/runs.rs @@ -49,7 +49,7 @@ fn render_run_queue_panel( ) -> impl IntoElement { div().w(px(420.0)).gap_5().child( div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -86,7 +86,7 @@ fn render_run_queue_panel( container.child( div() .mt(px(16.0)) - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel_muted()) @@ -127,7 +127,7 @@ fn run_queue_row( div() .id(SharedString::from(format!("run-row-{}", run.id))) - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(if active { theme::selection_border() @@ -154,42 +154,43 @@ fn run_queue_row( .items_center() .gap_3() .child( - div() - .flex_1() - .child( - div() - .text_sm() - .text_color(theme::text_primary()) - .truncate() - .child(title), - ) - .child( - div() - .mt(px(4.0)) - .text_xs() - .text_color(theme::text_muted()) - .truncate() - .child(subtitle), - ), + div() + .flex_1() + .child( + div() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight::SEMIBOLD) + .text_color(theme::text_primary()) + .truncate() + .child(title), + ) + .child( + div() + .mt(px(2.0)) + .text_size(px(11.0)) + .text_color(theme::text_muted()) + .truncate() + .child(subtitle), + ), ) .child(run_status_badge(run.status.as_str())), ) .child( div() - .mt(px(8.0)) + .mt(px(6.0)) .flex() .justify_between() .gap_3() .child( div() - .text_xs() + .text_size(px(11.0)) .text_color(theme::text_muted()) .line_clamp(1) .child(supporting_text), ) .child( div() - .text_xs() + .text_size(px(11.0)) .text_color(theme::text_muted()) .child(short_date(run.updated_at.as_str()).to_string()), ), @@ -222,7 +223,7 @@ fn render_run_detail_column<'a>( .flex() .items_center() .justify_center() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -254,7 +255,7 @@ fn runs_empty_state() -> impl IntoElement { .flex() .items_center() .justify_center() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -280,7 +281,7 @@ fn runs_empty_state() -> impl IntoElement { fn run_detail_panel(snapshot: &domain::ProfileSnapshot, run: &domain::Run) -> impl IntoElement { div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -350,7 +351,7 @@ fn run_detail_panel(snapshot: &domain::ProfileSnapshot, run: &domain::Run) -> im .child( div() .mt(px(16.0)) - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_inset_border()) .bg(theme::panel_inset()) @@ -370,7 +371,7 @@ fn run_detail_panel(snapshot: &domain::ProfileSnapshot, run: &domain::Run) -> im content.child( div() .mt(px(16.0)) - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::danger()) .bg(theme::danger_bg()) @@ -386,7 +387,7 @@ fn run_detail_panel(snapshot: &domain::ProfileSnapshot, run: &domain::Run) -> im fn run_trace_panel(snapshot: &domain::ProfileSnapshot, run: &domain::Run) -> impl IntoElement { div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -402,7 +403,7 @@ fn run_trace_panel(snapshot: &domain::ProfileSnapshot, run: &domain::Run) -> imp fn secondary_data_panel(title: &'static str, body: gpui::AnyElement) -> impl IntoElement { div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -654,7 +655,7 @@ fn run_live_controls_panel<'a>( cx: &'a mut Context, ) -> impl IntoElement + 'a { div() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) diff --git a/AgentCompany-Rust/crates/app_ui/src/app_root/settings.rs b/AgentCompany-Rust/crates/app_ui/src/app_root/settings.rs index c50ceb97..210df2f1 100644 --- a/AgentCompany-Rust/crates/app_ui/src/app_root/settings.rs +++ b/AgentCompany-Rust/crates/app_ui/src/app_root/settings.rs @@ -220,7 +220,7 @@ fn settings_tab_button( fn settings_panel(label: &'static str, rows: Vec) -> impl IntoElement { div() .p_5() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) @@ -290,7 +290,7 @@ where .id(SharedString::from(format!("settings-action-{label}"))) .px_3() .py_2() - .rounded_lg() + .rounded(px(0.0)) .cursor_pointer() .bg(if active { theme::primary_action() diff --git a/AgentCompany-Rust/crates/app_ui/src/app_root/sidebar.rs b/AgentCompany-Rust/crates/app_ui/src/app_root/sidebar.rs index 166bc0b8..0f7c91fb 100644 --- a/AgentCompany-Rust/crates/app_ui/src/app_root/sidebar.rs +++ b/AgentCompany-Rust/crates/app_ui/src/app_root/sidebar.rs @@ -17,7 +17,7 @@ impl AppRoot { ]; div() - .w(px(292.0)) + .w(px(256.0)) .h_full() .p_4() .gap_4() @@ -41,7 +41,7 @@ impl AppRoot { ) .child( div() - .text_xs() + .text_size(px(11.0)) .text_color(theme::text_subtle()) .child("local-first"), ), @@ -54,40 +54,38 @@ impl AppRoot { .child( div() .flex_1() - .px_4() - .py_3() + .px_3() + .py_2() .border_1() - .rounded_lg() + .rounded(px(0.0)) .border_color(theme::panel_border()) .bg(theme::panel()) - .child( - div().text_sm().text_color(theme::text_primary()).child( - self.snapshot - .current_company() - .map(|company| company.name.clone()) - .unwrap_or_else(|| "AgentCompany".to_string()), - ), - ) .child( div() - .text_xs() - .text_color(theme::text_muted()) - .child("native GPUI shell"), + .text_size(px(13.0)) + .font_weight(gpui::FontWeight::MEDIUM) + .text_color(theme::text_primary()) + .child( + self.snapshot + .current_company() + .map(|company| company.name.clone()) + .unwrap_or_else(|| "AgentCompany".to_string()), + ), ), ) .child( div() - .w(px(44.0)) - .h(px(44.0)) - .rounded_lg() + .w(px(30.0)) + .h(px(30.0)) + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) .flex() .items_center() .justify_center() - .text_sm() - .text_color(theme::text_secondary()) + .text_size(px(12.0)) + .text_color(theme::text_muted()) .child("⌘"), ), ) @@ -97,16 +95,10 @@ impl AppRoot { let company_id = company.id.clone(); div() .id(SharedString::from(format!("company-{}", company.id))) - .px_4() - .py_3() - .rounded_lg() + .px_3() + .py_2() + .rounded(px(0.0)) .cursor_pointer() - .border_1() - .border_color(if active { - theme::selection_border() - } else { - theme::panel_border() - }) .bg(if active { theme::selection_fill() } else { @@ -118,7 +110,12 @@ impl AppRoot { })) .child( div() - .text_sm() + .text_size(px(13.0)) + .font_weight(if active { + gpui::FontWeight::SEMIBOLD + } else { + gpui::FontWeight::MEDIUM + }) .text_color(if active { theme::sidebar_text_active() } else { @@ -126,12 +123,6 @@ impl AppRoot { }) .child(company.name.clone()), ) - .child( - div() - .text_xs() - .text_color(theme::text_muted()) - .child(format!("{} mode", company.execution_mode.replace('_', " "))), - ) })) .child(div().h(px(1.0)).bg(theme::sidebar_divider())) .children(sections.into_iter().map(|(section, badge)| { @@ -145,16 +136,10 @@ impl AppRoot { .flex() .items_center() .justify_between() - .px_4() - .py_3() - .rounded_lg() + .px_3() + .py(px(7.0)) + .rounded(px(0.0)) .cursor_pointer() - .border_1() - .border_color(if active { - theme::selection_border() - } else { - theme::sidebar_bg() - }) .bg(if active { theme::selection_fill() } else { @@ -170,7 +155,12 @@ impl AppRoot { this.state.section = section; cx.notify(); })) - .child(div().text_sm().child(label)) + .child( + div() + .text_size(px(13.0)) + .font_weight(gpui::FontWeight::MEDIUM) + .child(label), + ) .when_some(badge.filter(|count| *count > 0), |container, count| { container.child( div() @@ -183,7 +173,7 @@ impl AppRoot { } else { theme::badge_dark() }) - .text_xs() + .text_size(px(11.0)) .text_color(theme::panel()) .child(count.to_string()), ) @@ -200,23 +190,6 @@ impl AppRoot { cx.notify(); }, )) - .child( - div() - .px_4() - .py_3() - .rounded_lg() - .bg(theme::panel_muted()) - .child( - div() - .text_xs() - .text_color(theme::text_muted()) - .child(format!( - "{} agents · {} channels", - self.snapshot.agents.len(), - self.snapshot.agent_messages.len() - )), - ), - ) } } @@ -233,7 +206,7 @@ where .id(SharedString::from(format!("sidebar-footer-{label}"))) .px_4() .py_3() - .rounded_lg() + .rounded(px(0.0)) .cursor_pointer() .bg(if active { theme::selection_fill() diff --git a/AgentCompany-Rust/crates/app_ui/src/app_root/workspaces.rs b/AgentCompany-Rust/crates/app_ui/src/app_root/workspaces.rs index b55cd892..fa27cbb9 100644 --- a/AgentCompany-Rust/crates/app_ui/src/app_root/workspaces.rs +++ b/AgentCompany-Rust/crates/app_ui/src/app_root/workspaces.rs @@ -56,7 +56,7 @@ impl AppRoot { .flex() .items_center() .justify_center() - .rounded_lg() + .rounded(px(0.0)) .border_1() .border_color(theme::panel_border()) .bg(theme::panel()) diff --git a/AgentCompany-Rust/crates/app_ui/src/theme.rs b/AgentCompany-Rust/crates/app_ui/src/theme.rs index b735bd2c..31a6f84d 100644 --- a/AgentCompany-Rust/crates/app_ui/src/theme.rs +++ b/AgentCompany-Rust/crates/app_ui/src/theme.rs @@ -127,3 +127,40 @@ pub fn selection_border() -> Hsla { pub fn badge_dark() -> Hsla { rgb(0x6b7280).into() } + +// Tailwind v4 theme variable aliases (exact oklch → rgb from original styles.css) +pub fn card() -> Hsla { + rgb(0xffffff).into() +} + +pub fn muted() -> Hsla { + rgb(0xf7f7f7).into() +} + +pub fn accent() -> Hsla { + rgb(0xf7f7f7).into() +} + +pub fn foreground() -> Hsla { + rgb(0x222222).into() +} + +pub fn muted_foreground() -> Hsla { + rgb(0x5e5e5e).into() +} + +pub fn primary() -> Hsla { + rgb(0x2d2d2d).into() +} + +pub fn primary_foreground() -> Hsla { + rgb(0xfafafa).into() +} + +pub fn destructive() -> Hsla { + rgb(0xc74a4a).into() +} + +pub fn border() -> Hsla { + rgb(0xe8e8e8).into() +} diff --git a/AgentCompany-Rust/prd.json b/AgentCompany-Rust/prd.json index b965250a..31dd7e5c 100644 --- a/AgentCompany-Rust/prd.json +++ b/AgentCompany-Rust/prd.json @@ -302,7 +302,7 @@ "cargo test --workspace passes" ], "priority": 22, - "passes": true, + "passes": false, "notes": "Passed: shared native surface tokens were tightened toward screenshot-aligned desktop values, warming the pane fills, softening borders, and refining selection/accent colors without touching parent-directory source files." }, { @@ -315,7 +315,7 @@ "cargo test --workspace passes" ], "priority": 23, - "passes": true, + "passes": false, "notes": "Passed: messages and inbox chrome were tightened toward screenshot parity with calmer pane spacing, smaller radii, warmer sidebar treatment, lighter message avatar chrome, and denser list rows while keeping real interactions intact." }, { @@ -328,7 +328,7 @@ "cargo test --workspace passes" ], "priority": 24, - "passes": true, + "passes": false, "notes": "Passed: ui-parity-audit.md now records the fine-grained current-directory visual audit after the shared-skin and communication-skin passes, and the workspace still passes cargo clippy and cargo test." } ]