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:
Johannes du Plessis 2026-06-16 14:56:11 -07:00 • committed by GitHub
parent 801f93b4de
commit 876836bdfe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 58 additions and 52 deletions

View file

@ -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>
)} )}

View file

@ -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">

View file

@ -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">

View file

@ -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)]">

View file

@ -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)]"

View file

@ -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>

View file

@ -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.

View file

@ -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>

View file

@ -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 && (

View file

@ -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>

View file

@ -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}

View file

@ -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>
))} ))}

View file

@ -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>

View file

@ -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>
), ),

View file

@ -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>

View file

@ -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>

View file

@ -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"

View file

@ -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)]">

View file

@ -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}

View file

@ -127,6 +127,6 @@
@apply bg-background text-foreground; @apply bg-background text-foreground;
} }
html { html {
@apply font-sans; @apply font-sans antialiased;
} }
} }

View file

@ -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 * {