| author | |
| committer | |
| log | f26ee083fe41720207fb10616359500dcecc19d3 |
| tree | c0668ed670d5c836eb9c1a00979e38a5d66a1435 |
| parent | 315fcca10a826d8aa1cbdffc3ef5b5eb5a1e2f9d |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>109 files changed, 464 insertions(+), 433 deletions(-)
apps/web/src/browser/BrowserDeviceToolbar.tsx+1-1| ... | ... | @@ -175,7 +175,7 @@ export function BrowserDeviceToolbar({ |
| 175 | 175 | }} |
| 176 | 176 | > |
| 177 | 177 | {width >= 560 ? ( |
| 178 | <span className="mr-0.5 shrink-0 text-[11px] font-medium text-muted-foreground"> | |
| 178 | <span className="mr-0.5 shrink-0 text-2xs font-medium text-muted-foreground"> | |
| 179 | 179 | Dimensions |
| 180 | 180 | </span> |
| 181 | 181 | ) : null} |
apps/web/src/browser/HostedBrowserWebview.tsx+1-1| ... | ... | @@ -352,7 +352,7 @@ export function HostedBrowserWebview(props: { |
| 352 | 352 | /> |
| 353 | 353 | {activeDrag ? ( |
| 354 | 354 | <div |
| 355 | className="pointer-events-none absolute z-40 -translate-x-1/2 rounded-md border border-border/80 bg-background/95 px-2 py-1 text-[11px] font-medium tabular-nums text-foreground shadow-md backdrop-blur-sm" | |
| 355 | className="pointer-events-none absolute z-40 -translate-x-1/2 rounded-md border border-border/80 bg-background/95 px-2 py-1 text-2xs font-medium tabular-nums text-foreground shadow-md backdrop-blur-sm" | |
| 356 | 356 | style={{ |
| 357 | 357 | left: layout.viewportX + layout.viewportWidth / 2, |
| 358 | 358 | top: layout.viewportY + 10, |
apps/web/src/components/AgentsPanel.tsx+12-12| ... | ... | @@ -162,12 +162,12 @@ function AgentRow({ agent }: { agent: RuntimeSubagent }) { |
| 162 | 162 | <span className="col-start-2 row-start-1 flex min-w-0 items-baseline gap-2"> |
| 163 | 163 | <span className="min-w-0 truncate text-sm font-medium">{agent.title}</span> |
| 164 | 164 | {role ? ( |
| 165 | <span className="max-w-28 shrink-0 truncate rounded-sm border border-border/60 px-1 font-mono text-[.65rem] text-muted-foreground"> | |
| 165 | <span className="max-w-28 shrink-0 truncate rounded-sm border border-border/60 px-1 font-mono text-3xs text-muted-foreground"> | |
| 166 | 166 | {role} |
| 167 | 167 | </span> |
| 168 | 168 | ) : null} |
| 169 | 169 | </span> |
| 170 | <span className="col-start-3 row-start-1 min-w-14 text-right font-mono text-[.7rem] text-muted-foreground/80"> | |
| 170 | <span className="col-start-3 row-start-1 min-w-14 text-right font-mono text-2xs text-muted-foreground/80"> | |
| 171 | 171 | <span className="inline-flex items-center gap-1"> |
| 172 | 172 | <AgentElapsed agent={agent} /> |
| 173 | 173 | {agent.status === "completed" ? ( |
| ... | ... | @@ -183,7 +183,7 @@ function AgentRow({ agent }: { agent: RuntimeSubagent }) { |
| 183 | 183 | > |
| 184 | 184 | {activity ?? statusLabel} |
| 185 | 185 | </span> |
| 186 | <span className="col-start-2 col-end-4 row-start-3 truncate font-mono text-[.7rem] tabular-nums text-muted-foreground/70"> | |
| 186 | <span className="col-start-2 col-end-4 row-start-3 truncate font-mono text-2xs tabular-nums text-muted-foreground/70"> | |
| 187 | 187 | {metadata.join(" · ")} |
| 188 | 188 | </span> |
| 189 | 189 | <span className="sr-only">{statusLabel}</span> |
| ... | ... | @@ -234,7 +234,7 @@ function PhaseRail({ group }: { group: AgentPanelWorkflowGroup }) { |
| 234 | 234 | > |
| 235 | 235 | <span |
| 236 | 236 | className={cn( |
| 237 | "font-mono text-[.65rem]", | |
| 237 | "font-mono text-3xs", | |
| 238 | 238 | phase.state === "running" |
| 239 | 239 | ? "text-info-foreground" |
| 240 | 240 | : phase.state === "done" |
| ... | ... | @@ -247,7 +247,7 @@ function PhaseRail({ group }: { group: AgentPanelWorkflowGroup }) { |
| 247 | 247 | </span> |
| 248 | 248 | <span className="flex items-center gap-0.5"> |
| 249 | 249 | {phase.members.length === 0 ? ( |
| 250 | <span className="font-mono text-[.6rem] text-muted-foreground/50">–</span> | |
| 250 | <span className="font-mono text-3xs text-muted-foreground/50">–</span> | |
| 251 | 251 | ) : ( |
| 252 | 252 | phase.members.map((member) => <StatusDot key={member.id} status={member.status} />) |
| 253 | 253 | )} |
| ... | ... | @@ -281,7 +281,7 @@ function WorkflowScriptView({ |
| 281 | 281 | <div className="mx-1.5 mb-1 rounded-md border border-border/60 bg-background/60"> |
| 282 | 282 | <div className="flex items-center gap-2 border-b border-border/50 px-2 py-1"> |
| 283 | 283 | <Braces aria-hidden className="size-3 text-muted-foreground" /> |
| 284 | <span className="truncate font-mono text-[.65rem] text-muted-foreground"> | |
| 284 | <span className="truncate font-mono text-3xs text-muted-foreground"> | |
| 285 | 285 | {scriptPath.split("/").at(-1)} |
| 286 | 286 | </span> |
| 287 | 287 | <Button |
| ... | ... | @@ -296,7 +296,7 @@ function WorkflowScriptView({ |
| 296 | 296 | </div> |
| 297 | 297 | <div className="max-h-72 overflow-auto p-2"> |
| 298 | 298 | {result._tag === "Success" ? ( |
| 299 | <pre className="whitespace-pre-wrap break-words font-mono text-[.7rem] leading-relaxed text-foreground/90"> | |
| 299 | <pre className="whitespace-pre-wrap break-words font-mono text-2xs leading-relaxed text-foreground/90"> | |
| 300 | 300 | {result.value.contents} |
| 301 | 301 | {result.value.truncated ? "\n… (truncated)" : ""} |
| 302 | 302 | </pre> |
| ... | ... | @@ -339,7 +339,7 @@ function PhaseSection({ |
| 339 | 339 | onClick={() => setOpen((value) => !value)} |
| 340 | 340 | aria-expanded={open} |
| 341 | 341 | className={cn( |
| 342 | "mt-2 flex w-full items-center gap-1.5 rounded-sm px-1.5 text-left text-[.65rem] font-medium uppercase tracking-wider hover:bg-accent/40", | |
| 342 | "mt-2 flex w-full items-center gap-1.5 rounded-sm px-1.5 text-left text-3xs font-medium uppercase tracking-wider hover:bg-accent/40", | |
| 343 | 343 | phase.state === "done" |
| 344 | 344 | ? "text-success-foreground" |
| 345 | 345 | : phase.state === "running" |
| ... | ... | @@ -399,7 +399,7 @@ function ExpandedWorkflowSection({ |
| 399 | 399 | const canShowScript = scriptPath !== undefined && environmentId !== null && threadId !== null; |
| 400 | 400 | return ( |
| 401 | 401 | <section className="rounded-lg border border-border/50 bg-card/30 p-1.5"> |
| 402 | <div className="flex items-center gap-2 px-1.5 pt-0.5 text-[.65rem] font-medium uppercase tracking-wider text-muted-foreground"> | |
| 402 | <div className="flex items-center gap-2 px-1.5 pt-0.5 text-3xs font-medium uppercase tracking-wider text-muted-foreground"> | |
| 403 | 403 | <StatusDot status={group.workflow.status} /> |
| 404 | 404 | <span className="min-w-0 truncate"> |
| 405 | 405 | {group.workflow.workflowName ?? group.workflow.title} |
| ... | ... | @@ -486,7 +486,7 @@ function CollapsedWorkflowSection({ |
| 486 | 486 | <span className="truncate text-sm"> |
| 487 | 487 | {group.workflow.workflowName ?? group.workflow.title} |
| 488 | 488 | </span> |
| 489 | <span className="ml-auto flex items-center gap-1.5 font-mono text-[.7rem] text-muted-foreground/80"> | |
| 489 | <span className="ml-auto flex items-center gap-1.5 font-mono text-2xs text-muted-foreground/80"> | |
| 490 | 490 | {failed > 0 ? <span className="text-destructive-foreground">{failed} failed</span> : null} |
| 491 | 491 | <span>{members.length} agents</span> |
| 492 | 492 | <span className="tabular-nums">· {formatSubagentTokenCount(totalTokens)} tok</span> |
| ... | ... | @@ -557,7 +557,7 @@ export function AgentsPanel({ |
| 557 | 557 | ))} |
| 558 | 558 | {model.directAgents.length > 0 ? ( |
| 559 | 559 | <section> |
| 560 | <div className="px-1.5 pt-1 text-[.65rem] font-medium uppercase tracking-wider text-muted-foreground"> | |
| 560 | <div className="px-1.5 pt-1 text-3xs font-medium uppercase tracking-wider text-muted-foreground"> | |
| 561 | 561 | Direct spawns |
| 562 | 562 | </div> |
| 563 | 563 | {model.directAgents.map((agent) => ( |
| ... | ... | @@ -567,7 +567,7 @@ export function AgentsPanel({ |
| 567 | 567 | ) : null} |
| 568 | 568 | </div> |
| 569 | 569 | </ScrollArea> |
| 570 | <footer className="flex items-center justify-between border-t border-border/60 px-3 py-1.5 font-mono text-[.7rem] text-muted-foreground"> | |
| 570 | <footer className="flex items-center justify-between border-t border-border/60 px-3 py-1.5 font-mono text-2xs text-muted-foreground"> | |
| 571 | 571 | <span className="flex items-center gap-2"> |
| 572 | 572 | {model.runningCount + model.waitingCount > 0 ? ( |
| 573 | 573 | <span className="text-info-foreground"> |
apps/web/src/components/BranchToolbar.tsx+2-2| ... | ... | @@ -185,7 +185,7 @@ const MobileRunContextSelector = memo(function MobileRunContextSelector({ |
| 185 | 185 | > |
| 186 | 186 | <span |
| 187 | 187 | data-composer-label-motion |
| 188 | className="block w-full min-w-0 max-w-[240px] truncate transition-opacity duration-180 ease-[cubic-bezier(0.32,0.72,0,1)] group-data-[compact]/composer-context:opacity-0 motion-reduce:transition-none" | |
| 188 | className="block w-full min-w-0 max-w-[240px] truncate transition-opacity duration-180 ease-drawer group-data-[compact]/composer-context:opacity-0 motion-reduce:transition-none" | |
| 189 | 189 | > |
| 190 | 190 | {autoEnvironmentLabel ?? |
| 191 | 191 | (showEnvironmentIndicator ? (activeEnvironment?.label ?? "Run on") : workspaceLabel)} |
| ... | ... | @@ -197,7 +197,7 @@ const MobileRunContextSelector = memo(function MobileRunContextSelector({ |
| 197 | 197 | if (isLocked) { |
| 198 | 198 | return ( |
| 199 | 199 | <span |
| 200 | className="inline-flex h-7 min-w-0 max-w-[48%] flex-initial items-center justify-start gap-1 rounded-md border border-transparent px-[calc(--spacing(2)-1px)] font-normal text-muted-foreground/70 text-xs sm:h-6" | |
| 200 | className="inline-flex h-7 min-w-0 max-w-[48%] flex-initial items-center justify-start gap-1 rounded-md border border-transparent px-1.75 font-normal text-muted-foreground/70 text-xs sm:h-6" | |
| 201 | 201 | data-composer-context-control |
| 202 | 202 | > |
| 203 | 203 | {triggerContent} |
apps/web/src/components/BranchToolbarBranchSelector.tsx+2-2| ... | ... | @@ -757,7 +757,7 @@ export function BranchToolbarBranchSelector({ |
| 757 | 757 | > |
| 758 | 758 | <div className="flex w-full min-w-0 items-center justify-between gap-2"> |
| 759 | 759 | <MiddleTruncate value={itemValue} className="flex-1" /> |
| 760 | {badge && <span className="shrink-0 text-[10px] text-muted-foreground/45">{badge}</span>} | |
| 760 | {badge && <span className="shrink-0 text-3xs text-muted-foreground/45">{badge}</span>} | |
| 761 | 761 | </div> |
| 762 | 762 | </ComboboxItem> |
| 763 | 763 | ); |
| ... | ... | @@ -819,7 +819,7 @@ export function BranchToolbarBranchSelector({ |
| 819 | 819 | > |
| 820 | 820 | <span |
| 821 | 821 | data-composer-label-motion |
| 822 | className="flex w-full max-w-[240px] transition-opacity duration-180 ease-[cubic-bezier(0.32,0.72,0,1)] group-data-[compact]/composer-context:opacity-0 motion-reduce:transition-none" | |
| 822 | className="flex w-full max-w-[240px] transition-opacity duration-180 ease-drawer group-data-[compact]/composer-context:opacity-0 motion-reduce:transition-none" | |
| 823 | 823 | > |
| 824 | 824 | <MiddleTruncate value={triggerLabel} /> |
| 825 | 825 | </span> |
apps/web/src/components/BranchToolbarEnvModeSelector.tsx+3-3| ... | ... | @@ -61,7 +61,7 @@ export const BranchToolbarEnvModeSelector = memo(function BranchToolbarEnvModeSe |
| 61 | 61 | <Tooltip> |
| 62 | 62 | <TooltipTrigger |
| 63 | 63 | render={<span />} |
| 64 | className="inline-flex h-7 min-w-0 items-center gap-1 border border-transparent px-[calc(--spacing(2)-1px)] font-normal text-muted-foreground/70 text-xs sm:h-6" | |
| 64 | className="inline-flex h-7 min-w-0 items-center gap-1 border border-transparent px-1.75 font-normal text-muted-foreground/70 text-xs sm:h-6" | |
| 65 | 65 | data-composer-context-control |
| 66 | 66 | > |
| 67 | 67 | {forceNewWorktree ? ( |
| ... | ... | @@ -77,7 +77,7 @@ export const BranchToolbarEnvModeSelector = memo(function BranchToolbarEnvModeSe |
| 77 | 77 | > |
| 78 | 78 | <span |
| 79 | 79 | data-composer-label-motion |
| 80 | className="block w-full min-w-0 max-w-[240px] truncate transition-opacity duration-180 ease-[cubic-bezier(0.32,0.72,0,1)] group-data-[compact]/composer-context:opacity-0 motion-reduce:transition-none" | |
| 80 | className="block w-full min-w-0 max-w-[240px] truncate transition-opacity duration-180 ease-drawer group-data-[compact]/composer-context:opacity-0 motion-reduce:transition-none" | |
| 81 | 81 | > |
| 82 | 82 | {forceNewWorktree |
| 83 | 83 | ? resolveEnvModeLabel("worktree") |
| ... | ... | @@ -133,7 +133,7 @@ export const BranchToolbarEnvModeSelector = memo(function BranchToolbarEnvModeSe |
| 133 | 133 | > |
| 134 | 134 | <span |
| 135 | 135 | data-composer-label-motion |
| 136 | className="block w-full min-w-0 max-w-[240px] truncate transition-opacity duration-180 ease-[cubic-bezier(0.32,0.72,0,1)] group-data-[compact]/composer-context:opacity-0 motion-reduce:transition-none" | |
| 136 | className="block w-full min-w-0 max-w-[240px] truncate transition-opacity duration-180 ease-drawer group-data-[compact]/composer-context:opacity-0 motion-reduce:transition-none" | |
| 137 | 137 | > |
| 138 | 138 | <SelectValue /> |
| 139 | 139 | </span> |
apps/web/src/components/BranchToolbarEnvironmentSelector.tsx+3-3| ... | ... | @@ -63,7 +63,7 @@ export const BranchToolbarEnvironmentSelector = memo(function BranchToolbarEnvir |
| 63 | 63 | <Tooltip> |
| 64 | 64 | <TooltipTrigger |
| 65 | 65 | render={<span />} |
| 66 | className="inline-flex h-7 min-w-0 max-w-full items-center gap-1 border border-transparent px-[calc(--spacing(2)-1px)] font-normal text-muted-foreground/70 text-xs sm:h-6" | |
| 66 | className="inline-flex h-7 min-w-0 max-w-full items-center gap-1 border border-transparent px-1.75 font-normal text-muted-foreground/70 text-xs sm:h-6" | |
| 67 | 67 | data-composer-context-control |
| 68 | 68 | > |
| 69 | 69 | <EnvironmentMachineIcon |
| ... | ... | @@ -76,7 +76,7 @@ export const BranchToolbarEnvironmentSelector = memo(function BranchToolbarEnvir |
| 76 | 76 | > |
| 77 | 77 | <span |
| 78 | 78 | data-composer-label-motion |
| 79 | className="block w-full min-w-0 max-w-[240px] truncate transition-opacity duration-180 ease-[cubic-bezier(0.32,0.72,0,1)] group-data-[compact]/composer-context:opacity-0 motion-reduce:transition-none" | |
| 79 | className="block w-full min-w-0 max-w-[240px] truncate transition-opacity duration-180 ease-drawer group-data-[compact]/composer-context:opacity-0 motion-reduce:transition-none" | |
| 80 | 80 | > |
| 81 | 81 | {activeEnvironment?.label ?? "Run on"} |
| 82 | 82 | </span> |
| ... | ... | @@ -123,7 +123,7 @@ export const BranchToolbarEnvironmentSelector = memo(function BranchToolbarEnvir |
| 123 | 123 | > |
| 124 | 124 | <span |
| 125 | 125 | data-composer-label-motion |
| 126 | className="block w-full min-w-0 max-w-[240px] truncate transition-opacity duration-180 ease-[cubic-bezier(0.32,0.72,0,1)] group-data-[compact]/composer-context:opacity-0 motion-reduce:transition-none" | |
| 126 | className="block w-full min-w-0 max-w-[240px] truncate transition-opacity duration-180 ease-drawer group-data-[compact]/composer-context:opacity-0 motion-reduce:transition-none" | |
| 127 | 127 | > |
| 128 | 128 | <SelectValue /> |
| 129 | 129 | </span> |
apps/web/src/components/ChatMarkdown.tsx+3-3| ... | ... | @@ -974,12 +974,12 @@ function MarkdownCodeBlock({ |
| 974 | 974 | |
| 975 | 975 | return ( |
| 976 | 976 | <div |
| 977 | className="chat-markdown-codeblock my-[0.65rem] overflow-hidden rounded-[var(--radius)] border border-border/70 bg-secondary leading-snug dark:border-transparent dark:bg-input/32" | |
| 977 | className="chat-markdown-codeblock my-[0.65rem] overflow-hidden rounded-lg border border-border/70 bg-secondary leading-snug dark:border-transparent dark:bg-input/32" | |
| 978 | 978 | data-language={language} |
| 979 | 979 | data-wrap={wrapped ? "true" : "false"} |
| 980 | 980 | > |
| 981 | 981 | <div className="chat-markdown-codeblock-header flex items-center justify-between gap-2 pt-1.5 pr-1.5 pb-0 pl-3 select-none"> |
| 982 | <span className="inline-flex min-w-0 items-center gap-[0.4rem] [font-family:var(--font-mono,ui-monospace,SFMono-Regular,monospace)] [font-size:0.6875rem]"> | |
| 982 | <span className="inline-flex min-w-0 items-center gap-1.5 font-mono text-2xs"> | |
| 983 | 983 | <MarkdownCodeBlockTitleContent |
| 984 | 984 | fenceTitle={fenceTitle} |
| 985 | 985 | language={language} |
| ... | ... | @@ -2201,7 +2201,7 @@ const MarkdownFileLink = memo(function MarkdownFileLink({ |
| 2201 | 2201 | <TooltipPopup side="top" variant="code"> |
| 2202 | 2202 | {/* The full path: the chip already shows the shortened form, and a link |
| 2203 | 2203 | to the workspace root collapses to a bare label that repeats it. */} |
| 2204 | <div className="overflow-x-auto whitespace-nowrap [scrollbar-color:color-mix(in_srgb,var(--contrast-border)_78%,transparent)_transparent] [scrollbar-width:thin] [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-[color-mix(in_srgb,var(--contrast-border)_78%,transparent)] [&::-webkit-scrollbar-track]:bg-transparent"> | |
| 2204 | <div className="overflow-x-auto whitespace-nowrap scrollbar-thumb-border/78 scrollbar-track-transparent [scrollbar-width:thin] [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-border/78 [&::-webkit-scrollbar-track]:bg-transparent"> | |
| 2205 | 2205 | {targetPath} |
| 2206 | 2206 | </div> |
| 2207 | 2207 | </TooltipPopup> |
apps/web/src/components/ChatView.tsx+3-3| ... | ... | @@ -1220,7 +1220,7 @@ const PersistentThreadTerminalDrawer = memo(function PersistentThreadTerminalDra |
| 1220 | 1220 | "grid shrink-0 overflow-clip", |
| 1221 | 1221 | active ? (visible ? "grid-rows-[1fr]" : "grid-rows-[0fr]") : "hidden", |
| 1222 | 1222 | active && |
| 1223 | "[[data-panel-animations=true]_&]:transition-[grid-template-rows] [[data-panel-animations=true]_&]:[transition-duration:var(--panel-animation-duration)] [[data-panel-animations=true]_&]:ease-out", | |
| 1223 | "[[data-panel-animations=true]_&]:transition-[grid-template-rows] [[data-panel-animations=true]_&]:duration-(--panel-animation-duration) [[data-panel-animations=true]_&]:ease-out", | |
| 1224 | 1224 | active && visible && "[[data-panel-animations=true]_&]:starting:grid-rows-[0fr]!", |
| 1225 | 1225 | )} |
| 1226 | 1226 | > |
| ... | ... | @@ -9588,7 +9588,7 @@ export default function ChatView(props: ChatViewProps) { |
| 9588 | 9588 | className={cn( |
| 9589 | 9589 | "flex shrink-0", |
| 9590 | 9590 | panelAnimationsActive && |
| 9591 | "motion-safe:transition-opacity motion-safe:[transition-duration:var(--panel-animation-duration)] motion-safe:ease-out", | |
| 9591 | "motion-safe:transition-opacity motion-safe:duration-(--panel-animation-duration) motion-safe:ease-out", | |
| 9592 | 9592 | rightPanelOpen ? "pointer-events-auto opacity-100" : "pointer-events-none opacity-0", |
| 9593 | 9593 | )} |
| 9594 | 9594 | inert={!rightPanelOpen} |
| ... | ... | @@ -10015,7 +10015,7 @@ export default function ChatView(props: ChatViewProps) { |
| 10015 | 10015 | > |
| 10016 | 10016 | <div |
| 10017 | 10017 | ref={attachDraftHeroTransitionGroupRef} |
| 10018 | className="w-full ps-[calc(env(safe-area-inset-left)+0.75rem)] pe-[calc(env(safe-area-inset-right)+0.75rem)] sm:ps-[calc(env(safe-area-inset-left)+1.25rem)] sm:pe-[calc(env(safe-area-inset-right)+1.25rem)]" | |
| 10018 | className="w-full ps-(--workspace-gutter-start) pe-(--workspace-gutter-end)" | |
| 10019 | 10019 | > |
| 10020 | 10020 | <div |
| 10021 | 10021 | data-chat-composer-stack="true" |
apps/web/src/components/ComposerPromptEditorTiptap.tsx+2-2| ... | ... | @@ -190,7 +190,7 @@ function resolvedThemeFromDocument(): "light" | "dark" { |
| 190 | 190 | * paints the editor's node selection over it. |
| 191 | 191 | */ |
| 192 | 192 | const CHIP_NODE_SELECTION_CLASS_NAME = |
| 193 | "relative inline-flex select-none items-center align-middle leading-none data-[composer-chip-selected]:after:pointer-events-none data-[composer-chip-selected]:after:absolute data-[composer-chip-selected]:after:inset-0 data-[composer-chip-selected]:after:rounded-[6px] data-[composer-chip-selected]:after:bg-[Highlight] data-[composer-chip-selected]:after:opacity-30 data-[composer-chip-selected]:after:content-['']"; | |
| 193 | "relative inline-flex select-none items-center align-middle leading-none data-[composer-chip-selected]:after:pointer-events-none data-[composer-chip-selected]:after:absolute data-[composer-chip-selected]:after:inset-0 data-[composer-chip-selected]:after:rounded-sm data-[composer-chip-selected]:after:bg-[Highlight] data-[composer-chip-selected]:after:opacity-30 data-[composer-chip-selected]:after:content-['']"; | |
| 194 | 194 | |
| 195 | 195 | const ComposerMentionExtension = Node.create({ |
| 196 | 196 | name: "composer-mention", |
| ... | ... | @@ -1242,7 +1242,7 @@ function ComposerPromptEditorTiptapInner(props: ComposerPromptEditorProps) { |
| 1242 | 1242 | <ComposerCitationCommentContext value={citationCommentActions}> |
| 1243 | 1243 | <div |
| 1244 | 1244 | className={cn( |
| 1245 | "relative flow-root [font-family:var(--font-composer,var(--font-sans))] [font-size:var(--font-size-prompt,0.875rem)] [@media(max-width:39.999rem)_and_(pointer:coarse)]:[font-size:max(var(--font-size-prompt,1rem),16px)]", | |
| 1245 | "relative flow-root font-(family-name:--font-composer,var(--font-sans)) text-(length:--font-size-prompt,var(--text-sm)) max-sm:pointer-coarse:text-(length:--font-size-prompt-touch)", | |
| 1246 | 1246 | containerClassName, |
| 1247 | 1247 | )} |
| 1248 | 1248 | > |
apps/web/src/components/ContextChip.tsx+3-3| ... | ... | @@ -23,7 +23,7 @@ import { cn } from "~/lib/utils"; |
| 23 | 23 | * span with tabIndex for a tooltip) gets the focus outline. |
| 24 | 24 | */ |
| 25 | 25 | const contextChipVariants = cva( |
| 26 | "inline-flex h-[1.41em] max-w-full items-center gap-[0.33em] rounded-[0.5em] border px-[0.5em] align-middle font-medium text-[0.86em] leading-none [&_svg]:block [&_svg]:size-[1.17em] [&_svg]:shrink-0 [&_svg]:self-center [button&,a&,[data-popup-open]&]:cursor-pointer [button&,a&]:transition-colors [button&,a&]:motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--contrast-foreground)] disabled:cursor-default", | |
| 26 | "inline-flex h-[1.41em] max-w-full items-center gap-[0.33em] rounded-[0.5em] border px-[0.5em] align-middle font-medium text-[0.86em] leading-none [&_svg]:block [&_svg]:size-[1.17em] [&_svg]:shrink-0 [&_svg]:self-center [button&,a&,[data-popup-open]&]:cursor-pointer [button&,a&]:transition-colors [button&,a&]:motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-foreground disabled:cursor-default", | |
| 27 | 27 | { |
| 28 | 28 | defaultVariants: { kind: "neutral" }, |
| 29 | 29 | variants: { |
| ... | ... | @@ -71,7 +71,7 @@ const contextChipVariants = cva( |
| 71 | 71 | "citation", |
| 72 | 72 | ], |
| 73 | 73 | className: |
| 74 | "border-[color-mix(in_oklab,var(--context-chip-accent)_34%,var(--contrast-border))] bg-[color-mix(in_oklab,var(--context-chip-accent)_11%,transparent)] text-[color-mix(in_oklab,var(--context-chip-accent)_22%,var(--contrast-foreground))] [button:enabled&,a&]:hover:border-[color-mix(in_oklab,var(--context-chip-accent)_48%,var(--contrast-border))] [button:enabled&,a&]:hover:bg-[color-mix(in_oklab,var(--context-chip-accent)_17%,transparent)]", | |
| 74 | "[--context-chip-border:color-mix(in_oklab,var(--context-chip-accent)_34%,var(--contrast-border))] [--context-chip-border-hover:color-mix(in_oklab,var(--context-chip-accent)_48%,var(--contrast-border))] [--context-chip-foreground:color-mix(in_oklab,var(--context-chip-accent)_22%,var(--contrast-foreground))] border-(--context-chip-border) bg-(--context-chip-accent)/11 text-(--context-chip-foreground) [button:enabled&,a&]:hover:border-(--context-chip-border-hover) [button:enabled&,a&]:hover:bg-(--context-chip-accent)/17", | |
| 75 | 75 | }, |
| 76 | 76 | // State colors win over any kind. |
| 77 | 77 | { state: "unresolved", className: "text-foreground" }, |
| ... | ... | @@ -115,7 +115,7 @@ function ContextChipLabel({ className, ...props }: React.ComponentProps<"span">) |
| 115 | 115 | function ContextChipAction({ className, render, ...props }: useRender.ComponentProps<"button">) { |
| 116 | 116 | const defaultProps = { |
| 117 | 117 | className: cn( |
| 118 | "ml-[0.17em] inline-flex size-[1.17em] shrink-0 cursor-pointer items-center justify-center rounded-sm text-current transition-colors hover:bg-[color-mix(in_oklab,var(--context-chip-accent,var(--color-foreground))_17%,transparent)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring motion-reduce:transition-none [&_svg]:size-[0.85em]", | |
| 118 | "ml-[0.17em] inline-flex size-[1.17em] shrink-0 cursor-pointer items-center justify-center rounded-sm text-current transition-colors hover:bg-(--context-chip-accent,var(--color-foreground))/17 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring motion-reduce:transition-none [&_svg]:size-[0.85em]", | |
| 119 | 119 | className, |
| 120 | 120 | ), |
| 121 | 121 | "data-slot": "context-chip-action", |
apps/web/src/components/DiffPanel.tsx+6-6| ... | ... | @@ -765,7 +765,7 @@ export default function DiffPanel({ |
| 765 | 765 | value={baseRefQuery} |
| 766 | 766 | onChange={(event) => setBaseRefQuery(event.target.value)} |
| 767 | 767 | /> |
| 768 | <div className="grid shrink-0 grid-cols-[1rem_minmax(0,1fr)] items-center gap-2 border-b border-border/70 ps-3 pe-6.5 pt-2 pb-1.5 font-medium text-[10px] text-muted-foreground uppercase tracking-wide"> | |
| 768 | <div className="grid shrink-0 grid-cols-[1rem_minmax(0,1fr)] items-center gap-2 border-b border-border/70 ps-3 pe-6.5 pt-2 pb-1.5 font-medium text-3xs text-muted-foreground uppercase tracking-wide"> | |
| 769 | 769 | <span aria-hidden="true" /> |
| 770 | 770 | <div className="grid min-w-0 grid-cols-[minmax(0,1fr)_2rem] items-center"> |
| 771 | 771 | <span>Branch</span> |
| ... | ... | @@ -841,7 +841,7 @@ export default function DiffPanel({ |
| 841 | 841 | <DiffStatLabel |
| 842 | 842 | additions={diffLineStat.additions} |
| 843 | 843 | deletions={diffLineStat.deletions} |
| 844 | className="mr-1 text-[11px]" | |
| 844 | className="mr-1 text-2xs" | |
| 845 | 845 | layout="inline" |
| 846 | 846 | /> |
| 847 | 847 | ) : null} |
| ... | ... | @@ -992,14 +992,14 @@ export default function DiffPanel({ |
| 992 | 992 | <> |
| 993 | 993 | <div className="flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden bg-background"> |
| 994 | 994 | {isSelectedPatchTruncated && !lazySource && ( |
| 995 | <p className="shrink-0 border-b border-border/70 bg-muted/40 px-3 py-1.5 text-[11px] text-muted-foreground"> | |
| 995 | <p className="shrink-0 border-b border-border/70 bg-muted/40 px-3 py-1.5 text-2xs text-muted-foreground"> | |
| 996 | 996 | This preview exceeds the size limit. Changes shown are incomplete. |
| 997 | 997 | {selectedGitSource?.files ? " Totals include all changes." : ""} |
| 998 | 998 | </p> |
| 999 | 999 | )} |
| 1000 | 1000 | {selectedPatchError && !renderablePatch && ( |
| 1001 | 1001 | <div className="px-3"> |
| 1002 | <p className="mb-2 text-[11px] text-error/80">{selectedPatchError}</p> | |
| 1002 | <p className="mb-2 text-2xs text-error/80">{selectedPatchError}</p> | |
| 1003 | 1003 | </div> |
| 1004 | 1004 | )} |
| 1005 | 1005 | {!renderablePatch && !lazySource ? ( |
| ... | ... | @@ -1181,12 +1181,12 @@ export default function DiffPanel({ |
| 1181 | 1181 | ) : ( |
| 1182 | 1182 | <div className="min-h-0 flex-1 overflow-auto p-2"> |
| 1183 | 1183 | <div className="space-y-2"> |
| 1184 | <p className="text-[11px] text-muted-foreground/75"> | |
| 1184 | <p className="text-2xs text-muted-foreground/75"> | |
| 1185 | 1185 | {renderablePatch?.kind === "raw" ? renderablePatch.reason : null} |
| 1186 | 1186 | </p> |
| 1187 | 1187 | <pre |
| 1188 | 1188 | className={cn( |
| 1189 | "max-h-[72vh] rounded-md border border-border/70 bg-background/70 p-3 font-mono text-[11px] leading-relaxed text-muted-foreground/90", | |
| 1189 | "max-h-[72vh] rounded-md border border-border/70 bg-background/70 p-3 font-mono text-2xs leading-relaxed text-muted-foreground/90", | |
| 1190 | 1190 | wordWrap |
| 1191 | 1191 | ? "overflow-auto whitespace-pre-wrap wrap-break-word" |
| 1192 | 1192 | : "overflow-auto", |
apps/web/src/components/DiffPanelShell.tsx+1-1| ... | ... | @@ -13,7 +13,7 @@ function getDiffPanelHeaderRowClassName(mode: DiffPanelMode) { |
| 13 | 13 | "flex items-center justify-between gap-2", |
| 14 | 14 | mode === "embedded" ? "px-2" : "px-4", |
| 15 | 15 | shouldUseDragRegion |
| 16 | ? "drag-region h-[var(--workspace-topbar-height)] border-b border-border wco:h-[env(titlebar-area-height)] wco:pr-[calc(100vw-env(titlebar-area-width)-env(titlebar-area-x)+1em)]" | |
| 16 | ? "drag-region h-[var(--workspace-topbar-height)] border-b border-border wco:h-[env(titlebar-area-height)] wco:pr-(--workspace-native-controls-inset)" | |
| 17 | 17 | : "flex h-10 min-h-10 shrink-0 items-center border-b border-border/60 bg-background in-data-[preview-panel-mode=inline]:mb-3 in-data-[preview-panel-mode=inline]:h-7 in-data-[preview-panel-mode=inline]:min-h-7 in-data-[preview-panel-mode=inline]:border-b-transparent", |
| 18 | 18 | ); |
| 19 | 19 | } |
apps/web/src/components/LegacySidebar.tsx+5-5| ... | ... | @@ -234,7 +234,7 @@ const PROJECT_GROUPING_MODE_LABELS: Record<SidebarProjectGroupingMode, string> = |
| 234 | 234 | separate: "Keep separate", |
| 235 | 235 | }; |
| 236 | 236 | const SIDEBAR_ICON_ACTION_BUTTON_CLASS = |
| 237 | "inline-flex h-6 min-w-6 cursor-pointer items-center justify-center rounded-md px-[calc(--spacing(1)-1px)] text-icon-muted hover:text-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring"; | |
| 237 | "inline-flex h-6 min-w-6 cursor-pointer items-center justify-center rounded-md px-0.75 text-icon-muted hover:text-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring"; | |
| 238 | 238 | |
| 239 | 239 | function SidebarThreadDetailPrewarmer({ threadRef }: { readonly threadRef: ScopedThreadRef }) { |
| 240 | 240 | useEnvironmentThread(threadRef.environmentId, threadRef.threadId); |
| ... | ... | @@ -850,7 +850,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP |
| 850 | 850 | data-thread-selection-safe |
| 851 | 851 | data-testid={`thread-archive-confirm-${thread.id}`} |
| 852 | 852 | aria-label={`Confirm archive ${thread.title}`} |
| 853 | className="absolute top-1/2 right-1 inline-flex h-5 -translate-y-1/2 cursor-pointer items-center rounded-md bg-destructive/12 px-2 text-[10px] font-medium text-destructive transition-colors hover:bg-destructive/18 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-destructive/40" | |
| 853 | className="absolute top-1/2 right-1 inline-flex h-5 -translate-y-1/2 cursor-pointer items-center rounded-md bg-destructive/12 px-2 text-3xs font-medium text-destructive transition-colors hover:bg-destructive/18 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-destructive/40" | |
| 854 | 854 | onPointerDown={stopPropagationOnPointerDown} |
| 855 | 855 | onClick={handleConfirmArchiveClick} |
| 856 | 856 | > |
| ... | ... | @@ -920,7 +920,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP |
| 920 | 920 | render={ |
| 921 | 921 | <span |
| 922 | 922 | aria-label={jumpLabel} |
| 923 | className="inline-flex h-5 items-center rounded-full border border-border/80 bg-background/90 px-1.5 font-mono text-[10px] font-medium tracking-tight text-foreground shadow-sm" | |
| 923 | className="inline-flex h-5 items-center rounded-full border border-border/80 bg-background/90 px-1.5 font-mono text-3xs font-medium tracking-tight text-foreground shadow-sm" | |
| 924 | 924 | /> |
| 925 | 925 | } |
| 926 | 926 | > |
| ... | ... | @@ -930,7 +930,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP |
| 930 | 930 | </Tooltip> |
| 931 | 931 | ) : ( |
| 932 | 932 | <span |
| 933 | className={`text-[10px] tabular-nums ${ | |
| 933 | className={`text-3xs tabular-nums ${ | |
| 934 | 934 | isHighlighted ? "text-foreground" : "text-secondary-label" |
| 935 | 935 | }`} |
| 936 | 936 | > |
| ... | ... | @@ -2410,7 +2410,7 @@ const SidebarProjectItem = memo(function SidebarProjectItem(props: SidebarProjec |
| 2410 | 2410 | {project.displayName} |
| 2411 | 2411 | </span> |
| 2412 | 2412 | {project.groupedProjectCount > 1 ? ( |
| 2413 | <span className="shrink-0 text-secondary-label text-[10px]"> | |
| 2413 | <span className="shrink-0 text-secondary-label text-3xs"> | |
| 2414 | 2414 | {project.groupedProjectCount} projects |
| 2415 | 2415 | </span> |
| 2416 | 2416 | ) : null} |
apps/web/src/components/ProjectFavicon.tsx+2-2| ... | ... | @@ -19,7 +19,7 @@ const DynamicIcon = lazy(() => |
| 19 | 19 | ); |
| 20 | 20 | |
| 21 | 21 | function DynamicProjectIconFallback() { |
| 22 | return <FolderCodeIcon className="size-full text-[inherit]" />; | |
| 22 | return <FolderCodeIcon className="size-full text-inherit" />; | |
| 23 | 23 | } |
| 24 | 24 | |
| 25 | 25 | // The slice of a project that decides its icon. Every surface must pass the |
| ... | ... | @@ -176,7 +176,7 @@ function ProjectFaviconImage({ |
| 176 | 176 | <img |
| 177 | 177 | src={displayedSrc} |
| 178 | 178 | alt="" |
| 179 | className={cn("size-3.5 shrink-0 rounded-[37.5%] object-contain", className)} | |
| 179 | className={cn("size-3.5 shrink-0 rounded-[25%] object-contain", className)} | |
| 180 | 180 | onError={() => handleLoadError(displayedSrc)} |
| 181 | 181 | /> |
| 182 | 182 | ) : null} |
apps/web/src/components/PullRequestContextDetails.tsx+1-1| ... | ... | @@ -15,7 +15,7 @@ export function PullRequestContextDetails({ metadata }: { metadata: PullRequestC |
| 15 | 15 | <span className={state.toneClassName}>{state.label}</span> |
| 16 | 16 | </div> |
| 17 | 17 | <div className="wrap-break-word text-foreground">{metadata.title}</div> |
| 18 | <div className="flex min-w-0 items-center gap-1 text-secondary-label text-[10px]"> | |
| 18 | <div className="flex min-w-0 items-center gap-1 text-secondary-label text-3xs"> | |
| 19 | 19 | <code className="truncate">{metadata.headBranch}</code> |
| 20 | 20 | <ArrowRightIcon className="size-3 shrink-0" aria-hidden="true" /> |
| 21 | 21 | <code className="truncate">{metadata.baseBranch}</code> |
apps/web/src/components/RightPanelTabs.tsx+11-10| ... | ... | @@ -488,7 +488,7 @@ function RightPanelEmptyState(props: { |
| 488 | 488 | {action.badgeCount > 0 ? ( |
| 489 | 489 | <span |
| 490 | 490 | aria-hidden |
| 491 | className="absolute -top-1.5 -right-2 flex h-3.5 min-w-3.5 items-center justify-center rounded-full bg-info px-1 text-[9px] font-semibold tabular-nums text-white" | |
| 491 | className="absolute -top-1.5 -right-2 flex h-3.5 min-w-3.5 items-center justify-center rounded-full bg-info px-1 text-3xs font-semibold tabular-nums text-white" | |
| 492 | 492 | > |
| 493 | 493 | {action.badgeCount} |
| 494 | 494 | </span> |
| ... | ... | @@ -505,13 +505,13 @@ function RightPanelEmptyState(props: { |
| 505 | 505 | aria-label="Open a surface" |
| 506 | 506 | data-surface-launcher-keys={availableActions.map((action) => action.shortcut).join("")} |
| 507 | 507 | className={cn( |
| 508 | "flex min-h-0 flex-1 items-center justify-center overflow-y-auto px-6 pt-6 outline-none", | |
| 508 | "flex min-h-0 flex-1 items-center justify-center overflow-y-auto px-6 outline-none", | |
| 509 | 509 | // The panel topbar sits above this container; matching bottom padding |
| 510 | 510 | // keeps the list centered against the full panel, not the leftover. |
| 511 | "pb-[calc(var(--workspace-topbar-height)+--spacing(6))]", | |
| 511 | "pb-(--workspace-topbar-height)", | |
| 512 | 512 | )} |
| 513 | 513 | > |
| 514 | <div className="w-full max-w-xs"> | |
| 514 | <div className="w-full max-w-xs py-6"> | |
| 515 | 515 | <h3 className="mb-3 text-center font-medium text-foreground text-sm">Open a surface</h3> |
| 516 | 516 | <div className="flex flex-col gap-0.5"> |
| 517 | 517 | {actions.map((action) => |
| ... | ... | @@ -534,7 +534,7 @@ function RightPanelEmptyState(props: { |
| 534 | 534 | type="button" |
| 535 | 535 | onClick={action.onClick} |
| 536 | 536 | className={cn( |
| 537 | "flex h-8 w-full cursor-pointer items-center gap-2.5 rounded-[var(--control-radius)] px-2.5 text-left text-sm transition-colors group-hover:bg-accent/60", | |
| 537 | "flex h-8 w-full cursor-pointer items-center gap-2.5 rounded-(--control-radius) px-2.5 text-left text-sm transition-colors group-hover:bg-accent/60", | |
| 538 | 538 | isHighlighted(action) && "bg-accent/60", |
| 539 | 539 | )} |
| 540 | 540 | > |
| ... | ... | @@ -589,7 +589,7 @@ function RightPanelEmptyState(props: { |
| 589 | 589 | <div |
| 590 | 590 | tabIndex={0} |
| 591 | 591 | aria-disabled="true" |
| 592 | className="flex h-8 w-full cursor-default items-center gap-2.5 rounded-[var(--control-radius)] px-2.5 text-left text-sm opacity-50" | |
| 592 | className="flex h-8 w-full cursor-default items-center gap-2.5 rounded-(--control-radius) px-2.5 text-left text-sm opacity-50" | |
| 593 | 593 | > |
| 594 | 594 | {actionIcon(action, "size-4")} |
| 595 | 595 | <span className="min-w-0 flex-1 truncate">{action.label}</span> |
| ... | ... | @@ -1114,10 +1114,7 @@ export function RightPanelTabs(props: RightPanelTabsProps) { |
| 1114 | 1114 | // controls a few pixels higher and the cluster jumps on open. |
| 1115 | 1115 | props.mode === "inline" && !props.layoutControls ? "pr-28" : "pr-3", |
| 1116 | 1116 | ownsDesktopTitleBar && "drag-region", |
| 1117 | ownsDesktopTitleBar && | |
| 1118 | (props.layoutControls | |
| 1119 | ? "wco:pr-[var(--workspace-native-controls-inset)]" | |
| 1120 | : "wco:pr-[calc(var(--workspace-native-controls-inset)+6rem)]"), | |
| 1117 | ownsDesktopTitleBar && "wco:pr-(--workspace-native-controls-inset)", | |
| 1121 | 1118 | props.mode === "inline" && props.maximized && COLLAPSED_SIDEBAR_TITLEBAR_INSET_CLASS, |
| 1122 | 1119 | )} |
| 1123 | 1120 | data-right-panel-tabbar |
| ... | ... | @@ -1395,6 +1392,10 @@ export function RightPanelTabs(props: RightPanelTabsProps) { |
| 1395 | 1392 | </div> |
| 1396 | 1393 | ) : null} |
| 1397 | 1394 | {props.layoutControls} |
| 1395 | {ownsDesktopTitleBar && !props.layoutControls ? ( | |
| 1396 | // Keeps the tabs clear of the window controls when the layout toggles live elsewhere. | |
| 1397 | <span aria-hidden className="hidden w-24 shrink-0 wco:block" /> | |
| 1398 | ) : null} | |
| 1398 | 1399 | {ownsDesktopTitleBar ? ( |
| 1399 | 1400 | <span |
| 1400 | 1401 | aria-hidden |
apps/web/src/components/Sidebar.tsx+8-8| ... | ... | @@ -283,7 +283,7 @@ function JumpHintBadge(props: { label: string }) { |
| 283 | 283 | return ( |
| 284 | 284 | <span |
| 285 | 285 | aria-hidden |
| 286 | className="pointer-events-none absolute right-1.5 top-1/2 z-10 inline-flex h-5 -translate-y-1/2 items-center rounded-full border border-border/80 bg-background/95 px-1.5 font-mono text-[10px] font-medium tracking-tight text-foreground shadow-sm" | |
| 286 | className="pointer-events-none absolute right-1.5 top-1/2 z-10 inline-flex h-5 -translate-y-1/2 items-center rounded-full border border-border/80 bg-background/95 px-1.5 font-mono text-3xs font-medium tracking-tight text-foreground shadow-sm" | |
| 287 | 287 | > |
| 288 | 288 | {props.label} |
| 289 | 289 | </span> |
| ... | ... | @@ -760,7 +760,7 @@ const SidebarDraftRow = memo(function SidebarDraftRow(props: { |
| 760 | 760 | onClick={handleActivate} |
| 761 | 761 | onKeyDown={handleKeyDown} |
| 762 | 762 | > |
| 763 | <div className="relative z-10 h-[4.875rem] px-[var(--sidebar-row-content-inset)] py-[var(--sidebar-content-inset)]"> | |
| 763 | <div className="relative z-10 h-[4.875rem] px-(--sidebar-row-content-inset) py-(--sidebar-content-inset)"> | |
| 764 | 764 | <div className="flex h-5 min-w-0 items-center gap-1.5"> |
| 765 | 765 | <SquarePenIcon aria-hidden className={draftPenClassName} /> |
| 766 | 766 | {props.project ? ( |
| ... | ... | @@ -1408,7 +1408,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { |
| 1408 | 1408 | // keeps the hover color applied, so both the tint and the solid sidebar |
| 1409 | 1409 | // color are stacked as background images. |
| 1410 | 1410 | props.sortable?.isDragging && |
| 1411 | "bg-[linear-gradient(var(--sidebar-row-active),var(--sidebar-row-active)),linear-gradient(var(--sidebar),var(--sidebar))] text-sidebar-foreground opacity-100 shadow-lg", | |
| 1411 | "bg-sidebar bg-linear-to-b from-sidebar-row-active to-sidebar-row-active text-sidebar-foreground opacity-100 shadow-lg", | |
| 1412 | 1412 | ); |
| 1413 | 1413 | // dnd-kit props for the row root. Same bag on both variants: every row in |
| 1414 | 1414 | // the list translates around the gap as the drag passes it. |
| ... | ... | @@ -1433,7 +1433,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { |
| 1433 | 1433 | sortable?.isDragging && props.dropVerb !== null ? ( |
| 1434 | 1434 | <span |
| 1435 | 1435 | role="status" |
| 1436 | className="pointer-events-none ml-auto inline-flex h-5 shrink-0 items-center gap-1 rounded-sm border border-primary/40 bg-primary/10 px-1.5 text-[11px] font-medium text-primary" | |
| 1436 | className="pointer-events-none ml-auto inline-flex h-5 shrink-0 items-center gap-1 rounded-sm border border-primary/40 bg-primary/10 px-1.5 text-2xs font-medium text-primary" | |
| 1437 | 1437 | > |
| 1438 | 1438 | {dropVerbBadge[props.dropVerb]} |
| 1439 | 1439 | </span> |
| ... | ... | @@ -1478,7 +1478,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { |
| 1478 | 1478 | ? "text-muted-foreground" |
| 1479 | 1479 | : "text-secondary-label/70", |
| 1480 | 1480 | ), |
| 1481 | isRegeneratingTitle && "opacity-[0.55]", | |
| 1481 | isRegeneratingTitle && "opacity-55", | |
| 1482 | 1482 | )} |
| 1483 | 1483 | > |
| 1484 | 1484 | {thread.title} |
| ... | ... | @@ -1745,7 +1745,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { |
| 1745 | 1745 | /> |
| 1746 | 1746 | } |
| 1747 | 1747 | > |
| 1748 | <div className="relative z-10 h-[4.875rem] px-[var(--sidebar-row-content-inset)] py-[var(--sidebar-content-inset)]"> | |
| 1748 | <div className="relative z-10 h-[4.875rem] px-(--sidebar-row-content-inset) py-(--sidebar-content-inset)"> | |
| 1749 | 1749 | <div className="flex h-5 min-w-0 items-center gap-1.5"> |
| 1750 | 1750 | {draftIndicator} |
| 1751 | 1751 | {props.project ? ( |
| ... | ... | @@ -1956,7 +1956,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { |
| 1956 | 1956 | showBadge={showInstanceBadge} |
| 1957 | 1957 | // Glyph dims, badge stays saturated; offset matches the composer trigger. |
| 1958 | 1958 | iconClassName="size-3.5 opacity-60" |
| 1959 | badgeClassName="right-[-0.1875rem] bottom-[-0.1875rem] h-3 min-w-3 px-0.5 text-[7px]" | |
| 1959 | badgeClassName="right-[-0.1875rem] bottom-[-0.1875rem] h-3 min-w-3 px-0.5 text-3xs" | |
| 1960 | 1960 | /> |
| 1961 | 1961 | </span> |
| 1962 | 1962 | ) : null} |
| ... | ... | @@ -4912,7 +4912,7 @@ export default function Sidebar() { |
| 4912 | 4912 | <button |
| 4913 | 4913 | type="button" |
| 4914 | 4914 | onClick={openAddProjectCommandPalette} |
| 4915 | className="inline-flex cursor-pointer items-center gap-1.5 rounded-md border border-sidebar-border px-2.5 py-1 text-[11px] font-medium text-sidebar-muted-foreground transition-colors hover:bg-sidebar-row-hover hover:text-sidebar-foreground" | |
| 4915 | className="inline-flex cursor-pointer items-center gap-1.5 rounded-md border border-sidebar-border px-2.5 py-1 text-2xs font-medium text-sidebar-muted-foreground transition-colors hover:bg-sidebar-row-hover hover:text-sidebar-foreground" | |
| 4916 | 4916 | > |
| 4917 | 4917 | <PlusIcon className="-mx-0.5 size-3" /> |
| 4918 | 4918 | Add project |
apps/web/src/components/SlowRpcRequestToastCoordinator.tsx+1-1| ... | ... | @@ -22,7 +22,7 @@ function SlowRequestDetails({ requests }: { requests: ReadonlyArray<SlowRpcAckRe |
| 22 | 22 | key={request.requestId} |
| 23 | 23 | > |
| 24 | 24 | <div className="wrap-break-word font-medium text-foreground">{request.tag}</div> |
| 25 | <div className="mt-0.5 text-[10px] opacity-75"> | |
| 25 | <div className="mt-0.5 text-3xs opacity-75"> | |
| 26 | 26 | Started {new Date(request.startedAt).toLocaleTimeString()} |
| 27 | 27 | </div> |
| 28 | 28 | </li> |
apps/web/src/components/ThreadStatusIndicators.tsx+2-2| ... | ... | @@ -328,7 +328,7 @@ export function ThreadPullRequestsMiniList({ |
| 328 | 328 | {snapshot?.title ?? line.link.repository} |
| 329 | 329 | </span> |
| 330 | 330 | {line.stack ? ( |
| 331 | <span className="ml-auto shrink-0 pl-1 text-[10px]"> | |
| 331 | <span className="ml-auto shrink-0 pl-1 text-3xs"> | |
| 332 | 332 | {line.stack.kind === "native" ? "stack" : "chain"} · {line.stack.size} |
| 333 | 333 | </span> |
| 334 | 334 | ) : null} |
| ... | ... | @@ -463,7 +463,7 @@ export function ThreadStatusLabel({ |
| 463 | 463 | render={ |
| 464 | 464 | <span |
| 465 | 465 | aria-label={status.label} |
| 466 | className={`inline-flex items-center gap-1 text-[10px] ${status.colorClass}`} | |
| 466 | className={`inline-flex items-center gap-1 text-3xs ${status.colorClass}`} | |
| 467 | 467 | /> |
| 468 | 468 | } |
| 469 | 469 | > |
apps/web/src/components/ThreadTerminalDrawer.tsx+4-4| ... | ... | @@ -981,7 +981,7 @@ export function TerminalViewport({ |
| 981 | 981 | <div |
| 982 | 982 | ref={containerRef} |
| 983 | 983 | tabIndex={-1} |
| 984 | className="relative h-full w-full overflow-hidden bg-[var(--terminal-background)]" | |
| 984 | className="relative h-full w-full overflow-hidden bg-(--terminal-background)" | |
| 985 | 985 | /> |
| 986 | 986 | ); |
| 987 | 987 | } |
| ... | ... | @@ -1490,7 +1490,7 @@ export default function ThreadTerminalDrawer({ |
| 1490 | 1490 | <div className="min-h-0 w-full flex-1"> |
| 1491 | 1491 | <div |
| 1492 | 1492 | className={cn( |
| 1493 | "flex h-full min-h-0 bg-[var(--terminal-background)]", | |
| 1493 | "flex h-full min-h-0 bg-(--terminal-background)", | |
| 1494 | 1494 | hasTerminalSidebar && "gap-1.5", |
| 1495 | 1495 | )} |
| 1496 | 1496 | > |
| ... | ... | @@ -1653,7 +1653,7 @@ export default function ThreadTerminalDrawer({ |
| 1653 | 1653 | {showGroupHeaders && ( |
| 1654 | 1654 | <button |
| 1655 | 1655 | type="button" |
| 1656 | className={`flex h-[22px] w-full cursor-pointer items-center gap-1 rounded px-1.5 text-[11px] ${ | |
| 1656 | className={`flex h-[22px] w-full cursor-pointer items-center gap-1 rounded px-1.5 text-2xs ${ | |
| 1657 | 1657 | isGroupActive |
| 1658 | 1658 | ? "bg-accent/50 text-foreground" |
| 1659 | 1659 | : "text-muted-foreground hover:bg-accent/40 hover:text-foreground" |
| ... | ... | @@ -1662,7 +1662,7 @@ export default function ThreadTerminalDrawer({ |
| 1662 | 1662 | > |
| 1663 | 1663 | <GroupIcon className="size-3 shrink-0" /> |
| 1664 | 1664 | <span className="min-w-0 flex-1 truncate text-left">{groupLabel}</span> |
| 1665 | <span className="text-muted-foreground/70 text-[10px] tabular-nums"> | |
| 1665 | <span className="text-muted-foreground/70 text-3xs tabular-nums"> | |
| 1666 | 1666 | {terminalCount} |
| 1667 | 1667 | </span> |
| 1668 | 1668 | </button> |
apps/web/src/components/WorkspaceBreadcrumb.tsx+1-1| ... | ... | @@ -33,7 +33,7 @@ export function WorkspaceBreadcrumbText({ children, className, ...props }: Compo |
| 33 | 33 | // Center the capital letters with adjacent icons, not the font's leading. |
| 34 | 34 | // Padding preserves accents and descenders when a label is truncated. |
| 35 | 35 | className={cn( |
| 36 | "block min-w-0 truncate [text-box:trim-both_cap_alphabetic] supports-[text-box:trim-both_cap_alphabetic]:py-[0.5em]", | |
| 36 | "block min-w-0 truncate [text-box:trim-both_cap_alphabetic] supports-[text-box:trim-both_cap_alphabetic]:py-1.5", | |
| 37 | 37 | className, |
| 38 | 38 | )} |
| 39 | 39 | {...props} |
apps/web/src/components/WorkspacePageHeader.tsx+2-2| ... | ... | @@ -16,9 +16,9 @@ export function WorkspacePageHeader({ |
| 16 | 16 | return ( |
| 17 | 17 | <header |
| 18 | 18 | className={cn( |
| 19 | "flex h-[var(--workspace-topbar-height)] min-h-[var(--workspace-topbar-height)] shrink-0 items-center gap-3 pl-[calc(env(safe-area-inset-left)+0.75rem)] pr-[calc(env(safe-area-inset-right)+0.75rem)] [[data-panel-animations=true]_&]:motion-safe:transition-[padding-left,padding-right] [[data-panel-animations=true]_&]:motion-safe:[transition-duration:var(--panel-animation-duration)] [[data-panel-animations=true]_&]:motion-safe:ease-out sm:pl-[calc(env(safe-area-inset-left)+1.25rem)] sm:pr-[calc(env(safe-area-inset-right)+1.25rem)]", | |
| 19 | "flex h-[var(--workspace-topbar-height)] min-h-[var(--workspace-topbar-height)] shrink-0 items-center gap-3 pl-(--workspace-gutter-start) pr-(--workspace-gutter-end) [[data-panel-animations=true]_&]:motion-safe:transition-[padding-left,padding-right] [[data-panel-animations=true]_&]:motion-safe:duration-(--panel-animation-duration) [[data-panel-animations=true]_&]:motion-safe:ease-out", | |
| 20 | 20 | electron && "drag-region", |
| 21 | reserveNativeControls && "wco:pr-[var(--workspace-native-controls-inset)]", | |
| 21 | reserveNativeControls && "wco:pr-(--workspace-native-controls-inset)", | |
| 22 | 22 | COLLAPSED_SIDEBAR_TITLEBAR_INSET_CLASS, |
| 23 | 23 | className, |
| 24 | 24 | )} |
apps/web/src/components/auth/AuthSurfaceShell.tsx+1-1| ... | ... | @@ -27,7 +27,7 @@ export function AuthSurfaceShell({ children }: { readonly children: ReactNode }) |
| 27 | 27 | )} |
| 28 | 28 | <div className="absolute inset-0 bg-[linear-gradient(to_bottom,transparent_20%,rgba(7,18,55,0.46)_100%)]" /> |
| 29 | 29 | <div className="relative h-full p-5 sm:p-6"> |
| 30 | <p className="text-[10px] font-semibold tracking-[0.2em] text-white/80 uppercase"> | |
| 30 | <p className="text-3xs font-semibold tracking-widest text-white/80 uppercase"> | |
| 31 | 31 | {APP_DISPLAY_NAME} |
| 32 | 32 | </p> |
| 33 | 33 | </div> |
apps/web/src/components/chat/AssistantCitationChip.tsx+2-2| ... | ... | @@ -110,7 +110,7 @@ export function AssistantCitationChip({ |
| 110 | 110 | const composerSourceLink = ( |
| 111 | 111 | <Link |
| 112 | 112 | {...sourceLinkProps} |
| 113 | className="inline-flex h-full min-w-0 items-center gap-[0.33em] rounded-sm text-inherit no-underline focus-visible:outline-2 focus-visible:outline-[var(--contrast-foreground)]" | |
| 113 | className="inline-flex h-full min-w-0 items-center gap-[0.33em] rounded-sm text-inherit no-underline focus-visible:outline-2 focus-visible:outline-foreground" | |
| 114 | 114 | aria-label={`View cited assistant text: ${label}`} |
| 115 | 115 | > |
| 116 | 116 | <QuoteIcon aria-hidden="true" /> |
| ... | ... | @@ -120,7 +120,7 @@ export function AssistantCitationChip({ |
| 120 | 120 | const chatSourceLink = ( |
| 121 | 121 | <Link |
| 122 | 122 | {...sourceLinkProps} |
| 123 | className="inline-flex h-full min-w-0 items-center gap-[0.33em] rounded-sm text-inherit no-underline hover:bg-[color-mix(in_oklab,var(--context-chip-accent)_17%,transparent)] focus-visible:outline-2 focus-visible:outline-[var(--contrast-foreground)]" | |
| 123 | className="inline-flex h-full min-w-0 items-center gap-[0.33em] rounded-sm text-inherit no-underline hover:bg-(--context-chip-accent)/17 focus-visible:outline-2 focus-visible:outline-foreground" | |
| 124 | 124 | aria-label={`View cited assistant text: ${label}`} |
| 125 | 125 | > |
| 126 | 126 | <QuoteIcon aria-hidden="true" /> |
apps/web/src/components/chat/ChangedFilesTree.tsx+4-4| ... | ... | @@ -54,7 +54,7 @@ export const ChangedFilesCard = memo(function ChangedFilesCard(props: { |
| 54 | 54 | > |
| 55 | 55 | <div |
| 56 | 56 | data-changed-files-header="" |
| 57 | className="sticky top-2 z-10 flex items-center justify-between gap-2 rounded-t-lg bg-secondary px-3 py-2 dark:bg-[color-mix(in_srgb,var(--input)_20%,var(--background))]" | |
| 57 | className="sticky top-2 z-10 flex items-center justify-between gap-2 rounded-t-lg bg-secondary px-3 py-2 dark:bg-background dark:bg-linear-to-b dark:from-input/20 dark:to-input/20" | |
| 58 | 58 | > |
| 59 | 59 | <div className="flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1 text-xs font-medium text-foreground"> |
| 60 | 60 | <span> |
| ... | ... | @@ -206,11 +206,11 @@ export const ChangedFilesTree = memo(function ChangedFilesTree(props: { |
| 206 | 206 | ) : ( |
| 207 | 207 | <FolderClosedIcon className="size-3.5 shrink-0 text-muted-foreground/75" /> |
| 208 | 208 | )} |
| 209 | <span className="truncate font-mono text-[11px] text-muted-foreground/90 group-hover:text-foreground/90"> | |
| 209 | <span className="truncate font-mono text-2xs text-muted-foreground/90 group-hover:text-foreground/90"> | |
| 210 | 210 | {node.name} |
| 211 | 211 | </span> |
| 212 | 212 | {hasNonZeroStat(node.stat) && ( |
| 213 | <span className="ml-auto shrink-0 font-mono text-[10px] tabular-nums"> | |
| 213 | <span className="ml-auto shrink-0 font-mono text-3xs tabular-nums"> | |
| 214 | 214 | <DiffStatLabel additions={node.stat.additions} deletions={node.stat.deletions} /> |
| 215 | 215 | </span> |
| 216 | 216 | )} |
| ... | ... | @@ -251,7 +251,7 @@ export const ChangedFilesTree = memo(function ChangedFilesTree(props: { |
| 251 | 251 | <MiddleTruncate value={node.name} /> |
| 252 | 252 | </span> |
| 253 | 253 | {node.stat && ( |
| 254 | <span className="ml-auto shrink-0 font-mono text-[10px] tabular-nums"> | |
| 254 | <span className="ml-auto shrink-0 font-mono text-3xs tabular-nums"> | |
| 255 | 255 | <DiffStatLabel additions={node.stat.additions} deletions={node.stat.deletions} /> |
| 256 | 256 | </span> |
| 257 | 257 | )} |
apps/web/src/components/chat/ChatComposer.tsx+8-8| ... | ... | @@ -381,7 +381,7 @@ function SnapShotAttachmentFrame({ |
| 381 | 381 | className={cn( |
| 382 | 382 | animateArrival && |
| 383 | 383 | !animationId && |
| 384 | "origin-center transition-[opacity,scale] duration-300 ease-[cubic-bezier(.2,.8,.2,1)] starting:scale-95 starting:opacity-0 motion-reduce:transition-none motion-reduce:starting:scale-100 motion-reduce:starting:opacity-100", | |
| 384 | "origin-center transition-[opacity,scale] duration-300 ease-drawer starting:scale-95 starting:opacity-0 motion-reduce:transition-none motion-reduce:starting:scale-100 motion-reduce:starting:opacity-100", | |
| 385 | 385 | className, |
| 386 | 386 | )} |
| 387 | 387 | {...props} |
| ... | ... | @@ -6365,7 +6365,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 6365 | 6365 | data-chat-composer-surface="true" |
| 6366 | 6366 | data-chat-composer-mobile-collapsed={isComposerCollapsedMobile ? "true" : "false"} |
| 6367 | 6367 | className={cn( |
| 6368 | "rounded-[20px] transition-[background-color] duration-200", | |
| 6368 | "rounded-3xl transition-[background-color] duration-200", | |
| 6369 | 6369 | isDragOverComposer ? "bg-accent/45 ring-1 ring-primary/70" : null, |
| 6370 | 6370 | projectSelectionRequired ? "opacity-75" : null, |
| 6371 | 6371 | composerProviderState.composerSurfaceClassName, |
| ... | ... | @@ -6377,7 +6377,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 6377 | 6377 | type="button" |
| 6378 | 6378 | data-chat-composer-transition-prompt="true" |
| 6379 | 6379 | className={cn( |
| 6380 | "min-w-0 flex-1 truncate bg-transparent p-0 text-left text-[14px] focus:outline-none", | |
| 6380 | "min-w-0 flex-1 truncate bg-transparent p-0 text-left text-sm focus:outline-none", | |
| 6381 | 6381 | (activePendingProgress ? activePendingProgress.customAnswer : prompt.trim()) |
| 6382 | 6382 | ? "text-foreground" |
| 6383 | 6383 | : "text-placeholder", |
| ... | ... | @@ -6477,7 +6477,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 6477 | 6477 | "mb-3 flex max-w-full gap-2", |
| 6478 | 6478 | pendingSnapShotIds.length > 0 || |
| 6479 | 6479 | expandedComposerImages.some((image) => image.source?.kind === "snap-shot") |
| 6480 | ? "snap-x snap-proximity overflow-x-auto overscroll-x-contain pb-1 [scrollbar-color:color-mix(in_srgb,var(--contrast-foreground)_18%,transparent)_transparent] [scrollbar-width:thin] [&::-webkit-scrollbar]:h-2.5 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:border-3 [&::-webkit-scrollbar-thumb]:border-transparent [&::-webkit-scrollbar-thumb]:bg-[color-mix(in_srgb,var(--contrast-foreground)_18%,transparent)] [&::-webkit-scrollbar-thumb]:bg-clip-content [&::-webkit-scrollbar-thumb:hover]:bg-[color-mix(in_srgb,var(--contrast-foreground)_28%,transparent)] [&::-webkit-scrollbar-track]:mx-1 [&::-webkit-scrollbar-track]:bg-transparent" | |
| 6480 | ? "snap-x snap-proximity overflow-x-auto overscroll-x-contain pb-1 scrollbar-thumb-foreground/18 scrollbar-track-transparent [scrollbar-width:thin] [&::-webkit-scrollbar]:h-2.5 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:border-3 [&::-webkit-scrollbar-thumb]:border-transparent [&::-webkit-scrollbar-thumb]:bg-foreground/18 [&::-webkit-scrollbar-thumb]:bg-clip-content [&::-webkit-scrollbar-thumb:hover]:bg-foreground/28 [&::-webkit-scrollbar-track]:mx-1 [&::-webkit-scrollbar-track]:bg-transparent" | |
| 6481 | 6481 | : "flex-wrap", |
| 6482 | 6482 | )} |
| 6483 | 6483 | > |
| ... | ... | @@ -6532,14 +6532,14 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 6532 | 6532 | alt={image.name} |
| 6533 | 6533 | className="h-full w-full object-cover" |
| 6534 | 6534 | fallback={ |
| 6535 | <span className="flex h-full items-center justify-center px-1 text-[10px] text-secondary-label"> | |
| 6535 | <span className="flex h-full items-center justify-center px-1 text-3xs text-secondary-label"> | |
| 6536 | 6536 | {image.name} |
| 6537 | 6537 | </span> |
| 6538 | 6538 | } |
| 6539 | 6539 | /> |
| 6540 | 6540 | </button> |
| 6541 | 6541 | ) : ( |
| 6542 | <div className="flex h-full w-full items-center justify-center px-1 text-center text-[10px] text-secondary-label"> | |
| 6542 | <div className="flex h-full w-full items-center justify-center px-1 text-center text-3xs text-secondary-label"> | |
| 6543 | 6543 | {image.name} |
| 6544 | 6544 | </div> |
| 6545 | 6545 | )} |
| ... | ... | @@ -6572,7 +6572,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 6572 | 6572 | </Tooltip> |
| 6573 | 6573 | )} |
| 6574 | 6574 | {upload?.status === "uploading" && ( |
| 6575 | <span className="pointer-events-none absolute inset-x-0 bottom-0 bg-background/85 px-1 text-center text-[10px] text-foreground"> | |
| 6575 | <span className="pointer-events-none absolute inset-x-0 bottom-0 bg-background/85 px-1 text-center text-3xs text-foreground"> | |
| 6576 | 6576 | {formatAttachmentUploadProgress(upload.progress)} |
| 6577 | 6577 | </span> |
| 6578 | 6578 | )} |
| ... | ... | @@ -6671,7 +6671,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 6671 | 6671 | <PlayIcon className="relative z-10 size-4 fill-current drop-shadow-md" /> |
| 6672 | 6672 | </button> |
| 6673 | 6673 | {upload?.status === "uploading" && ( |
| 6674 | <span className="pointer-events-none absolute inset-x-0 bottom-0 bg-background/85 px-1 text-center text-[10px] text-foreground"> | |
| 6674 | <span className="pointer-events-none absolute inset-x-0 bottom-0 bg-background/85 px-1 text-center text-3xs text-foreground"> | |
| 6675 | 6675 | {formatAttachmentUploadProgress(upload.progress)} |
| 6676 | 6676 | </span> |
| 6677 | 6677 | )} |
apps/web/src/components/chat/ChatHeader.tsx+2-2| ... | ... | @@ -494,8 +494,8 @@ export const ChatHeader = memo(function ChatHeader({ |
| 494 | 494 | "flex shrink-0 items-center justify-end gap-2 @3xl/header-actions:gap-3", |
| 495 | 495 | // Reserve two panel toggles plus their 4px gaps and 1px edge inset. |
| 496 | 496 | // The page header adds 8px more right padding at sm. |
| 497 | rightPanelOpen ? "pr-0" : "pr-[calc(--spacing(18)+1px)] sm:pr-[calc(--spacing(14)+1px)]", | |
| 498 | "[[data-panel-animations=true]_&]:motion-safe:transition-[padding-right] [[data-panel-animations=true]_&]:motion-safe:[transition-duration:var(--panel-animation-duration)] [[data-panel-animations=true]_&]:motion-safe:ease-out", | |
| 497 | rightPanelOpen ? "pr-0" : "pr-18.25 sm:pr-14.25", | |
| 498 | "[[data-panel-animations=true]_&]:motion-safe:transition-[padding-right] [[data-panel-animations=true]_&]:motion-safe:duration-(--panel-animation-duration) [[data-panel-animations=true]_&]:motion-safe:ease-out", | |
| 499 | 499 | )} |
| 500 | 500 | > |
| 501 | 501 | <Menu open={actionsCollapsed && actionsOpen} onOpenChange={setActionsOpen}> |
apps/web/src/components/chat/ComposerBanner.tsx+14-22| ... | ... | @@ -51,17 +51,17 @@ function Surface({ |
| 51 | 51 | surfaceColors, |
| 52 | 52 | "relative isolate border-0 bg-transparent shadow-none [--chat-composer-attached-tint:transparent]", |
| 53 | 53 | variantColors[variant], |
| 54 | // The mask cut-off (1rem) bleeds one pixel past the seam (1rem + 1px): Chromium | |
| 55 | // drops the last device-pixel row of a filtered backdrop when the cut-off lands | |
| 56 | // off the device-pixel grid, and the composer's surface starts exactly there. | |
| 57 | // The composer's own glass covers the extra row, so the overlap never shows. | |
| 54 | 58 | placement === "attached" |
| 55 | ? "[--chat-composer-attachment-overlap:calc(1rem+1px)] before:rounded-t-[16px]" | |
| 56 | : "[--chat-composer-attachment-overlap:0px] before:rounded-[1rem]", | |
| 59 | ? "[--chat-composer-attachment-overlap:calc(1rem+1px)] before:rounded-t-2xl before:mask-t-from-transparent before:mask-t-from-4 before:mask-t-to-black before:mask-t-to-4" | |
| 60 | : "[--chat-composer-attachment-overlap:0px] before:rounded-2xl", | |
| 57 | 61 | "before:pointer-events-none before:absolute before:inset-0 before:-z-1 before:border before:border-(--chat-composer-attached-outline)", |
| 58 | "before:bg-[color-mix(in_srgb,var(--chat-composer-attached-surface)_var(--glass-opacity),transparent)] before:bg-[linear-gradient(var(--chat-composer-attached-tint),var(--chat-composer-attached-tint))] before:backdrop-blur-(--glass-blur) before:backdrop-saturate-(--glass-saturation)", | |
| 59 | // The mask cut-off bleeds one pixel past the seam: Chromium drops the last | |
| 60 | // device-pixel row of a filtered backdrop when the cut-off lands off the | |
| 61 | // device-pixel grid, and the composer's surface starts exactly there. The | |
| 62 | // composer's own glass covers the extra row, so the overlap never shows. | |
| 63 | "before:mask-[linear-gradient(to_top,transparent_0_calc(var(--chat-composer-attachment-overlap)-1px),black_calc(var(--chat-composer-attachment-overlap)-1px))] before:shadow-[0_12px_28px_-18px_rgb(0_0_0/40%)] dark:before:shadow-[0_14px_32px_-18px_rgb(0_0_0/75%)]", | |
| 64 | "dark:supports-[(backdrop-filter:blur(1px))_or_(-webkit-backdrop-filter:blur(1px))]:before:bg-[linear-gradient(var(--chat-composer-attached-tint),var(--chat-composer-attached-tint)),linear-gradient(to_top,transparent_0_var(--chat-composer-attachment-overlap),rgb(0_0_0/18%)_var(--chat-composer-attachment-overlap),transparent_calc(var(--chat-composer-attachment-overlap)+10px))]", | |
| 62 | "before:bg-(--chat-composer-attached-surface)/(--glass-opacity) before:bg-linear-to-b before:from-(--chat-composer-attached-tint) before:to-(--chat-composer-attached-tint) before:backdrop-blur-(--glass-blur) before:backdrop-saturate-(--glass-saturation)", | |
| 63 | "before:shadow-composer dark:before:shadow-composer-dark", | |
| 64 | "dark:supports-[(backdrop-filter:blur(1px))_or_(-webkit-backdrop-filter:blur(1px))]:before:bg-composer-seam-above", | |
| 65 | 65 | "not-supports-[((backdrop-filter:blur(1px))_or_(-webkit-backdrop-filter:blur(1px)))]:before:bg-(--chat-composer-attached-surface)", |
| 66 | 66 | className, |
| 67 | 67 | )} |
| ... | ... | @@ -91,8 +91,8 @@ function Peek({ |
| 91 | 91 | className={cn( |
| 92 | 92 | surfaceColors, |
| 93 | 93 | neutralOutline, |
| 94 | "absolute inset-x-0 bottom-0 z-0 mx-auto h-3 w-[96%] cursor-pointer rounded-t-2xl border border-b-0 shadow-[0_6px_18px_rgb(0_0_0/6%)]", | |
| 95 | "bg-[color-mix(in_srgb,var(--chat-composer-attached-surface)_var(--glass-opacity),transparent)] backdrop-blur-(--glass-blur) backdrop-saturate-(--glass-saturation)", | |
| 94 | "absolute inset-x-0 bottom-0 z-0 mx-auto h-3 w-[96%] cursor-pointer rounded-t-2xl border border-b-0 shadow-md", | |
| 95 | "bg-(--chat-composer-attached-surface)/(--glass-opacity) backdrop-blur-(--glass-blur) backdrop-saturate-(--glass-saturation)", | |
| 96 | 96 | "not-supports-[((backdrop-filter:blur(1px))_or_(-webkit-backdrop-filter:blur(1px)))]:bg-(--chat-composer-attached-surface)", |
| 97 | 97 | "transition-opacity duration-150 ease-out focus-visible:outline-2 focus-visible:outline-ring", |
| 98 | 98 | peekBorder[variant], |
| ... | ... | @@ -161,7 +161,7 @@ function Root({ |
| 161 | 161 | return ( |
| 162 | 162 | <Surface |
| 163 | 163 | className={cn( |
| 164 | "min-w-0 px-1 pt-(--composer-banner-padding-block) pb-[calc(var(--chat-composer-attachment-overlap)+var(--composer-banner-padding-block))] text-xs/4 [--composer-banner-icon-column:--spacing(7)] [--composer-banner-padding-block:--spacing(1)] sm:[--composer-banner-icon-column:--spacing(6)]", | |
| 164 | "min-w-0 px-1 py-(--composer-banner-padding-block) after:block after:h-(--chat-composer-attachment-overlap) text-xs/4 [--composer-banner-icon-column:--spacing(7)] [--composer-banner-padding-block:--spacing(1)] sm:[--composer-banner-icon-column:--spacing(6)]", | |
| 165 | 165 | density === "comfortable" && "[--composer-banner-padding-block:--spacing(1.25)]", |
| 166 | 166 | density === "spacious" && "px-3 [--composer-banner-padding-block:--spacing(3)]", |
| 167 | 167 | width === "content" ? "w-fit max-w-full flex-none" : "@container", |
| ... | ... | @@ -189,7 +189,7 @@ function Row({ |
| 189 | 189 | className: cn( |
| 190 | 190 | "group/banner-row grid min-h-(--composer-banner-icon-column) w-full min-w-0 grid-cols-[var(--composer-banner-icon-column)_minmax(0,1fr)_auto] items-center gap-x-1 text-start", |
| 191 | 191 | "not-has-[>[data-slot=composer-banner-actions]]:grid-cols-[var(--composer-banner-icon-column)_minmax(0,1fr)]", |
| 192 | "[&:is(button)]:cursor-pointer [&:is(button)]:rounded-[0.5rem] [&:is(button)]:focus-visible:outline-2 [&:is(button)]:focus-visible:-outline-offset-2 [&:is(button)]:focus-visible:outline-ring", | |
| 192 | "[&:is(button)]:cursor-pointer [&:is(button)]:rounded-md [&:is(button)]:focus-visible:outline-2 [&:is(button)]:focus-visible:-outline-offset-2 [&:is(button)]:focus-visible:outline-ring", | |
| 193 | 193 | layout === "wrap-actions" && |
| 194 | 194 | "@max-[400px]:*:data-[slot=composer-banner-content]:min-h-(--composer-banner-icon-column)", |
| 195 | 195 | layout === "wrap-actions-narrow" && |
| ... | ... | @@ -306,15 +306,7 @@ function Count({ className, ...props }: ComponentProps<"span">) { |
| 306 | 306 | } |
| 307 | 307 | |
| 308 | 308 | function Body({ className, ...props }: ComponentProps<"div">) { |
| 309 | return ( | |
| 310 | <div | |
| 311 | className={cn( | |
| 312 | "min-w-0 ps-[calc(var(--composer-banner-icon-column)+(--spacing(1)))]", | |
| 313 | className, | |
| 314 | )} | |
| 315 | {...props} | |
| 316 | /> | |
| 317 | ); | |
| 309 | return <div className={cn("min-w-0 ps-8 sm:ps-7", className)} {...props} />; | |
| 318 | 310 | } |
| 319 | 311 | |
| 320 | 312 | function Dot({ className, ...props }: ComponentProps<"span">) { |
apps/web/src/components/chat/ComposerBannerStack.tsx+2-2| ... | ... | @@ -123,7 +123,7 @@ export function ComposerBannerStack({ className, items }: ComposerBannerStackPro |
| 123 | 123 | <div |
| 124 | 124 | key={frontItem.id} |
| 125 | 125 | className={cn( |
| 126 | "relative z-10 transition-[translate,opacity] duration-220 ease-in", | |
| 126 | "relative z-10 transition-[opacity,translate] duration-220 ease-in", | |
| 127 | 127 | exitingItemId === frontItem.id |
| 128 | 128 | ? "pointer-events-none translate-y-16 opacity-0" |
| 129 | 129 | : "opacity-100", |
| ... | ... | @@ -218,7 +218,7 @@ export function ComposerBannerStack({ className, items }: ComposerBannerStackPro |
| 218 | 218 | <div |
| 219 | 219 | key={item.id} |
| 220 | 220 | className={cn( |
| 221 | "transition-[translate,opacity] duration-220 ease-in", | |
| 221 | "transition-[opacity,translate] duration-220 ease-in", | |
| 222 | 222 | exitingItemId === item.id |
| 223 | 223 | ? "pointer-events-none translate-y-28 opacity-0" |
| 224 | 224 | : "opacity-100", |
apps/web/src/components/chat/ComposerControl.tsx+3-3| ... | ... | @@ -16,10 +16,10 @@ export type ComposerControlSize = "sm" | "xs"; |
| 16 | 16 | */ |
| 17 | 17 | function composerControlClassName(size: ComposerControlSize, className?: string) { |
| 18 | 18 | return cn( |
| 19 | "relative inline-flex shrink-0 cursor-pointer items-center justify-center whitespace-nowrap rounded-[var(--control-radius)] border border-transparent text-base outline-none hover:bg-accent data-pressed:bg-accent focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 data-disabled:pointer-events-none data-disabled:opacity-64 pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 [&:active:not([aria-haspopup])]:scale-[0.97] [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:-mx-0.5 [&_svg[data-composer-control-icon]]:mx-0 [&_svg:not([class*='text-'])]:text-[var(--control-icon-color)]", | |
| 19 | "relative inline-flex shrink-0 cursor-pointer items-center justify-center whitespace-nowrap rounded-(--control-radius) border border-transparent text-base outline-none hover:bg-accent data-pressed:bg-accent focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 data-disabled:pointer-events-none data-disabled:opacity-64 pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 [&:active:not([aria-haspopup])]:scale-[0.97] [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:-mx-0.5 [&_svg[data-composer-control-icon]]:mx-0", | |
| 20 | 20 | size === "xs" |
| 21 | ? "h-7 gap-1 px-[calc(--spacing(2)-1px)] font-normal text-muted-foreground/70 text-sm [--control-icon-color:currentColor] hover:text-foreground/80 sm:h-6 sm:text-xs [&_svg:not([class*='size-'])]:size-4 sm:[&_svg:not([class*='size-'])]:size-3.5 [&_svg[data-composer-control-chevron]]:ms-0 [&_svg[data-composer-control-chevron]]:-me-1" | |
| 22 | : "h-7 gap-1.5 px-2.5 font-medium text-secondary-label [--control-icon-color:var(--contrast-muted-foreground)] hover:text-foreground sm:text-sm [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4", | |
| 21 | ? "h-7 gap-1 px-1.75 font-normal text-muted-foreground/70 text-sm hover:text-foreground/80 sm:h-6 sm:text-xs [&_svg:not([class*='size-'])]:size-4 sm:[&_svg:not([class*='size-'])]:size-3.5 [&_svg[data-composer-control-chevron]]:ms-0 [&_svg[data-composer-control-chevron]]:-me-1" | |
| 22 | : "h-7 gap-1.5 px-2.5 font-medium text-secondary-label [&_svg:not([class*='text-'])]:text-muted-foreground hover:text-foreground sm:text-sm [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4", | |
| 23 | 23 | "aria-pressed:bg-accent aria-pressed:text-accent-foreground aria-pressed:hover:bg-accent/80", |
| 24 | 24 | className, |
| 25 | 25 | ); |
apps/web/src/components/chat/ComposerPendingApprovalPanel.tsx+1-1| ... | ... | @@ -41,7 +41,7 @@ export const ComposerPendingApprovalPanel = memo(function ComposerPendingApprova |
| 41 | 41 | className={cn("flex min-w-0 flex-1 flex-col items-start gap-1", className)} |
| 42 | 42 | role="group" |
| 43 | 43 | > |
| 44 | <span className="flex w-full min-w-0 items-center gap-2 text-[11px] text-muted-foreground"> | |
| 44 | <span className="flex w-full min-w-0 items-center gap-2 text-2xs text-muted-foreground"> | |
| 45 | 45 | <span className="shrink-0 font-medium text-warning">{fallbackLabel}</span> |
| 46 | 46 | {approval.appName ? <span className="min-w-0 truncate">{approval.appName}</span> : null} |
| 47 | 47 | {pendingCount > 1 ? ( |
apps/web/src/components/chat/ComposerPendingUserInputPanel.tsx+3-5| ... | ... | @@ -198,7 +198,7 @@ const ComposerPendingUserInputCard = memo(function ComposerPendingUserInputCard( |
| 198 | 198 | </ComposerBanner.Content> |
| 199 | 199 | <ComposerBanner.Actions> |
| 200 | 200 | {prompt.questions.length > 1 ? ( |
| 201 | <span className="text-[10px] font-medium text-muted-foreground tabular-nums"> | |
| 201 | <span className="text-3xs font-medium text-muted-foreground tabular-nums"> | |
| 202 | 202 | {questionIndex + 1}/{prompt.questions.length} |
| 203 | 203 | </span> |
| 204 | 204 | ) : null} |
| ... | ... | @@ -257,9 +257,7 @@ const ComposerPendingUserInputCard = memo(function ComposerPendingUserInputCard( |
| 257 | 257 | <div className="min-w-0 flex-1 flex flex-col gap-0.5"> |
| 258 | 258 | <span className="text-sm font-medium">{option.label}</span> |
| 259 | 259 | {option.description && option.description !== option.label ? ( |
| 260 | <span className="text-secondary-label text-[11px]"> | |
| 261 | {option.description} | |
| 262 | </span> | |
| 260 | <span className="text-secondary-label text-2xs">{option.description}</span> | |
| 263 | 261 | ) : null} |
| 264 | 262 | </div> |
| 265 | 263 | {isSelected ? ( |
| ... | ... | @@ -267,7 +265,7 @@ const ComposerPendingUserInputCard = memo(function ComposerPendingUserInputCard( |
| 267 | 265 | ) : shortcutKey !== null ? ( |
| 268 | 266 | <kbd |
| 269 | 267 | className={cn( |
| 270 | "flex size-5 shrink-0 items-center justify-center text-[10px] font-medium text-muted-foreground tabular-nums", | |
| 268 | "flex size-5 shrink-0 items-center justify-center text-3xs font-medium text-muted-foreground tabular-nums", | |
| 271 | 269 | )} |
| 272 | 270 | > |
| 273 | 271 | {shortcutKey} |
apps/web/src/components/chat/ComposerPrimaryActions.tsx+2-2| ... | ... | @@ -91,7 +91,7 @@ export const ComposerPrimaryActions = memo(function ComposerPrimaryActions({ |
| 91 | 91 | <button |
| 92 | 92 | type="button" |
| 93 | 93 | className={cn( |
| 94 | "flex cursor-pointer items-center justify-center rounded-full bg-destructive/90 text-white shadow-xs shadow-destructive/24 inset-shadow-[0_1px_--theme(--color-white/16%)] transition-all duration-150 hover:bg-destructive hover:scale-105 active:inset-shadow-[0_1px_--theme(--color-black/8%)] active:shadow-none", | |
| 94 | "flex cursor-pointer items-center justify-center rounded-full bg-destructive/90 text-white shadow-xs shadow-destructive/24 inset-shadow-2xs inset-shadow-white/16 transition-all duration-150 hover:bg-destructive hover:scale-105 active:inset-shadow-black/8 active:shadow-none", | |
| 95 | 95 | insidePendingAction |
| 96 | 96 | ? "size-8 sm:size-7" |
| 97 | 97 | : hasSendableContent |
| ... | ... | @@ -215,7 +215,7 @@ export const ComposerPrimaryActions = memo(function ComposerPrimaryActions({ |
| 215 | 215 | <button |
| 216 | 216 | type="submit" |
| 217 | 217 | className={cn( |
| 218 | "relative isolate flex h-9 w-9 items-center justify-center overflow-hidden rounded-full shadow-xs transition-all duration-150 enabled:cursor-pointer enabled:inset-shadow-[0_1px_--theme(--color-white/16%)] hover:scale-105 active:inset-shadow-[0_1px_--theme(--color-black/8%)] active:shadow-none disabled:pointer-events-none disabled:opacity-30 disabled:shadow-none disabled:hover:scale-100 sm:h-8 sm:w-8", | |
| 218 | "relative isolate flex h-9 w-9 items-center justify-center overflow-hidden rounded-full shadow-xs transition-all duration-150 enabled:cursor-pointer enabled:inset-shadow-2xs enabled:inset-shadow-white/16 hover:scale-105 active:inset-shadow-black/8 active:shadow-none disabled:pointer-events-none disabled:opacity-30 disabled:shadow-none disabled:hover:scale-100 sm:h-8 sm:w-8", | |
| 219 | 219 | stageBackdropVariant |
| 220 | 220 | ? "bg-transparent text-white enabled:shadow-black/24 enabled:hover:brightness-110" |
| 221 | 221 | : "bg-message-action text-message-action-foreground enabled:shadow-message-action/24 hover:bg-message-action-hover", |
apps/web/src/components/chat/ComposerStashBadge.tsx+1-1| ... | ... | @@ -25,7 +25,7 @@ export const ComposerStashBadge = memo(function ComposerStashBadge(props: { |
| 25 | 25 | key={props.pulseKey} |
| 26 | 26 | className={cn( |
| 27 | 27 | props.pulsing |
| 28 | ? "animate-[prompt-stash-count-enter_180ms_ease-out_both] text-primary motion-reduce:animate-none" | |
| 28 | ? "text-primary transition-[opacity,translate] duration-180 ease-out starting:translate-y-0.5 starting:opacity-0 motion-reduce:transition-none" | |
| 29 | 29 | : "text-muted-foreground", |
| 30 | 30 | )} |
| 31 | 31 | > |
apps/web/src/components/chat/ComposerSurface.tsx+10-10| ... | ... | @@ -19,7 +19,7 @@ function Shell({ |
| 19 | 19 | "[html[data-theme-id]_&]:[--chat-composer-glass-surface:var(--app-theme-surface-raised)] [html[data-theme-id]_&]:[--chat-composer-outline:var(--app-theme-toolbar-border)]", |
| 20 | 20 | "dark:[html[data-theme-id]:not([data-theme-id=t3-chat])_&]:[--chat-composer-highlight:color-mix(in_srgb,var(--app-theme-input)_12%,transparent)] dark:[html[data-theme-id]:not([data-theme-id=t3-chat])_&]:[--chat-composer-outline:color-mix(in_srgb,var(--app-theme-input)_30%,var(--background))]", |
| 21 | 21 | "dark:[html[data-theme-id=t3-chat]_&]:[--chat-composer-highlight:color-mix(in_srgb,#432d48_12%,transparent)] dark:[html[data-theme-id=t3-chat]_&]:[--chat-composer-outline:#241e28]", |
| 22 | "before:pointer-events-none before:absolute before:inset-0 before:z-0 before:rounded-[22px] before:bg-[color-mix(in_srgb,var(--chat-composer-glass-surface)_var(--glass-opacity),transparent)] before:backdrop-blur-(--glass-blur) before:backdrop-saturate-(--glass-saturation)", | |
| 22 | "before:pointer-events-none before:absolute before:inset-0 before:z-0 before:rounded-3xl before:bg-(--chat-composer-glass-surface)/(--glass-opacity) before:backdrop-blur-(--glass-blur) before:backdrop-saturate-(--glass-saturation)", | |
| 23 | 23 | "not-supports-[((backdrop-filter:blur(1px))_or_(-webkit-backdrop-filter:blur(1px)))]:before:bg-(--chat-composer-glass-surface)", |
| 24 | 24 | "has-data-[composer-banner-surface=attached]:before:hidden", |
| 25 | 25 | contextStrip && [ |
| ... | ... | @@ -37,7 +37,7 @@ function Shell({ |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | const outlineClasses = |
| 40 | "after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:border after:border-(--chat-composer-outline) dark:after:shadow-[inset_0_1px_var(--chat-composer-highlight)]"; | |
| 40 | "after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:border after:border-(--chat-composer-outline) dark:after:inset-shadow-2xs dark:after:inset-shadow-(color:--chat-composer-highlight)"; | |
| 41 | 41 | |
| 42 | 42 | // The bottom strip continues the outline, so leave the seam between its corners open. |
| 43 | 43 | const contextSeamClasses = |
| ... | ... | @@ -48,7 +48,7 @@ function Host({ className, ...props }: ComponentProps<"div">) { |
| 48 | 48 | <div |
| 49 | 49 | data-slot="composer-host" |
| 50 | 50 | className={cn( |
| 51 | "relative z-10 w-full rounded-[22px] shadow-[0_12px_28px_-18px_rgb(0_0_0/40%)] after:z-1 dark:shadow-none", | |
| 51 | "relative z-10 w-full rounded-3xl shadow-composer after:z-1 dark:shadow-none", | |
| 52 | 52 | outlineClasses, |
| 53 | 53 | contextSeamClasses, |
| 54 | 54 | "group-has-data-[composer-banner-surface=attached]/composer-surface:shadow-none group-has-data-[composer-banner-surface=attached]/composer-surface:after:hidden", |
| ... | ... | @@ -64,12 +64,12 @@ function Main({ className, ...props }: ComponentProps<"div">) { |
| 64 | 64 | <div |
| 65 | 65 | data-chat-composer-main-surface="true" |
| 66 | 66 | className={cn( |
| 67 | "group relative z-10 rounded-[22px] p-px transition-colors duration-200", | |
| 67 | "group relative z-10 rounded-3xl p-px transition-colors duration-200", | |
| 68 | 68 | outlineClasses, |
| 69 | 69 | contextSeamClasses, |
| 70 | 70 | "after:z-20 after:hidden group-has-data-[composer-banner-surface=attached]/composer-surface:after:block", |
| 71 | "group-has-data-[composer-banner-surface=attached]/composer-surface:bg-[color-mix(in_srgb,var(--chat-composer-glass-surface)_var(--glass-opacity),transparent)] group-has-data-[composer-banner-surface=attached]/composer-surface:backdrop-blur-(--glass-blur) group-has-data-[composer-banner-surface=attached]/composer-surface:backdrop-saturate-(--glass-saturation)", | |
| 72 | "group-has-data-[composer-banner-surface=attached]/composer-surface:shadow-[0_12px_28px_-18px_rgb(0_0_0/40%)] dark:group-has-data-[composer-banner-surface=attached]/composer-surface:shadow-none", | |
| 71 | "group-has-data-[composer-banner-surface=attached]/composer-surface:bg-(--chat-composer-glass-surface)/(--glass-opacity) group-has-data-[composer-banner-surface=attached]/composer-surface:backdrop-blur-(--glass-blur) group-has-data-[composer-banner-surface=attached]/composer-surface:backdrop-saturate-(--glass-saturation)", | |
| 72 | "group-has-data-[composer-banner-surface=attached]/composer-surface:shadow-composer dark:group-has-data-[composer-banner-surface=attached]/composer-surface:shadow-none", | |
| 73 | 73 | "not-supports-[((backdrop-filter:blur(1px))_or_(-webkit-backdrop-filter:blur(1px)))]:group-has-data-[composer-banner-surface=attached]/composer-surface:bg-(--chat-composer-glass-surface)", |
| 74 | 74 | "group-has-data-[composer-banner-surface=attached]/composer-surface:**:data-[chat-composer-mobile-collapsed=true]:min-h-[calc(1rem+1px)]", |
| 75 | 75 | className, |
| ... | ... | @@ -85,10 +85,10 @@ function ContextStrip({ className, ...props }: ComponentProps<"div">) { |
| 85 | 85 | data-slot="composer-context-strip" |
| 86 | 86 | className={cn( |
| 87 | 87 | "group/composer-context relative isolate mx-auto -mt-4 flex w-[calc(100%-2*var(--chat-composer-drawer-inset))] items-center gap-2 overflow-x-clip overflow-y-visible ps-1 pe-2 pt-5 pb-1", |
| 88 | "before:absolute before:inset-0 before:-z-1 before:rounded-b-[16px] before:border before:border-(--chat-composer-outline) before:mask-[linear-gradient(to_bottom,transparent_0_1rem,black_1rem)] before:shadow-[0_12px_28px_-18px_rgb(0_0_0/40%)]", | |
| 89 | "dark:before:border-white/7 dark:before:bg-[linear-gradient(to_bottom,transparent_0_1rem,rgb(0_0_0/18%)_1rem,transparent_calc(1rem+10px)),linear-gradient(rgb(255_255_255/1%),rgb(255_255_255/1%))] dark:before:shadow-[0_14px_32px_-18px_rgb(0_0_0/75%)]", | |
| 90 | "group-has-data-[composer-banner-surface=attached]/composer-surface:before:bg-[color-mix(in_srgb,var(--chat-composer-glass-surface)_var(--glass-opacity),transparent)] group-has-data-[composer-banner-surface=attached]/composer-surface:before:backdrop-blur-(--glass-blur) group-has-data-[composer-banner-surface=attached]/composer-surface:before:backdrop-saturate-(--glass-saturation)", | |
| 91 | "not-supports-[clip-path:shape(from_0_0,line_to_1px_1px)]:before:bg-[color-mix(in_srgb,var(--chat-composer-glass-surface)_var(--glass-opacity),transparent)] not-supports-[clip-path:shape(from_0_0,line_to_1px_1px)]:before:backdrop-blur-(--glass-blur) not-supports-[clip-path:shape(from_0_0,line_to_1px_1px)]:before:backdrop-saturate-(--glass-saturation)", | |
| 88 | "before:absolute before:inset-0 before:-z-1 before:rounded-b-2xl before:border before:border-(--chat-composer-outline) before:mask-b-from-transparent before:mask-b-from-4 before:mask-b-to-black before:mask-b-to-4 before:shadow-composer", | |
| 89 | "dark:before:border-white/7 dark:before:bg-composer-seam-below dark:before:shadow-composer-dark", | |
| 90 | "group-has-data-[composer-banner-surface=attached]/composer-surface:before:bg-(--chat-composer-glass-surface)/(--glass-opacity) group-has-data-[composer-banner-surface=attached]/composer-surface:before:backdrop-blur-(--glass-blur) group-has-data-[composer-banner-surface=attached]/composer-surface:before:backdrop-saturate-(--glass-saturation)", | |
| 91 | "not-supports-[clip-path:shape(from_0_0,line_to_1px_1px)]:before:bg-(--chat-composer-glass-surface)/(--glass-opacity) not-supports-[clip-path:shape(from_0_0,line_to_1px_1px)]:before:backdrop-blur-(--glass-blur) not-supports-[clip-path:shape(from_0_0,line_to_1px_1px)]:before:backdrop-saturate-(--glass-saturation)", | |
| 92 | 92 | className, |
| 93 | 93 | )} |
| 94 | 94 | {...props} |
apps/web/src/components/chat/ComposerTasksBadge.tsx+1-1| ... | ... | @@ -200,7 +200,7 @@ export const ComposerTasksContent = memo(function ComposerTasksContent({ |
| 200 | 200 | </ComposerBanner.Content> |
| 201 | 201 | <ComposerBanner.Actions> |
| 202 | 202 | <span |
| 203 | className="w-12 text-right text-[10px]/4 text-muted-foreground/45 tabular-nums" | |
| 203 | className="w-12 text-right text-3xs/4 text-muted-foreground/45 tabular-nums" | |
| 204 | 204 | data-composer-task-duration="true" |
| 205 | 205 | > |
| 206 | 206 | {step.durationMs !== undefined |
apps/web/src/components/chat/ContextWindowMeter.tsx+6-6| ... | ... | @@ -92,11 +92,11 @@ export function ContextWindowMeter(props: { |
| 92 | 92 | width="sm" |
| 93 | 93 | className="text-left whitespace-normal" |
| 94 | 94 | > |
| 95 | <div className="flex flex-col gap-2 p-[var(--floating-content-inset)]"> | |
| 95 | <div className="flex flex-col gap-2 p-(--floating-content-inset)"> | |
| 96 | 96 | <div className="flex items-center justify-between gap-3"> |
| 97 | 97 | <div className="font-medium text-muted-foreground text-xs">Context Window</div> |
| 98 | 98 | {usage.maxTokens !== null && usedPercentage ? ( |
| 99 | <div className="text-secondary-label text-[11px] tabular-nums"> | |
| 99 | <div className="text-secondary-label text-2xs tabular-nums"> | |
| 100 | 100 | <span>{usedPercentage}</span> |
| 101 | 101 | <span className="mx-1">·</span> |
| 102 | 102 | <span> |
| ... | ... | @@ -105,7 +105,7 @@ export function ContextWindowMeter(props: { |
| 105 | 105 | </span> |
| 106 | 106 | </div> |
| 107 | 107 | ) : ( |
| 108 | <div className="text-secondary-label text-[11px] tabular-nums"> | |
| 108 | <div className="text-secondary-label text-2xs tabular-nums"> | |
| 109 | 109 | {formatContextWindowTokens(usage.usedTokens)} |
| 110 | 110 | </div> |
| 111 | 111 | )} |
| ... | ... | @@ -126,7 +126,7 @@ export function ContextWindowMeter(props: { |
| 126 | 126 | </div> |
| 127 | 127 | ) : null} |
| 128 | 128 | {showTotalProcessed ? ( |
| 129 | <div className="flex items-center justify-between gap-3 text-[11px] leading-4"> | |
| 129 | <div className="flex items-center justify-between gap-3 text-2xs leading-4"> | |
| 130 | 130 | <span className="text-secondary-label">Total processed</span> |
| 131 | 131 | <span className="font-medium tabular-nums text-secondary-label"> |
| 132 | 132 | {formatContextWindowTokens(totalProcessedTokens)} |
| ... | ... | @@ -134,7 +134,7 @@ export function ContextWindowMeter(props: { |
| 134 | 134 | </div> |
| 135 | 135 | ) : null} |
| 136 | 136 | {usage.compactsAutomatically ? ( |
| 137 | <div className="mt-1 text-pretty text-secondary-label text-[11px] font-medium"> | |
| 137 | <div className="mt-1 text-pretty text-secondary-label text-2xs font-medium"> | |
| 138 | 138 | {formatContextWindowCompactionMessage(modelDisplayName, usage.autoCompactThreshold)} |
| 139 | 139 | </div> |
| 140 | 140 | ) : null} |
| ... | ... | @@ -151,7 +151,7 @@ export function ContextWindowMeter(props: { |
| 151 | 151 | Compact context |
| 152 | 152 | </Button> |
| 153 | 153 | {compactDisabled && compactDisabledReason ? ( |
| 154 | <div className="text-pretty text-secondary-label text-[11px]"> | |
| 154 | <div className="text-pretty text-secondary-label text-2xs"> | |
| 155 | 155 | {compactDisabledReason} |
| 156 | 156 | </div> |
| 157 | 157 | ) : null} |
apps/web/src/components/chat/ExpandedImageDialog.tsx+1-1| ... | ... | @@ -219,7 +219,7 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({ |
| 219 | 219 | accessibilityDetails ? ( |
| 220 | 220 | <SnapShotAccessibilityData |
| 221 | 221 | details={accessibilityDetails} |
| 222 | className="h-[min(var(--media-height),40rem)] w-[min(var(--media-width),42rem)] animate-[snap-shot-contents-enter_140ms_ease-out] rounded-lg border border-border/70 bg-background p-4 text-xs leading-5 shadow-2xl motion-reduce:animate-none" | |
| 222 | className="h-[min(var(--media-height),40rem)] w-[min(var(--media-width),42rem)] transition-opacity duration-140 ease-out starting:opacity-0 rounded-lg border border-border/70 bg-background p-4 text-xs leading-5 shadow-2xl motion-reduce:transition-none" | |
| 223 | 223 | /> |
| 224 | 224 | ) : null |
| 225 | 225 | ) : item.src === null || failedImageSrc === item.src ? ( |
apps/web/src/components/chat/MessagesTimeline.tsx+22-22| ... | ... | @@ -344,7 +344,7 @@ function TimelineLoadEarlierHeader({ |
| 344 | 344 | fade: boolean; |
| 345 | 345 | }) { |
| 346 | 346 | return ( |
| 347 | <div className={fade ? "pt-[var(--workspace-titlebar-scroll-fade-height)]" : "pt-3 sm:pt-4"}> | |
| 347 | <div className={fade ? "pt-(--workspace-titlebar-scroll-fade-height)" : "pt-3 sm:pt-4"}> | |
| 348 | 348 | <div className="mx-auto w-full max-w-3xl pb-2"> |
| 349 | 349 | <button |
| 350 | 350 | type="button" |
| ... | ... | @@ -1539,7 +1539,7 @@ function TimelineMinimap({ |
| 1539 | 1539 | <span |
| 1540 | 1540 | aria-hidden="true" |
| 1541 | 1541 | className={cn( |
| 1542 | "pointer-events-none absolute left-0 h-0.5 -translate-y-1/2 rounded-full bg-muted-foreground/35 transition-[background-color,width] duration-150 data-[in-view=true]:bg-foreground/90", | |
| 1542 | "pointer-events-none absolute left-0 h-0.5 -translate-y-1/2 rounded-full bg-muted-foreground/35 transition-[width,background-color] duration-150 data-[in-view=true]:bg-foreground/90", | |
| 1543 | 1543 | activeDistance === 0 |
| 1544 | 1544 | ? "w-6 bg-muted-foreground/75" |
| 1545 | 1545 | : activeDistance === 1 |
| ... | ... | @@ -1885,7 +1885,7 @@ function UserVideoAttachment({ file }: { readonly file: ChatFileAttachment }) { |
| 1885 | 1885 | |
| 1886 | 1886 | if (asset === null && src === null) { |
| 1887 | 1887 | return ( |
| 1888 | <div className="flex aspect-[4/3] w-full items-center justify-center rounded-lg border border-border/80 bg-black px-2 py-3 text-center text-[11px] text-white/70"> | |
| 1888 | <div className="flex aspect-[4/3] w-full items-center justify-center rounded-lg border border-border/80 bg-black px-2 py-3 text-center text-2xs text-white/70"> | |
| 1889 | 1889 | {file.name} |
| 1890 | 1890 | </div> |
| 1891 | 1891 | ); |
| ... | ... | @@ -2112,7 +2112,7 @@ function UserTimelineRow({ row }: { row: Extract<TimelineRow, { kind: "message" |
| 2112 | 2112 | /> |
| 2113 | 2113 | </button> |
| 2114 | 2114 | ) : ( |
| 2115 | <div className="flex min-h-[72px] items-center justify-center px-2 py-3 text-center text-secondary-label text-[11px]"> | |
| 2115 | <div className="flex min-h-[72px] items-center justify-center px-2 py-3 text-center text-secondary-label text-2xs"> | |
| 2116 | 2116 | {image.name} |
| 2117 | 2117 | </div> |
| 2118 | 2118 | )} |
| ... | ... | @@ -2756,7 +2756,7 @@ function ReasoningTraceBlock({ |
| 2756 | 2756 | className="flex min-h-6 cursor-pointer select-none items-center gap-1.5 rounded-md px-0.5 text-start text-sm leading-relaxed transition-colors hover:bg-accent/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring/70" |
| 2757 | 2757 | > |
| 2758 | 2758 | <span className="flex size-6 shrink-0 items-center justify-center text-icon-muted"> |
| 2759 | <BrainIcon aria-hidden className="block size-4 shrink-0 stroke-[1.8] opacity-70" /> | |
| 2759 | <BrainIcon aria-hidden className="block size-4 shrink-0 stroke-2 opacity-70" /> | |
| 2760 | 2760 | </span> |
| 2761 | 2761 | <span |
| 2762 | 2762 | ref={streaming ? observeVisibleAnimation : undefined} |
| ... | ... | @@ -2829,7 +2829,7 @@ const ReasoningTimelineRow = memo(function ReasoningTimelineRow({ |
| 2829 | 2829 | className="flex cursor-pointer select-none items-center gap-1.5 rounded-md px-0.5 py-0.5 text-start transition-colors hover:bg-accent/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring/70" |
| 2830 | 2830 | > |
| 2831 | 2831 | <span className="flex size-6 shrink-0 items-center justify-center text-icon-muted"> |
| 2832 | <BrainIcon aria-hidden className="block size-4 shrink-0 stroke-[1.8] opacity-70" /> | |
| 2832 | <BrainIcon aria-hidden className="block size-4 shrink-0 stroke-2 opacity-70" /> | |
| 2833 | 2833 | </span> |
| 2834 | 2834 | <span className="flex min-w-0 flex-1 items-center gap-1.5"> |
| 2835 | 2835 | <span className="relative min-w-0 flex-1 truncate text-secondary-label text-sm leading-relaxed"> |
| ... | ... | @@ -3208,7 +3208,7 @@ function LiveActivityContent({ |
| 3208 | 3208 | <ToolActivityIconView |
| 3209 | 3209 | icon={toolIcon} |
| 3210 | 3210 | fallbackName={iconName} |
| 3211 | className="block size-4 shrink-0 stroke-[1.8]" | |
| 3211 | className="block size-4 shrink-0 stroke-2" | |
| 3212 | 3212 | muted={!highlighted} |
| 3213 | 3213 | /> |
| 3214 | 3214 | </span> |
| ... | ... | @@ -3329,7 +3329,7 @@ function WorkGroupToggleTimelineRow({ |
| 3329 | 3329 | fallbackName={ |
| 3330 | 3330 | row.summaryToolIcon ?? row.toolSurface ?? toolGroupSummaryIconName(row.summaryKind) |
| 3331 | 3331 | } |
| 3332 | className="size-4 shrink-0 stroke-[1.8]" | |
| 3332 | className="size-4 shrink-0 stroke-2" | |
| 3333 | 3333 | muted |
| 3334 | 3334 | /> |
| 3335 | 3335 | </span> |
| ... | ... | @@ -3545,7 +3545,7 @@ function UserMessagePreviewAnnotationDetails(props: { |
| 3545 | 3545 | {props.record.comment} |
| 3546 | 3546 | </div> |
| 3547 | 3547 | ) : null} |
| 3548 | <div className="mt-1 flex items-center gap-2 text-secondary-label text-[10px]"> | |
| 3548 | <div className="mt-1 flex items-center gap-2 text-secondary-label text-3xs"> | |
| 3549 | 3549 | {props.record.targetSummary ? ( |
| 3550 | 3550 | <span className="truncate">{props.record.targetSummary}</span> |
| 3551 | 3551 | ) : null} |
| ... | ... | @@ -3577,7 +3577,7 @@ function UserMessagePreviewAnnotationDetails(props: { |
| 3577 | 3577 | ) : null} |
| 3578 | 3578 | </div> |
| 3579 | 3579 | {element.htmlPreview?.trim() ? ( |
| 3580 | <pre className="mt-1 max-h-24 overflow-auto whitespace-pre-wrap rounded bg-muted/60 px-2 py-1.5 text-[10px] leading-relaxed"> | |
| 3580 | <pre className="mt-1 max-h-24 overflow-auto whitespace-pre-wrap rounded bg-muted/60 px-2 py-1.5 text-3xs leading-relaxed"> | |
| 3581 | 3581 | {element.htmlPreview.trim()} |
| 3582 | 3582 | </pre> |
| 3583 | 3583 | ) : null} |
| ... | ... | @@ -3585,7 +3585,7 @@ function UserMessagePreviewAnnotationDetails(props: { |
| 3585 | 3585 | ); |
| 3586 | 3586 | })} |
| 3587 | 3587 | {(props.record.elements?.length ?? 0) > visibleElements.length ? ( |
| 3588 | <div className="text-secondary-label text-[10px]"> | |
| 3588 | <div className="text-secondary-label text-3xs"> | |
| 3589 | 3589 | {(props.record.elements?.length ?? 0) - visibleElements.length} more selected |
| 3590 | 3590 | elements |
| 3591 | 3591 | </div> |
| ... | ... | @@ -3611,7 +3611,7 @@ function UserMessageElementDetails({ |
| 3611 | 3611 | <div className="truncate text-message-foreground text-xs font-medium"> |
| 3612 | 3612 | {record.pageTitle?.trim() || record.pageUrl} |
| 3613 | 3613 | </div> |
| 3614 | <div className="mt-0.5 truncate text-secondary-label text-[10px]">{record.pageUrl}</div> | |
| 3614 | <div className="mt-0.5 truncate text-secondary-label text-3xs">{record.pageUrl}</div> | |
| 3615 | 3615 | </div> |
| 3616 | 3616 | <div className="space-y-2 px-3 py-2.5"> |
| 3617 | 3617 | <div className="flex min-w-0 items-center gap-2 text-xs"> |
| ... | ... | @@ -4013,7 +4013,7 @@ function UserMessageReviewCommentCard({ comment }: { comment: ReviewCommentConte |
| 4013 | 4013 | <div className="text-message-foreground text-xs font-medium"> |
| 4014 | 4014 | {formatWorkspaceRelativePath(comment.filePath, ctx.workspaceRoot)} |
| 4015 | 4015 | </div> |
| 4016 | <div className="text-secondary-label text-[11px]"> | |
| 4016 | <div className="text-secondary-label text-2xs"> | |
| 4017 | 4017 | {comment.sectionTitle} · {comment.rangeLabel} |
| 4018 | 4018 | </div> |
| 4019 | 4019 | </div> |
| ... | ... | @@ -4153,7 +4153,7 @@ function ToolActivityIconView(props: { |
| 4153 | 4153 | muted: boolean; |
| 4154 | 4154 | }) { |
| 4155 | 4155 | const { resolvedTheme } = use(TimelineRowCtx); |
| 4156 | const fallbackClassName = cn(props.className, props.muted && "opacity-70 light:brightness-[.6]"); | |
| 4156 | const fallbackClassName = cn(props.className, props.muted && "opacity-70 light:brightness-60"); | |
| 4157 | 4157 | if (!props.icon) { |
| 4158 | 4158 | return <WorkEntryIcon name={props.fallbackName} className={fallbackClassName} />; |
| 4159 | 4159 | } |
| ... | ... | @@ -4213,7 +4213,7 @@ function NativeAppToolActivityIcon(props: { |
| 4213 | 4213 | return ( |
| 4214 | 4214 | <WorkEntryIcon |
| 4215 | 4215 | name={props.fallbackName} |
| 4216 | className={cn(props.className, props.muted && "opacity-70 light:brightness-[.6]")} | |
| 4216 | className={cn(props.className, props.muted && "opacity-70 light:brightness-60")} | |
| 4217 | 4217 | /> |
| 4218 | 4218 | ); |
| 4219 | 4219 | } |
| ... | ... | @@ -4258,14 +4258,14 @@ function ToolActivityImageIcon(props: { |
| 4258 | 4258 | {displayedSrc === null ? ( |
| 4259 | 4259 | <WorkEntryIcon |
| 4260 | 4260 | name={props.fallbackName} |
| 4261 | className={cn(props.className, props.muted && "opacity-70 light:brightness-[.6]")} | |
| 4261 | className={cn(props.className, props.muted && "opacity-70 light:brightness-60")} | |
| 4262 | 4262 | /> |
| 4263 | 4263 | ) : null} |
| 4264 | 4264 | {displayedSrc ? ( |
| 4265 | 4265 | <span |
| 4266 | 4266 | className={cn( |
| 4267 | 4267 | props.className, |
| 4268 | "inline-block overflow-hidden rounded-[3px] bg-background", | |
| 4268 | "inline-block overflow-hidden rounded-xs bg-background", | |
| 4269 | 4269 | props.muted && "opacity-70", |
| 4270 | 4270 | )} |
| 4271 | 4271 | > |
| ... | ... | @@ -4275,7 +4275,7 @@ function ToolActivityImageIcon(props: { |
| 4275 | 4275 | aria-hidden |
| 4276 | 4276 | decoding="async" |
| 4277 | 4277 | referrerPolicy="no-referrer" |
| 4278 | className={cn("block size-full object-contain", props.muted && "light:brightness-[.6]")} | |
| 4278 | className={cn("block size-full object-contain", props.muted && "light:brightness-60")} | |
| 4279 | 4279 | onError={() => handleLoadError(displayedSrc)} |
| 4280 | 4280 | /> |
| 4281 | 4281 | </span> |
| ... | ... | @@ -4429,7 +4429,7 @@ function buildToolCallExpandedBody( |
| 4429 | 4429 | } |
| 4430 | 4430 | |
| 4431 | 4431 | const toolCallExpandedBodyClassName = |
| 4432 | "max-h-64 cursor-text overflow-auto whitespace-pre-wrap break-words font-mono text-secondary-label text-[length:var(--font-size-code,0.6875rem)] leading-relaxed select-text"; | |
| 4432 | "max-h-64 cursor-text overflow-auto whitespace-pre-wrap break-words font-mono text-secondary-label text-(length:--font-size-code,var(--text-2xs)) leading-relaxed select-text"; | |
| 4433 | 4433 | |
| 4434 | 4434 | function workEntryIconName(workEntry: TimelineWorkEntry): WorkEntryIconName { |
| 4435 | 4435 | if ( |
| ... | ... | @@ -4640,12 +4640,12 @@ function AgentSpawnMemberRow({ |
| 4640 | 4640 | {agent.title} |
| 4641 | 4641 | </span> |
| 4642 | 4642 | {role ? ( |
| 4643 | <span className="max-w-28 shrink-0 truncate rounded-sm border border-border/60 px-1 font-mono text-[.65rem] text-muted-foreground"> | |
| 4643 | <span className="max-w-28 shrink-0 truncate rounded-sm border border-border/60 px-1 font-mono text-3xs text-muted-foreground"> | |
| 4644 | 4644 | {role} |
| 4645 | 4645 | </span> |
| 4646 | 4646 | ) : null} |
| 4647 | 4647 | </p> |
| 4648 | <span className="shrink-0 font-mono text-[.7rem] tabular-nums text-muted-foreground"> | |
| 4648 | <span className="shrink-0 font-mono text-2xs tabular-nums text-muted-foreground"> | |
| 4649 | 4649 | {statusLabel} |
| 4650 | 4650 | </span> |
| 4651 | 4651 | </div> |
| ... | ... | @@ -4821,7 +4821,7 @@ const PlainWorkEntryRow = memo(function PlainWorkEntryRow(props: { |
| 4821 | 4821 | <ToolActivityIconView |
| 4822 | 4822 | icon={entryToolIcon} |
| 4823 | 4823 | fallbackName={entryIconName} |
| 4824 | className="block size-4 shrink-0 stroke-[1.8]" | |
| 4824 | className="block size-4 shrink-0 stroke-2" | |
| 4825 | 4825 | muted |
| 4826 | 4826 | /> |
| 4827 | 4827 | </span> |
apps/web/src/components/chat/ModelListRow.tsx+1-1| ... | ... | @@ -70,7 +70,7 @@ export const ModelListRow = memo(function ModelListRow(props: { |
| 70 | 70 | </div> |
| 71 | 71 | {props.showNewBadge ? ( |
| 72 | 72 | <span |
| 73 | className="shrink-0 rounded border border-update/35 bg-update/15 px-0.5 py-px text-[10px] font-bold uppercase leading-none tracking-wide text-update-foreground" | |
| 73 | className="shrink-0 rounded border border-update/35 bg-update/15 px-0.5 py-px text-3xs font-bold uppercase leading-none tracking-wide text-update-foreground" | |
| 74 | 74 | aria-label="New model" |
| 75 | 75 | > |
| 76 | 76 | New |
apps/web/src/components/chat/ModelPickerSidebar.tsx+3-5| ... | ... | @@ -123,7 +123,7 @@ export const ModelPickerSidebar = memo(function ModelPickerSidebar(props: { |
| 123 | 123 | render={ |
| 124 | 124 | <Toolbar.Button |
| 125 | 125 | className={cn( |
| 126 | "relative isolate flex w-full cursor-pointer aspect-square items-center justify-center rounded-md transition-colors hover:bg-[color-mix(in_srgb,var(--popover)_90%,var(--contrast-foreground))] focus-visible:bg-[color-mix(in_srgb,var(--popover)_90%,var(--contrast-foreground))] focus-visible:outline-none", | |
| 126 | "relative isolate flex w-full cursor-pointer aspect-square items-center justify-center rounded-md transition-colors hover:bg-foreground/10 focus-visible:bg-foreground/10 focus-visible:outline-none", | |
| 127 | 127 | )} |
| 128 | 128 | onClick={() => handleSelect("favorites")} |
| 129 | 129 | type="button" |
| ... | ... | @@ -171,7 +171,7 @@ export const ModelPickerSidebar = memo(function ModelPickerSidebar(props: { |
| 171 | 171 | const button = ( |
| 172 | 172 | <Toolbar.Button |
| 173 | 173 | className={cn( |
| 174 | "relative isolate flex w-full cursor-pointer aspect-square items-center justify-center rounded-md transition-colors hover:bg-[color-mix(in_srgb,var(--popover)_90%,var(--contrast-foreground))] focus-visible:bg-[color-mix(in_srgb,var(--popover)_90%,var(--contrast-foreground))] focus-visible:outline-none", | |
| 174 | "relative isolate flex w-full cursor-pointer aspect-square items-center justify-center rounded-md transition-colors hover:bg-foreground/10 focus-visible:bg-foreground/10 focus-visible:outline-none", | |
| 175 | 175 | isDisabled && "opacity-50 cursor-not-allowed hover:bg-transparent", |
| 176 | 176 | )} |
| 177 | 177 | data-provider-accent-color={entry.accentColor} |
| ... | ... | @@ -210,9 +210,7 @@ export const ModelPickerSidebar = memo(function ModelPickerSidebar(props: { |
| 210 | 210 | ? "var(--background)" |
| 211 | 211 | : "color-mix(in oklab, var(--muted) 30%, transparent)" |
| 212 | 212 | } |
| 213 | {...(entry.accentColor | |
| 214 | ? { badgeClassName: "h-3 min-w-3 px-0.5 text-[7px]" } | |
| 215 | : {})} | |
| 213 | {...(entry.accentColor ? { badgeClassName: "h-3 min-w-3 px-0.5 text-3xs" } : {})} | |
| 216 | 214 | /> |
| 217 | 215 | {showNewBadge ? ( |
| 218 | 216 | <span className={NEW_BADGE_CLASS} aria-hidden> |
apps/web/src/components/chat/PanelLayoutControls.tsx+1-1| ... | ... | @@ -78,7 +78,7 @@ export const PanelLayoutControls = memo(function PanelLayoutControls({ |
| 78 | 78 | {liveAgentCount > 0 ? ( |
| 79 | 79 | <span |
| 80 | 80 | aria-hidden |
| 81 | className="absolute -top-1 -right-1 flex h-3.5 min-w-3.5 items-center justify-center rounded-full bg-info px-1 text-[9px] font-semibold tabular-nums text-white" | |
| 81 | className="absolute -top-1 -right-1 flex h-3.5 min-w-3.5 items-center justify-center rounded-full bg-info px-1 text-3xs font-semibold tabular-nums text-white" | |
| 82 | 82 | > |
| 83 | 83 | {liveAgentCount} |
| 84 | 84 | </span> |
apps/web/src/components/chat/ProposedPlanCard.tsx+1-1| ... | ... | @@ -146,7 +146,7 @@ export const ProposedPlanCard = memo(function ProposedPlanCard({ |
| 146 | 146 | }; |
| 147 | 147 | |
| 148 | 148 | return ( |
| 149 | <div className="rounded-[24px] border border-border/80 bg-card/70 p-4 sm:p-5"> | |
| 149 | <div className="rounded-3xl border border-border/80 bg-card/70 p-4 sm:p-5"> | |
| 150 | 150 | <div className="flex flex-wrap items-center justify-between gap-3"> |
| 151 | 151 | <div className="flex min-w-0 items-center gap-2"> |
| 152 | 152 | <Badge variant="secondary">Plan</Badge> |
apps/web/src/components/chat/ProviderInstanceIcon.tsx+3-3| ... | ... | @@ -38,7 +38,7 @@ export const ProviderInstanceIcon = memo(function ProviderInstanceIcon(props: { |
| 38 | 38 | {Icon ? ( |
| 39 | 39 | <Icon className={cn("size-5 shrink-0", props.iconClassName)} aria-hidden /> |
| 40 | 40 | ) : ( |
| 41 | <span className={cn("text-[10px] font-semibold leading-none", props.iconClassName)}> | |
| 41 | <span className={cn("text-3xs font-semibold leading-none", props.iconClassName)}> | |
| 42 | 42 | {providerInstanceInitials(props.displayName)} |
| 43 | 43 | </span> |
| 44 | 44 | )} |
| ... | ... | @@ -55,9 +55,9 @@ export const ProviderInstanceIcon = memo(function ProviderInstanceIcon(props: { |
| 55 | 55 | {props.showBadge ? ( |
| 56 | 56 | <span |
| 57 | 57 | className={cn( |
| 58 | "pointer-events-none absolute right-0 bottom-0 z-10 flex h-3.5 min-w-3.5 items-center justify-center rounded-full border px-0.5 text-[8px] font-semibold leading-none shadow-sm", | |
| 58 | "pointer-events-none absolute right-0 bottom-0 z-10 flex h-3.5 min-w-3.5 items-center justify-center rounded-full border px-0.5 text-3xs font-semibold leading-none shadow-sm", | |
| 59 | 59 | props.accentColor |
| 60 | ? "bg-[var(--provider-accent)] text-white" | |
| 60 | ? "bg-(--provider-accent) text-white" | |
| 61 | 61 | : "bg-card text-muted-foreground", |
| 62 | 62 | props.badgeClassName, |
| 63 | 63 | )} |
apps/web/src/components/chat/ProviderModelPicker.test.tsx+1-1| ... | ... | @@ -174,6 +174,6 @@ describe("ProviderModelPicker", () => { |
| 174 | 174 | expect(markup).toContain(">CP</span>"); |
| 175 | 175 | expect(markup).toContain("size-4"); |
| 176 | 176 | expect(markup).toContain("h-3"); |
| 177 | expect(markup).toContain("text-[7px]"); | |
| 177 | expect(markup).toContain("text-3xs"); | |
| 178 | 178 | }); |
| 179 | 179 | }); |
apps/web/src/components/chat/ProviderModelPicker.tsx+3-3| ... | ... | @@ -229,13 +229,13 @@ export const ProviderModelPicker = memo(function ProviderModelPicker(props: { |
| 229 | 229 | driverKind={selection.entry.driverKind} |
| 230 | 230 | displayName={selection.entry.displayName} |
| 231 | 231 | accentColor={selection.entry.accentColor} |
| 232 | className="size-4 rounded-full bg-[var(--chat-composer-glass-surface,var(--background))] ring-2 ring-[var(--chat-composer-glass-surface,var(--background))]" | |
| 232 | className="size-4 rounded-full bg-(--chat-composer-glass-surface,var(--background)) ring-2 ring-(--chat-composer-glass-surface,var(--background))" | |
| 233 | 233 | iconClassName="size-4" |
| 234 | 234 | /> |
| 235 | 235 | ) : null, |
| 236 | 236 | )} |
| 237 | 237 | {selectedEntries.length > 3 ? ( |
| 238 | <span className="relative z-30 flex size-4 items-center justify-center rounded-full bg-[var(--chat-composer-glass-surface,var(--background))] text-[9px] ring-2 ring-[var(--chat-composer-glass-surface,var(--background))]"> | |
| 238 | <span className="relative z-30 flex size-4 items-center justify-center rounded-full bg-(--chat-composer-glass-surface,var(--background)) text-3xs ring-2 ring-(--chat-composer-glass-surface,var(--background))"> | |
| 239 | 239 | +{selectedEntries.length - 3} |
| 240 | 240 | </span> |
| 241 | 241 | ) : null} |
| ... | ... | @@ -250,7 +250,7 @@ export const ProviderModelPicker = memo(function ProviderModelPicker(props: { |
| 250 | 250 | iconClassName={cn("size-4", props.activeProviderIconClassName)} |
| 251 | 251 | indicatorBackground={props.instanceIndicatorBackground ?? "var(--contrast-input)"} |
| 252 | 252 | badgeClassName={cn( |
| 253 | "right-[-0.125rem] bottom-[-0.125rem] h-3 min-w-3 px-0.5 text-[7px]", | |
| 253 | "right-[-0.125rem] bottom-[-0.125rem] h-3 min-w-3 px-0.5 text-3xs", | |
| 254 | 254 | size === "xs" && "shadow-none", |
| 255 | 255 | )} |
| 256 | 256 | /> |
apps/web/src/components/chat/SnapShotAttachmentDetails.tsx+4-4| ... | ... | @@ -169,7 +169,7 @@ export function SnapShotContentsButton({ |
| 169 | 169 | {accessibilityDetails ? ( |
| 170 | 170 | <SnapShotAccessibilityData |
| 171 | 171 | details={accessibilityDetails} |
| 172 | className="max-h-64 rounded-md border border-border/70 bg-muted/45 p-2.5 text-[11px] leading-4" | |
| 172 | className="max-h-64 rounded-md border border-border/70 bg-muted/45 p-2.5 text-2xs leading-4" | |
| 173 | 173 | /> |
| 174 | 174 | ) : includesAccessibility ? ( |
| 175 | 175 | <div className="rounded-md border border-border/70 bg-muted/45 p-2.5 text-muted-foreground text-xs leading-4"> |
| ... | ... | @@ -204,16 +204,16 @@ export function SnapShotAttachmentDetails({ |
| 204 | 204 | {source.appIconDataUrl ? ( |
| 205 | 205 | <img src={source.appIconDataUrl} alt="" className="size-7 shrink-0 rounded-md" /> |
| 206 | 206 | ) : ( |
| 207 | <div className="flex size-7 shrink-0 items-center justify-center rounded-md bg-white/20 text-[10px] font-medium text-white uppercase"> | |
| 207 | <div className="flex size-7 shrink-0 items-center justify-center rounded-md bg-white/20 text-3xs font-medium text-white uppercase"> | |
| 208 | 208 | {source.appName.slice(0, 1)} |
| 209 | 209 | </div> |
| 210 | 210 | )} |
| 211 | 211 | <div className="min-w-0 flex-1"> |
| 212 | <div className="flex min-w-0 items-center gap-1.5 text-[11px] font-medium leading-3.5 text-white"> | |
| 212 | <div className="flex min-w-0 items-center gap-1.5 text-2xs font-medium leading-3.5 text-white"> | |
| 213 | 213 | <span className="truncate">{source.appName}</span> |
| 214 | 214 | <SnapShotContentsButton source={source} className="pointer-events-auto" /> |
| 215 | 215 | </div> |
| 216 | <div className="truncate text-[9px] leading-3.5 text-white/70"> | |
| 216 | <div className="truncate text-3xs leading-3.5 text-white/70"> | |
| 217 | 217 | {source.windowTitle || "Captured window"} |
| 218 | 218 | </div> |
| 219 | 219 | </div> |
apps/web/src/components/chat/WorktreeSetupCard.tsx+2-2| ... | ... | @@ -56,7 +56,7 @@ function useNowWhile(active: boolean): number { |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | function StageIcon({ status }: { status: WorktreeSetupStage["status"] }) { |
| 59 | const className = "size-4 shrink-0 stroke-[1.8]"; | |
| 59 | const className = "size-4 shrink-0 stroke-2"; | |
| 60 | 60 | switch (status) { |
| 61 | 61 | case "done": |
| 62 | 62 | return <CheckIcon aria-hidden className={className} />; |
| ... | ... | @@ -240,7 +240,7 @@ function OutputTail({ lines, failed }: { lines: ReadonlyArray<string>; failed: b |
| 240 | 240 | return ( |
| 241 | 241 | <pre |
| 242 | 242 | className={cn( |
| 243 | "mb-1 ml-8 overflow-hidden rounded-md border px-2.5 py-1.5 font-mono text-[11px] leading-relaxed select-text", | |
| 243 | "mb-1 ml-8 overflow-hidden rounded-md border px-2.5 py-1.5 font-mono text-2xs leading-relaxed select-text", | |
| 244 | 244 | failed |
| 245 | 245 | ? "border-destructive/20 bg-error-surface text-destructive-foreground" |
| 246 | 246 | : "border-border bg-code text-muted-foreground", |
apps/web/src/components/clerk/ClerkUserProfilePage.tsx+2-2| ... | ... | @@ -22,9 +22,9 @@ export function ClerkUserProfilePage({ |
| 22 | 22 | <div className={cn("w-full min-w-0 text-foreground", className)}> |
| 23 | 23 | <header className="flex flex-col gap-3 pb-4 sm:flex-row sm:items-start sm:justify-between sm:gap-4 sm:pr-8"> |
| 24 | 24 | <div className="min-w-0"> |
| 25 | <h2 className="text-[1.0625rem] leading-6 font-semibold">{title}</h2> | |
| 25 | <h2 className="text-base leading-6 font-semibold">{title}</h2> | |
| 26 | 26 | {description ? ( |
| 27 | <p className="mt-1 max-w-[34rem] text-[0.8125rem] leading-[1.125rem] text-muted-foreground sm:min-h-9"> | |
| 27 | <p className="mt-1 max-w-[34rem] text-xs leading-4.5 text-muted-foreground sm:min-h-9"> | |
| 28 | 28 | {description} |
| 29 | 29 | </p> |
| 30 | 30 | ) : null} |
apps/web/src/components/clerk/MobileClientsUserProfilePage.tsx+5-5| ... | ... | @@ -38,14 +38,14 @@ function MobileClientRow({ device }: { readonly device: RelayClientDeviceRecord |
| 38 | 38 | <ClerkUserProfileRow icon={<SmartphoneIcon className="size-4" />}> |
| 39 | 39 | <div className="flex flex-col gap-0.5 sm:flex-row sm:items-start sm:justify-between sm:gap-3"> |
| 40 | 40 | <div className="min-w-0"> |
| 41 | <h3 className="truncate text-[0.8125rem] leading-[1.125rem] font-medium text-foreground"> | |
| 41 | <h3 className="truncate text-sm leading-4.5 font-medium text-foreground"> | |
| 42 | 42 | {device.label} |
| 43 | 43 | </h3> |
| 44 | <p className="text-xs leading-[1.125rem] text-muted-foreground"> | |
| 44 | <p className="text-xs leading-4.5 text-muted-foreground"> | |
| 45 | 45 | {mobileClientPlatformLabel(device)} |
| 46 | 46 | </p> |
| 47 | 47 | </div> |
| 48 | <p className="shrink-0 text-[0.6875rem] leading-4 text-muted-foreground/75"> | |
| 48 | <p className="shrink-0 text-2xs leading-4 text-muted-foreground/75"> | |
| 49 | 49 | {mobileClientUpdatedAtLabel(device.updatedAt)} |
| 50 | 50 | </p> |
| 51 | 51 | </div> |
| ... | ... | @@ -56,7 +56,7 @@ function MobileClientRow({ device }: { readonly device: RelayClientDeviceRecord |
| 56 | 56 | /> |
| 57 | 57 | <MobileClientStatusBadge enabled={device.liveActivities.enabled} label="Live Activities" /> |
| 58 | 58 | </div> |
| 59 | <p className="mt-1.5 text-xs leading-[1.125rem] text-muted-foreground/80"> | |
| 59 | <p className="mt-1.5 text-xs leading-4.5 text-muted-foreground/80"> | |
| 60 | 60 | {mobileClientNotificationDetail(device)} |
| 61 | 61 | </p> |
| 62 | 62 | </ClerkUserProfileRow> |
| ... | ... | @@ -123,7 +123,7 @@ export function MobileClientsUserProfilePage() { |
| 123 | 123 | <div> |
| 124 | 124 | {devicesState.error ? ( |
| 125 | 125 | <div |
| 126 | className="mb-4 flex flex-col gap-3 border-t border-destructive/35 py-3 text-[0.8125rem] sm:flex-row sm:items-center sm:justify-between" | |
| 126 | className="mb-4 flex flex-col gap-3 border-t border-destructive/35 py-3 text-xs sm:flex-row sm:items-center sm:justify-between" | |
| 127 | 127 | role="alert" |
| 128 | 128 | > |
| 129 | 129 | <div> |
apps/web/src/components/clerk/T3ConnectUserProfilePage.tsx+7-7| ... | ... | @@ -51,10 +51,10 @@ export function T3ConnectEnvironmentRow(props: { |
| 51 | 51 | <Collapsible open={props.confirmationOpen} onOpenChange={props.onConfirmationChange}> |
| 52 | 52 | <div className="flex items-start gap-4"> |
| 53 | 53 | <div className="min-w-0 flex-1"> |
| 54 | <h3 className="truncate text-[0.8125rem] leading-[1.125rem] font-medium text-foreground"> | |
| 54 | <h3 className="truncate text-sm leading-4.5 font-medium text-foreground"> | |
| 55 | 55 | {environment.label} |
| 56 | 56 | </h3> |
| 57 | <p className="mt-1 text-xs leading-[1.125rem] text-muted-foreground"> | |
| 57 | <p className="mt-1 text-xs leading-4.5 text-muted-foreground"> | |
| 58 | 58 | {linkedAtLabel(environment.linkedAt)} · {endpointLabel(environment)} |
| 59 | 59 | </p> |
| 60 | 60 | </div> |
| ... | ... | @@ -74,13 +74,13 @@ export function T3ConnectEnvironmentRow(props: { |
| 74 | 74 | role="group" |
| 75 | 75 | aria-label={`Confirm deregistration of ${environment.label}`} |
| 76 | 76 | > |
| 77 | <h4 className="text-[0.8125rem] leading-[1.125rem] font-semibold text-foreground"> | |
| 77 | <h4 className="text-sm leading-4.5 font-semibold text-foreground"> | |
| 78 | 78 | Deregister server |
| 79 | 79 | </h4> |
| 80 | <p className="mt-1 text-[0.8125rem] leading-[1.125rem] text-muted-foreground"> | |
| 80 | <p className="mt-1 text-xs leading-4.5 text-muted-foreground"> | |
| 81 | 81 | “{environment.label}” will be removed from this account. |
| 82 | 82 | </p> |
| 83 | <p className="mt-4 max-w-xl text-[0.8125rem] leading-[1.125rem] text-muted-foreground"> | |
| 83 | <p className="mt-4 max-w-xl text-xs leading-4.5 text-muted-foreground"> | |
| 84 | 84 | T3 Connect access will be revoked, any managed tunnel will be removed, and a host |
| 85 | 85 | space will become available. Local connections on your devices are not changed. |
| 86 | 86 | </p> |
| ... | ... | @@ -205,7 +205,7 @@ export function T3ConnectUserProfilePage() { |
| 205 | 205 | > |
| 206 | 206 | <div> |
| 207 | 207 | {environmentsState.error ? ( |
| 208 | <div className="mb-4 border-t border-destructive/35 py-3 text-[0.8125rem]" role="alert"> | |
| 208 | <div className="mb-4 border-t border-destructive/35 py-3 text-xs" role="alert"> | |
| 209 | 209 | <p className="font-medium text-destructive-foreground"> |
| 210 | 210 | Could not load T3 Connect environments |
| 211 | 211 | </p> |
| ... | ... | @@ -214,7 +214,7 @@ export function T3ConnectUserProfilePage() { |
| 214 | 214 | ) : null} |
| 215 | 215 | |
| 216 | 216 | {isInitialLoad ? ( |
| 217 | <p className="border-t py-4 text-[0.8125rem] text-muted-foreground" role="status"> | |
| 217 | <p className="border-t py-4 text-xs text-muted-foreground" role="status"> | |
| 218 | 218 | Loading environments… |
| 219 | 219 | </p> |
| 220 | 220 | ) : environments.length > 0 ? ( |
apps/web/src/components/cloud/ConnectCliAuthSurface.tsx+1-3| ... | ... | @@ -23,9 +23,7 @@ function ConnectCliAuthMessage({ |
| 23 | 23 | return ( |
| 24 | 24 | <> |
| 25 | 25 | {eyebrow ? ( |
| 26 | <p className="text-[10px] font-semibold tracking-[0.18em] text-primary uppercase"> | |
| 27 | {eyebrow} | |
| 28 | </p> | |
| 26 | <p className="text-3xs font-semibold tracking-widest text-primary uppercase">{eyebrow}</p> | |
| 29 | 27 | ) : null} |
| 30 | 28 | <h1 className="mt-2 text-2xl font-semibold tracking-tight sm:text-3xl">{title}</h1> |
| 31 | 29 | <p className="mt-2 text-sm leading-relaxed text-muted-foreground">{description}</p> |
apps/web/src/components/composerContextPresentation.tsx+1-1| ... | ... | @@ -269,7 +269,7 @@ function ComposerReviewCommentDetails({ comment }: { comment: ReviewCommentConte |
| 269 | 269 | <div className="space-y-2 overflow-hidden rounded-lg border border-border/70 bg-background/70 p-3"> |
| 270 | 270 | <div className="space-y-1"> |
| 271 | 271 | <div className="truncate text-xs font-medium text-foreground">{comment.filePath}</div> |
| 272 | <div className="text-secondary-label text-[11px]"> | |
| 272 | <div className="text-secondary-label text-2xs"> | |
| 273 | 273 | {comment.sectionTitle} · {comment.rangeLabel} |
| 274 | 274 | </div> |
| 275 | 275 | </div> |
apps/web/src/components/contextChipParts.tsx+4-4| ... | ... | @@ -208,8 +208,8 @@ export function ImageChipButton({ |
| 208 | 208 | <ImageIcon /> |
| 209 | 209 | )} |
| 210 | 210 | <ContextChipLabel className="max-w-72">{middleTruncateAttachmentName(name)}</ContextChipLabel> |
| 211 | <span className="shrink-0 text-[10px] text-current">{size}</span> | |
| 212 | {suffix ? <span className="text-[10px] text-current">{suffix}</span> : null} | |
| 211 | <span className="shrink-0 text-3xs text-current">{size}</span> | |
| 212 | {suffix ? <span className="text-3xs text-current">{suffix}</span> : null} | |
| 213 | 213 | </ContextChip> |
| 214 | 214 | ); |
| 215 | 215 | } |
| ... | ... | @@ -284,8 +284,8 @@ function FileChipContent(props: { |
| 284 | 284 | <ContextChipLabel className="max-w-72"> |
| 285 | 285 | {middleTruncateAttachmentName(props.name)} |
| 286 | 286 | </ContextChipLabel> |
| 287 | <span className="shrink-0 text-[10px] text-current">{props.size}</span> | |
| 288 | {props.suffix ? <span className="text-[10px] text-current">{props.suffix}</span> : null} | |
| 287 | <span className="shrink-0 text-3xs text-current">{props.size}</span> | |
| 288 | {props.suffix ? <span className="text-3xs text-current">{props.suffix}</span> : null} | |
| 289 | 289 | </> |
| 290 | 290 | ); |
| 291 | 291 | } |
apps/web/src/components/device/DeviceStreamView.tsx+1-1| ... | ... | @@ -404,7 +404,7 @@ export function DeviceStreamView(props: { |
| 404 | 404 | }} |
| 405 | 405 | > |
| 406 | 406 | {element.label ? ( |
| 407 | <span className="absolute -top-3.5 left-0 max-w-full truncate rounded-sm bg-info px-1 text-[9px] leading-3.5 text-white"> | |
| 407 | <span className="absolute -top-3.5 left-0 max-w-full truncate rounded-sm bg-info px-1 text-3xs leading-3.5 text-white"> | |
| 408 | 408 | {element.label} |
| 409 | 409 | </span> |
| 410 | 410 | ) : null} |
apps/web/src/components/device/DeviceToolsPanel.tsx+1-1| ... | ... | @@ -640,7 +640,7 @@ function EventLogSection(props: { |
| 640 | 640 | /> |
| 641 | 641 | </CollapsibleTrigger> |
| 642 | 642 | <CollapsiblePanel> |
| 643 | <ol className="max-h-64 overflow-y-auto px-3 py-2 font-mono text-[11px] leading-relaxed"> | |
| 643 | <ol className="max-h-64 overflow-y-auto px-3 py-2 font-mono text-2xs leading-relaxed"> | |
| 644 | 644 | {entries.length === 0 ? ( |
| 645 | 645 | <li className="text-muted-foreground">No events yet.</li> |
| 646 | 646 | ) : ( |
apps/web/src/components/diffs/DiffCommentAnnotation.tsx+2-2| ... | ... | @@ -65,7 +65,7 @@ export function DiffCommentAnnotation({ |
| 65 | 65 | onPointerDown={(event) => event.stopPropagation()} |
| 66 | 66 | > |
| 67 | 67 | <MessageCircle className="mt-0.5 size-3.5 shrink-0 text-primary/70" aria-hidden="true" /> |
| 68 | <p className="min-w-0 flex-1 whitespace-pre-wrap text-[13px] leading-5">{displayedText}</p> | |
| 68 | <p className="min-w-0 flex-1 whitespace-pre-wrap text-sm leading-5">{displayedText}</p> | |
| 69 | 69 | {onDelete ? ( |
| 70 | 70 | <span className="-my-1 -mr-1 flex shrink-0 opacity-0 transition-opacity group-hover/comment:opacity-100 focus-within:opacity-100 max-sm:opacity-100"> |
| 71 | 71 | <Button |
| ... | ... | @@ -113,7 +113,7 @@ export function DiffCommentAnnotation({ |
| 113 | 113 | }} |
| 114 | 114 | /> |
| 115 | 115 | <div className="mt-1.5 flex items-center gap-1"> |
| 116 | <span className="mr-auto text-[10px] text-muted-foreground/70">⌘/Ctrl Enter to send</span> | |
| 116 | <span className="mr-auto text-3xs text-muted-foreground/70">⌘/Ctrl Enter to send</span> | |
| 117 | 117 | <Button variant="ghost-muted" size="xs" onClick={onCancel}> |
| 118 | 118 | Cancel |
| 119 | 119 | </Button> |
apps/web/src/components/files/FilePreviewPanel.tsx+1-1| ... | ... | @@ -1172,7 +1172,7 @@ export default function FilePreviewPanel({ |
| 1172 | 1172 | !isMedia && |
| 1173 | 1173 | !renderBrowserFile && |
| 1174 | 1174 | file.data?.truncated ? ( |
| 1175 | <div className="shrink-0 border-b border-warning/20 bg-warning-surface px-3 py-1.5 text-[11px] text-warning-foreground"> | |
| 1175 | <div className="shrink-0 border-b border-warning/20 bg-warning-surface px-3 py-1.5 text-2xs text-warning-foreground"> | |
| 1176 | 1176 | Preview limited to the first 1 MB of a {file.data.byteLength.toLocaleString()} byte file. |
| 1177 | 1177 | </div> |
| 1178 | 1178 | ) : null} |
apps/web/src/components/files/fileSurfaceChrome.tsx+1-1| ... | ... | @@ -114,7 +114,7 @@ export function FileSurfaceNotice(props: { readonly children: ReactNode }) { |
| 114 | 114 | return ( |
| 115 | 115 | <div |
| 116 | 116 | role="status" |
| 117 | className="shrink-0 border-b border-warning/20 bg-warning-surface px-3 py-1.5 text-[11px] text-warning-foreground" | |
| 117 | className="shrink-0 border-b border-warning/20 bg-warning-surface px-3 py-1.5 text-2xs text-warning-foreground" | |
| 118 | 118 | > |
| 119 | 119 | {props.children} |
| 120 | 120 | </div> |
apps/web/src/components/onboarding/WelcomeWizard.tsx+3-5| ... | ... | @@ -193,7 +193,7 @@ export function WelcomeWizard({ |
| 193 | 193 | identity={ |
| 194 | 194 | <div className="flex items-baseline gap-1.5" role="img" aria-label="T3 Code"> |
| 195 | 195 | <T3Wordmark className="h-4 w-auto shrink-0" aria-hidden /> |
| 196 | <span className="text-[1.4rem] font-medium tracking-tight text-muted-foreground"> | |
| 196 | <span className="text-2xl font-medium tracking-tight text-muted-foreground"> | |
| 197 | 197 | Code |
| 198 | 198 | </span> |
| 199 | 199 | </div> |
| ... | ... | @@ -892,7 +892,7 @@ function AgentInstallTerminal({ |
| 892 | 892 | className="mt-4 overflow-hidden rounded-lg border border-border/70 bg-background text-foreground" |
| 893 | 893 | > |
| 894 | 894 | <div className="flex items-center justify-between border-b border-border/60 bg-background/60 px-3 py-1.5"> |
| 895 | <span className="text-[11px] font-medium text-muted-foreground"> | |
| 895 | <span className="text-2xs font-medium text-muted-foreground"> | |
| 896 | 896 | {setupState === "writeFailed" ? ( |
| 897 | 897 | <> |
| 898 | 898 | Run <code className="rounded bg-muted px-1 font-mono">{command}</code> in this |
| ... | ... | @@ -1445,9 +1445,7 @@ function ImportCandidateRow({ |
| 1445 | 1445 | {label} |
| 1446 | 1446 | </span> |
| 1447 | 1447 | {secondary !== undefined ? ( |
| 1448 | <span className="truncate font-mono text-[11px] text-muted-foreground"> | |
| 1449 | {secondary} | |
| 1450 | </span> | |
| 1448 | <span className="truncate font-mono text-2xs text-muted-foreground">{secondary}</span> | |
| 1451 | 1449 | ) : null} |
| 1452 | 1450 | </TooltipTrigger> |
| 1453 | 1451 | <TooltipPopup variant="code">{candidate.path}</TooltipPopup> |
apps/web/src/components/preview/AgentBrowserCursor.tsx+1-1| ... | ... | @@ -55,7 +55,7 @@ function AgentBrowserCursorEvent(props: { |
| 55 | 55 | |
| 56 | 56 | return ( |
| 57 | 57 | <div |
| 58 | className="pointer-events-none absolute left-0 top-0 z-40 transition-[transform,opacity] duration-150 ease-out motion-reduce:transition-none" | |
| 58 | className="pointer-events-none absolute left-0 top-0 z-40 transition-[opacity,transform] duration-150 ease-out motion-reduce:transition-none" | |
| 59 | 59 | style={{ |
| 60 | 60 | opacity: agentBrowserCursorOpacity(active, controller), |
| 61 | 61 | transform: `translate3d(${event.x * zoomFactor * (content?.scale ?? 1) + (content?.x ?? 0) - (content?.scrollLeft ?? 0)}px, ${event.y * zoomFactor * (content?.scale ?? 1) + (content?.y ?? 0) - (content?.scrollTop ?? 0)}px, 0)`, |
apps/web/src/components/preview/BrowserMockup.tsx+3-3| ... | ... | @@ -6,16 +6,16 @@ export function BrowserMockup({ className }: { className?: string }) { |
| 6 | 6 | <div |
| 7 | 7 | aria-hidden |
| 8 | 8 | className={cn( |
| 9 | "relative flex flex-col gap-0.5 overflow-hidden rounded-[5px] border border-border/60 bg-card p-1 shadow-xs/5", | |
| 9 | "relative flex flex-col gap-0.5 overflow-hidden rounded-sm border border-border/60 bg-card p-1 shadow-xs/5", | |
| 10 | 10 | className, |
| 11 | 11 | )} |
| 12 | 12 | > |
| 13 | <div className="flex gap-[2px]"> | |
| 13 | <div className="flex gap-0.5"> | |
| 14 | 14 | <span className="size-[3px] rounded-full bg-destructive/80" /> |
| 15 | 15 | <span className="size-[3px] rounded-full bg-warning/80" /> |
| 16 | 16 | <span className="size-[3px] rounded-full bg-success/80" /> |
| 17 | 17 | </div> |
| 18 | <div className="mt-[1px] flex flex-1 flex-col gap-[2px]"> | |
| 18 | <div className="mt-[1px] flex flex-1 flex-col gap-0.5"> | |
| 19 | 19 | <span className="h-[2px] w-full rounded-full bg-muted-foreground/30" /> |
| 20 | 20 | <span className="h-[2px] w-3/5 rounded-full bg-muted-foreground/20" /> |
| 21 | 21 | </div> |
apps/web/src/components/preview/PreviewPanelShell.tsx+1-1| ... | ... | @@ -126,7 +126,7 @@ export function PreviewPanelShell(props: { |
| 126 | 126 | : "shrink-0 border-l border-border" |
| 127 | 127 | : "w-full", |
| 128 | 128 | collapsible && |
| 129 | "[[data-panel-animations=true]_&]:transition-[width] [[data-panel-animations=true]_&]:[transition-duration:var(--panel-animation-duration)] [[data-panel-animations=true]_&]:ease-out", | |
| 129 | "[[data-panel-animations=true]_&]:transition-[width] [[data-panel-animations=true]_&]:duration-(--panel-animation-duration) [[data-panel-animations=true]_&]:ease-out", | |
| 130 | 130 | collapsible && open && "[[data-panel-animations=true]_&]:starting:w-0!", |
| 131 | 131 | collapsible && !open && "pointer-events-none", |
| 132 | 132 | )} |
apps/web/src/components/pullRequest/PullRequestCodeTab.tsx+2-2| ... | ... | @@ -828,7 +828,7 @@ function PullRequestCodeTab({ |
| 828 | 828 | <PullRequestDiffStat |
| 829 | 829 | additions={additions} |
| 830 | 830 | deletions={deletions} |
| 831 | className="font-mono text-[11px]" | |
| 831 | className="font-mono text-2xs" | |
| 832 | 832 | /> |
| 833 | 833 | ); |
| 834 | 834 | const viewedFiles = filesViewedRef.current; |
| ... | ... | @@ -842,7 +842,7 @@ function PullRequestCodeTab({ |
| 842 | 842 | attribute is what the header's capture listener looks for. */} |
| 843 | 843 | <label |
| 844 | 844 | data-viewed-toggle="" |
| 845 | className="flex cursor-pointer select-none items-center gap-1.5 text-[11px] text-muted-foreground" | |
| 845 | className="flex cursor-pointer select-none items-center gap-1.5 text-2xs text-muted-foreground" | |
| 846 | 846 | onClick={(event) => event.stopPropagation()} |
| 847 | 847 | > |
| 848 | 848 | <Checkbox |
apps/web/src/components/pullRequest/PullRequestComposer.tsx+1-1| ... | ... | @@ -93,7 +93,7 @@ export function PullRequestComposer({ |
| 93 | 93 | {pendingComments.length > 0 ? ( |
| 94 | 94 | <span |
| 95 | 95 | aria-hidden |
| 96 | className="absolute -top-1 -right-1 flex h-3.5 min-w-3.5 items-center justify-center rounded-full bg-info px-1 text-[9px] font-semibold tabular-nums text-white" | |
| 96 | className="absolute -top-1 -right-1 flex h-3.5 min-w-3.5 items-center justify-center rounded-full bg-info px-1 text-3xs font-semibold tabular-nums text-white" | |
| 97 | 97 | > |
| 98 | 98 | {pendingComments.length} |
| 99 | 99 | </span> |
apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx+4-4| ... | ... | @@ -2260,7 +2260,7 @@ export function PullRequestDetailPanel({ |
| 2260 | 2260 | <span className="shrink-0">{formatRelativeTimeLabel(detail.updatedAt)}</span> |
| 2261 | 2261 | </span> |
| 2262 | 2262 | <span aria-hidden className="h-3 w-px shrink-0 bg-border/70" /> |
| 2263 | <span className="flex min-w-0 flex-1 items-center gap-1.5 font-mono text-[11px] text-muted-foreground/65"> | |
| 2263 | <span className="flex min-w-0 flex-1 items-center gap-1.5 font-mono text-2xs text-muted-foreground/65"> | |
| 2264 | 2264 | {/* An out-of-date base wears the warning on the branch name itself, so the |
| 2265 | 2265 | name is amber and pointing at either the name or the mark opens the way |
| 2266 | 2266 | out. Up to date, the name keeps its plain tooltip. */} |
| ... | ... | @@ -2322,7 +2322,7 @@ export function PullRequestDetailPanel({ |
| 2322 | 2322 | <TooltipPopup side="top">{detail.headBranch}</TooltipPopup> |
| 2323 | 2323 | </Tooltip> |
| 2324 | 2324 | </span> |
| 2325 | <span className="ml-auto inline-flex shrink-0 items-center justify-end gap-2 text-[11px]"> | |
| 2325 | <span className="ml-auto inline-flex shrink-0 items-center justify-end gap-2 text-2xs"> | |
| 2326 | 2326 | <span |
| 2327 | 2327 | className="inline-flex items-center gap-1 tabular-nums" |
| 2328 | 2328 | aria-label={`${detail.changedFiles.toLocaleString()} changed ${ |
| ... | ... | @@ -2335,7 +2335,7 @@ export function PullRequestDetailPanel({ |
| 2335 | 2335 | <PullRequestDiffStat |
| 2336 | 2336 | additions={detail.additions} |
| 2337 | 2337 | deletions={detail.deletions} |
| 2338 | className="shrink-0 font-mono text-[11px]" | |
| 2338 | className="shrink-0 font-mono text-2xs" | |
| 2339 | 2339 | /> |
| 2340 | 2340 | </span> |
| 2341 | 2341 | </div> |
| ... | ... | @@ -2609,7 +2609,7 @@ export function PullRequestDetailPanel({ |
| 2609 | 2609 | <div className="ml-auto flex shrink-0 items-center gap-2 text-xs text-muted-foreground"> |
| 2610 | 2610 | <PullRequestMetaLine |
| 2611 | 2611 | className={cn( |
| 2612 | "whitespace-nowrap text-[11px] transition-opacity", | |
| 2612 | "whitespace-nowrap text-2xs transition-opacity", | |
| 2613 | 2613 | (activityPending || activityError) && "opacity-35", |
| 2614 | 2614 | )} |
| 2615 | 2615 | > |
apps/web/src/components/pullRequest/PullRequestLinkPreview.tsx+1-1| ... | ... | @@ -106,7 +106,7 @@ export function PullRequestLinkPreview({ |
| 106 | 106 | )) |
| 107 | 107 | ) : ( |
| 108 | 108 | <div className="min-w-0"> |
| 109 | <div className="flex min-w-0 items-center gap-1.5 text-[11px] text-muted-foreground"> | |
| 109 | <div className="flex min-w-0 items-center gap-1.5 text-2xs text-muted-foreground"> | |
| 110 | 110 | <span className="min-w-0 truncate">{detail.repository}</span> |
| 111 | 111 | <span className="shrink-0">#{detail.number}</span> |
| 112 | 112 | <span aria-hidden>·</span> |
apps/web/src/components/pullRequest/PullRequestListRow.tsx+4-4| ... | ... | @@ -68,7 +68,7 @@ export function PullRequestRowGlyph({ |
| 68 | 68 | /> |
| 69 | 69 | </span> |
| 70 | 70 | </span> |
| 71 | {below ? <span className="inline-flex text-[11px]">{below}</span> : null} | |
| 71 | {below ? <span className="inline-flex text-2xs">{below}</span> : null} | |
| 72 | 72 | </span> |
| 73 | 73 | ); |
| 74 | 74 | } |
| ... | ... | @@ -100,15 +100,15 @@ export function PullRequestRowLines({ |
| 100 | 100 | {number} |
| 101 | 101 | <span className="min-w-0 truncate text-sm">{title}</span> |
| 102 | 102 | {signals ? ( |
| 103 | <span className="flex shrink-0 items-center gap-1 text-[11px]">{signals}</span> | |
| 103 | <span className="flex shrink-0 items-center gap-1 text-2xs">{signals}</span> | |
| 104 | 104 | ) : null} |
| 105 | 105 | {status ? ( |
| 106 | <span className="ml-auto flex shrink-0 items-center gap-1.5 text-[11px]">{status}</span> | |
| 106 | <span className="ml-auto flex shrink-0 items-center gap-1.5 text-2xs">{status}</span> | |
| 107 | 107 | ) : null} |
| 108 | 108 | </span> |
| 109 | 109 | <span |
| 110 | 110 | className={cn( |
| 111 | "flex min-w-0 items-center gap-1.5 overflow-hidden text-[11px] text-muted-foreground", | |
| 111 | "flex min-w-0 items-center gap-1.5 overflow-hidden text-2xs text-muted-foreground", | |
| 112 | 112 | metaClassName, |
| 113 | 113 | )} |
| 114 | 114 | > |
apps/web/src/components/pullRequest/PullRequestRow.tsx+1-1| ... | ... | @@ -204,7 +204,7 @@ function PullRequestRowImpl({ |
| 204 | 204 | <Tooltip> |
| 205 | 205 | <TooltipTrigger |
| 206 | 206 | render={ |
| 207 | <span className="flex min-w-6 items-center gap-1 overflow-hidden rounded-full border border-border/60 px-1 text-[10px]" /> | |
| 207 | <span className="flex min-w-6 items-center gap-1 overflow-hidden rounded-full border border-border/60 px-1 text-3xs" /> | |
| 208 | 208 | } |
| 209 | 209 | > |
| 210 | 210 | <span className="sr-only">matched in the description</span> |
apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx+2-2| ... | ... | @@ -401,7 +401,7 @@ function CommentGroup({ |
| 401 | 401 | </span> |
| 402 | 402 | ))} |
| 403 | 403 | {authors.length > 3 ? ( |
| 404 | <span className="relative flex size-6 items-center justify-center rounded-full bg-muted text-[10px] text-muted-foreground ring-2 ring-background"> | |
| 404 | <span className="relative flex size-6 items-center justify-center rounded-full bg-muted text-3xs text-muted-foreground ring-2 ring-background"> | |
| 405 | 405 | +{authors.length - 3} |
| 406 | 406 | </span> |
| 407 | 407 | ) : null} |
| ... | ... | @@ -412,7 +412,7 @@ function CommentGroup({ |
| 412 | 412 | > |
| 413 | 413 | <span className="min-w-0 flex-1 space-y-1"> |
| 414 | 414 | <span className="block text-xs font-medium text-foreground/90">{label}</span> |
| 415 | <span className="flex flex-wrap gap-x-1.5 text-[11px] text-muted-foreground"> | |
| 415 | <span className="flex flex-wrap gap-x-1.5 text-2xs text-muted-foreground"> | |
| 416 | 416 | <span> |
| 417 | 417 | {authors.length} {authors.length === 1 ? "author" : "authors"} |
| 418 | 418 | </span> |
apps/web/src/components/pullRequest/PullRequestTimelineTab.tsx+8-10| ... | ... | @@ -141,7 +141,7 @@ function ActorTimelineMarker({ |
| 141 | 141 | <PullRequestActorAvatar |
| 142 | 142 | actor={actor} |
| 143 | 143 | className={cn( |
| 144 | "size-7 bg-muted text-[9px] transition-opacity", | |
| 144 | "size-7 bg-muted text-3xs transition-opacity", | |
| 145 | 145 | muted && "opacity-45 grayscale", |
| 146 | 146 | )} |
| 147 | 147 | /> |
| ... | ... | @@ -156,9 +156,7 @@ function friendlyReviewState(value: string): string { |
| 156 | 156 | |
| 157 | 157 | function ReviewStateBadge({ state }: { state: string }) { |
| 158 | 158 | return ( |
| 159 | <span className="text-[10px] font-medium text-muted-foreground"> | |
| 160 | {friendlyReviewState(state)} | |
| 161 | </span> | |
| 159 | <span className="text-3xs font-medium text-muted-foreground">{friendlyReviewState(state)}</span> | |
| 162 | 160 | ); |
| 163 | 161 | } |
| 164 | 162 | |
| ... | ... | @@ -224,7 +222,7 @@ function ConversationCard({ |
| 224 | 222 | <span className="text-muted-foreground">{event.title}</span> |
| 225 | 223 | {event.reviewState ? <ReviewStateBadge state={event.reviewState} /> : null} |
| 226 | 224 | </div> |
| 227 | <PullRequestMetaLine className="mt-1 flex-wrap text-[11px] text-muted-foreground"> | |
| 225 | <PullRequestMetaLine className="mt-1 flex-wrap text-2xs text-muted-foreground"> | |
| 228 | 226 | <span>{formatRelativeTimeLabel(event.at)}</span> |
| 229 | 227 | {event.path ? ( |
| 230 | 228 | <span className="inline-flex min-w-0 items-center gap-1"> |
| ... | ... | @@ -330,7 +328,7 @@ function ConversationGroup({ |
| 330 | 328 | <span className="block text-xs font-semibold"> |
| 331 | 329 | {events.length.toLocaleString()} {events.length === 1 ? "comment" : "comments"} |
| 332 | 330 | </span> |
| 333 | <span className="block truncate text-[10px] text-muted-foreground"> | |
| 331 | <span className="block truncate text-3xs text-muted-foreground"> | |
| 334 | 332 | {actors.length.toLocaleString()} {actors.length === 1 ? "author" : "authors"} ·{" "} |
| 335 | 333 | {formatRelativeTimeLabel(first.at)} |
| 336 | 334 | </span> |
| ... | ... | @@ -391,7 +389,7 @@ function CommitEvent({ |
| 391 | 389 | <div className="truncate text-xs font-semibold text-foreground transition-colors group-hover:text-primary"> |
| 392 | 390 | {event.body ?? "Untitled commit"} |
| 393 | 391 | </div> |
| 394 | <div className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-[10px] text-muted-foreground"> | |
| 392 | <div className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-3xs text-muted-foreground"> | |
| 395 | 393 | <code className="font-mono">{event.id.slice(0, 7)}</code> |
| 396 | 394 | <span>{formatRelativeTimeLabel(event.at)}</span> |
| 397 | 395 | </div> |
| ... | ... | @@ -400,7 +398,7 @@ function CommitEvent({ |
| 400 | 398 | <PullRequestDiffStat |
| 401 | 399 | additions={event.additions} |
| 402 | 400 | deletions={event.deletions} |
| 403 | className="ml-auto shrink-0 font-mono text-[10px]" | |
| 401 | className="ml-auto shrink-0 font-mono text-3xs" | |
| 404 | 402 | /> |
| 405 | 403 | ) : null} |
| 406 | 404 | </div> |
| ... | ... | @@ -433,7 +431,7 @@ function LifecycleEvent({ event }: { event: PullRequestTimelineEvent }) { |
| 433 | 431 | {event.actor ? <ActorName actor={event.actor} /> : null} |
| 434 | 432 | <span className="font-semibold text-foreground">{presentation.label}</span> |
| 435 | 433 | </div> |
| 436 | <div className="mt-0.5 text-[11px] text-muted-foreground"> | |
| 434 | <div className="mt-0.5 text-2xs text-muted-foreground"> | |
| 437 | 435 | {formatRelativeTimeLabel(event.at)} |
| 438 | 436 | </div> |
| 439 | 437 | </div> |
| ... | ... | @@ -500,7 +498,7 @@ function ReviewVerdictEvent({ |
| 500 | 498 | </Tooltip> |
| 501 | 499 | </div> |
| 502 | 500 | <div className="mt-0.5 flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1"> |
| 503 | <PullRequestMetaLine className="flex-wrap text-[11px] text-muted-foreground"> | |
| 501 | <PullRequestMetaLine className="flex-wrap text-2xs text-muted-foreground"> | |
| 504 | 502 | <span>{formatRelativeTimeLabel(event.at)}</span> |
| 505 | 503 | {event.path ? ( |
| 506 | 504 | <span className="inline-flex min-w-0 items-center gap-1"> |
apps/web/src/components/pullRequest/ThreadPullRequestsPanel.tsx+1-1| ... | ... | @@ -308,7 +308,7 @@ function EnabledThreadPullRequestsPanel({ threadRef }: { threadRef: ScopedThread |
| 308 | 308 | ))} |
| 309 | 309 | </div> |
| 310 | 310 | </ScrollArea> |
| 311 | <footer className="flex items-center justify-between border-t border-border/60 px-2 py-1.5 text-[.7rem] text-muted-foreground"> | |
| 311 | <footer className="flex items-center justify-between border-t border-border/60 px-2 py-1.5 text-2xs text-muted-foreground"> | |
| 312 | 312 | <span> |
| 313 | 313 | {openCount} open · {links.length} linked |
| 314 | 314 | {lastSynced ? ` · synced ${formatRelativeTimeLabel(lastSynced)}` : ""} |
apps/web/src/components/pullRequest/pullRequestPresentation.tsx+1-1| ... | ... | @@ -428,7 +428,7 @@ export function PullRequestActorAvatar({ |
| 428 | 428 | <span |
| 429 | 429 | aria-hidden |
| 430 | 430 | className={cn( |
| 431 | "flex size-4 shrink-0 items-center justify-center rounded-full bg-muted text-[8px] font-medium text-muted-foreground", | |
| 431 | "flex size-4 shrink-0 items-center justify-center rounded-full bg-muted text-3xs font-medium text-muted-foreground", | |
| 432 | 432 | className, |
| 433 | 433 | )} |
| 434 | 434 | > |
apps/web/src/components/search/HighlightedSearchLine.tsx+1-1| ... | ... | @@ -111,7 +111,7 @@ function HighlightedTokens(props: { |
| 111 | 111 | .map((segment) => |
| 112 | 112 | segment.isMatch ? ( |
| 113 | 113 | <mark |
| 114 | className="rounded-[2px] bg-primary/25 text-inherit" | |
| 114 | className="rounded-xs bg-primary/25 text-inherit" | |
| 115 | 115 | key={`${segment.start}:${segment.end}:match`} |
| 116 | 116 | style={tokenStyle(segment.token)} |
| 117 | 117 | > |
apps/web/src/components/search/ProjectContentSearchDialog.tsx+1-1| ... | ... | @@ -265,7 +265,7 @@ function OpenContentSearchDialog(props: { |
| 265 | 265 | {path.directory} |
| 266 | 266 | </span> |
| 267 | 267 | ) : null} |
| 268 | <span className="ml-auto rounded-full bg-muted px-1.5 py-0.5 tabular-nums text-[10px] text-muted-foreground"> | |
| 268 | <span className="ml-auto rounded-full bg-muted px-1.5 py-0.5 tabular-nums text-3xs text-muted-foreground"> | |
| 269 | 269 | {group.matches.length} |
| 270 | 270 | </span> |
| 271 | 271 | </div> |
apps/web/src/components/settings/AddProviderInstanceDialog.tsx+4-4| ... | ... | @@ -310,7 +310,7 @@ export function AddProviderInstanceDialog({ |
| 310 | 310 | value={label} |
| 311 | 311 | onChange={(event) => setLabel(event.target.value)} |
| 312 | 312 | /> |
| 313 | <span className="text-[11px] text-muted-foreground"> | |
| 313 | <span className="text-2xs text-muted-foreground"> | |
| 314 | 314 | Shown in the provider list. Optional. |
| 315 | 315 | </span> |
| 316 | 316 | </label> |
| ... | ... | @@ -326,9 +326,9 @@ export function AddProviderInstanceDialog({ |
| 326 | 326 | aria-invalid={showInstanceIdError} |
| 327 | 327 | /> |
| 328 | 328 | {showInstanceIdError ? ( |
| 329 | <span className="text-[11px] text-destructive">{instanceIdError}</span> | |
| 329 | <span className="text-2xs text-destructive">{instanceIdError}</span> | |
| 330 | 330 | ) : ( |
| 331 | <span className="text-[11px] text-muted-foreground"> | |
| 331 | <span className="text-2xs text-muted-foreground"> | |
| 332 | 332 | Routing key used by threads and sessions. Letters, digits, '-', or '_'. |
| 333 | 333 | </span> |
| 334 | 334 | )} |
| ... | ... | @@ -374,7 +374,7 @@ export function AddProviderInstanceDialog({ |
| 374 | 374 | </Button> |
| 375 | 375 | ) : null} |
| 376 | 376 | </div> |
| 377 | <span className="text-[11px] text-muted-foreground"> | |
| 377 | <span className="text-2xs text-muted-foreground"> | |
| 378 | 378 | Optional marker shown in the picker. |
| 379 | 379 | </span> |
| 380 | 380 | </div> |
apps/web/src/components/settings/ConnectionsSettings.tsx+10-10| ... | ... | @@ -771,11 +771,11 @@ const PairingLinkListRow = memo(function PairingLinkListRow({ |
| 771 | 771 | <AccessScopeSummary scopes={pairingLink.scopes} label="Pairing link scopes" /> |
| 772 | 772 | </p> |
| 773 | 773 | {!credential ? ( |
| 774 | <p className="text-[11px] text-muted-foreground/70"> | |
| 774 | <p className="text-2xs text-muted-foreground/70"> | |
| 775 | 775 | Create a new link to share from this client. |
| 776 | 776 | </p> |
| 777 | 777 | ) : shareablePairingUrl === null ? ( |
| 778 | <p className="text-[11px] text-muted-foreground/70"> | |
| 778 | <p className="text-2xs text-muted-foreground/70"> | |
| 779 | 779 | Copy the token and pair from another client using this backend&apos;s reachable host. |
| 780 | 780 | </p> |
| 781 | 781 | ) : null} |
| ... | ... | @@ -882,7 +882,7 @@ const PairingLinkListRow = memo(function PairingLinkListRow({ |
| 882 | 882 | role="radiogroup" |
| 883 | 883 | aria-label="Endpoint the pairing QR code and URL use" |
| 884 | 884 | > |
| 885 | <p className="text-[11px] text-muted-foreground/70">Reach this machine via</p> | |
| 885 | <p className="text-2xs text-muted-foreground/70">Reach this machine via</p> | |
| 886 | 886 | {endpointCopyOptions.map((option) => { |
| 887 | 887 | const isSelected = option.id === selectedQrOption?.id; |
| 888 | 888 | return ( |
| ... | ... | @@ -907,7 +907,7 @@ const PairingLinkListRow = memo(function PairingLinkListRow({ |
| 907 | 907 | > |
| 908 | 908 | {option.label} |
| 909 | 909 | </span> |
| 910 | <span className="min-w-0 truncate text-[11px] text-muted-foreground/70"> | |
| 910 | <span className="min-w-0 truncate text-2xs text-muted-foreground/70"> | |
| 911 | 911 | {option.detail} |
| 912 | 912 | </span> |
| 913 | 913 | </button> |
| ... | ... | @@ -919,7 +919,7 @@ const PairingLinkListRow = memo(function PairingLinkListRow({ |
| 919 | 919 | <Tooltip> |
| 920 | 920 | <TooltipTrigger |
| 921 | 921 | render={ |
| 922 | <code className="min-w-0 flex-1 truncate font-mono text-[11px] text-muted-foreground"> | |
| 922 | <code className="min-w-0 flex-1 truncate font-mono text-2xs text-muted-foreground"> | |
| 923 | 923 | {qrPairingUrl} |
| 924 | 924 | </code> |
| 925 | 925 | } |
| ... | ... | @@ -951,7 +951,7 @@ const PairingLinkListRow = memo(function PairingLinkListRow({ |
| 951 | 951 | </div> |
| 952 | 952 | ) : ( |
| 953 | 953 | <div className="flex size-[192px] shrink-0 items-center justify-center self-center rounded-xl border border-border/50 p-4 sm:self-start"> |
| 954 | <p className="text-center text-[11px] text-muted-foreground/70"> | |
| 954 | <p className="text-center text-2xs text-muted-foreground/70"> | |
| 955 | 955 | No QR for this endpoint. Another device scanning a loopback link would dial itself; |
| 956 | 956 | copy the URL for use on this machine instead. |
| 957 | 957 | </p> |
| ... | ... | @@ -1011,7 +1011,7 @@ const ConnectedClientListRow = memo(function ConnectedClientListRow({ |
| 1011 | 1011 | /> |
| 1012 | 1012 | <h3 className="text-sm font-medium text-foreground">{primaryLabel}</h3> |
| 1013 | 1013 | {clientSession.current ? ( |
| 1014 | <span className="text-[10px] text-muted-foreground/80 rounded-md border border-border/50 bg-muted/50 px-1 py-0.5"> | |
| 1014 | <span className="text-3xs text-muted-foreground/80 rounded-md border border-border/50 bg-muted/50 px-1 py-0.5"> | |
| 1015 | 1015 | This device |
| 1016 | 1016 | </span> |
| 1017 | 1017 | ) : null} |
| ... | ... | @@ -1335,14 +1335,14 @@ const AdvertisedEndpointListRow = memo(function AdvertisedEndpointListRow({ |
| 1335 | 1335 | </Tooltip> |
| 1336 | 1336 | ) : null} |
| 1337 | 1337 | {!isAvailable ? ( |
| 1338 | <span className="shrink-0 rounded-md border border-border/70 px-1 py-0.5 text-[10px] text-muted-foreground"> | |
| 1338 | <span className="shrink-0 rounded-md border border-border/70 px-1 py-0.5 text-3xs text-muted-foreground"> | |
| 1339 | 1339 | Setup required |
| 1340 | 1340 | </span> |
| 1341 | 1341 | ) : null} |
| 1342 | 1342 | </div> |
| 1343 | 1343 | <div className="ml-auto flex min-h-6 shrink-0 items-center justify-end gap-2"> |
| 1344 | 1344 | {isDefault ? ( |
| 1345 | <span className="rounded-md border border-primary/30 bg-primary/10 px-1 py-0.5 text-[10px] text-primary"> | |
| 1345 | <span className="rounded-md border border-primary/30 bg-primary/10 px-1 py-0.5 text-3xs text-primary"> | |
| 1346 | 1346 | Default |
| 1347 | 1347 | </span> |
| 1348 | 1348 | ) : null} |
| ... | ... | @@ -2660,7 +2660,7 @@ export function ConnectionsSettings() { |
| 2660 | 2660 | </label> |
| 2661 | 2661 | </div> |
| 2662 | 2662 | <div> |
| 2663 | <span className="mt-1 block text-[11px] text-muted-foreground"> | |
| 2663 | <span className="mt-1 block text-2xs text-muted-foreground"> | |
| 2664 | 2664 | Paste a full pairing URL here to fill both fields automatically. |
| 2665 | 2665 | </span> |
| 2666 | 2666 | </div> |
apps/web/src/components/settings/CustomModelEditor.tsx+2-2| ... | ... | @@ -169,7 +169,7 @@ export function CustomModelEditor({ |
| 169 | 169 | className="min-w-0 flex-1" |
| 170 | 170 | aria-label="Choice label" |
| 171 | 171 | /> |
| 172 | <label className="flex shrink-0 items-center gap-1.5 text-[11px] text-muted-foreground"> | |
| 172 | <label className="flex shrink-0 items-center gap-1.5 text-2xs text-muted-foreground"> | |
| 173 | 173 | <Switch |
| 174 | 174 | size="sm" |
| 175 | 175 | checked={choice.isDefault} |
| ... | ... | @@ -201,7 +201,7 @@ export function CustomModelEditor({ |
| 201 | 201 | className="flex flex-col gap-2 rounded-md border border-border/60 bg-background/40 p-2.5" |
| 202 | 202 | > |
| 203 | 203 | <div className="flex flex-wrap items-center gap-2"> |
| 204 | <span className="w-14 shrink-0 text-[11px] text-muted-foreground">Option {index + 1}</span> | |
| 204 | <span className="w-14 shrink-0 text-2xs text-muted-foreground">Option {index + 1}</span> | |
| 205 | 205 | {presets.length > 0 ? ( |
| 206 | 206 | <Select |
| 207 | 207 | value={idSelectValue(descriptor)} |
apps/web/src/components/settings/DiagnosticsSettings.tsx+10-10| ... | ... | @@ -94,7 +94,7 @@ function StatBlock({ |
| 94 | 94 | }) { |
| 95 | 95 | return ( |
| 96 | 96 | <div className="min-w-0 border-border/60 px-4 py-3 sm:px-5"> |
| 97 | <div className="flex min-w-0 items-center gap-1.5 text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground/70"> | |
| 97 | <div className="flex min-w-0 items-center gap-1.5 text-2xs font-medium uppercase tracking-widest text-muted-foreground/70"> | |
| 98 | 98 | <span className="min-w-0 truncate">{label}</span> |
| 99 | 99 | {tooltip ? ( |
| 100 | 100 | <Tooltip> |
| ... | ... | @@ -183,7 +183,7 @@ function DiagnosticsTable({ |
| 183 | 183 | ))} |
| 184 | 184 | </colgroup> |
| 185 | 185 | ) : null} |
| 186 | <thead className="border-b border-border/60 text-[11px] uppercase tracking-[0.08em] text-muted-foreground/70"> | |
| 186 | <thead className="border-b border-border/60 text-2xs uppercase tracking-widest text-muted-foreground/70"> | |
| 187 | 187 | <tr> |
| 188 | 188 | {headers.map((header, index) => ( |
| 189 | 189 | <th |
| ... | ... | @@ -215,7 +215,7 @@ function TraceIdCell({ traceId }: { traceId: string }) { |
| 215 | 215 | <Tooltip> |
| 216 | 216 | <TooltipTrigger |
| 217 | 217 | render={ |
| 218 | <span className="min-w-0 flex-1 truncate font-mono text-[11px]"> | |
| 218 | <span className="min-w-0 flex-1 truncate font-mono text-2xs"> | |
| 219 | 219 | {shortenTraceId(traceId)} |
| 220 | 220 | </span> |
| 221 | 221 | } |
| ... | ... | @@ -362,7 +362,7 @@ function ProcessDiagnosticsTable({ |
| 362 | 362 | <col className="w-[11%]" /> |
| 363 | 363 | <col className="w-[6%]" /> |
| 364 | 364 | </colgroup> |
| 365 | <thead className="sticky top-0 z-10 border-b border-border/60 bg-card text-[11px] uppercase tracking-[0.08em] text-muted-foreground/70"> | |
| 365 | <thead className="sticky top-0 z-10 border-b border-border/60 bg-card text-2xs uppercase tracking-widest text-muted-foreground/70"> | |
| 366 | 366 | <tr> |
| 367 | 367 | <th className="px-4 py-2 font-semibold sm:pl-5">Name</th> |
| 368 | 368 | <th className="px-3 py-2 text-right font-semibold">CPU</th> |
| ... | ... | @@ -588,7 +588,7 @@ function ProcessResourceHistoryTable({ |
| 588 | 588 | <col className="w-[16%]" /> |
| 589 | 589 | <col className="w-[10%]" /> |
| 590 | 590 | </colgroup> |
| 591 | <thead className="sticky top-0 z-10 border-b border-border/60 bg-card text-[11px] uppercase tracking-[0.08em] text-muted-foreground/70"> | |
| 591 | <thead className="sticky top-0 z-10 border-b border-border/60 bg-card text-2xs uppercase tracking-widest text-muted-foreground/70"> | |
| 592 | 592 | <tr> |
| 593 | 593 | <th className="px-4 py-2 font-semibold sm:pl-5">Process</th> |
| 594 | 594 | <th className="px-3 py-2 text-right font-semibold">CPU Time</th> |
| ... | ... | @@ -662,15 +662,15 @@ function DiagnosticsLastChecked({ checkedAt }: { checkedAt: DateTime.Utc | null |
| 662 | 662 | const relative = getRelativeTimeState(checkedAt ? DateTime.formatIso(checkedAt) : null); |
| 663 | 663 | |
| 664 | 664 | if (relative.status === "missing") { |
| 665 | return <span className="text-[11px] text-muted-foreground/50">Checking</span>; | |
| 665 | return <span className="text-2xs text-muted-foreground/50">Checking</span>; | |
| 666 | 666 | } |
| 667 | 667 | |
| 668 | 668 | if (relative.status === "invalid") { |
| 669 | return <span className="text-[11px] text-muted-foreground/50">Checked unavailable</span>; | |
| 669 | return <span className="text-2xs text-muted-foreground/50">Checked unavailable</span>; | |
| 670 | 670 | } |
| 671 | 671 | |
| 672 | 672 | return ( |
| 673 | <span className="text-[11px] text-muted-foreground/60"> | |
| 673 | <span className="text-2xs text-muted-foreground/60"> | |
| 674 | 674 | {relative.suffix ? ( |
| 675 | 675 | <> |
| 676 | 676 | Checked <span className="font-mono tabular-nums">{relative.value}</span> {relative.suffix} |
| ... | ... | @@ -1222,7 +1222,7 @@ export function DiagnosticsSettingsPanel() { |
| 1222 | 1222 | <col className="w-[26%]" /> |
| 1223 | 1223 | <col className="w-[30%]" /> |
| 1224 | 1224 | </colgroup> |
| 1225 | <thead className="border-b border-border/60 text-[11px] uppercase tracking-[0.08em] text-muted-foreground/70"> | |
| 1225 | <thead className="border-b border-border/60 text-2xs uppercase tracking-widest text-muted-foreground/70"> | |
| 1226 | 1226 | <tr> |
| 1227 | 1227 | <th className="whitespace-nowrap px-4 py-2.5 font-semibold sm:pl-5">Time</th> |
| 1228 | 1228 | <th className="whitespace-nowrap px-4 py-2.5 font-semibold">Level</th> |
| ... | ... | @@ -1241,7 +1241,7 @@ export function DiagnosticsSettingsPanel() { |
| 1241 | 1241 | {formatRelativeNoWrap(event.seenAt)} |
| 1242 | 1242 | </td> |
| 1243 | 1243 | <td className="px-4 py-3 align-top"> |
| 1244 | <span className="inline-flex rounded bg-muted px-1.5 py-0.5 font-mono text-[11px] font-medium uppercase text-foreground/80"> | |
| 1244 | <span className="inline-flex rounded bg-muted px-1.5 py-0.5 font-mono text-2xs font-medium uppercase text-foreground/80"> | |
| 1245 | 1245 | {event.level} |
| 1246 | 1246 | </span> |
| 1247 | 1247 | </td> |
apps/web/src/components/settings/FontFamilyPicker.tsx+1-3| ... | ... | @@ -173,9 +173,7 @@ export function FontFamilyPicker({ |
| 173 | 173 | {family} |
| 174 | 174 | </span> |
| 175 | 175 | <span className="flex shrink-0 items-center gap-1.5"> |
| 176 | {isDefault ? ( | |
| 177 | <span className="text-[10px] text-muted-foreground/60">default</span> | |
| 178 | ) : null} | |
| 176 | {isDefault ? <span className="text-3xs text-muted-foreground/60">default</span> : null} | |
| 179 | 177 | {item === selectedValue ? ( |
| 180 | 178 | <CheckIcon className="size-3.5 text-muted-foreground" /> |
| 181 | 179 | ) : null} |
apps/web/src/components/settings/KeybindingsSettings.tsx+8-8| ... | ... | @@ -255,7 +255,7 @@ function WarningTooltipIcon({ |
| 255 | 255 | tabIndex={focusable ? 0 : undefined} |
| 256 | 256 | aria-label={label} |
| 257 | 257 | className={cn( |
| 258 | "inline-flex size-5 shrink-0 items-center justify-center rounded-sm text-warning outline-none transition-colors hover:bg-warning/10 focus-visible:ring-[3px] focus-visible:ring-warning/25", | |
| 258 | "inline-flex size-5 shrink-0 items-center justify-center rounded-sm text-warning outline-none transition-colors hover:bg-warning/10 focus-visible:ring-3 focus-visible:ring-warning/25", | |
| 259 | 259 | className, |
| 260 | 260 | )} |
| 261 | 261 | /> |
| ... | ... | @@ -668,7 +668,7 @@ function WhenExpressionBuilder({ |
| 668 | 668 | ) : null} |
| 669 | 669 | </InputGroup> |
| 670 | 670 | {parseError ? ( |
| 671 | <div className="flex items-center gap-1.5 text-[11px] text-destructive"> | |
| 671 | <div className="flex items-center gap-1.5 text-2xs text-destructive"> | |
| 672 | 672 | <CircleXIcon className="size-3.5" /> |
| 673 | 673 | {parseError} |
| 674 | 674 | </div> |
| ... | ... | @@ -698,7 +698,7 @@ function WhenExpressionBuilder({ |
| 698 | 698 | </div> |
| 699 | 699 | )} |
| 700 | 700 | {parseError ? ( |
| 701 | <div className="pointer-events-none absolute inset-0 flex items-center justify-center rounded-lg border border-destructive/30 bg-background/75 p-4 text-center text-xs text-destructive backdrop-blur-[1px]"> | |
| 701 | <div className="pointer-events-none absolute inset-0 flex items-center justify-center rounded-lg border border-destructive/30 bg-background/75 p-4 text-center text-xs text-destructive backdrop-blur-xs"> | |
| 702 | 702 | Fix the expression above to continue editing visually. |
| 703 | 703 | </div> |
| 704 | 704 | ) : null} |
| ... | ... | @@ -842,7 +842,7 @@ function KeybindingKeyControl({ |
| 842 | 842 | onClick={() => setDraft({ isRecording: true })} |
| 843 | 843 | aria-label={`Edit shortcut for ${commandLabel(row.command)}: ${formatShortcutLabel(row.binding.shortcut)}`} |
| 844 | 844 | className={cn( |
| 845 | "inline-flex h-8 cursor-pointer items-center rounded-md border border-transparent px-1.5 sm:h-7 outline-none transition-colors hover:border-border/70 hover:bg-accent focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/24", | |
| 845 | "inline-flex h-8 cursor-pointer items-center rounded-md border border-transparent px-1.5 sm:h-7 outline-none transition-colors hover:border-border/70 hover:bg-accent focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/24", | |
| 846 | 846 | pillClassName, |
| 847 | 847 | )} |
| 848 | 848 | > |
| ... | ... | @@ -989,7 +989,7 @@ function KeybindingRowWhen({ |
| 989 | 989 | }) { |
| 990 | 990 | return ( |
| 991 | 991 | <span className="flex h-6 items-center gap-1.5"> |
| 992 | <span className="text-[12px] leading-none text-muted-foreground/70">When</span> | |
| 992 | <span className="text-xs leading-none text-muted-foreground/70">When</span> | |
| 993 | 993 | <WhenClauseControl |
| 994 | 994 | label={commandLabel(row.command)} |
| 995 | 995 | expression={editor.whenDraftExpression} |
| ... | ... | @@ -1234,7 +1234,7 @@ function NewKeybindingSettingsRow(props: NewKeybindingProps) { |
| 1234 | 1234 | title="New keybinding" |
| 1235 | 1235 | description={ |
| 1236 | 1236 | <span className="flex h-6 items-center gap-1.5"> |
| 1237 | <span className="text-[12px] leading-none text-muted-foreground/70">When</span> | |
| 1237 | <span className="text-xs leading-none text-muted-foreground/70">When</span> | |
| 1238 | 1238 | <NewKeybindingWhen draft={draft} variables={variables} /> |
| 1239 | 1239 | </span> |
| 1240 | 1240 | } |
| ... | ... | @@ -1312,7 +1312,7 @@ function KeybindingsList(props: KeybindingsListProps) { |
| 1312 | 1312 | /** Shown in the browser build only; the desktop app receives every shortcut. */ |
| 1313 | 1313 | function BrowserKeybindingNotice() { |
| 1314 | 1314 | return ( |
| 1315 | <div className="flex items-center gap-2 px-3 py-2.5 text-[12px] leading-[1.45] text-muted-foreground sm:px-4"> | |
| 1315 | <div className="flex items-center gap-2 px-3 py-2.5 text-xs leading-normal text-muted-foreground sm:px-4"> | |
| 1316 | 1316 | <TriangleAlertIcon className="size-3.5 shrink-0 text-warning" aria-hidden /> |
| 1317 | 1317 | <span> |
| 1318 | 1318 | Some shortcuts may be claimed by the browser before T3 Code sees them. Use the desktop app |
| ... | ... | @@ -1488,7 +1488,7 @@ export function KeybindingsSettingsPanel() { |
| 1488 | 1488 | const cancelAdd = useCallback(() => setIsAddingBinding(false), []); |
| 1489 | 1489 | |
| 1490 | 1490 | const bindingsCount = ( |
| 1491 | <span className="text-[11px] text-muted-foreground"> | |
| 1491 | <span className="text-2xs text-muted-foreground"> | |
| 1492 | 1492 | {rows.length + (isAddingBinding ? 1 : 0)}{" "} |
| 1493 | 1493 | {rows.length + (isAddingBinding ? 1 : 0) === 1 ? "binding" : "bindings"} |
| 1494 | 1494 | </span> |
apps/web/src/components/settings/OpenSourceLicenses.tsx+1-1| ... | ... | @@ -179,7 +179,7 @@ function LicenseManifestError({ message, onRetry }: { message: string; onRetry: |
| 179 | 179 | <div className="flex flex-col items-start gap-3 px-3 py-5 sm:px-4"> |
| 180 | 180 | <div className="flex flex-col gap-1"> |
| 181 | 181 | <h3 className="text-sm font-medium text-foreground">Open-source notices are unavailable</h3> |
| 182 | <p className="max-w-[70ch] text-pretty text-[13px] leading-[1.45] text-muted-foreground/80"> | |
| 182 | <p className="max-w-[70ch] text-pretty text-xs leading-normal text-muted-foreground/80"> | |
| 183 | 183 | {message} |
| 184 | 184 | </p> |
| 185 | 185 | </div> |
apps/web/src/components/settings/PanelAnimationsPreview.tsx+1-1| ... | ... | @@ -5,7 +5,7 @@ import { cn } from "~/lib/utils"; |
| 5 | 5 | export function PanelAnimationsPreview({ durationMs }: { durationMs: number }) { |
| 6 | 6 | const [panelsOpen, setPanelsOpen] = useState(true); |
| 7 | 7 | const transitionClass = |
| 8 | "transition-[width,height,border-width] [transition-duration:var(--preview-duration)] ease-out motion-reduce:transition-none"; | |
| 8 | "transition-[width,height,border-width] duration-(--preview-duration) ease-out motion-reduce:transition-none"; | |
| 9 | 9 | |
| 10 | 10 | return ( |
| 11 | 11 | <button |
apps/web/src/components/settings/ProjectActionsList.tsx+2-2| ... | ... | @@ -34,12 +34,12 @@ export function ProjectActionsList({ |
| 34 | 34 | <ScriptIcon icon={script.icon} className="size-4 shrink-0 text-muted-foreground" /> |
| 35 | 35 | <span className="min-w-0 truncate">{script.name}</span> |
| 36 | 36 | {script.runOnWorktreeCreate ? ( |
| 37 | <span className="shrink-0 rounded-sm border border-border/60 px-1.5 py-px text-[11px] font-normal text-muted-foreground"> | |
| 37 | <span className="shrink-0 rounded-sm border border-border/60 px-1.5 py-px text-2xs font-normal text-muted-foreground"> | |
| 38 | 38 | setup |
| 39 | 39 | </span> |
| 40 | 40 | ) : null} |
| 41 | 41 | {script.previewUrl ? ( |
| 42 | <span className="shrink-0 rounded-sm border border-border/60 px-1.5 py-px text-[11px] font-normal text-muted-foreground max-sm:hidden"> | |
| 42 | <span className="shrink-0 rounded-sm border border-border/60 px-1.5 py-px text-2xs font-normal text-muted-foreground max-sm:hidden"> | |
| 43 | 43 | preview · desktop only |
| 44 | 44 | </span> |
| 45 | 45 | ) : null} |
apps/web/src/components/settings/ProviderInstanceCard.test.ts+1-1| ... | ... | @@ -118,7 +118,7 @@ describe("deriveProviderModelsForDisplay", () => { |
| 118 | 118 | |
| 119 | 119 | expect(markup).toContain("Authenticated as"); |
| 120 | 120 | expect(markup).toContain('aria-label="Toggle account email visibility"'); |
| 121 | expect(markup).toContain("blur-[2px]"); | |
| 121 | expect(markup).toContain("blur-xs"); | |
| 122 | 122 | expect(markup).not.toContain("developer@example.com"); |
| 123 | 123 | }); |
| 124 | 124 | it("surfaces a failed probe message in both the list row and the editor", () => { |
apps/web/src/components/settings/ProviderInstanceCard.tsx+7-7| ... | ... | @@ -570,7 +570,7 @@ export function ProviderInstanceCard({ |
| 570 | 570 | showBadge={Boolean(accentColor)} |
| 571 | 571 | className="size-5" |
| 572 | 572 | iconClassName="size-4 text-foreground/80" |
| 573 | badgeClassName="right-[-0.125rem] bottom-[-0.125rem] h-3 min-w-3 px-0.5 text-[7px]" | |
| 573 | badgeClassName="right-[-0.125rem] bottom-[-0.125rem] h-3 min-w-3 px-0.5 text-3xs" | |
| 574 | 574 | /> |
| 575 | 575 | ) : FallbackIconComponent ? ( |
| 576 | 576 | <span className="inline-flex size-5 shrink-0 items-center justify-center"> |
| ... | ... | @@ -578,7 +578,7 @@ export function ProviderInstanceCard({ |
| 578 | 578 | </span> |
| 579 | 579 | ) : ( |
| 580 | 580 | <span |
| 581 | className="inline-flex size-5 shrink-0 items-center justify-center text-[10px] font-semibold leading-none text-foreground/80" | |
| 581 | className="inline-flex size-5 shrink-0 items-center justify-center text-3xs font-semibold leading-none text-foreground/80" | |
| 582 | 582 | aria-hidden |
| 583 | 583 | > |
| 584 | 584 | {providerInstanceInitials(displayName)} |
| ... | ... | @@ -655,7 +655,7 @@ export function ProviderInstanceCard({ |
| 655 | 655 | <span className="flex min-w-0 items-center gap-2"> |
| 656 | 656 | <span className="truncate text-sm font-medium text-foreground">{displayName}</span> |
| 657 | 657 | {String(instanceId) !== String(instance.driver) ? ( |
| 658 | <code className="min-w-0 truncate rounded bg-muted/60 px-1 py-0.5 text-[10px] text-muted-foreground"> | |
| 658 | <code className="min-w-0 truncate rounded bg-muted/60 px-1 py-0.5 text-3xs text-muted-foreground"> | |
| 659 | 659 | {instanceId} |
| 660 | 660 | </code> |
| 661 | 661 | ) : null} |
| ... | ... | @@ -708,7 +708,7 @@ export function ProviderInstanceCard({ |
| 708 | 708 | ) |
| 709 | 709 | ) : null} |
| 710 | 710 | </span> |
| 711 | <span className="mt-0.5 flex items-start gap-1.5 text-[13px] leading-[1.45] text-muted-foreground/80"> | |
| 711 | <span className="mt-0.5 flex items-start gap-1.5 text-xs leading-normal text-muted-foreground/80"> | |
| 712 | 712 | {statusDotNode ? ( |
| 713 | 713 | <span className="flex h-[1.45em] shrink-0 items-center">{statusDotNode}</span> |
| 714 | 714 | ) : null} |
| ... | ... | @@ -775,7 +775,7 @@ export function ProviderInstanceCard({ |
| 775 | 775 | <PopoverPopup side="bottom" align="end" width="md"> |
| 776 | 776 | <div className="grid min-w-0 gap-3"> |
| 777 | 777 | <div className="grid gap-0.5"> |
| 778 | <p className="text-[13px] font-semibold leading-tight text-foreground"> | |
| 778 | <p className="text-sm font-semibold leading-tight text-foreground"> | |
| 779 | 779 | {versionAdvisory.title} |
| 780 | 780 | </p> |
| 781 | 781 | <p |
| ... | ... | @@ -807,7 +807,7 @@ export function ProviderInstanceCard({ |
| 807 | 807 | </Button> |
| 808 | 808 | ) : null} |
| 809 | 809 | {onRunVersionAction && updateCommand ? ( |
| 810 | <div className="flex items-center gap-2 text-[10px] font-medium uppercase tracking-wider text-muted-foreground"> | |
| 810 | <div className="flex items-center gap-2 text-3xs font-medium uppercase tracking-wider text-muted-foreground"> | |
| 811 | 811 | <span aria-hidden className="h-px flex-1 bg-border" /> |
| 812 | 812 | or, update manually using |
| 813 | 813 | <span aria-hidden className="h-px flex-1 bg-border" /> |
| ... | ... | @@ -815,7 +815,7 @@ export function ProviderInstanceCard({ |
| 815 | 815 | ) : null} |
| 816 | 816 | {updateCommand ? ( |
| 817 | 817 | <div className="flex min-w-0 items-center gap-1 rounded-md border border-border/70 bg-muted/40 py-0.5 pr-0.5 pl-2"> |
| 818 | <code className="min-w-0 flex-1 truncate font-mono text-[11px] text-foreground"> | |
| 818 | <code className="min-w-0 flex-1 truncate font-mono text-2xs text-foreground"> | |
| 819 | 819 | {updateCommand} |
| 820 | 820 | </code> |
| 821 | 821 | <Tooltip> |
apps/web/src/components/settings/ProviderModelsSection.tsx+4-4| ... | ... | @@ -470,19 +470,19 @@ export function ProviderModelsSection({ |
| 470 | 470 | <span className="flex min-w-0 items-baseline gap-2"> |
| 471 | 471 | <span className={cn(nameClassName, "truncate")}>{model.name}</span> |
| 472 | 472 | {model.name !== model.slug ? ( |
| 473 | <code className="truncate font-mono text-[11px] text-muted-foreground/70"> | |
| 473 | <code className="truncate font-mono text-2xs text-muted-foreground/70"> | |
| 474 | 474 | {model.slug} |
| 475 | 475 | </code> |
| 476 | 476 | ) : null} |
| 477 | 477 | {model.isCustom ? ( |
| 478 | <span className="text-[11px] text-muted-foreground/70">custom</span> | |
| 478 | <span className="text-2xs text-muted-foreground/70">custom</span> | |
| 479 | 479 | ) : null} |
| 480 | 480 | </span> |
| 481 | 481 | {/* |
| 482 | 482 | Always a grid item so the columns line up across rows; the text |
| 483 | 483 | itself drops out on phone widths where it would starve the name. |
| 484 | 484 | */} |
| 485 | <span className="text-[11px] text-muted-foreground/70"> | |
| 485 | <span className="text-2xs text-muted-foreground/70"> | |
| 486 | 486 | {capLabels.length > 0 ? ( |
| 487 | 487 | <span className="hidden sm:inline">{capLabels.join(" · ")}</span> |
| 488 | 488 | ) : null} |
| ... | ... | @@ -494,7 +494,7 @@ export function ProviderModelsSection({ |
| 494 | 494 | }; |
| 495 | 495 | |
| 496 | 496 | const groupLabel = (label: string, isFirst: boolean) => ( |
| 497 | <div className={cn("px-2 pb-1.5 text-[11px] text-muted-foreground", isFirst ? "pt-1" : "pt-5")}> | |
| 497 | <div className={cn("px-2 pb-1.5 text-2xs text-muted-foreground", isFirst ? "pt-1" : "pt-5")}> | |
| 498 | 498 | {label} |
| 499 | 499 | </div> |
| 500 | 500 | ); |
apps/web/src/components/settings/ProviderSettingsForm.tsx+1-1| ... | ... | @@ -240,7 +240,7 @@ function ProviderSettingsFieldRow({ |
| 240 | 240 | const inputId = `${idPrefix}-${field.key}`; |
| 241 | 241 | const descriptionClassName = |
| 242 | 242 | variant === "dialog" |
| 243 | ? "text-[11px] text-muted-foreground" | |
| 243 | ? "text-2xs text-muted-foreground" | |
| 244 | 244 | : "mt-1 block text-xs text-muted-foreground"; |
| 245 | 245 | const label = <span className="text-xs font-medium text-foreground">{field.label}</span>; |
| 246 | 246 | const description = field.description ? ( |
apps/web/src/components/settings/RedactedSensitiveText.tsx+2-2| ... | ... | @@ -44,8 +44,8 @@ export function RedactedSensitiveText(props: { |
| 44 | 44 | <button |
| 45 | 45 | type="button" |
| 46 | 46 | className={cn( |
| 47 | "min-w-0 cursor-pointer rounded-sm font-mono text-[11px] leading-normal transition hover:text-foreground", | |
| 48 | revealed ? "text-muted-foreground" : "select-none text-muted-foreground blur-[2px]", | |
| 47 | "min-w-0 cursor-pointer rounded-sm font-mono text-2xs leading-normal transition hover:text-foreground", | |
| 48 | revealed ? "text-muted-foreground" : "select-none text-muted-foreground blur-xs", | |
| 49 | 49 | props.className, |
| 50 | 50 | )} |
| 51 | 51 | onClick={() => setRevealed((current) => !current)} |
apps/web/src/components/settings/ResourceTelemetryDiagnostics.tsx+35-35| ... | ... | @@ -194,7 +194,7 @@ function SourceStatusBadge({ |
| 194 | 194 | return ( |
| 195 | 195 | <span |
| 196 | 196 | className={cn( |
| 197 | "inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-[10px] font-semibold uppercase tracking-[0.08em]", | |
| 197 | "inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-3xs font-semibold uppercase tracking-widest", | |
| 198 | 198 | tone === "neutral" && "border-border/70 bg-muted/45 text-muted-foreground", |
| 199 | 199 | tone === "default" && "border-success/25 bg-success/10 text-success-foreground", |
| 200 | 200 | tone === "warning" && "border-warning/30 bg-warning/10 text-warning-foreground", |
| ... | ... | @@ -218,14 +218,14 @@ function SourceStatusBadge({ |
| 218 | 218 | function LastSampleLabel({ sampledAt }: { sampledAt: DateTime.Utc | null }) { |
| 219 | 219 | useRelativeTimeTick(); |
| 220 | 220 | if (!sampledAt) { |
| 221 | return <span className="text-[11px] text-muted-foreground/55">Waiting for sample</span>; | |
| 221 | return <span className="text-2xs text-muted-foreground/55">Waiting for sample</span>; | |
| 222 | 222 | } |
| 223 | 223 | const relative = formatRelativeTime(DateTime.formatIso(sampledAt)); |
| 224 | 224 | if (!relative) { |
| 225 | return <span className="text-[11px] text-muted-foreground/55">Waiting for sample</span>; | |
| 225 | return <span className="text-2xs text-muted-foreground/55">Waiting for sample</span>; | |
| 226 | 226 | } |
| 227 | 227 | return ( |
| 228 | <span className="text-[11px] text-muted-foreground/60"> | |
| 228 | <span className="text-2xs text-muted-foreground/60"> | |
| 229 | 229 | Updated <span className="font-mono tabular-nums">{relative.value}</span> |
| 230 | 230 | {relative.suffix ? ` ${relative.suffix}` : ""} |
| 231 | 231 | </span> |
| ... | ... | @@ -247,7 +247,7 @@ function IconStat({ |
| 247 | 247 | }) { |
| 248 | 248 | return ( |
| 249 | 249 | <div className="group min-w-0 px-4 py-4 sm:px-5"> |
| 250 | <div className="flex items-center gap-2 text-[10px] font-semibold uppercase tracking-[0.11em] text-muted-foreground/70"> | |
| 250 | <div className="flex items-center gap-2 text-3xs font-semibold uppercase tracking-widest text-muted-foreground/70"> | |
| 251 | 251 | <span className="text-muted-foreground/55 transition-colors group-hover:text-foreground/65"> |
| 252 | 252 | {icon} |
| 253 | 253 | </span> |
| ... | ... | @@ -255,7 +255,7 @@ function IconStat({ |
| 255 | 255 | </div> |
| 256 | 256 | <div |
| 257 | 257 | className={cn( |
| 258 | "mt-2.5 truncate font-mono text-2xl font-semibold tracking-[-0.05em] tabular-nums text-foreground", | |
| 258 | "mt-2.5 truncate font-mono text-2xl font-semibold tracking-tighter tabular-nums text-foreground", | |
| 259 | 259 | tone === "warning" && "text-warning-foreground", |
| 260 | 260 | tone === "danger" && "text-destructive", |
| 261 | 261 | )} |
| ... | ... | @@ -263,7 +263,7 @@ function IconStat({ |
| 263 | 263 | {value} |
| 264 | 264 | </div> |
| 265 | 265 | {detail ? ( |
| 266 | <div className="mt-1.5 truncate text-[10px] text-muted-foreground/60">{detail}</div> | |
| 266 | <div className="mt-1.5 truncate text-3xs text-muted-foreground/60">{detail}</div> | |
| 267 | 267 | ) : null} |
| 268 | 268 | </div> |
| 269 | 269 | ); |
| ... | ... | @@ -282,10 +282,10 @@ function AggregateCard({ |
| 282 | 282 | <div className="relative overflow-hidden border-t border-border/60 px-4 py-4 first:border-t-0 md:border-t-0 md:border-l md:first:border-l-0 sm:px-5"> |
| 283 | 283 | <span className={cn("absolute inset-x-5 top-0 h-0.5 rounded-full opacity-75", accentClass)} /> |
| 284 | 284 | <div className="flex items-center justify-between gap-3"> |
| 285 | <div className="text-[10px] font-semibold uppercase tracking-[0.11em] text-muted-foreground/75"> | |
| 285 | <div className="text-3xs font-semibold uppercase tracking-widest text-muted-foreground/75"> | |
| 286 | 286 | {label} |
| 287 | 287 | </div> |
| 288 | <div className="rounded-md bg-muted/55 px-1.5 py-0.5 font-mono text-[9px] tabular-nums text-muted-foreground/70"> | |
| 288 | <div className="rounded-md bg-muted/55 px-1.5 py-0.5 font-mono text-3xs tabular-nums text-muted-foreground/70"> | |
| 289 | 289 | {aggregate.processCount} {aggregate.processCount === 1 ? "process" : "processes"} |
| 290 | 290 | </div> |
| 291 | 291 | </div> |
| ... | ... | @@ -302,7 +302,7 @@ function AggregateCard({ |
| 302 | 302 | function MetricPair({ label, value }: { label: string; value: string }) { |
| 303 | 303 | return ( |
| 304 | 304 | <div className="min-w-0"> |
| 305 | <div className="text-[9px] font-semibold uppercase tracking-[0.08em] text-muted-foreground/45"> | |
| 305 | <div className="text-3xs font-semibold uppercase tracking-widest text-muted-foreground/45"> | |
| 306 | 306 | {label} |
| 307 | 307 | </div> |
| 308 | 308 | <div className="truncate font-mono text-xs font-medium tabular-nums text-foreground/90"> |
| ... | ... | @@ -319,8 +319,8 @@ function HealthSource({ label, health }: { label: string; health: ResourceTeleme |
| 319 | 319 | return ( |
| 320 | 320 | <div className="flex items-start justify-between gap-4 border-t border-border/50 py-3 first:border-t-0"> |
| 321 | 321 | <div className="min-w-0"> |
| 322 | <div className="text-[13px] font-medium text-foreground">{label}</div> | |
| 323 | <div className="mt-1 text-[11px] leading-relaxed text-muted-foreground/65"> | |
| 322 | <div className="text-sm font-medium text-foreground">{label}</div> | |
| 323 | <div className="mt-1 text-2xs leading-relaxed text-muted-foreground/65"> | |
| 324 | 324 | {expectedInBrowser |
| 325 | 325 | ? "Available when this page runs inside the desktop app." |
| 326 | 326 | : Option.match(health.lastError, { |
| ... | ... | @@ -356,10 +356,10 @@ function DetailRow({ |
| 356 | 356 | }) { |
| 357 | 357 | return ( |
| 358 | 358 | <div className="flex items-center justify-between gap-4 border-t border-border/50 py-2.5 first:border-t-0"> |
| 359 | <span className="text-[11px] text-muted-foreground/75">{label}</span> | |
| 359 | <span className="text-2xs text-muted-foreground/75">{label}</span> | |
| 360 | 360 | <span |
| 361 | 361 | className={cn( |
| 362 | "min-w-0 truncate text-right font-mono text-[11px] tabular-nums text-foreground/85", | |
| 362 | "min-w-0 truncate text-right font-mono text-2xs tabular-nums text-foreground/85", | |
| 363 | 363 | valueClassName, |
| 364 | 364 | )} |
| 365 | 365 | > |
| ... | ... | @@ -405,7 +405,7 @@ function ResourceHistoryChart({ |
| 405 | 405 | |
| 406 | 406 | return ( |
| 407 | 407 | <div className="border-t border-border/60 px-4 py-4 sm:px-5"> |
| 408 | <div className="mb-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-[10px] text-muted-foreground/65"> | |
| 408 | <div className="mb-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-3xs text-muted-foreground/65"> | |
| 409 | 409 | <span className="inline-flex items-center gap-1.5"> |
| 410 | 410 | <span className="h-1.5 w-3 rounded-full bg-foreground/70" /> CPU average |
| 411 | 411 | </span> |
| ... | ... | @@ -529,7 +529,7 @@ function ProcessActions({ |
| 529 | 529 | onSignal: (process: ResourceTelemetryProcess, signal: ServerProcessSignal) => void; |
| 530 | 530 | }) { |
| 531 | 531 | if (!canSignalProcess(process)) { |
| 532 | return <span className="text-[10px] text-muted-foreground/35">—</span>; | |
| 532 | return <span className="text-3xs text-muted-foreground/35">—</span>; | |
| 533 | 533 | } |
| 534 | 534 | const isSignaling = signalingKeys.has(processIdentityKey(process)); |
| 535 | 535 | return ( |
| ... | ... | @@ -586,7 +586,7 @@ function ProcessTable({ |
| 586 | 586 | <col className="w-[6%]" /> |
| 587 | 587 | <col className="w-[4%]" /> |
| 588 | 588 | </colgroup> |
| 589 | <thead className="sticky top-0 z-10 border-b border-border/60 bg-card text-[10px] uppercase tracking-[0.08em] text-muted-foreground/65"> | |
| 589 | <thead className="sticky top-0 z-10 border-b border-border/60 bg-card text-3xs uppercase tracking-widest text-muted-foreground/65"> | |
| 590 | 590 | <tr> |
| 591 | 591 | <th className="px-4 py-2 font-semibold sm:pl-5">Process</th> |
| 592 | 592 | <th className="px-3 py-2 font-semibold">Category</th> |
| ... | ... | @@ -618,7 +618,7 @@ function ProcessTable({ |
| 618 | 618 | onToggle={toggle} |
| 619 | 619 | /> |
| 620 | 620 | </td> |
| 621 | <td className="truncate px-3 py-2 text-[11px] text-muted-foreground"> | |
| 621 | <td className="truncate px-3 py-2 text-2xs text-muted-foreground"> | |
| 622 | 622 | {categoryLabel(process.category)} |
| 623 | 623 | </td> |
| 624 | 624 | <td className="px-3 py-2 text-right font-mono tabular-nums"> |
| ... | ... | @@ -689,7 +689,7 @@ function HistoryProcessTable({ |
| 689 | 689 | <col className="w-[7%]" /> |
| 690 | 690 | <col className="w-[5%]" /> |
| 691 | 691 | </colgroup> |
| 692 | <thead className="sticky top-0 z-10 border-b border-border/60 bg-card text-[10px] uppercase tracking-[0.08em] text-muted-foreground/65"> | |
| 692 | <thead className="sticky top-0 z-10 border-b border-border/60 bg-card text-3xs uppercase tracking-widest text-muted-foreground/65"> | |
| 693 | 693 | <tr> |
| 694 | 694 | <th className="px-4 py-2 font-semibold sm:pl-5">Process</th> |
| 695 | 695 | <th className="px-3 py-2 font-semibold">Category</th> |
| ... | ... | @@ -726,7 +726,7 @@ function HistoryProcessTable({ |
| 726 | 726 | </TooltipPopup> |
| 727 | 727 | </Tooltip> |
| 728 | 728 | </td> |
| 729 | <td className="truncate px-3 py-2 text-[11px] text-muted-foreground"> | |
| 729 | <td className="truncate px-3 py-2 text-2xs text-muted-foreground"> | |
| 730 | 730 | {categoryLabel(process.category)} |
| 731 | 731 | </td> |
| 732 | 732 | <td className="px-3 py-2 text-right font-mono tabular-nums"> |
| ... | ... | @@ -771,7 +771,7 @@ function AttributionTable({ entries }: { entries: ReadonlyArray<ResourceAttribut |
| 771 | 771 | <col className="w-[10%]" /> |
| 772 | 772 | <col className="w-[12%]" /> |
| 773 | 773 | </colgroup> |
| 774 | <thead className="border-b border-border/60 text-[10px] uppercase tracking-[0.08em] text-muted-foreground/65"> | |
| 774 | <thead className="border-b border-border/60 text-3xs uppercase tracking-widest text-muted-foreground/65"> | |
| 775 | 775 | <tr> |
| 776 | 776 | <th className="px-4 py-2 font-semibold sm:pl-5">Component</th> |
| 777 | 777 | <th className="px-3 py-2 font-semibold">Operation</th> |
| ... | ... | @@ -983,10 +983,10 @@ export function ResourceTelemetryDiagnostics({ |
| 983 | 983 | </div> |
| 984 | 984 | } |
| 985 | 985 | > |
| 986 | <div className="overflow-hidden rounded-2xl border border-border/70 bg-card shadow-[0_1px_1px_rgb(0_0_0/0.03),0_8px_30px_rgb(0_0_0/0.035)]"> | |
| 986 | <div className="overflow-hidden rounded-2xl border border-border/70 bg-card shadow-sm/5"> | |
| 987 | 987 | <div className="flex flex-col gap-3 border-b border-border/60 bg-linear-to-r from-muted/45 via-muted/20 to-transparent px-4 py-4 sm:flex-row sm:items-center sm:justify-between sm:px-5"> |
| 988 | 988 | <div> |
| 989 | <div className="text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground/70"> | |
| 989 | <div className="text-3xs font-semibold uppercase tracking-widest text-muted-foreground/70"> | |
| 990 | 990 | T3 system footprint |
| 991 | 991 | </div> |
| 992 | 992 | <p className="mt-1 max-w-xl text-xs leading-relaxed text-muted-foreground"> |
| ... | ... | @@ -994,7 +994,7 @@ export function ResourceTelemetryDiagnostics({ |
| 994 | 994 | the monitor itself. |
| 995 | 995 | </p> |
| 996 | 996 | </div> |
| 997 | <div className="flex items-center gap-2 text-[10px] text-muted-foreground/65"> | |
| 997 | <div className="flex items-center gap-2 text-3xs text-muted-foreground/65"> | |
| 998 | 998 | <span className="size-1.5 rounded-full bg-success" /> |
| 999 | 999 | Sampling every {snapshot ? formatSampleInterval(snapshot.sampleIntervalMs) : "..."} |
| 1000 | 1000 | </div> |
| ... | ... | @@ -1091,9 +1091,9 @@ export function ResourceTelemetryDiagnostics({ |
| 1091 | 1091 | ) : null |
| 1092 | 1092 | } |
| 1093 | 1093 | > |
| 1094 | <div className="grid overflow-hidden rounded-2xl border border-border/70 bg-card shadow-[0_1px_1px_rgb(0_0_0/0.03)] md:grid-cols-2 md:divide-x md:divide-border/60"> | |
| 1094 | <div className="grid overflow-hidden rounded-2xl border border-border/70 bg-card shadow-xs/5 md:grid-cols-2 md:divide-x md:divide-border/60"> | |
| 1095 | 1095 | <div className="px-4 py-4 sm:px-5"> |
| 1096 | <div className="mb-3 flex items-center gap-2 text-[10px] font-semibold uppercase tracking-[0.12em] text-muted-foreground/70"> | |
| 1096 | <div className="mb-3 flex items-center gap-2 text-3xs font-semibold uppercase tracking-widest text-muted-foreground/70"> | |
| 1097 | 1097 | <span className="flex size-6 items-center justify-center rounded-md bg-muted/60"> |
| 1098 | 1098 | <BatteryIcon className="size-3.5" /> |
| 1099 | 1099 | </span> |
| ... | ... | @@ -1150,10 +1150,10 @@ export function ResourceTelemetryDiagnostics({ |
| 1150 | 1150 | </> |
| 1151 | 1151 | ) : ( |
| 1152 | 1152 | <div className="rounded-xl border border-dashed border-border/70 bg-muted/20 px-4 py-5"> |
| 1153 | <div className="text-[13px] font-medium text-foreground"> | |
| 1153 | <div className="text-sm font-medium text-foreground"> | |
| 1154 | 1154 | Desktop host signals not connected |
| 1155 | 1155 | </div> |
| 1156 | <p className="mt-1.5 max-w-sm text-[11px] leading-relaxed text-muted-foreground/70"> | |
| 1156 | <p className="mt-1.5 max-w-sm text-2xs leading-relaxed text-muted-foreground/70"> | |
| 1157 | 1157 | Power, idle, lock, and thermal state are supplied by the desktop host. Process |
| 1158 | 1158 | telemetry remains fully active in this browser session. |
| 1159 | 1159 | </p> |
| ... | ... | @@ -1161,7 +1161,7 @@ export function ResourceTelemetryDiagnostics({ |
| 1161 | 1161 | )} |
| 1162 | 1162 | </div> |
| 1163 | 1163 | <div className="border-t border-border/60 px-4 py-4 md:border-t-0 sm:px-5"> |
| 1164 | <div className="mb-3 flex items-center gap-2 text-[10px] font-semibold uppercase tracking-[0.12em] text-muted-foreground/70"> | |
| 1164 | <div className="mb-3 flex items-center gap-2 text-3xs font-semibold uppercase tracking-widest text-muted-foreground/70"> | |
| 1165 | 1165 | <span className="flex size-6 items-center justify-center rounded-md bg-muted/60"> |
| 1166 | 1166 | <GaugeIcon className="size-3.5" /> |
| 1167 | 1167 | </span> |
| ... | ... | @@ -1228,7 +1228,7 @@ export function ResourceTelemetryDiagnostics({ |
| 1228 | 1228 | </div> |
| 1229 | 1229 | } |
| 1230 | 1230 | > |
| 1231 | <div className="overflow-hidden rounded-2xl border border-border/70 bg-card shadow-[0_1px_1px_rgb(0_0_0/0.03)]"> | |
| 1231 | <div className="overflow-hidden rounded-2xl border border-border/70 bg-card shadow-xs/5"> | |
| 1232 | 1232 | {history.error ? ( |
| 1233 | 1233 | <div className="flex items-start gap-2 border-b border-destructive/20 bg-destructive/5 px-4 py-3 text-xs text-destructive sm:px-5"> |
| 1234 | 1234 | <AlertTriangleIcon className="mt-0.5 size-3.5 shrink-0" /> |
| ... | ... | @@ -1245,13 +1245,13 @@ export function ResourceTelemetryDiagnostics({ |
| 1245 | 1245 | icon={<CpuIcon className="size-4 text-muted-foreground" />} |
| 1246 | 1246 | headerAction={ |
| 1247 | 1247 | snapshot ? ( |
| 1248 | <span className="text-[10px] text-muted-foreground/55"> | |
| 1248 | <span className="text-3xs text-muted-foreground/55"> | |
| 1249 | 1249 | Identity: <span className="font-mono">PID + start time</span> |
| 1250 | 1250 | </span> |
| 1251 | 1251 | ) : null |
| 1252 | 1252 | } |
| 1253 | 1253 | > |
| 1254 | <div className="overflow-hidden rounded-2xl border border-border/70 bg-card shadow-[0_1px_1px_rgb(0_0_0/0.03)]"> | |
| 1254 | <div className="overflow-hidden rounded-2xl border border-border/70 bg-card shadow-xs/5"> | |
| 1255 | 1255 | <ProcessTable |
| 1256 | 1256 | processes={snapshot?.processes ?? []} |
| 1257 | 1257 | signalingKeys={signalingKeys} |
| ... | ... | @@ -1264,11 +1264,11 @@ export function ResourceTelemetryDiagnostics({ |
| 1264 | 1264 | title="Instrumented application I/O" |
| 1265 | 1265 | icon={<DatabaseIcon className="size-4 text-muted-foreground" />} |
| 1266 | 1266 | headerAction={ |
| 1267 | <span className="text-[10px] text-muted-foreground/55">Logical bytes by operation</span> | |
| 1267 | <span className="text-3xs text-muted-foreground/55">Logical bytes by operation</span> | |
| 1268 | 1268 | } |
| 1269 | 1269 | > |
| 1270 | <div className="overflow-hidden rounded-2xl border border-border/70 bg-card shadow-[0_1px_1px_rgb(0_0_0/0.03)]"> | |
| 1271 | <div className="bg-muted/15 px-4 py-3 text-[11px] leading-relaxed text-muted-foreground sm:px-5"> | |
| 1270 | <div className="overflow-hidden rounded-2xl border border-border/70 bg-card shadow-xs/5"> | |
| 1271 | <div className="bg-muted/15 px-4 py-3 text-2xs leading-relaxed text-muted-foreground sm:px-5"> | |
| 1272 | 1272 | Native counters identify which process is reading or writing. These application-level |
| 1273 | 1273 | counters identify known T3 operations so process spikes can be correlated with specific |
| 1274 | 1274 | persistence and logging paths. |
apps/web/src/components/settings/SettingsPanels.tsx+4-4| ... | ... | @@ -264,7 +264,7 @@ function AboutVersionTitle() { |
| 264 | 264 | return ( |
| 265 | 265 | <span className="inline-flex items-baseline gap-2"> |
| 266 | 266 | <span>Version</span> |
| 267 | <code className="text-[11px] font-medium text-muted-foreground">{APP_VERSION}</code> | |
| 267 | <code className="text-2xs font-medium text-muted-foreground">{APP_VERSION}</code> | |
| 268 | 268 | </span> |
| 269 | 269 | ); |
| 270 | 270 | } |
| ... | ... | @@ -1368,8 +1368,8 @@ export function AppearanceSettingsPanel() { |
| 1368 | 1368 | : "flex shrink-0 gap-1" |
| 1369 | 1369 | } |
| 1370 | 1370 | > |
| 1371 | <span className="size-2 rounded-full bg-[var(--diff-deletion)]" /> | |
| 1372 | <span className="size-2 rounded-full bg-[var(--diff-addition)]" /> | |
| 1371 | <span className="size-2 rounded-full bg-diff-deletion" /> | |
| 1372 | <span className="size-2 rounded-full bg-diff-addition" /> | |
| 1373 | 1373 | </span> |
| 1374 | 1374 | <SelectValue> |
| 1375 | 1375 | {settings.diffColorScheme === "blue-orange" ? "Blue & orange" : "Red & green"} |
| ... | ... | @@ -2046,7 +2046,7 @@ function LegacyFeaturesSection() { |
| 2046 | 2046 | <section id="legacy-features" ref={targetRef} tabIndex={-1} className="space-y-2.5"> |
| 2047 | 2047 | <Collapsible open={open} onOpenChange={setOpen}> |
| 2048 | 2048 | <CollapsibleTrigger className="group flex min-h-8 w-full items-center gap-2 px-3 sm:px-4"> |
| 2049 | <h2 className="text-sm font-normal tracking-[-0.005em] text-foreground/70 transition-colors group-hover:text-foreground"> | |
| 2049 | <h2 className="text-sm font-normal text-foreground/70 transition-colors group-hover:text-foreground"> | |
| 2050 | 2050 | Legacy features |
| 2051 | 2051 | </h2> |
| 2052 | 2052 | <ChevronRightIcon className="size-4 text-muted-foreground transition-transform duration-200 group-data-panel-open:rotate-90" /> |
apps/web/src/components/settings/SettingsSidebarNav.tsx+1-1| ... | ... | @@ -311,7 +311,7 @@ export function SettingsSidebarNav({ pathname }: { pathname: string }) { |
| 311 | 311 | <span className="block truncate text-sm font-medium text-sidebar-foreground"> |
| 312 | 312 | {item.title} |
| 313 | 313 | </span> |
| 314 | <span className="block truncate text-[11px] text-sidebar-muted-foreground/75"> | |
| 314 | <span className="block truncate text-2xs text-sidebar-muted-foreground/75"> | |
| 315 | 315 | {SETTINGS_SECTION_LABELS[item.to]} |
| 316 | 316 | </span> |
| 317 | 317 | </span> |
apps/web/src/components/settings/SnapShotSetupDialog.tsx+2-6| ... | ... | @@ -268,9 +268,7 @@ export function SnapShotSetupDialog({ |
| 268 | 268 | permissions={[ |
| 269 | 269 | { |
| 270 | 270 | id: "screenRecording", |
| 271 | icon: ( | |
| 272 | <MacScreenRecordingIcon className="size-8 shrink-0 drop-shadow-[0_1px_1px_#0005]" /> | |
| 273 | ), | |
| 271 | icon: <MacScreenRecordingIcon className="size-8 shrink-0 drop-shadow-sm" />, | |
| 274 | 272 | title: "Screen Recording", |
| 275 | 273 | description: "Capture the window you're using.", |
| 276 | 274 | granted: macPermissions.screenRecording, |
| ... | ... | @@ -278,9 +276,7 @@ export function SnapShotSetupDialog({ |
| 278 | 276 | }, |
| 279 | 277 | { |
| 280 | 278 | id: "accessibility", |
| 281 | icon: ( | |
| 282 | <MacAccessibilityIcon className="size-8 shrink-0 drop-shadow-[0_1px_1px_#0005]" /> | |
| 283 | ), | |
| 279 | icon: <MacAccessibilityIcon className="size-8 shrink-0 drop-shadow-sm" />, | |
| 284 | 280 | title: "Accessibility", |
| 285 | 281 | description: includeAccessibility |
| 286 | 282 | ? "Include text and controls from the captured app." |
apps/web/src/components/settings/SourceControlSettings.tsx+4-6| ... | ... | @@ -242,8 +242,8 @@ function itemSummary({ |
| 242 | 242 | return ( |
| 243 | 243 | <span> |
| 244 | 244 | {item.label} is not authenticated on this server. Sign in or configure credentials using |
| 245 | the <code className="rounded bg-muted px-1 py-px text-[11px]">{item.executable}</code>{" "} | |
| 246 | tool on the server host to enable change request features. | |
| 245 | the <code className="rounded bg-muted px-1 py-px text-2xs">{item.executable}</code> tool | |
| 246 | on the server host to enable change request features. | |
| 247 | 247 | </span> |
| 248 | 248 | ); |
| 249 | 249 | } |
| ... | ... | @@ -294,9 +294,7 @@ function DiscoveryItemRow({ |
| 294 | 294 | <div className="min-w-0 flex-1 space-y-1"> |
| 295 | 295 | <div className="flex min-w-0 flex-wrap items-center gap-2"> |
| 296 | 296 | <SourceControlItemMark item={item} /> |
| 297 | <span className="truncate text-sm font-medium tracking-[-0.005em] text-foreground"> | |
| 298 | {item.label} | |
| 299 | </span> | |
| 297 | <span className="truncate text-sm font-medium text-foreground">{item.label}</span> | |
| 300 | 298 | {version ? <code className="text-xs text-muted-foreground">{version}</code> : null} |
| 301 | 299 | {isVcsNotReady(item) ? ( |
| 302 | 300 | <Badge variant="warning" size="sm"> |
| ... | ... | @@ -309,7 +307,7 @@ function DiscoveryItemRow({ |
| 309 | 307 | </Badge> |
| 310 | 308 | ) : null} |
| 311 | 309 | </div> |
| 312 | <p className="flex min-w-0 flex-wrap items-center gap-x-1 text-[13px] leading-[1.45] text-muted-foreground/80"> | |
| 310 | <p className="flex min-w-0 flex-wrap items-center gap-x-1 text-xs leading-normal text-muted-foreground/80"> | |
| 313 | 311 | {itemSummary({ item, auth, authAccount })} |
| 314 | 312 | </p> |
| 315 | 313 | </div> |
apps/web/src/components/settings/ThemeColorPicker.tsx+4-4| ... | ... | @@ -171,7 +171,7 @@ function ThemeColorPickerPanel({ |
| 171 | 171 | <div className="flex items-center justify-between border-b border-border/70 px-4 py-3"> |
| 172 | 172 | <div className="min-w-0"> |
| 173 | 173 | <p className="truncate text-xs font-semibold text-foreground">{label}</p> |
| 174 | <p className="text-[11px] text-muted-foreground">Choose a color</p> | |
| 174 | <p className="text-2xs text-muted-foreground">Choose a color</p> | |
| 175 | 175 | </div> |
| 176 | 176 | <span |
| 177 | 177 | className="size-7 shrink-0 rounded-full shadow-sm" |
| ... | ... | @@ -193,7 +193,7 @@ function ThemeColorPickerPanel({ |
| 193 | 193 | /> |
| 194 | 194 | <div className="grid grid-cols-[1fr_1.2fr] gap-2"> |
| 195 | 195 | <label className="grid min-w-0 gap-1"> |
| 196 | <span className="px-1 text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground"> | |
| 196 | <span className="px-1 text-3xs font-semibold uppercase tracking-widest text-muted-foreground"> | |
| 197 | 197 | HEX |
| 198 | 198 | </span> |
| 199 | 199 | <span className="flex min-w-0 items-center gap-2 rounded-lg border border-input bg-background px-2 focus-within:border-ring"> |
| ... | ... | @@ -219,7 +219,7 @@ function ThemeColorPickerPanel({ |
| 219 | 219 | </span> |
| 220 | 220 | </label> |
| 221 | 221 | <label className="grid min-w-0 gap-1"> |
| 222 | <span className="px-1 text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground"> | |
| 222 | <span className="px-1 text-3xs font-semibold uppercase tracking-widest text-muted-foreground"> | |
| 223 | 223 | RGB |
| 224 | 224 | </span> |
| 225 | 225 | <span className="flex min-w-0 items-center rounded-lg border border-input bg-background px-2 focus-within:border-ring"> |
| ... | ... | @@ -323,7 +323,7 @@ export const ThemeColorField = memo(function ThemeColorField({ |
| 323 | 323 | <div |
| 324 | 324 | className={cn( |
| 325 | 325 | "flex min-h-11 min-w-0 items-center gap-2 rounded-lg px-2 py-1.5 transition-[background-color,box-shadow]", |
| 326 | selected && "bg-accent/60 shadow-[inset_0_0_0_1px_var(--ring)]", | |
| 326 | selected && "bg-accent/60 inset-ring inset-ring-ring", | |
| 327 | 327 | )} |
| 328 | 328 | data-theme-color-role={role} |
| 329 | 329 | > |
apps/web/src/components/settings/ThemeImportDialog.tsx+4-4| ... | ... | @@ -111,12 +111,12 @@ function ThemeJsonEditor({ |
| 111 | 111 | }, []); |
| 112 | 112 | |
| 113 | 113 | return ( |
| 114 | <div className="relative overflow-hidden rounded-xl border border-input bg-background shadow-xs/5 focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/24"> | |
| 114 | <div className="relative overflow-hidden rounded-xl border border-input bg-background shadow-xs/5 focus-within:border-ring focus-within:ring-3 focus-within:ring-ring/24"> | |
| 115 | 115 | {isPlainText ? null : ( |
| 116 | 116 | <pre |
| 117 | 117 | ref={highlightRef} |
| 118 | 118 | aria-hidden |
| 119 | className="pointer-events-none absolute inset-0 m-0 overflow-hidden whitespace-pre-wrap break-words p-3 font-mono text-[12px] leading-5 text-foreground" | |
| 119 | className="pointer-events-none absolute inset-0 m-0 overflow-hidden whitespace-pre-wrap break-words p-3 font-mono text-xs leading-5 text-foreground" | |
| 120 | 120 | > |
| 121 | 121 | <code dangerouslySetInnerHTML={{ __html: highlightedJson }} /> |
| 122 | 122 | </pre> |
| ... | ... | @@ -124,7 +124,7 @@ function ThemeJsonEditor({ |
| 124 | 124 | <textarea |
| 125 | 125 | aria-label="Theme JSON" |
| 126 | 126 | className={cn( |
| 127 | "relative z-10 block min-h-44 w-full resize-y overflow-auto bg-transparent p-3 font-mono text-[12px] leading-5 caret-foreground outline-none placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground", | |
| 127 | "relative z-10 block min-h-44 w-full resize-y overflow-auto bg-transparent p-3 font-mono text-xs leading-5 caret-foreground outline-none placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground", | |
| 128 | 128 | isPlainText ? "text-foreground" : "text-transparent", |
| 129 | 129 | )} |
| 130 | 130 | id={id} |
| ... | ... | @@ -438,7 +438,7 @@ export function ThemeImportDialog({ |
| 438 | 438 | |
| 439 | 439 | <div className="flex items-center gap-3" aria-hidden> |
| 440 | 440 | <div className="h-px flex-1 bg-border" /> |
| 441 | <span className="text-muted-foreground text-[11px] uppercase tracking-wider"> | |
| 441 | <span className="text-muted-foreground text-2xs uppercase tracking-wider"> | |
| 442 | 442 | or import a file |
| 443 | 443 | </span> |
| 444 | 444 | <div className="h-px flex-1 bg-border" /> |
apps/web/src/components/settings/ThemeSettings.tsx+5-5| ... | ... | @@ -231,12 +231,12 @@ function ThemeLibraryCard({ |
| 231 | 231 | </button> |
| 232 | 232 | </ThemeVariantTooltip> |
| 233 | 233 | <span |
| 234 | className="pointer-events-none absolute bottom-0 left-1/2 inline-flex max-w-24 -translate-x-1/2 items-center gap-1 text-[11px] font-medium text-foreground" | |
| 234 | className="pointer-events-none absolute bottom-0 left-1/2 inline-flex max-w-24 -translate-x-1/2 items-center gap-1 text-2xs font-medium text-foreground" | |
| 235 | 235 | style={{ marginLeft: rootOffsetX }} |
| 236 | 236 | > |
| 237 | 237 | <span className="truncate">{selected.option.label}</span> |
| 238 | 238 | {options.length > 1 ? ( |
| 239 | <span className="shrink-0 rounded-full bg-muted px-1 text-[9px] text-muted-foreground"> | |
| 239 | <span className="shrink-0 rounded-full bg-muted px-1 text-3xs text-muted-foreground"> | |
| 240 | 240 | +{options.length - 1} |
| 241 | 241 | </span> |
| 242 | 242 | ) : null} |
| ... | ... | @@ -256,7 +256,7 @@ function ThemeLibraryCard({ |
| 256 | 256 | aria-label={`Use ${option.label} for ${mode} mode${optionIsActive ? ", currently active" : ""}`} |
| 257 | 257 | aria-pressed={optionIsActive} |
| 258 | 258 | className={cn( |
| 259 | "absolute left-1/2 top-1 z-30 flex size-7 items-center justify-center rounded-full bg-background shadow-sm outline-none transition-[transform,opacity] duration-200 ease-out motion-reduce:transition-none focus-visible:ring-2 focus-visible:ring-ring", | |
| 259 | "absolute left-1/2 top-1 z-30 flex size-7 items-center justify-center rounded-full bg-background shadow-sm outline-none transition-[opacity,transform] duration-200 ease-out motion-reduce:transition-none focus-visible:ring-2 focus-visible:ring-ring", | |
| 260 | 260 | optionIsActive ? "ring-2 ring-ring" : "ring-1 ring-border/70", |
| 261 | 261 | )} |
| 262 | 262 | style={{ |
| ... | ... | @@ -884,12 +884,12 @@ export function ThemeLibrary({ |
| 884 | 884 | |
| 885 | 885 | return ( |
| 886 | 886 | <div className="space-y-3"> |
| 887 | <h3 className="px-3 text-sm font-normal tracking-[-0.005em] text-foreground/70 sm:px-4"> | |
| 887 | <h3 className="px-3 text-sm font-normal text-foreground/70 sm:px-4"> | |
| 888 | 888 | {searchableSetting("color-scheme").title} |
| 889 | 889 | </h3> |
| 890 | 890 | {renderModeTiles()} |
| 891 | 891 | <div className="flex min-h-8 flex-wrap items-center justify-between gap-3 px-3 pt-2 sm:px-4"> |
| 892 | <h3 className="text-sm font-normal tracking-[-0.005em] text-foreground/70"> | |
| 892 | <h3 className="text-sm font-normal text-foreground/70"> | |
| 893 | 893 | {searchableSetting("theme").title} |
| 894 | 894 | </h3> |
| 895 | 895 | <div className="flex flex-wrap items-center justify-end gap-2"> |
apps/web/src/components/settings/ThemeWireframe.tsx+2-2| ... | ... | @@ -66,7 +66,7 @@ function ThemeWireframePane({ |
| 66 | 66 | |
| 67 | 67 | {/* Composer */} |
| 68 | 68 | <span |
| 69 | className="absolute bottom-[8%] left-[26%] right-[6%] flex h-[15%] items-center justify-between rounded-md px-[2.5%]" | |
| 69 | className="absolute bottom-[8%] left-[26%] right-[6%] flex h-[15%] items-center justify-between rounded-md px-1" | |
| 70 | 70 | style={{ |
| 71 | 71 | backgroundColor: colors.surface, |
| 72 | 72 | boxShadow: `inset 0 0 0 1px ${line}`, |
| ... | ... | @@ -92,7 +92,7 @@ function ThemeWireframePane({ |
| 92 | 92 | > |
| 93 | 93 | {[0, 1, 2].map((row) => ( |
| 94 | 94 | <span |
| 95 | className="absolute left-[11%] right-[11%] flex items-center gap-[5%]" | |
| 95 | className="absolute left-[11%] right-[11%] flex items-center gap-1" | |
| 96 | 96 | key={row} |
| 97 | 97 | style={{ top: `${10 + row * 30}%`, height: "20%" }} |
| 98 | 98 | > |
apps/web/src/components/settings/settingsLayout.tsx+4-4| ... | ... | @@ -202,7 +202,7 @@ export function SettingsSection({ |
| 202 | 202 | className="flex min-h-7 items-start justify-between gap-4 px-3 sm:px-4" |
| 203 | 203 | > |
| 204 | 204 | <div className="min-w-0"> |
| 205 | <h2 className="flex min-h-7 items-center gap-2 text-sm font-normal tracking-[-0.005em] text-foreground/70"> | |
| 205 | <h2 className="flex min-h-7 items-center gap-2 text-sm font-normal text-foreground/70"> | |
| 206 | 206 | {icon} |
| 207 | 207 | {title} |
| 208 | 208 | </h2> |
| ... | ... | @@ -228,7 +228,7 @@ export function SettingsUnavailableGroup({ |
| 228 | 228 | |
| 229 | 229 | return ( |
| 230 | 230 | <div className="border-border/60 bg-muted/20 py-1.5"> |
| 231 | <div className="flex items-start gap-2 px-3 py-2 text-[12px] leading-relaxed text-muted-foreground sm:px-4"> | |
| 231 | <div className="flex items-start gap-2 px-3 py-2 text-xs leading-relaxed text-muted-foreground sm:px-4"> | |
| 232 | 232 | <InfoIcon className="mt-0.5 size-3.5 shrink-0 text-warning" /> |
| 233 | 233 | <p>{message}</p> |
| 234 | 234 | </div> |
| ... | ... | @@ -435,7 +435,7 @@ export function SettingsRow({ |
| 435 | 435 | <div className="flex flex-col gap-3 @min-[32rem]/settings-row:grid @min-[32rem]/settings-row:grid-cols-[minmax(0,1fr)_minmax(10rem,auto)] @min-[32rem]/settings-row:items-center @min-[32rem]/settings-row:gap-8"> |
| 436 | 436 | <div className="min-w-0 flex-1 space-y-1"> |
| 437 | 437 | <div className="flex min-h-5 items-center gap-1.5"> |
| 438 | <h3 className="text-sm font-medium tracking-[-0.005em] text-foreground">{title}</h3> | |
| 438 | <h3 className="text-sm font-medium text-foreground">{title}</h3> | |
| 439 | 439 | {renderedInheritance ? ( |
| 440 | 440 | <span className="inline-flex h-5 w-5 shrink-0 items-center justify-center"> |
| 441 | 441 | {renderedInheritance} |
| ... | ... | @@ -446,7 +446,7 @@ export function SettingsRow({ |
| 446 | 446 | </span> |
| 447 | 447 | </div> |
| 448 | 448 | {description ? ( |
| 449 | <p className="max-w-xl text-[13px] leading-[1.45] text-muted-foreground/80"> | |
| 449 | <p className="max-w-xl text-xs leading-normal text-muted-foreground/80"> | |
| 450 | 450 | {description} |
| 451 | 451 | </p> |
| 452 | 452 | ) : null} |
apps/web/src/components/sidebar/SidebarProviderUpdatePill.tsx+2-2| ... | ... | @@ -125,7 +125,7 @@ export function SidebarProviderUpdatePill() { |
| 125 | 125 | |
| 126 | 126 | return ( |
| 127 | 127 | <div |
| 128 | className={`group/provider-update relative flex min-h-7 w-full shrink-0 items-center overflow-hidden rounded-lg text-[11px] leading-4 font-medium transform-gpu transition-all duration-180 ease-[cubic-bezier(0.22,1,0.36,1)] will-change-transform ${ | |
| 128 | className={`group/provider-update relative flex min-h-7 w-full shrink-0 items-center overflow-hidden rounded-lg text-2xs leading-4 font-medium transform-gpu transition-all duration-180 ease-drawer will-change-transform ${ | |
| 129 | 129 | PROVIDER_UPDATE_PILL_STYLES[displayedView.tone] |
| 130 | 130 | } ${ |
| 131 | 131 | exitingKey === displayedView.key |
| ... | ... | @@ -152,7 +152,7 @@ export function SidebarProviderUpdatePill() { |
| 152 | 152 | <div |
| 153 | 153 | key={displayedView.key} |
| 154 | 154 | aria-hidden="true" |
| 155 | className={`pointer-events-none absolute inset-y-0 left-0 w-full origin-left animate-[provider-update-pill-countdown_var(--provider-update-pill-dismiss-ms)_linear_forwards] border-r border-current/15 shadow-[inset_0_1px_0_rgb(255_255_255_/_0.08)] ${ | |
| 155 | className={`pointer-events-none absolute inset-y-0 left-0 w-full origin-left scale-x-0 transition-transform duration-(--provider-update-pill-dismiss-ms) ease-linear starting:scale-x-100 border-r border-current/15 inset-shadow-2xs inset-shadow-white/8 ${ | |
| 156 | 156 | PROVIDER_UPDATE_PILL_PROGRESS_STYLES[displayedView.tone] |
| 157 | 157 | }`} |
| 158 | 158 | style={ |
apps/web/src/components/sidebar/SidebarThreadHeader.tsx+1-1| ... | ... | @@ -83,7 +83,7 @@ export function SidebarThreadHeader({ |
| 83 | 83 | ref={searchFieldRef} |
| 84 | 84 | className="flex h-8 min-w-0 flex-1 items-center gap-2 rounded-md px-2 py-1.5 text-sm font-medium text-sidebar-muted-foreground hover:bg-sidebar-row-hover hover:text-sidebar-foreground" |
| 85 | 85 | > |
| 86 | <SearchIcon className="size-4 shrink-0 text-[var(--sidebar-icon-color)]" /> | |
| 86 | <SearchIcon className="size-4 shrink-0 text-(--sidebar-icon-color)" /> | |
| 87 | 87 | <SidebarInput |
| 88 | 88 | ref={searchInputRef} |
| 89 | 89 | nativeInput |
apps/web/src/components/sidebar/SidebarUpdatePill.tsx+1-1| ... | ... | @@ -311,7 +311,7 @@ function SidebarUpdateControl() { |
| 311 | 311 | !isInteractionDisabled && "hover:bg-sidebar-row-hover", |
| 312 | 312 | ) |
| 313 | 313 | : cn( |
| 314 | "text-[var(--sidebar-icon-color)]", | |
| 314 | "text-(--sidebar-icon-color)", | |
| 315 | 315 | !isInteractionDisabled && "hover:bg-sidebar-row-hover hover:text-sidebar-foreground", |
| 316 | 316 | ), |
| 317 | 317 | disabled && !showUpdateIconState && "opacity-60", |
apps/web/src/components/usage/UsageLimitsPooled.tsx+5-5| ... | ... | @@ -52,7 +52,7 @@ function AccountChip({ email }: { readonly email: string }) { |
| 52 | 52 | <span |
| 53 | 53 | role="img" |
| 54 | 54 | aria-label={`Account ${accountInitials(email)}`} |
| 55 | className="inline-flex size-4 shrink-0 items-center justify-center rounded-full text-[9px] leading-none font-semibold" | |
| 55 | className="inline-flex size-4 shrink-0 items-center justify-center rounded-full text-3xs leading-none font-semibold" | |
| 56 | 56 | style={{ backgroundColor: `oklch(0.85 0.08 ${hue})`, color: `oklch(0.35 0.1 ${hue})` }} |
| 57 | 57 | > |
| 58 | 58 | {accountInitials(email)} |
| ... | ... | @@ -269,7 +269,7 @@ function PoolSegment({ |
| 269 | 269 | ) : null} |
| 270 | 270 | <span |
| 271 | 271 | aria-hidden |
| 272 | className="absolute inset-0 flex items-center justify-center text-[10px] leading-none font-semibold text-foreground/80 tabular-nums @2xl/pool:hidden" | |
| 272 | className="absolute inset-0 flex items-center justify-center text-3xs leading-none font-semibold text-foreground/80 tabular-nums @2xl/pool:hidden" | |
| 273 | 273 | > |
| 274 | 274 | {index} |
| 275 | 275 | </span> |
| ... | ... | @@ -277,7 +277,7 @@ function PoolSegment({ |
| 277 | 277 | <AccountName account={account} className="min-w-0 truncate font-medium text-foreground" /> |
| 278 | 278 | <span className="shrink-0 font-semibold text-foreground tabular-nums">{remaining}%</span> |
| 279 | 279 | {/* Countdown and badge get their own plate: fill and hatching run under them otherwise. */} |
| 280 | <span className="ms-auto flex shrink-0 items-center gap-1.5 rounded-sm bg-background/85 px-1.5 py-0.5 text-[11px] text-foreground tabular-nums"> | |
| 280 | <span className="ms-auto flex shrink-0 items-center gap-1.5 rounded-sm bg-background/85 px-1.5 py-0.5 text-2xs text-foreground tabular-nums"> | |
| 281 | 281 | {resetsIn?.replace("resets in ", "↻ ") ?? ""} |
| 282 | 282 | {credits ? ( |
| 283 | 283 | <> |
| ... | ... | @@ -348,7 +348,7 @@ function LegendRow({ |
| 348 | 348 | render={<Button variant="ghost" size="compact" />} |
| 349 | 349 | className="min-w-0 @2xl/pool:hidden" |
| 350 | 350 | > |
| 351 | <span className="relative inline-flex size-4 shrink-0 items-center justify-center rounded-sm text-[10px] leading-none font-semibold text-foreground/80 tabular-nums"> | |
| 351 | <span className="relative inline-flex size-4 shrink-0 items-center justify-center rounded-sm text-3xs leading-none font-semibold text-foreground/80 tabular-nums"> | |
| 352 | 352 | <span |
| 353 | 353 | aria-hidden |
| 354 | 354 | className="absolute inset-0 rounded-sm opacity-35" |
| ... | ... | @@ -359,7 +359,7 @@ function LegendRow({ |
| 359 | 359 | </span> |
| 360 | 360 | <AccountName account={account} className="min-w-0 truncate font-medium text-foreground" /> |
| 361 | 361 | <span className="shrink-0 font-semibold text-foreground tabular-nums">{remaining}%</span> |
| 362 | <span className="ms-auto flex shrink-0 items-center gap-1.5 text-[11px] text-muted-foreground tabular-nums"> | |
| 362 | <span className="ms-auto flex shrink-0 items-center gap-1.5 text-2xs text-muted-foreground tabular-nums"> | |
| 363 | 363 | {resetsIn?.replace("resets in ", "↻ ") ?? ""} |
| 364 | 364 | {credits ? ( |
| 365 | 365 | <> |
apps/web/src/components/usage/UsagePage.tsx+1-1| ... | ... | @@ -428,7 +428,7 @@ export function UsagePage() { |
| 428 | 428 | <span className="truncate"> |
| 429 | 429 | {PROVIDER_PRESENTATION[provider].label} |
| 430 | 430 | </span> |
| 431 | <span className="shrink-0 whitespace-nowrap text-[11px] text-muted-foreground tabular-nums"> | |
| 431 | <span className="shrink-0 whitespace-nowrap text-2xs text-muted-foreground tabular-nums"> | |
| 432 | 432 | {sessionLabel} |
| 433 | 433 | </span> |
| 434 | 434 | </span> |
apps/web/src/components/usage/UsageProviderChart.tsx+2-2| ... | ... | @@ -322,7 +322,7 @@ export function UsageProviderChart({ |
| 322 | 322 | {ticks.map((tick) => ( |
| 323 | 323 | <span |
| 324 | 324 | key={tick} |
| 325 | className="absolute right-0 -translate-y-1/2 text-[10px] text-muted-foreground tabular-nums" | |
| 325 | className="absolute right-0 -translate-y-1/2 text-3xs text-muted-foreground tabular-nums" | |
| 326 | 326 | style={{ top: `${(toY(tick) / VIEW_HEIGHT) * 100}%` }} |
| 327 | 327 | > |
| 328 | 328 | {tick === 0 ? "0" : format(tick)} |
| ... | ... | @@ -434,7 +434,7 @@ export function UsageProviderChart({ |
| 434 | 434 | </div> |
| 435 | 435 | </div> |
| 436 | 436 | |
| 437 | <div className="flex justify-between pl-16 text-[10px] text-muted-foreground uppercase"> | |
| 437 | <div className="flex justify-between pl-16 text-3xs text-muted-foreground uppercase"> | |
| 438 | 438 | <span>{periods[0] === undefined ? "" : formatPeriod(periods[0])}</span> |
| 439 | 439 | <span> |
| 440 | 440 | {periods[Math.floor(periods.length / 2)] === undefined |
apps/web/src/index.css+46-34| ... | ... | @@ -116,6 +116,17 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil |
| 116 | 116 | --workspace-titlebar-control-size: 1.75rem; |
| 117 | 117 | --workspace-titlebar-control-gap: 0.75rem; |
| 118 | 118 | --workspace-titlebar-scroll-fade-height: 1.5rem; |
| 119 | /* The prompt on phones: iOS zooms into any input under 16px on focus. */ | |
| 120 | --font-size-prompt-touch: max(var(--font-size-prompt, 1rem), 16px); | |
| 121 | /* Horizontal gutter shared by the page header and the chat column, clear of | |
| 122 | the device's safe area. */ | |
| 123 | --workspace-gutter: 0.75rem; | |
| 124 | --workspace-gutter-start: calc(env(safe-area-inset-left) + var(--workspace-gutter)); | |
| 125 | --workspace-gutter-end: calc(env(safe-area-inset-right) + var(--workspace-gutter)); | |
| 126 | ||
| 127 | @variant sm { | |
| 128 | --workspace-gutter: 1.25rem; | |
| 129 | } | |
| 119 | 130 | |
| 120 | 131 | @variant dark { |
| 121 | 132 | --appearance-contrast-target: white; |
| ... | ... | @@ -148,6 +159,41 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil |
| 148 | 159 | } |
| 149 | 160 | |
| 150 | 161 | @theme inline { |
| 162 | /* Two steps below Tailwind's text-xs (12px) for dense UI: metadata rows, | |
| 163 | badges, counters, keyboard hints and diagnostics tables. 2xs is 11px, | |
| 164 | 3xs is 10px and the floor of the scale. Registered with tailwind-merge in | |
| 165 | lib/utils.ts so cn() treats them as font sizes, not colours. */ | |
| 166 | --text-2xs: 0.6875rem; | |
| 167 | --text-2xs--line-height: calc(1 / 0.6875); | |
| 168 | --text-3xs: 0.625rem; | |
| 169 | --text-3xs--line-height: calc(0.875 / 0.625); | |
| 170 | /* Motion. drawer is the decelerating curve for surfaces that slide or pop in | |
| 171 | (composer context, pills). */ | |
| 172 | --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); | |
| 173 | /* The composer's elevation: a soft drop pulled in under the surface, shared | |
| 174 | by the composer, its context strip and attached banners. */ | |
| 175 | --shadow-composer: 0 12px 28px -18px rgb(0 0 0 / 40%); | |
| 176 | --shadow-composer-dark: 0 14px 32px -18px rgb(0 0 0 / 75%); | |
| 177 | /* Dark-mode shade where an attached surface meets the composer: 10px of | |
| 178 | shadow fading away from the seam. Inline, so the offsets resolve on the | |
| 179 | element. below: the context strip under the composer (1rem seam, faint | |
| 180 | white fill). above: an attached banner over it (its tint on top). */ | |
| 181 | --background-image-composer-seam-below: | |
| 182 | linear-gradient( | |
| 183 | to bottom, | |
| 184 | transparent 0 1rem, | |
| 185 | rgb(0 0 0 / 18%) 1rem, | |
| 186 | transparent calc(1rem + 10px) | |
| 187 | ), | |
| 188 | linear-gradient(rgb(255 255 255 / 1%), rgb(255 255 255 / 1%)); | |
| 189 | --background-image-composer-seam-above: | |
| 190 | linear-gradient(var(--chat-composer-attached-tint), var(--chat-composer-attached-tint)), | |
| 191 | linear-gradient( | |
| 192 | to top, | |
| 193 | transparent 0 var(--chat-composer-attachment-overlap), | |
| 194 | rgb(0 0 0 / 18%) var(--chat-composer-attachment-overlap), | |
| 195 | transparent calc(var(--chat-composer-attachment-overlap) + 10px) | |
| 196 | ); | |
| 151 | 197 | --color-zinc-25: oklch(99.2% 0 0); |
| 152 | 198 | --animate-skeleton: skeleton 2.4s infinite; |
| 153 | 199 | /* Duty-cycled indicator animations: long holds with stepped ramps, so the |
| ... | ... | @@ -1936,40 +1982,6 @@ code { |
| 1936 | 1982 | overflow-wrap: anywhere; |
| 1937 | 1983 | } |
| 1938 | 1984 | |
| 1939 | /* Prompt-stash save acknowledgement: the new count fades up from just below | |
| 1940 | its resting position, once, then stops. One-shot and event-driven (React | |
| 1941 | remounts the element by key on each stash) — no continuous animation. */ | |
| 1942 | @keyframes prompt-stash-count-enter { | |
| 1943 | from { | |
| 1944 | opacity: 0; | |
| 1945 | transform: translateY(2px); | |
| 1946 | } | |
| 1947 | to { | |
| 1948 | opacity: 1; | |
| 1949 | transform: translateY(0); | |
| 1950 | } | |
| 1951 | } | |
| 1952 | ||
| 1953 | /* Expanded capture preview swaps between the screenshot and its extracted text. | |
| 1954 | One-shot fade on whichever panel mounts, so nothing repaints continuously. */ | |
| 1955 | @keyframes snap-shot-contents-enter { | |
| 1956 | from { | |
| 1957 | opacity: 0; | |
| 1958 | } | |
| 1959 | to { | |
| 1960 | opacity: 1; | |
| 1961 | } | |
| 1962 | } | |
| 1963 | ||
| 1964 | @keyframes provider-update-pill-countdown { | |
| 1965 | from { | |
| 1966 | transform: scaleX(1); | |
| 1967 | } | |
| 1968 | to { | |
| 1969 | transform: scaleX(0); | |
| 1970 | } | |
| 1971 | } | |
| 1972 | ||
| 1973 | 1985 | :root { |
| 1974 | 1986 | --diff-addition: var(--success); |
| 1975 | 1987 | --diff-deletion: var(--destructive); |
apps/web/src/lib/utils.ts+5-1| ... | ... | @@ -1,9 +1,13 @@ |
| 1 | 1 | import { MessageId, ProjectId, ThreadId } from "@t3tools/contracts"; |
| 2 | 2 | import { type CxOptions, cx } from "class-variance-authority"; |
| 3 | 3 | import * as Encoding from "effect/Encoding"; |
| 4 | import { twMerge } from "tailwind-merge"; | |
| 4 | import { extendTailwindMerge } from "tailwind-merge"; | |
| 5 | 5 | import { DraftId } from "../composerDraftStore"; |
| 6 | 6 | |
| 7 | // The theme's extra font sizes (index.css). Unregistered, tailwind-merge reads | |
| 8 | // text-2xs as a colour and drops it next to text-muted-foreground. | |
| 9 | const twMerge = extendTailwindMerge({ extend: { theme: { text: ["2xs", "3xs"] } } }); | |
| 10 | ||
| 7 | 11 | export function cn(...inputs: CxOptions) { |
| 8 | 12 | return twMerge(cx(inputs)); |
| 9 | 13 | } |
vite.config.ts+40| ... | ... | @@ -225,6 +225,41 @@ export default defineConfig({ |
| 225 | 225 | rules: { |
| 226 | 226 | // A className built at runtime on a ui component is one no-restyle cannot read. |
| 227 | 227 | "shadcn/require-static-classes": "error", |
| 228 | // Appearance values come from the theme and Tailwind's scales. Layout stays free | |
| 229 | // (placement belongs to the parent); the other entries are values no scale can hold. | |
| 230 | "shadcn/no-arbitrary-values": [ | |
| 231 | "error", | |
| 232 | { | |
| 233 | allow: [ | |
| 234 | "layout", | |
| 235 | // Which properties an element animates is per-element behaviour, like layout, | |
| 236 | // not a design value; timing curves and durations still come from the theme. | |
| 237 | "transition", | |
| 238 | // Overlays that follow their frame's corner, which is set at runtime | |
| 239 | // (floating preview) or by the element they decorate (composer outline). | |
| 240 | "rounded-[inherit]", | |
| 241 | // Inline chips size in em so they scale with the text they sit in | |
| 242 | // (the composer honours the prompt font-size preference). | |
| 243 | "gap-[0.33em]", | |
| 244 | "px-[0.5em]", | |
| 245 | "rounded-[0.5em]", | |
| 246 | "text-[0.86em]", | |
| 247 | // Project icons render from 14px to 48px and keep one proportional corner. | |
| 248 | "rounded-[25%]", | |
| 249 | // An emoji project icon fills its container, whatever size the parent gives it. | |
| 250 | "text-[length:80cqh]", | |
| 251 | // The platform's own selection colour on a selected composer chip. | |
| 252 | "bg-[Highlight]", | |
| 253 | // Brand marks keep their brand colours (Cursor, Grok, Claude). | |
| 254 | "fill-[#26251E]", | |
| 255 | "fill-[#EDECEC]", | |
| 256 | "fill-[#0F0F0F]", | |
| 257 | "fill-[#F5F5F5]", | |
| 258 | "fill-[#d97757]", | |
| 259 | "text-[#d97757]", | |
| 260 | ], | |
| 261 | }, | |
| 262 | ], | |
| 228 | 263 | "shadcn/no-restyle": [ |
| 229 | 264 | "error", |
| 230 | 265 | { |
| ... | ... | @@ -242,6 +277,11 @@ export default defineConfig({ |
| 242 | 277 | ], |
| 243 | 278 | }, |
| 244 | 279 | }, |
| 280 | { | |
| 281 | // The sign-in masthead is T3 brand artwork: fixed gradients, not theme surfaces. | |
| 282 | files: ["apps/web/src/components/auth/AuthSurfaceShell.tsx"], | |
| 283 | rules: { "shadcn/no-arbitrary-values": "off" }, | |
| 284 | }, | |
| 245 | 285 | { |
| 246 | 286 | // Shared client code must not call APIs missing from Hermes. Our ESNext |
| 247 | 287 | // TypeScript target accepts them even when they would crash mobile at launch. |