Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 32 additions & 36 deletions src/components/ChatInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -748,35 +748,33 @@ export const ChatInput: React.FC<ChatInputProps> = ({
)}
<div className="flex items-center">
<ChatToggles modelString={preferredModel}>
<div className="mr-3 flex h-[11px] items-center gap-1 @[700px]:[&_.help-indicator-wrapper]:hidden">
<div className="mr-3 flex items-center gap-1.5">
<ModelSelector
ref={modelSelectorRef}
value={preferredModel}
onChange={setPreferredModel}
recentModels={recentModels}
onComplete={() => inputRef.current?.focus()}
/>
<span className="help-indicator-wrapper">
<TooltipWrapper inline>
<HelpIndicator>?</HelpIndicator>
<Tooltip className="tooltip" align="left" width="wide">
<strong>Click to edit</strong> or use{" "}
{formatKeybind(KEYBINDS.OPEN_MODEL_SELECTOR)}
<br />
<br />
<strong>Abbreviations:</strong>
<br />• <code>/model opus</code> - Claude Opus 4.1
<br />• <code>/model sonnet</code> - Claude Sonnet 4.5
<br />
<br />
<strong>Full format:</strong>
<br />
<code>/model provider:model-name</code>
<br />
(e.g., <code>/model anthropic:claude-sonnet-4-5</code>)
</Tooltip>
</TooltipWrapper>
</span>
<TooltipWrapper inline>
<HelpIndicator>?</HelpIndicator>
<Tooltip className="tooltip" align="left" width="wide">
<strong>Click to edit</strong> or use{" "}
{formatKeybind(KEYBINDS.OPEN_MODEL_SELECTOR)}
<br />
<br />
<strong>Abbreviations:</strong>
<br />• <code>/model opus</code> - Claude Opus 4.1
<br />• <code>/model sonnet</code> - Claude Sonnet 4.5
<br />
<br />
<strong>Full format:</strong>
<br />
<code>/model provider:model-name</code>
<br />
(e.g., <code>/model anthropic:claude-sonnet-4-5</code>)
</Tooltip>
</TooltipWrapper>
</div>
</ChatToggles>
<div className="max-@[700px]:hidden ml-auto flex items-center gap-1.5">
Expand All @@ -799,20 +797,18 @@ export const ChatInput: React.FC<ChatInputProps> = ({
onChange={setMode}
/>
</div>
<span className="help-indicator-wrapper">
<TooltipWrapper inline>
<HelpIndicator>?</HelpIndicator>
<Tooltip className="tooltip" align="center" width="wide">
<strong>Exec Mode:</strong> AI edits files and execute commands
<br />
<br />
<strong>Plan Mode:</strong> AI proposes plans but does not edit files
<br />
<br />
Toggle with: {formatKeybind(KEYBINDS.TOGGLE_MODE)}
</Tooltip>
</TooltipWrapper>
</span>
<TooltipWrapper inline>
<HelpIndicator>?</HelpIndicator>
<Tooltip className="tooltip" align="center" width="wide">
<strong>Exec Mode:</strong> AI edits files and execute commands
<br />
<br />
<strong>Plan Mode:</strong> AI proposes plans but does not edit files
<br />
<br />
Toggle with: {formatKeybind(KEYBINDS.TOGGLE_MODE)}
</Tooltip>
</TooltipWrapper>
</div>
</div>
</div>
Expand Down
7 changes: 1 addition & 6 deletions src/components/Context1MCheckbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,7 @@ export const Context1MCheckbox: React.FC<Context1MCheckboxProps> = ({ modelStrin
return (
<div className="ml-2 flex items-center gap-1.5">
<label className="text-foreground flex cursor-pointer items-center gap-1 truncate text-[10px] select-none hover:text-white">
<input
type="checkbox"
checked={use1M}
onChange={(e) => setUse1M(e.target.checked)}
className="border-border-light bg-dark hover:border-accent checked:bg-accent checked:border-accent relative m-0 h-[11px] w-3 cursor-pointer appearance-none rounded-sm border checked:after:absolute checked:after:top-0 checked:after:left-[3px] checked:after:h-[6px] checked:after:w-1 checked:after:rotate-45 checked:after:border-r-[1.5px] checked:after:border-b-[1.5px] checked:after:border-solid checked:after:border-white checked:after:content-['']"
/>
<input type="checkbox" checked={use1M} onChange={(e) => setUse1M(e.target.checked)} />
1M Context
</label>
<TooltipWrapper inline>
Expand Down
4 changes: 1 addition & 3 deletions src/components/Messages/ChatBarrier/StreamingBarrier.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ export const StreamingBarrier: React.FC<StreamingBarrierProps> = ({
{tokenCount !== undefined && (
<span className="text-assistant-border font-mono text-[11px] whitespace-nowrap select-none">
~{tokenCount.toLocaleString()} tokens
{tps !== undefined && tps > 0 && (
<span className="text-text-dim ml-1">@ {tps} t/s</span>
)}
{tps !== undefined && tps > 0 && <span className="text-dim ml-1">@ {tps} t/s</span>}
</span>
)}
</div>
Expand Down
8 changes: 4 additions & 4 deletions src/components/ProjectSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ const ProjectDragLayer: React.FC = () => {
<div className="pointer-events-none fixed inset-0 z-[9999] cursor-grabbing">
<div style={{ transform: `translate(${currentOffset.x + 10}px, ${currentOffset.y + 10}px)` }}>
<div className="bg-hover/95 text-foreground border-l-accent flex w-fit max-w-72 min-w-44 items-center rounded border-l-[3px] px-3 py-1.5 shadow-[0_6px_24px_rgba(0,0,0,0.4)]">
<span className="text-text-dim mr-1.5 text-xs">⠿</span>
<span className="text-dim mr-1.5 text-xs">⠿</span>
<span className="text-muted mr-2 text-[10px]">▶</span>
<div className="min-w-0 flex-1">
<div className="text-foreground truncate text-sm font-medium tracking-[0.2px]">
Expand Down Expand Up @@ -482,7 +482,7 @@ const ProjectSidebarInner: React.FC<ProjectSidebarProps> = ({
<span
data-drag-handle
aria-hidden
className="text-text-dim mr-1.5 cursor-grab text-xs opacity-0 transition-opacity duration-150 select-none"
className="text-dim mr-1.5 cursor-grab text-xs opacity-0 transition-opacity duration-150 select-none"
>
</span>
Expand Down Expand Up @@ -596,12 +596,12 @@ const ProjectSidebarInner: React.FC<ProjectSidebarProps> = ({
>
<div className="flex items-center gap-1.5">
<span>Older than {formatOldWorkspaceThreshold()}</span>
<span className="text-text-dim font-normal">
<span className="text-dim font-normal">
({old.length})
</span>
</div>
<span
className="arrow text-text-dim text-[11px] transition-transform duration-200 ease-in-out"
className="arrow text-dim text-[11px] transition-transform duration-200 ease-in-out"
style={{
transform: showOldWorkspaces
? "rotate(90deg)"
Expand Down
8 changes: 4 additions & 4 deletions src/components/RightSidebar/CodeReview/FileTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ const TreeNodeContent: React.FC<{
className={cn(
"flex-1",
isFullyRead &&
"text-text-dim line-through [text-decoration-color:var(--color-read)] [text-decoration-thickness:2px]",
isUnknownState && !isFullyRead && "text-text-dim",
"text-dim line-through [text-decoration-color:var(--color-read)] [text-decoration-thickness:2px]",
isUnknownState && !isFullyRead && "text-dim",
!isFullyRead && !isUnknownState && "text-muted"
)}
>
Expand Down Expand Up @@ -181,8 +181,8 @@ const TreeNodeContent: React.FC<{
className={cn(
"flex-1",
isFullyRead &&
"text-text-dim line-through [text-decoration-color:var(--color-read)] [text-decoration-thickness:2px]",
isUnknownState && !isFullyRead && "text-text-dim",
"text-dim line-through [text-decoration-color:var(--color-read)] [text-decoration-thickness:2px]",
isUnknownState && !isFullyRead && "text-dim",
!isFullyRead && !isUnknownState && "text-foreground"
)}
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/RightSidebar/CodeReview/ReviewControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export const ReviewControls: React.FC<ReviewControlsProps> = ({
onBlur={handleBaseBlur}
onKeyDown={handleBaseKeyDown}
placeholder="HEAD, main, etc."
className="bg-dark text-foreground border-border-medium hover:border-accent focus:border-accent placeholder:text-text-dim w-36 rounded border px-2 py-1 font-mono text-[11px] transition-[border-color] duration-200 focus:outline-none"
className="bg-dark text-foreground border-border-medium hover:border-accent focus:border-accent placeholder:text-dim w-36 rounded border px-2 py-1 font-mono text-[11px] transition-[border-color] duration-200 focus:outline-none"
/>
<datalist id="base-suggestions">
<option value="HEAD" />
Expand Down
2 changes: 1 addition & 1 deletion src/components/RightSidebar/CodeReview/ReviewPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ export const ReviewPanel: React.FC<ReviewPanelProps> = ({
placeholder={`Search in files and hunks... (${formatKeybind(KEYBINDS.FOCUS_REVIEW_SEARCH)})`}
value={searchState.input}
onChange={(e) => setSearchState({ ...searchState, input: e.target.value })}
className="text-foreground placeholder:text-text-dim focus:bg-separator flex h-full flex-1 items-center border-none bg-transparent px-2.5 py-1.5 font-sans text-xs leading-[1.4] outline-none"
className="text-foreground placeholder:text-dim focus:bg-separator flex h-full flex-1 items-center border-none bg-transparent px-2.5 py-1.5 font-sans text-xs leading-[1.4] outline-none"
/>
<TooltipWrapper inline>
<button
Expand Down
4 changes: 2 additions & 2 deletions src/components/RightSidebar/ConsumerBreakdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const ConsumerBreakdownComponent: React.FC<ConsumerBreakdownProps> = ({ consumer
}

if (consumers.consumers.length === 0) {
return <div className="text-text-dim py-3 text-left italic">No consumer data available</div>;
return <div className="text-dim py-3 text-left italic">No consumer data available</div>;
}

return (
Expand Down Expand Up @@ -85,7 +85,7 @@ const ConsumerBreakdownComponent: React.FC<ConsumerBreakdownProps> = ({ consumer
)}
</div>
{consumer.fixedTokens && consumer.variableTokens && (
<div className="text-text-dim text-left text-[11px]">
<div className="text-dim text-left text-[11px]">
Tool definition: {formatTokens(consumer.fixedTokens)} • Usage:{" "}
{formatTokens(consumer.variableTokens)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/RightSidebar/CostsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ const CostsTabComponent: React.FC<CostsTabProps> = ({ workspaceId }) => {
</td>
<td className="text-foreground py-1 pr-2 [&:last-child]:pr-0 [&:last-child]:text-right">
{isNegligible ? (
<span className="text-text-dim italic">{costDisplay}</span>
<span className="text-dim italic">{costDisplay}</span>
) : (
costDisplay
)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/RightSidebar/VerticalTokenMeter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ const VerticalTokenMeterComponent: React.FC<{ data: TokenMeterData }> = ({ data
{data.maxTokens && ` / ${formatTokens(data.maxTokens)}`}
{data.maxTokens && ` (${data.totalPercentage.toFixed(1)}%)`}
</div>
<div className="text-text-dim mt-2 text-[10px] italic">
<div className="text-dim mt-2 text-[10px] italic">
💡 Expand your viewport to see full details
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/SecretsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,15 @@ const SecretsModal: React.FC<SecretsModalProps> = ({
onChange={(e) => updateSecret(index, "key", e.target.value)}
placeholder="SECRET_NAME"
disabled={isLoading}
className="bg-modal-bg border-border-medium focus:border-accent placeholder:text-text-dim w-full rounded border px-2.5 py-1.5 font-mono text-[13px] text-white focus:outline-none"
className="bg-modal-bg border-border-medium focus:border-accent placeholder:text-dim w-full rounded border px-2.5 py-1.5 font-mono text-[13px] text-white focus:outline-none"
/>
<input
type={visibleSecrets.has(index) ? "text" : "password"}
value={secret.value}
onChange={(e) => updateSecret(index, "value", e.target.value)}
placeholder="secret value"
disabled={isLoading}
className="bg-modal-bg border-border-medium focus:border-accent placeholder:text-text-dim w-full rounded border px-2.5 py-1.5 font-mono text-[13px] text-white focus:outline-none"
className="bg-modal-bg border-border-medium focus:border-accent placeholder:text-dim w-full rounded border px-2.5 py-1.5 font-mono text-[13px] text-white focus:outline-none"
/>
<button
type="button"
Expand Down
7 changes: 1 addition & 6 deletions src/components/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,7 @@ export const HelpIndicator: React.FC<{ className?: string; children?: React.Reac
children,
}) => (
<span
className={cn(
"text-text-dim text-[7px] cursor-help inline-block align-baseline",
"border border-border-subtle rounded-full w-2.5 h-[10px] leading-[8px]",
"text-center font-bold mb-[2px]",
className
)}
className={cn("text-muted flex cursor-help items-center text-[10px] leading-none", className)}
>
{children}
</span>
Expand Down
51 changes: 40 additions & 11 deletions src/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -205,16 +205,21 @@
--color-token-cached: hsl(0 0% 50%);

/* Font Variables */
--font-primary: IBM Plex Sans, sans-serif;
--font-monospace: JetBrains Mono, Consolas, Monaco, monospace;
/* Primary UI Font - System fonts for best native appearance */
--font-primary:
system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue",
Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";

/* Monospace Font - Code and technical content */
--font-monospace:
"Monaco", "Menlo", "Ubuntu Mono", "Consolas", "Courier New", monospace,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

body {
background-color: var(--color-background);
color: var(--color-foreground);
font-family:
IBM Plex Sans,
sans-serif;
font-family: var(--font-primary);
font-size: 14px;
}

Expand Down Expand Up @@ -271,11 +276,7 @@ body,
}

code {
font-family:
JetBrains Mono,
Consolas,
Monaco,
monospace;
font-family: var(--font-monospace);
}

/* Native tooltips */
Expand Down Expand Up @@ -493,7 +494,8 @@ code {
}

.markdown-content li {
margin: 0.4em 0;
margin: 0;
padding: 0 0 4px 0;
display: list-item;
}

Expand Down Expand Up @@ -773,3 +775,30 @@ pre code {
background-position: 0% 50%;
}
}

/* Font utility classes */
.font-primary {
font-family: var(--font-primary);
}

.font-monospace {
font-family: var(--font-monospace);
}

/* Text color utility classes */

/* Checkbox utility classes */
input[type="checkbox"] {
@apply relative m-0 h-3 w-3 cursor-pointer appearance-none rounded-sm border border-border-light bg-dark;
@apply hover:border-accent;
@apply focus-visible:outline focus-visible:outline-2 focus-visible:outline-accent focus-visible:outline-offset-2;
@apply checked:bg-accent checked:border-accent;
@apply checked:after:absolute checked:after:top-[2px] checked:after:left-[4px] checked:after:h-[6px] checked:after:w-[2.5px];
@apply checked:after:rotate-45 checked:after:border-r-[1.5px] checked:after:border-b-[1.5px];
@apply checked:after:border-solid checked:after:border-white checked:after:content-[''];
}

.text-dim {
color: var(--color-dim);
}