mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-04 20:42:11 +00:00
Normalize frontend typography + enable font smoothing (#1546)
Lighter, more consistent type across the dashboard and agent UI: unify title sizes, drop semibold/bold in chrome to medium, harmonize stray text-sm to text-xs, normalize chat markdown headings, and enable antialiased font smoothing (fixes heavy text on dark backgrounds). Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This commit is contained in:
parent
801f93b4de
commit
876836bdfe
21 changed files with 58 additions and 52 deletions
|
|
@ -38,7 +38,7 @@ export function AppShell({
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
<header className="mb-8">
|
<header className="mb-8">
|
||||||
<h1 className="font-heading text-lg font-medium">{title}</h1>
|
<h1 className="font-heading text-base font-medium">{title}</h1>
|
||||||
{description && (
|
{description && (
|
||||||
<p className="mt-1 text-xs text-muted-foreground">{description}</p>
|
<p className="mt-1 text-xs text-muted-foreground">{description}</p>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -98,11 +98,11 @@ export function AgentThreadView({ thread }: AgentThreadViewProps) {
|
||||||
</div>
|
</div>
|
||||||
) : isHydrating ? (
|
) : isHydrating ? (
|
||||||
<div className="flex flex-1 flex-col items-center justify-center gap-4 px-6">
|
<div className="flex flex-1 flex-col items-center justify-center gap-4 px-6">
|
||||||
<p className="text-sm text-[var(--ui-text-dim)]">Loading conversation…</p>
|
<p className="text-xs text-[var(--ui-text-dim)]">Loading conversation…</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-1 flex-col items-center justify-center gap-4 px-6">
|
<div className="flex flex-1 flex-col items-center justify-center gap-4 px-6">
|
||||||
<p className="text-sm text-[var(--ui-text-dim)]">
|
<p className="text-xs text-[var(--ui-text-dim)]">
|
||||||
This thread has no messages yet.
|
This thread has no messages yet.
|
||||||
</p>
|
</p>
|
||||||
<div className="w-full max-w-3xl">
|
<div className="w-full max-w-3xl">
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ function ThreadGroup({
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setCollapsed((value) => !value)}
|
onClick={() => setCollapsed((value) => !value)}
|
||||||
className="flex w-full items-center gap-1 px-2 py-1 text-left text-[10px] font-semibold tracking-wide text-[var(--ui-text-dim)] uppercase transition-colors hover:text-[var(--ui-text-muted)]"
|
className="flex w-full items-center gap-1 px-2 py-1 text-left text-[10px] font-medium tracking-wide text-[var(--ui-text-dim)] uppercase transition-colors hover:text-[var(--ui-text-muted)]"
|
||||||
aria-expanded={!collapsed}
|
aria-expanded={!collapsed}
|
||||||
>
|
>
|
||||||
<ToggleIcon className="size-3" />
|
<ToggleIcon className="size-3" />
|
||||||
|
|
@ -270,7 +270,7 @@ function ResolvedThreadGroup({
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setCollapsed((value) => !value)}
|
onClick={() => setCollapsed((value) => !value)}
|
||||||
className="flex w-full items-center gap-1 px-2 py-1 text-left text-[10px] font-semibold tracking-wide text-[var(--ui-text-dim)] uppercase transition-colors hover:text-[var(--ui-text-muted)]"
|
className="flex w-full items-center gap-1 px-2 py-1 text-left text-[10px] font-medium tracking-wide text-[var(--ui-text-dim)] uppercase transition-colors hover:text-[var(--ui-text-muted)]"
|
||||||
aria-expanded={!collapsed}
|
aria-expanded={!collapsed}
|
||||||
>
|
>
|
||||||
<ToggleIcon className="size-3" />
|
<ToggleIcon className="size-3" />
|
||||||
|
|
@ -486,10 +486,10 @@ function ThreadRow({
|
||||||
<Dialog.Backdrop className="fixed inset-0 z-50 bg-black/50 data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0" />
|
<Dialog.Backdrop className="fixed inset-0 z-50 bg-black/50 data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0" />
|
||||||
<Dialog.Popup className="fixed top-1/2 left-1/2 z-50 w-[min(28rem,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-popover p-6 text-popover-foreground shadow-md ring-1 ring-foreground/10 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95">
|
<Dialog.Popup className="fixed top-1/2 left-1/2 z-50 w-[min(28rem,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-popover p-6 text-popover-foreground shadow-md ring-1 ring-foreground/10 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95">
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<Dialog.Title className="text-base font-semibold">
|
<Dialog.Title className="text-sm font-medium">
|
||||||
Delete thread
|
Delete thread
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<Dialog.Description className="text-sm text-muted-foreground">
|
<Dialog.Description className="text-xs text-muted-foreground">
|
||||||
Delete "{thread.title}"? This cannot be undone.
|
Delete "{thread.title}"? This cannot be undone.
|
||||||
</Dialog.Description>
|
</Dialog.Description>
|
||||||
<div className="mt-2 flex justify-end gap-2">
|
<div className="mt-2 flex justify-end gap-2">
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ export function AgentsThreadsPage({
|
||||||
<main className="flex min-w-0 flex-1 flex-col overflow-y-auto px-6 py-8">
|
<main className="flex min-w-0 flex-1 flex-col overflow-y-auto px-6 py-8">
|
||||||
<div className="mx-auto flex w-full max-w-3xl flex-1 flex-col gap-6">
|
<div className="mx-auto flex w-full max-w-3xl flex-1 flex-col gap-6">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="font-heading text-lg font-medium text-[var(--ui-text)]">
|
<h1 className="font-heading text-base font-medium text-[var(--ui-text)]">
|
||||||
Threads
|
Threads
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-xs text-[var(--ui-text-muted)]">
|
<p className="text-xs text-[var(--ui-text-muted)]">
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ export function AutomationEditor({ mode, schedule }: AutomationEditorProps) {
|
||||||
return (
|
return (
|
||||||
<div className="flex min-w-0 flex-1 flex-col overflow-y-auto">
|
<div className="flex min-w-0 flex-1 flex-col overflow-y-auto">
|
||||||
<header className="flex items-center justify-between gap-3 px-6 py-4 max-md:pt-14">
|
<header className="flex items-center justify-between gap-3 px-6 py-4 max-md:pt-14">
|
||||||
<div className="flex min-w-0 items-center gap-1.5 text-sm text-[var(--ui-text-dim)]">
|
<div className="flex min-w-0 items-center gap-1.5 text-xs text-[var(--ui-text-dim)]">
|
||||||
<Link
|
<Link
|
||||||
to="/agents/automations"
|
to="/agents/automations"
|
||||||
className="shrink-0 transition-colors hover:text-[var(--ui-text)]"
|
className="shrink-0 transition-colors hover:text-[var(--ui-text)]"
|
||||||
|
|
@ -179,10 +179,10 @@ export function AutomationEditor({ mode, schedule }: AutomationEditorProps) {
|
||||||
value={name}
|
value={name}
|
||||||
onChange={(e) => setName(e.target.value)}
|
onChange={(e) => setName(e.target.value)}
|
||||||
placeholder="Untitled automation"
|
placeholder="Untitled automation"
|
||||||
className="w-full bg-transparent text-2xl font-semibold text-[var(--ui-text)] outline-none placeholder:text-[var(--ui-text-dim)]"
|
className="w-full bg-transparent text-base font-medium text-[var(--ui-text)] outline-none placeholder:text-[var(--ui-text-dim)]"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="mt-3 flex items-center gap-3 text-sm">
|
<div className="mt-3 flex items-center gap-3 text-xs">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Switch checked={enabled} onCheckedChange={setEnabled} />
|
<Switch checked={enabled} onCheckedChange={setEnabled} />
|
||||||
<span className="text-[var(--ui-text-muted)]">
|
<span className="text-[var(--ui-text-muted)]">
|
||||||
|
|
@ -255,7 +255,7 @@ export function AutomationEditor({ mode, schedule }: AutomationEditorProps) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{errorMessage && (
|
{errorMessage && (
|
||||||
<p className="mt-4 text-sm text-[var(--ui-danger)]">{errorMessage}</p>
|
<p className="mt-4 text-xs text-[var(--ui-danger)]">{errorMessage}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -264,7 +264,7 @@ export function AutomationEditor({ mode, schedule }: AutomationEditorProps) {
|
||||||
|
|
||||||
function SectionLabel({ children }: { children: React.ReactNode }) {
|
function SectionLabel({ children }: { children: React.ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<h2 className="mt-8 mb-2 text-sm font-medium text-[var(--ui-text-muted)]">
|
<h2 className="mt-8 mb-2 text-xs font-medium text-[var(--ui-text-muted)]">
|
||||||
{children}
|
{children}
|
||||||
</h2>
|
</h2>
|
||||||
)
|
)
|
||||||
|
|
@ -310,7 +310,7 @@ function ModelPicker({
|
||||||
type="button"
|
type="button"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onClick={() => setOpen((value) => !value)}
|
onClick={() => setOpen((value) => !value)}
|
||||||
className="flex items-center gap-1 text-sm text-[var(--ui-text-muted)] transition-opacity hover:opacity-80 disabled:opacity-60"
|
className="flex items-center gap-1 text-xs text-[var(--ui-text-muted)] transition-opacity hover:opacity-80 disabled:opacity-60"
|
||||||
>
|
>
|
||||||
<span>{formatModelSelection(models, selection)}</span>
|
<span>{formatModelSelection(models, selection)}</span>
|
||||||
{!disabled && <CaretDownIcon className="size-3.5 opacity-60" />}
|
{!disabled && <CaretDownIcon className="size-3.5 opacity-60" />}
|
||||||
|
|
@ -331,7 +331,7 @@ function ModelPicker({
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
}}
|
}}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex w-full items-center gap-2 px-3 py-1.5 text-left text-sm whitespace-nowrap transition-colors hover:bg-[var(--ui-panel-2)]",
|
"flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs whitespace-nowrap transition-colors hover:bg-[var(--ui-panel-2)]",
|
||||||
selected
|
selected
|
||||||
? "text-[var(--ui-text)]"
|
? "text-[var(--ui-text)]"
|
||||||
: "text-[var(--ui-text-muted)]"
|
: "text-[var(--ui-text-muted)]"
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,10 @@ export function AutomationsList() {
|
||||||
return (
|
return (
|
||||||
<div className="flex min-w-0 flex-1 flex-col overflow-y-auto">
|
<div className="flex min-w-0 flex-1 flex-col overflow-y-auto">
|
||||||
<div className="mx-auto w-full max-w-4xl px-6 py-8 max-md:pt-16">
|
<div className="mx-auto w-full max-w-4xl px-6 py-8 max-md:pt-16">
|
||||||
<h1 className="text-2xl font-semibold text-[var(--ui-text)]">
|
<h1 className="text-base font-medium text-[var(--ui-text)]">
|
||||||
Automations
|
Automations
|
||||||
</h1>
|
</h1>
|
||||||
<p className="mt-1 text-sm text-[var(--ui-text-muted)]">
|
<p className="mt-1 text-xs text-[var(--ui-text-muted)]">
|
||||||
Run Open SWE on a recurring schedule. Each run starts a fresh agent
|
Run Open SWE on a recurring schedule. Each run starts a fresh agent
|
||||||
thread.
|
thread.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -58,7 +58,7 @@ export function AutomationsList() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-8 flex items-center justify-between">
|
<div className="mt-8 flex items-center justify-between">
|
||||||
<span className="text-sm font-medium text-[var(--ui-text-muted)]">
|
<span className="text-xs font-medium text-[var(--ui-text-muted)]">
|
||||||
{total} {total === 1 ? "automation" : "automations"}
|
{total} {total === 1 ? "automation" : "automations"}
|
||||||
</span>
|
</span>
|
||||||
<Link to="/agents/automations/new" className={buttonVariants()}>
|
<Link to="/agents/automations/new" className={buttonVariants()}>
|
||||||
|
|
@ -102,7 +102,7 @@ function StatCard({
|
||||||
<div className="text-xs text-[var(--ui-text-dim)]">{label}</div>
|
<div className="text-xs text-[var(--ui-text-dim)]">{label}</div>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"mt-1 text-2xl font-semibold",
|
"mt-1 text-lg font-medium",
|
||||||
highlight ? "text-[var(--ui-danger)]" : "text-[var(--ui-text)]"
|
highlight ? "text-[var(--ui-danger)]" : "text-[var(--ui-text)]"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
@ -121,7 +121,7 @@ function EmptyState() {
|
||||||
<h3 className="mt-4 text-sm font-medium text-[var(--ui-text)]">
|
<h3 className="mt-4 text-sm font-medium text-[var(--ui-text)]">
|
||||||
No automations yet
|
No automations yet
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mt-1 max-w-sm text-sm text-[var(--ui-text-muted)]">
|
<p className="mt-1 max-w-sm text-xs text-[var(--ui-text-muted)]">
|
||||||
Schedule Open SWE to run on a recurring cadence — review code, triage
|
Schedule Open SWE to run on a recurring cadence — review code, triage
|
||||||
issues, or keep docs up to date.
|
issues, or keep docs up to date.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -100,16 +100,16 @@ export function OnboardingDialog() {
|
||||||
<Dialog.Popup className="fixed top-1/2 left-1/2 z-50 w-[min(28rem,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-popover p-6 text-popover-foreground shadow-md ring-1 ring-foreground/10 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95">
|
<Dialog.Popup className="fixed top-1/2 left-1/2 z-50 w-[min(28rem,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-popover p-6 text-popover-foreground shadow-md ring-1 ring-foreground/10 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95">
|
||||||
{step === "model" ? (
|
{step === "model" ? (
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<Dialog.Title className="text-base font-semibold">
|
<Dialog.Title className="text-sm font-medium">
|
||||||
Choose your default model
|
Choose your default model
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<Dialog.Description className="text-sm text-muted-foreground">
|
<Dialog.Description className="text-xs text-muted-foreground">
|
||||||
Pick the model Open SWE uses when you don't specify one. You can
|
Pick the model Open SWE uses when you don't specify one. You can
|
||||||
change this anytime in your settings.
|
change this anytime in your settings.
|
||||||
</Dialog.Description>
|
</Dialog.Description>
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<div className="flex items-center justify-between gap-3">
|
<div className="flex items-center justify-between gap-3">
|
||||||
<span className="text-sm font-medium">Default model</span>
|
<span className="text-xs font-medium">Default model</span>
|
||||||
<Select
|
<Select
|
||||||
value={modelId}
|
value={modelId}
|
||||||
onValueChange={(v) => v && setModelId(v)}
|
onValueChange={(v) => v && setModelId(v)}
|
||||||
|
|
@ -127,7 +127,7 @@ export function OnboardingDialog() {
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between gap-3">
|
<div className="flex items-center justify-between gap-3">
|
||||||
<span className="text-sm font-medium">Reasoning effort</span>
|
<span className="text-xs font-medium">Reasoning effort</span>
|
||||||
<Select
|
<Select
|
||||||
value={effort}
|
value={effort}
|
||||||
onValueChange={(v) => v && setEffort(v)}
|
onValueChange={(v) => v && setEffort(v)}
|
||||||
|
|
@ -171,11 +171,11 @@ export function OnboardingDialog() {
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<IoLogoSlack className="size-6 shrink-0 text-muted-foreground" />
|
<IoLogoSlack className="size-6 shrink-0 text-muted-foreground" />
|
||||||
<Dialog.Title className="text-base font-semibold">
|
<Dialog.Title className="text-sm font-medium">
|
||||||
Connect your Slack account
|
Connect your Slack account
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
</div>
|
</div>
|
||||||
<Dialog.Description className="text-sm text-muted-foreground">
|
<Dialog.Description className="text-xs text-muted-foreground">
|
||||||
Connect Slack so that when you tag Open SWE, it can resolve your
|
Connect Slack so that when you tag Open SWE, it can resolve your
|
||||||
GitHub account. We use the email Slack verifies, which also lets
|
GitHub account. We use the email Slack verifies, which also lets
|
||||||
Linear mentions resolve to you.
|
Linear mentions resolve to you.
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,7 @@ function useConversations(key: string) {
|
||||||
function EmptyState({ onPick }: { onPick: (prompt: string) => void }) {
|
function EmptyState({ onPick }: { onPick: (prompt: string) => void }) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-1 flex-col gap-4 p-4">
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||||
<p className="text-sm text-foreground">
|
<p className="text-[13px] text-foreground">
|
||||||
I've reviewed this PR. Ask me about the diff, the findings, or the
|
I've reviewed this PR. Ask me about the diff, the findings, or the
|
||||||
surrounding code — I have read-only access to the repository.
|
surrounding code — I have read-only access to the repository.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -239,7 +239,7 @@ function EmptyState({ onPick }: { onPick: (prompt: string) => void }) {
|
||||||
key={prompt}
|
key={prompt}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => onPick(prompt)}
|
onClick={() => onPick(prompt)}
|
||||||
className="flex items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm text-foreground hover:bg-muted/60"
|
className="flex items-center gap-2 rounded-md px-2 py-1.5 text-left text-[13px] text-foreground hover:bg-muted/60"
|
||||||
>
|
>
|
||||||
<SparkleIcon className="size-4 shrink-0 text-muted-foreground" />
|
<SparkleIcon className="size-4 shrink-0 text-muted-foreground" />
|
||||||
{prompt}
|
{prompt}
|
||||||
|
|
@ -327,7 +327,7 @@ function ChatBody({
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"text-sm text-foreground",
|
"text-[13px] text-foreground",
|
||||||
isUser
|
isUser
|
||||||
? "max-w-[85%] rounded-lg bg-muted px-3 py-2"
|
? "max-w-[85%] rounded-lg bg-muted px-3 py-2"
|
||||||
: "w-full",
|
: "w-full",
|
||||||
|
|
@ -346,7 +346,7 @@ function ChatBody({
|
||||||
})}
|
})}
|
||||||
{busy && (
|
{busy && (
|
||||||
<div className="flex justify-start">
|
<div className="flex justify-start">
|
||||||
<div className="px-3 py-2 text-sm text-muted-foreground">
|
<div className="px-3 py-2 text-xs text-muted-foreground">
|
||||||
Thinking…
|
Thinking…
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ export function ReviewSidebarPanel({ data }: { data: ReviewSidebarData }) {
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-0 flex-1 flex-col pb-2">
|
<div className="flex min-h-0 flex-1 flex-col pb-2">
|
||||||
<div className="flex items-center justify-between gap-2 px-4 py-1">
|
<div className="flex items-center justify-between gap-2 px-4 py-1">
|
||||||
<span className="text-[10px] font-semibold tracking-wide text-[var(--ui-text-dim)] uppercase">
|
<span className="text-[10px] font-medium tracking-wide text-[var(--ui-text-dim)] uppercase">
|
||||||
{data.title}
|
{data.title}
|
||||||
</span>
|
</span>
|
||||||
{hasGroups && (
|
{hasGroups && (
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ export function ScheduleTriggerPicker({
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setOpen((value) => !value)}
|
onClick={() => setOpen((value) => !value)}
|
||||||
className="flex w-full items-center gap-2 rounded-lg px-3 py-2.5 text-sm text-[var(--ui-text-muted)] transition-colors hover:bg-[var(--ui-panel-2)] hover:text-[var(--ui-text)]"
|
className="flex w-full items-center gap-2 rounded-lg px-3 py-2.5 text-xs text-[var(--ui-text-muted)] transition-colors hover:bg-[var(--ui-panel-2)] hover:text-[var(--ui-text)]"
|
||||||
>
|
>
|
||||||
<PlusIcon className="size-4" />
|
<PlusIcon className="size-4" />
|
||||||
{triggerLabel}
|
{triggerLabel}
|
||||||
|
|
@ -49,7 +49,7 @@ export function ScheduleTriggerPicker({
|
||||||
|
|
||||||
{open && (
|
{open && (
|
||||||
<div className="absolute top-full left-0 z-50 mt-1 w-72 overflow-hidden rounded-xl border border-[var(--ui-border)] bg-[var(--ui-surface)] py-1 shadow-lg">
|
<div className="absolute top-full left-0 z-50 mt-1 w-72 overflow-hidden rounded-xl border border-[var(--ui-border)] bg-[var(--ui-surface)] py-1 shadow-lg">
|
||||||
<div className="flex items-center gap-2 px-3 py-1.5 text-[11px] font-semibold tracking-wide text-[var(--ui-text-dim)] uppercase">
|
<div className="flex items-center gap-2 px-3 py-1.5 text-[11px] font-medium tracking-wide text-[var(--ui-text-dim)] uppercase">
|
||||||
<ClockIcon className="size-3.5" />
|
<ClockIcon className="size-3.5" />
|
||||||
Scheduled
|
Scheduled
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -62,7 +62,7 @@ export function ScheduleTriggerPicker({
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
}}
|
}}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex w-full items-center gap-2 px-3 py-2 text-left text-sm text-[var(--ui-text-muted)] transition-colors hover:bg-[var(--ui-panel-2)] hover:text-[var(--ui-text)]"
|
"flex w-full items-center gap-2 px-3 py-2 text-left text-xs text-[var(--ui-text-muted)] transition-colors hover:bg-[var(--ui-panel-2)] hover:text-[var(--ui-text)]"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<span className="flex-1">{option.label}</span>
|
<span className="flex-1">{option.label}</span>
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ export function AgentMessage({
|
||||||
{isExpanded && (
|
{isExpanded && (
|
||||||
<div className="pt-1 pb-1 space-y-0.5">
|
<div className="pt-1 pb-1 space-y-0.5">
|
||||||
{item.chunks.map((chunk, chunkIndex) => (
|
{item.chunks.map((chunk, chunkIndex) => (
|
||||||
<div key={chunk.toolCallId || `explored-chunk-${item.id}-${chunkIndex}`} className="flex-1 min-w-0 text-gray-500">
|
<div key={chunk.toolCallId || `explored-chunk-${item.id}-${chunkIndex}`} className="flex-1 min-w-0 text-[color:var(--ui-text-dim)]">
|
||||||
<ToolExecution
|
<ToolExecution
|
||||||
chunk={chunk}
|
chunk={chunk}
|
||||||
projectPath={projectPath}
|
projectPath={projectPath}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export function ChunkRenderer({
|
||||||
return <span className="text-red-400">{chunk.text}</span>;
|
return <span className="text-red-400">{chunk.text}</span>;
|
||||||
case "list":
|
case "list":
|
||||||
return (
|
return (
|
||||||
<div className="text-gray-300 ml-2">
|
<div className="text-[color:var(--ui-text-muted)] ml-2">
|
||||||
{chunk.lines.map((line, i) => (
|
{chunk.lines.map((line, i) => (
|
||||||
<div key={i}>- {line}</div>
|
<div key={i}>- {line}</div>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -345,7 +345,7 @@ export const CloudPromptBar = memo(function CloudPromptBarComponent({
|
||||||
>
|
>
|
||||||
{isDragOver && (
|
{isDragOver && (
|
||||||
<div className="pointer-events-none absolute inset-0 z-20 flex items-center justify-center rounded-2xl bg-[var(--ui-surface)]/80 backdrop-blur-sm">
|
<div className="pointer-events-none absolute inset-0 z-20 flex items-center justify-center rounded-2xl bg-[var(--ui-surface)]/80 backdrop-blur-sm">
|
||||||
<span className="rounded-md bg-[var(--ui-panel-2)] px-3 py-1.5 text-sm font-medium text-[color:var(--ui-accent)]">
|
<span className="rounded-md bg-[var(--ui-panel-2)] px-3 py-1.5 text-xs font-medium text-[color:var(--ui-accent)]">
|
||||||
Drop images here
|
Drop images here
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -32,17 +32,17 @@ const STREAMDOWN_ANIMATED = {
|
||||||
|
|
||||||
const STREAMDOWN_COMPONENTS = {
|
const STREAMDOWN_COMPONENTS = {
|
||||||
h1: ({ children }: { children?: ReactNode }) => (
|
h1: ({ children }: { children?: ReactNode }) => (
|
||||||
<div className="text-[color:var(--ui-accent)] text-[20px] font-semibold mt-4 mb-2 tracking-tight">
|
<div className="text-[color:var(--ui-text)] text-[15px] font-medium mt-4 mb-1.5 tracking-tight">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
h2: ({ children }: { children?: ReactNode }) => (
|
h2: ({ children }: { children?: ReactNode }) => (
|
||||||
<div className="text-[color:var(--ui-accent)] text-[17px] font-semibold mt-3 mb-2 tracking-tight">
|
<div className="text-[color:var(--ui-text)] text-[14px] font-medium mt-3 mb-1.5 tracking-tight">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
h3: ({ children }: { children?: ReactNode }) => (
|
h3: ({ children }: { children?: ReactNode }) => (
|
||||||
<div className="text-[color:var(--ui-accent)] text-[15px] font-semibold mt-3 mb-1">
|
<div className="text-[color:var(--ui-text)] text-[13px] font-medium mt-3 mb-1">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ function UserMappingsSection({ enabled }: { enabled: boolean }) {
|
||||||
items.map((m: UserMapping) => (
|
items.map((m: UserMapping) => (
|
||||||
<div
|
<div
|
||||||
key={m.github_login}
|
key={m.github_login}
|
||||||
className="flex items-center justify-between gap-2 border-b border-border py-1.5 text-sm last:border-b-0"
|
className="flex items-center justify-between gap-2 border-b border-border py-1.5 text-xs last:border-b-0"
|
||||||
>
|
>
|
||||||
<div className="flex min-w-0 flex-col">
|
<div className="flex min-w-0 flex-col">
|
||||||
<span className="truncate font-medium">{m.github_login}</span>
|
<span className="truncate font-medium">{m.github_login}</span>
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,12 @@ function EditAutomationPage() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto w-full max-w-3xl px-6 py-16 text-center">
|
<div className="mx-auto w-full max-w-3xl px-6 py-16 text-center">
|
||||||
<p className="text-sm text-[var(--ui-text-muted)]">
|
<p className="text-xs text-[var(--ui-text-muted)]">
|
||||||
This automation could not be found.
|
This automation could not be found.
|
||||||
</p>
|
</p>
|
||||||
<Link
|
<Link
|
||||||
to="/agents/automations"
|
to="/agents/automations"
|
||||||
className="mt-3 inline-block text-sm text-[var(--ui-accent)] hover:underline"
|
className="mt-3 inline-block text-xs text-[var(--ui-accent)] hover:underline"
|
||||||
>
|
>
|
||||||
Back to Automations
|
Back to Automations
|
||||||
</Link>
|
</Link>
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,10 @@ function ReviewDetailPage() {
|
||||||
<span className="inline-flex min-w-0 items-center gap-1.5 truncate">
|
<span className="inline-flex min-w-0 items-center gap-1.5 truncate">
|
||||||
<GitPullRequestIcon className="size-3.5 shrink-0 text-muted-foreground" />
|
<GitPullRequestIcon className="size-3.5 shrink-0 text-muted-foreground" />
|
||||||
<span className="truncate font-medium">
|
<span className="truncate font-medium">
|
||||||
{owner}/{repo}#{number}
|
{owner}/{repo}
|
||||||
|
<span className="ml-1.5 font-normal text-muted-foreground">
|
||||||
|
#{number}
|
||||||
|
</span>
|
||||||
{detail.data ? ` ${detail.data.pr.title}` : ""}
|
{detail.data ? ` ${detail.data.pr.title}` : ""}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -632,7 +635,7 @@ function PrHeader({ detail }: { detail: ReviewDetail }) {
|
||||||
<GitPullRequestIcon className="size-3" />
|
<GitPullRequestIcon className="size-3" />
|
||||||
{pr.state}
|
{pr.state}
|
||||||
</span>
|
</span>
|
||||||
<h1 className="mt-2 text-lg font-medium">
|
<h1 className="mt-2 text-base font-medium">
|
||||||
<a
|
<a
|
||||||
href={detail.url}
|
href={detail.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ function ReviewsPage() {
|
||||||
return (
|
return (
|
||||||
<main className="min-w-0 flex-1 overflow-y-auto">
|
<main className="min-w-0 flex-1 overflow-y-auto">
|
||||||
<div className="mx-auto max-w-3xl px-6 py-8">
|
<div className="mx-auto max-w-3xl px-6 py-8">
|
||||||
<h1 className="font-heading text-lg font-medium text-[var(--ui-text)]">
|
<h1 className="font-heading text-base font-medium text-[var(--ui-text)]">
|
||||||
PR Reviews
|
PR Reviews
|
||||||
</h1>
|
</h1>
|
||||||
<p className="mt-1 text-xs text-[var(--ui-text-muted)]">
|
<p className="mt-1 text-xs text-[var(--ui-text-muted)]">
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ function UsagePage() {
|
||||||
Failed to load usage data: {leaderboard.error.message}
|
Failed to load usage data: {leaderboard.error.message}
|
||||||
</p>
|
</p>
|
||||||
) : !leaderboard.data?.rows.length ? (
|
) : !leaderboard.data?.rows.length ? (
|
||||||
<div className="p-6 text-center text-sm text-muted-foreground">
|
<div className="p-6 text-center text-xs text-muted-foreground">
|
||||||
No Open SWE Agent usage has been recorded for{" "}
|
No Open SWE Agent usage has been recorded for{" "}
|
||||||
{PERIOD_LABELS[activePeriod].toLowerCase()} yet.
|
{PERIOD_LABELS[activePeriod].toLowerCase()} yet.
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -128,7 +128,7 @@ function UsagePage() {
|
||||||
) : leaderboard.data?.reviewer_stats ? (
|
) : leaderboard.data?.reviewer_stats ? (
|
||||||
<ReviewerStats stats={leaderboard.data.reviewer_stats} />
|
<ReviewerStats stats={leaderboard.data.reviewer_stats} />
|
||||||
) : (
|
) : (
|
||||||
<div className="p-6 text-center text-sm text-muted-foreground">
|
<div className="p-6 text-center text-xs text-muted-foreground">
|
||||||
No reviewer stats have been recorded for{" "}
|
No reviewer stats have been recorded for{" "}
|
||||||
{PERIOD_LABELS[activePeriod].toLowerCase()} yet.
|
{PERIOD_LABELS[activePeriod].toLowerCase()} yet.
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -147,7 +147,7 @@ function UsageTable({
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="overflow-x-auto">
|
<div className="overflow-x-auto">
|
||||||
<table className="w-full min-w-[760px] text-sm">
|
<table className="w-full min-w-[760px] text-xs">
|
||||||
<thead className="border-b border-border text-xs text-muted-foreground">
|
<thead className="border-b border-border text-xs text-muted-foreground">
|
||||||
<tr>
|
<tr>
|
||||||
<th className="w-14 px-4 py-3 text-left font-normal">Rank</th>
|
<th className="w-14 px-4 py-3 text-left font-normal">Rank</th>
|
||||||
|
|
@ -238,7 +238,7 @@ function ReviewerStats({ stats }: { stats: ReviewerStatsPayload }) {
|
||||||
{cards.map((card) => (
|
{cards.map((card) => (
|
||||||
<div key={card.label} className="rounded-md border border-border p-3">
|
<div key={card.label} className="rounded-md border border-border p-3">
|
||||||
<div className="text-xs text-muted-foreground">{card.label}</div>
|
<div className="text-xs text-muted-foreground">{card.label}</div>
|
||||||
<div className="mt-1 text-xl font-medium tabular-nums">
|
<div className="mt-1 text-lg font-medium tabular-nums">
|
||||||
{formatNumber(card.value)}
|
{formatNumber(card.value)}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-1 text-xs text-muted-foreground">
|
<div className="mt-1 text-xs text-muted-foreground">
|
||||||
|
|
@ -277,7 +277,7 @@ function CounterList({
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-xs font-medium text-muted-foreground">{title}</h3>
|
<h3 className="text-xs font-medium text-muted-foreground">{title}</h3>
|
||||||
{rows.length ? (
|
{rows.length ? (
|
||||||
<ul className="mt-2 space-y-2 text-sm">
|
<ul className="mt-2 space-y-2 text-xs">
|
||||||
{rows.map((row) => (
|
{rows.map((row) => (
|
||||||
<li
|
<li
|
||||||
key={row.name}
|
key={row.name}
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,6 @@
|
||||||
@apply bg-background text-foreground;
|
@apply bg-background text-foreground;
|
||||||
}
|
}
|
||||||
html {
|
html {
|
||||||
@apply font-sans;
|
@apply font-sans antialiased;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -44,6 +44,9 @@
|
||||||
background: var(--ui-bg);
|
background: var(--ui-bg);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
line-height: 1.45;
|
line-height: 1.45;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
.agents-ui * {
|
.agents-ui * {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue