Ver código fonte

fix(ui): migrate to --v2-font-family-sans variable and improve home empty state (#29552)

Brendan Allan 2 meses atrás
pai
commit
e2dc89c6f3
31 arquivos alterados com 139 adições e 137 exclusões
  1. 89 88
      packages/app/src/pages/home.tsx
  2. 1 1
      packages/ui/src/v2/components/accordion-v2.css
  3. 1 1
      packages/ui/src/v2/components/accordion-v2.stories.tsx
  4. 1 1
      packages/ui/src/v2/components/avatar-v2.css
  5. 1 1
      packages/ui/src/v2/components/badge-v2.css
  6. 1 1
      packages/ui/src/v2/components/basic-tool-v2.css
  7. 1 1
      packages/ui/src/v2/components/button-v2.css
  8. 3 3
      packages/ui/src/v2/components/checkbox-v2.css
  9. 1 1
      packages/ui/src/v2/components/checkbox-v2.stories.tsx
  10. 2 2
      packages/ui/src/v2/components/dialog-v2.css
  11. 1 1
      packages/ui/src/v2/components/diff-changes-v2.css
  12. 2 2
      packages/ui/src/v2/components/field-v2.css
  13. 2 2
      packages/ui/src/v2/components/inline-input-v2.css
  14. 1 1
      packages/ui/src/v2/components/inline-input-v2.stories.tsx
  15. 2 2
      packages/ui/src/v2/components/keybind-v2.css
  16. 1 1
      packages/ui/src/v2/components/line-comment-v2.css
  17. 9 9
      packages/ui/src/v2/components/menu-v2.css
  18. 1 1
      packages/ui/src/v2/components/menu-v2.stories.tsx
  19. 5 5
      packages/ui/src/v2/components/radio-v2.css
  20. 1 1
      packages/ui/src/v2/components/radio-v2.stories.tsx
  21. 1 1
      packages/ui/src/v2/components/segmented-control-v2.css
  22. 2 2
      packages/ui/src/v2/components/segmented-control-v2.stories.tsx
  23. 1 1
      packages/ui/src/v2/components/select-v2.css
  24. 2 2
      packages/ui/src/v2/components/switch-v2.css
  25. 1 1
      packages/ui/src/v2/components/tabs-v2.css
  26. 1 1
      packages/ui/src/v2/components/text-input-v2.css
  27. 1 1
      packages/ui/src/v2/components/text-input-v2.stories.tsx
  28. 1 1
      packages/ui/src/v2/components/textarea-v2.css
  29. 1 1
      packages/ui/src/v2/components/textarea-v2.stories.tsx
  30. 1 1
      packages/ui/src/v2/components/tool-error-card-v2.css
  31. 1 0
      packages/ui/src/v2/styles/theme.css

+ 89 - 88
packages/app/src/pages/home.tsx

@@ -72,13 +72,11 @@ function HomeDesign() {
   const [state, setState] = createStore({ search: "", project: undefined as string | undefined })
 
   const projects = createMemo(() => layout.projects.list())
-  const selectedProject = createMemo(
-    () => projects().find((project) => project.worktree === state.project) ?? projects()[0],
-  )
+  const selectedProject = createMemo(() => projects().find((project) => project.worktree === state.project))
   const directories = (project: LocalProject) => [project.worktree, ...(project.sandboxes ?? [])]
   const projectDirectories = createMemo(() => {
     const project = selectedProject()
-    if (!project) return []
+    if (!project) return [...projects().flatMap((project) => directories(project))]
     return directories(project)
   })
   const search = createMemo(() => state.search.trim())
@@ -93,8 +91,8 @@ function HomeDesign() {
   const projectByID = createMemo(
     () => new Map(projects().flatMap((project) => (project.id ? [[project.id, project] as const] : []))),
   )
-  const records = createMemo(() =>
-    [
+  const records = createMemo(() => {
+    return [
       ...new Map(
         projectDirectories()
           .flatMap((directory) => sortedRootSessions(sync.child(directory, { bootstrap: false })[0], Date.now()))
@@ -116,8 +114,8 @@ function HomeDesign() {
         if (!value) return true
         return `${record.session.title} ${record.projectName}`.toLowerCase().includes(value)
       })
-      .slice(0, HOME_SESSION_LIMIT),
-  )
+      .slice(0, HOME_SESSION_LIMIT)
+  })
   const groups = createMemo(() => groupSessions(records(), language))
 
   function selectProject(directory: string) {
@@ -224,7 +222,7 @@ function HomeDesign() {
         aria-label={language.t("sidebar.project.recentSessions")}
       >
         <Show
-          when={selectedProject()}
+          when={projectDirectories().length > 0}
           fallback={
             <HomeEmptyState
               icon="folder-add-left"
@@ -302,8 +300,8 @@ function HomeProjectColumn(props: {
   const layout = useLayout()
   const projects = createMemo(() => layout.projects.list())
   return (
-    <aside class="flex min-w-0 flex-col lg:pt-[52px]" aria-label={props.language.t("home.projects")}>
-      <div class="flex h-7 min-w-0 items-center justify-between pl-3">
+    <aside class="flex min-w-0 flex-col lg:pt-[52px] gap-4" aria-label={props.language.t("home.projects")}>
+      <div class="flex h-7 min-w-0 items-center justify-between pl-1.5">
         <div class={HOME_SECTION_LABEL}>{props.language.t("home.projects")}</div>
         <IconButtonV2
           data-action="home-add-project"
@@ -315,8 +313,8 @@ function HomeProjectColumn(props: {
           aria-label={props.language.t("home.project.add")}
         />
       </div>
-      <For
-        each={servers.list()}
+      <Show
+        when={servers.list().length > 1}
         fallback={
           <ProjectList
             projects={projects()}
@@ -332,61 +330,63 @@ function HomeProjectColumn(props: {
           />
         }
       >
-        {(server) => {
-          const key = ServerConnection.key(server)
-          const healthy = () => !!servers.health[key]?.healthy
-          const [open, setOpen] = createSignal(true)
-
-          return (
-            <div class="mt-4 max-h-[min(572px,calc(100vh_-_300px))] min-w-0 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
-              <div class="relative h-7 group">
-                <button
-                  class="w-full h-full px-1.5 gap-2 flex flex-row items-center hover:not-disabled:bg-v2-overlay-simple-overlay-hover rounded-[4px]"
-                  disabled={!healthy()}
-                  onClick={() => setOpen((o) => !o)}
-                >
-                  <div class="size-4 flex items-center justify-center">
-                    <ServerHealthIndicator health={servers.health[key]} />
-                  </div>
-                  <div class="flex flex-row items-center gap-1">
-                    <span>{server.displayName ?? new URL(server.http.url).host}</span>
-                    <Show when={healthy()}>
-                      <IconV2
-                        name="outline-chevron-down"
-                        class="text-v2-icon-icon-muted data-[open=false]:-rotate-90"
-                        data-open={open()}
-                      />
-                    </Show>
-                  </div>
-                </button>
-                <IconButtonV2
-                  class="absolute right-1 inset-y-1 opacity-0 group-hover:opacity-100"
-                  name="out"
-                  variant="ghost-muted"
-                  size="small"
-                  icon={<IconV2 name="outline-dots" class="text-v2-icon-icon-muted" />}
-                />
+        <For each={servers.list()}>
+          {(server) => {
+            const key = ServerConnection.key(server)
+            const healthy = () => !!servers.health[key]?.healthy
+            const [open, setOpen] = createSignal(true)
+
+            return (
+              <div class="max-h-[min(572px,calc(100vh_-_300px))] min-w-0 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
+                <div class="relative h-7 group">
+                  <button
+                    class="w-full h-full px-1.5 gap-2 flex flex-row items-center hover:not-disabled:bg-v2-overlay-simple-overlay-hover rounded-[4px]"
+                    disabled={!healthy()}
+                    onClick={() => setOpen((o) => !o)}
+                  >
+                    <div class="size-4 flex items-center justify-center">
+                      <ServerHealthIndicator health={servers.health[key]} />
+                    </div>
+                    <div class="flex flex-row items-center gap-1">
+                      <span>{server.displayName ?? new URL(server.http.url).host}</span>
+                      <Show when={healthy()}>
+                        <IconV2
+                          name="outline-chevron-down"
+                          class="text-v2-icon-icon-muted data-[open=false]:-rotate-90"
+                          data-open={open()}
+                        />
+                      </Show>
+                    </div>
+                  </button>
+                  <IconButtonV2
+                    class="absolute right-1 inset-y-1 opacity-0 group-hover:opacity-100"
+                    name="out"
+                    variant="ghost-muted"
+                    size="small"
+                    icon={<IconV2 name="outline-dots" class="text-v2-icon-icon-muted" />}
+                  />
+                </div>
+                <Show when={healthy() && open()}>
+                  <div class="h-px bg-v2-border-border-base mx-3 my-1" />
+                  <ProjectList
+                    projects={projects()}
+                    selectedProject={props.selectedProject}
+                    onSelectedProjectChange={props.selectProject}
+                    onChooseProject={props.chooseProject}
+                    openNewSession={props.openNewSession}
+                    editProject={props.editProject}
+                    closeProject={props.closeProject}
+                    clearNotifications={props.clearNotifications}
+                    unseenCount={props.unseenCount}
+                    language={props.language}
+                  />
+                </Show>
               </div>
-              <Show when={healthy() && open()}>
-                <div class="h-px bg-v2-border-border-base mx-3 my-1" />
-                <ProjectList
-                  projects={projects()}
-                  selectedProject={props.selectedProject}
-                  onSelectedProjectChange={props.selectProject}
-                  onChooseProject={props.chooseProject}
-                  openNewSession={props.openNewSession}
-                  editProject={props.editProject}
-                  closeProject={props.closeProject}
-                  clearNotifications={props.clearNotifications}
-                  unseenCount={props.unseenCount}
-                  language={props.language}
-                />
-              </Show>
-            </div>
-          )
-        }}
-      </For>
-      <div class="mt-4 flex min-w-0 flex-col gap-1">
+            )
+          }}
+        </For>
+      </Show>
+      <div class="flex min-w-0 flex-col gap-1">
         <button
           type="button"
           class={`${HOME_PROJECT_NAV_ROW} text-v2-text-text-faint [&>[data-slot=icon-svg]]:text-v2-icon-icon-muted`}
@@ -420,12 +420,14 @@ function HomeProjectRow(props: {
   language: ReturnType<typeof useLanguage>
 }) {
   const name = createMemo(() => displayName(props.project))
+  const [menuOpen, setMenuOpen] = createSignal(false)
+
   return (
-    <div class="group/project relative flex h-8 min-w-0 items-center rounded-[6px] hover:bg-v2-overlay-simple-overlay-hover focus-within:bg-v2-overlay-simple-overlay-hover">
+    <div class="group/project relative flex h-8 min-w-0 items-center rounded-[6px]">
       <button
         type="button"
         data-component="home-project-row"
-        class={`${HOME_PROJECT_NAV_ROW} pr-16`}
+        class={`${HOME_PROJECT_NAV_ROW} pr-16 peer`}
         classList={{ "bg-v2-overlay-simple-overlay-hover": props.selected }}
         data-selected={props.selected ? "" : undefined}
         aria-current={props.selected ? "page" : undefined}
@@ -434,49 +436,48 @@ function HomeProjectRow(props: {
         <HomeProjectAvatar project={props.project} />
         <span>{name()}</span>
       </button>
-      <div class="absolute right-1 top-1/2 flex -translate-y-1/2 items-center gap-0.5 opacity-0 transition-opacity group-hover/project:opacity-100 group-focus-within/project:opacity-100">
-        <IconButtonV2
-          data-action="home-project-new-session"
-          variant="ghost-muted"
-          size="small"
-          icon={<IconV2 name="edit" />}
-          aria-label={props.language.t("command.session.new")}
-          onClick={(event) => {
-            event.stopPropagation()
-            props.openNewSession(props.project.worktree)
-          }}
-        />
-        <MenuV2 gutter={4} modal={false} placement="bottom-end">
+      <div
+        class="absolute right-1 top-1/2 flex -translate-y-1/2 items-center gap-0.5 opacity-0 transition-opacity group-hover/project:opacity-100 peer-focus-visible:opacity-100 focus-within:opacity-100 data-[menu=true]:opacity-100"
+        data-menu={menuOpen()}
+      >
+        <MenuV2 gutter={4} modal={false} placement="bottom-end" open={menuOpen()} onOpenChange={setMenuOpen}>
           <MenuV2.Trigger
             as={IconButtonV2}
             data-action="home-project-menu"
             variant="ghost-muted"
             size="small"
-            icon={<IconV2 name="menu" />}
+            icon={<IconV2 name="outline-dots" />}
             aria-label={props.language.t("common.moreOptions")}
           />
           <MenuV2.Portal>
             <MenuV2.Content>
               <MenuV2.Item onSelect={() => props.openNewSession(props.project.worktree)}>
-                <Icon name="new-session" size="small" />
                 {props.language.t("command.session.new")}
               </MenuV2.Item>
               <MenuV2.Item onSelect={() => props.editProject(props.project)}>
-                <Icon name="edit" size="small" />
                 {props.language.t("common.edit")}
               </MenuV2.Item>
               <MenuV2.Item disabled={props.unseenCount === 0} onSelect={() => props.clearNotifications(props.project)}>
-                <Icon name="circle-check" size="small" />
                 {props.language.t("sidebar.project.clearNotifications")}
               </MenuV2.Item>
               <MenuV2.Separator />
               <MenuV2.Item onSelect={() => props.closeProject(props.project.worktree)}>
-                <Icon name="close" size="small" />
                 {props.language.t("common.close")}
               </MenuV2.Item>
             </MenuV2.Content>
           </MenuV2.Portal>
         </MenuV2>
+        <IconButtonV2
+          data-action="home-project-new-session"
+          variant="ghost-muted"
+          size="small"
+          icon={<IconV2 name="edit" />}
+          aria-label={props.language.t("command.session.new")}
+          onClick={(event) => {
+            event.stopPropagation()
+            props.openNewSession(props.project.worktree)
+          }}
+        />
       </div>
     </div>
   )
@@ -565,7 +566,7 @@ function HomeSessionGroupHeader(props: { title: string; onNewSession?: () => voi
             variant="ghost"
             size="normal"
             icon="edit"
-            class="h-7 px-2 text-v2-text-text-muted [font-weight:530]"
+            class="h-7 px-2 text-v2-text-text-muted"
             onClick={onNewSession()}
           >
             {language.t("command.session.new")}

+ 1 - 1
packages/ui/src/v2/components/accordion-v2.css

@@ -15,7 +15,7 @@
   box-shadow: 0 0 0 0.5px var(--accordion-v2-border);
   overflow: hidden;
 
-  font-family: var(--font-family-sans), "Inter", system-ui, sans-serif;
+  font-family: var(--v2-font-family-sans), "Inter", system-ui, sans-serif;
   color: var(--accordion-v2-fg);
 
   -webkit-font-smoothing: antialiased;

+ 1 - 1
packages/ui/src/v2/components/accordion-v2.stories.tsx

@@ -32,7 +32,7 @@ export default {
   },
 }
 
-const frame = { width: "346px", "font-family": "var(--font-family-sans)", "font-size": "13px" } as const
+const frame = { width: "346px", "font-family": "var(--v2-font-family-sans)", "font-size": "13px" } as const
 
 export const Basic = {
   render: () => (

+ 1 - 1
packages/ui/src/v2/components/avatar-v2.css

@@ -14,7 +14,7 @@
   height: 28px;
   border-radius: var(--avatar-radius);
   border: 0.5px solid var(--v2-border-border-base);
-  font-family: var(--font-family-sans);
+  font-family: var(--v2-font-family-sans);
   font-weight: 530;
   font-size: var(--avatar-font-size);
   line-height: 1;

+ 1 - 1
packages/ui/src/v2/components/badge-v2.css

@@ -13,7 +13,7 @@
   border: 0.5px solid var(--border-border-base);
   background: var(--background-bg-layer-02);
 
-  font-family: var(--font-family-sans);
+  font-family: var(--v2-font-family-sans);
   font-style: normal;
   font-weight: 530;
   font-size: 11px;

+ 1 - 1
packages/ui/src/v2/components/basic-tool-v2.css

@@ -21,7 +21,7 @@
   gap: 8px;
   min-width: 0;
   width: 100%;
-  font-family: var(--font-family-sans), var(--sans), system-ui, sans-serif;
+  font-family: var(--v2-font-family-sans), var(--sans), system-ui, sans-serif;
   font-variant-numeric: tabular-nums;
 
   [data-slot="basic-tool-v2-trigger"] {

+ 1 - 1
packages/ui/src/v2/components/button-v2.css

@@ -11,7 +11,7 @@
   justify-content: center;
   gap: 6px;
   border-radius: 6px;
-  font-family: var(--font-family-sans);
+  font-family: var(--v2-font-family-sans);
   font-style: normal;
   font-weight: 530;
   font-size: 13px;

+ 3 - 3
packages/ui/src/v2/components/checkbox-v2.css

@@ -10,7 +10,7 @@
 
   [data-slot="checkbox-v2-error"] {
     color: var(--state-fg-danger);
-    font-family: var(--font-family-sans);
+    font-family: var(--v2-font-family-sans);
     font-size: 12px;
     font-weight: var(--font-weight-regular);
     line-height: var(--line-height-normal);
@@ -90,7 +90,7 @@
     display: inline-flex;
     user-select: none;
     color: inherit;
-    font-family: var(--font-family-sans);
+    font-family: var(--v2-font-family-sans);
     font-style: normal;
     font-weight: 440;
     font-variant-numeric: tabular-nums;
@@ -109,7 +109,7 @@
 
   [data-slot="checkbox-v2-description"] {
     color: var(--text-text-muted);
-    font-family: var(--font-family-sans);
+    font-family: var(--v2-font-family-sans);
     font-size: 11px;
     font-weight: 440;
     line-height: 1;

+ 1 - 1
packages/ui/src/v2/components/checkbox-v2.stories.tsx

@@ -49,7 +49,7 @@ export const Controlled = {
           label="Controlled checkbox"
           description="Toggled from Storybook state."
         />
-        <div style={{ "font-family": "var(--font-family-sans)", "font-size": "12px", color: "#808080" }}>
+        <div style={{ "font-family": "var(--v2-font-family-sans)", "font-size": "12px", color: "#808080" }}>
           Checked: {String(checked())}
         </div>
       </div>

+ 2 - 2
packages/ui/src/v2/components/dialog-v2.css

@@ -64,7 +64,7 @@
 
         [data-slot="dialog-title"] {
           margin: 0;
-          font-family: "Inter", var(--font-family-sans);
+          font-family: "Inter", var(--v2-font-family-sans);
           font-weight: 530;
           font-size: 15px;
           line-height: 100%;
@@ -74,7 +74,7 @@
         }
 
         [data-slot="dialog-description"] {
-          font-family: "Inter", var(--font-family-sans);
+          font-family: "Inter", var(--v2-font-family-sans);
           font-weight: 440;
           font-size: 13px;
           line-height: 100%;

+ 1 - 1
packages/ui/src/v2/components/diff-changes-v2.css

@@ -6,7 +6,7 @@
 
   [data-slot="diff-changes-additions"],
   [data-slot="diff-changes-deletions"] {
-    font-family: var(--font-family-sans);
+    font-family: var(--v2-font-family-sans);
     font-size: 11px;
     font-style: normal;
     font-weight: 440;

+ 2 - 2
packages/ui/src/v2/components/field-v2.css

@@ -17,7 +17,7 @@
   margin: 0;
   padding: 0;
   border: 0;
-  font-family: var(--font-family-sans);
+  font-family: var(--v2-font-family-sans);
   font-style: normal;
   font-weight: 530;
   font-size: 13px;
@@ -76,7 +76,7 @@
   align-self: stretch;
   width: 100%;
   min-height: 11px;
-  font-family: var(--font-family-sans);
+  font-family: var(--v2-font-family-sans);
   font-style: normal;
   font-weight: 440;
   font-size: 11px;

+ 2 - 2
packages/ui/src/v2/components/inline-input-v2.css

@@ -81,7 +81,7 @@
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
-  font-family: var(--font-family-sans);
+  font-family: var(--v2-font-family-sans);
   font-style: normal;
   font-weight: 440;
   font-size: 13px;
@@ -138,7 +138,7 @@
   border: 0;
   background: transparent;
   outline: none;
-  font-family: var(--font-family-sans);
+  font-family: var(--v2-font-family-sans);
   font-style: normal;
   font-weight: 440;
   font-size: 13px;

+ 1 - 1
packages/ui/src/v2/components/inline-input-v2.stories.tsx

@@ -86,7 +86,7 @@ export const Controlled = {
         />
         <div
           style={{
-            "font-family": "var(--font-family-sans)",
+            "font-family": "var(--v2-font-family-sans)",
             "font-size": "12px",
             color: "var(--text-text-faint)",
           }}

+ 2 - 2
packages/ui/src/v2/components/keybind-v2.css

@@ -6,7 +6,7 @@
 
 [data-component="keybind-v2"] {
   box-sizing: border-box;
-  font-family: var(--font-family-sans), var(--sans), system-ui, sans-serif;
+  font-family: var(--v2-font-family-sans), var(--sans), system-ui, sans-serif;
   font-variant-numeric: tabular-nums;
   display: inline-flex;
   flex-direction: row;
@@ -53,7 +53,7 @@
   padding: 0px;
   flex: 1 1 auto;
   align-self: stretch;
-  font-family: "Inter", var(--font-family-sans), var(--sans), system-ui, sans-serif;
+  font-family: "Inter", var(--v2-font-family-sans), var(--sans), system-ui, sans-serif;
   font-style: normal;
   font-weight: 530;
   font-size: 11px;

+ 1 - 1
packages/ui/src/v2/components/line-comment-v2.css

@@ -6,7 +6,7 @@
 
 [data-component="line-comment-v2"] {
   box-sizing: border-box;
-  font-family: var(--font-family-sans), var(--sans), system-ui, sans-serif;
+  font-family: var(--v2-font-family-sans), var(--sans), system-ui, sans-serif;
   font-variant-numeric: tabular-nums;
   min-width: 0;
   width: 100%;

+ 9 - 9
packages/ui/src/v2/components/menu-v2.css

@@ -6,12 +6,12 @@
   padding: 2px;
   min-width: 160px;
 
-  background: var(--background-bg-layer-01);
+  background: var(--v2-background-bg-layer-01);
   border-radius: 6px;
-  box-shadow: var(--elevation-floating);
+  box-shadow: var(--v2-elevation-floating);
 
   outline: none;
-  font-family: var(--font-family-sans), "Inter", system-ui, sans-serif;
+  font-family: var(--v2-font-family-sans), "Inter", system-ui, sans-serif;
 
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
@@ -31,9 +31,9 @@
   --menu-v2-fg-subtle: var(--text-text-muted);
   --menu-v2-icon: var(--icon-icon-base);
   --menu-v2-accent: var(--text-text-accent);
-  --menu-v2-badge-bg: var(--background-bg-layer-02);
-  --menu-v2-badge-border: var(--border-border-base);
-  --menu-v2-hover: var(--overlay-simple-overlay-hover);
+  --menu-v2-badge-bg: var(--v2-background-bg-layer-02);
+  --menu-v2-badge-border: var(--v2-border-border-base);
+  --menu-v2-hover: var(--v2-overlay-simple-overlay-hover);
 
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
@@ -52,7 +52,7 @@
   cursor: default;
   user-select: none;
 
-  font-family: var(--font-family-sans), "Inter", system-ui, sans-serif;
+  font-family: var(--v2-font-family-sans), "Inter", system-ui, sans-serif;
   font-variation-settings: "slnt" 0;
   font-variant-numeric: tabular-nums;
   color: var(--menu-v2-fg);
@@ -153,7 +153,7 @@
   height: 1px;
   width: calc(100% + 4px);
   margin: 2px -2px;
-  background: var(--border-border-muted);
+  background: var(--v2-border-border-muted);
   border: none;
 }
 
@@ -164,7 +164,7 @@
   height: 28px;
   padding: 0 12px;
 
-  font-family: var(--font-family-sans), "Inter", system-ui, sans-serif;
+  font-family: var(--v2-font-family-sans), "Inter", system-ui, sans-serif;
   font-size: 11px;
   font-weight: 530;
   line-height: 100%;

+ 1 - 1
packages/ui/src/v2/components/menu-v2.stories.tsx

@@ -179,7 +179,7 @@ export const Context = {
             border: "1px dashed rgba(0, 0, 0, 0.2)",
             color: "#5c5c5c",
             "font-size": "13px",
-            "font-family": "var(--font-family-sans)",
+            "font-family": "var(--v2-font-family-sans)",
             "user-select": "none",
           }}
         >

+ 5 - 5
packages/ui/src/v2/components/radio-v2.css

@@ -9,7 +9,7 @@
     align-items: center;
     user-select: none;
     color: var(--text-text-faint);
-    font-family: var(--font-family-sans);
+    font-family: var(--v2-font-family-sans);
     font-size: 11px;
     font-style: normal;
     font-weight: 440;
@@ -20,7 +20,7 @@
 
   [data-slot="radio-v2-description"] {
     color: var(--text-text-faint);
-    font-family: var(--font-family-sans);
+    font-family: var(--v2-font-family-sans);
     font-size: 11px;
     font-weight: 440;
     line-height: 1.2;
@@ -35,7 +35,7 @@
 
   [data-slot="radio-v2-error"] {
     color: var(--state-fg-danger);
-    font-family: var(--font-family-sans);
+    font-family: var(--v2-font-family-sans);
     font-size: 12px;
     font-weight: var(--font-weight-regular);
     line-height: var(--line-height-normal);
@@ -167,7 +167,7 @@
     display: inline-flex;
     user-select: none;
     color: inherit;
-    font-family: var(--font-family-sans);
+    font-family: var(--v2-font-family-sans);
     font-style: normal;
     font-weight: 440;
     font-variant-numeric: tabular-nums;
@@ -186,7 +186,7 @@
 
   [data-slot="radio-v2-item-description"] {
     color: var(--text-text-muted);
-    font-family: var(--font-family-sans);
+    font-family: var(--v2-font-family-sans);
     font-size: 11px;
     font-weight: 440;
     line-height: 1;

+ 1 - 1
packages/ui/src/v2/components/radio-v2.stories.tsx

@@ -50,7 +50,7 @@ export const Controlled = {
           <RadioItemV2 value="weekly" label="Weekly" />
           <RadioItemV2 value="never" label="Never" />
         </RadioGroupV2>
-        <div style={{ "font-family": "var(--font-family-sans)", "font-size": "12px", color: "#808080" }}>
+        <div style={{ "font-family": "var(--v2-font-family-sans)", "font-size": "12px", color: "#808080" }}>
           Selected: {value()}
         </div>
       </div>

+ 1 - 1
packages/ui/src/v2/components/segmented-control-v2.css

@@ -34,7 +34,7 @@
   background: transparent;
   box-shadow: none;
   cursor: pointer;
-  font-family: var(--font-family-sans), var(--sans);
+  font-family: var(--v2-font-family-sans), var(--sans);
   font-style: normal;
   font-weight: 440;
   font-size: 13px;

+ 2 - 2
packages/ui/src/v2/components/segmented-control-v2.stories.tsx

@@ -56,7 +56,7 @@ export const Controlled = {
           <SegmentedControlItemV2 value="b">Grid</SegmentedControlItemV2>
           <SegmentedControlItemV2 value="c">Board</SegmentedControlItemV2>
         </SegmentedControlV2>
-        <div style={{ "font-family": "var(--font-family-sans)", "font-size": "12px", color: "#808080" }}>
+        <div style={{ "font-family": "var(--v2-font-family-sans)", "font-size": "12px", color: "#808080" }}>
           Value: {value()}
         </div>
       </div>
@@ -74,7 +74,7 @@ export const AllowDeselect = {
           <SegmentedControlItemV2 value="b">B</SegmentedControlItemV2>
           <SegmentedControlItemV2 value="c">C</SegmentedControlItemV2>
         </SegmentedControlV2>
-        <div style={{ "font-family": "var(--font-family-sans)", "font-size": "12px", color: "#808080" }}>
+        <div style={{ "font-family": "var(--v2-font-family-sans)", "font-size": "12px", color: "#808080" }}>
           Value: {value() === null ? "none" : value()}
         </div>
       </div>

+ 1 - 1
packages/ui/src/v2/components/select-v2.css

@@ -110,7 +110,7 @@
   background: transparent;
   outline: none;
   text-align: left;
-  font-family: var(--font-family-sans);
+  font-family: var(--v2-font-family-sans);
   font-style: normal;
   font-weight: 440;
   font-size: 13px;

+ 2 - 2
packages/ui/src/v2/components/switch-v2.css

@@ -65,7 +65,7 @@
     height: 16px;
     user-select: none;
     color: var(--text-text-faint);
-    font-family: var(--font-family-sans);
+    font-family: var(--v2-font-family-sans);
     font-size: 11px;
     font-style: normal;
     font-weight: 440;
@@ -76,7 +76,7 @@
 
   [data-slot="switch-error"] {
     color: var(--state-fg-danger);
-    font-family: var(--font-family-sans);
+    font-family: var(--v2-font-family-sans);
     font-size: 12px;
     font-weight: var(--font-weight-regular);
     line-height: var(--line-height-normal);

+ 1 - 1
packages/ui/src/v2/components/tabs-v2.css

@@ -9,7 +9,7 @@
   height: 100%;
   display: flex;
   overflow: clip;
-  font-family: var(--font-family-sans);
+  font-family: var(--v2-font-family-sans);
 }
 
 [data-component="tabs-v2"][data-orientation="horizontal"] {

+ 1 - 1
packages/ui/src/v2/components/text-input-v2.css

@@ -67,7 +67,7 @@
   border: 0;
   background: transparent;
   outline: none;
-  font-family: var(--font-family-sans);
+  font-family: var(--v2-font-family-sans);
   font-style: normal;
   font-weight: 440;
   font-size: 13px;

+ 1 - 1
packages/ui/src/v2/components/text-input-v2.stories.tsx

@@ -85,7 +85,7 @@ export const Controlled = {
         <TextInputV2 value={value()} onInput={(e) => setValue(e.currentTarget.value)} placeholder="Type here…" />
         <div
           style={{
-            "font-family": "var(--font-family-sans)",
+            "font-family": "var(--v2-font-family-sans)",
             "font-size": "12px",
             color: "var(--text-text-faint)",
           }}

+ 1 - 1
packages/ui/src/v2/components/textarea-v2.css

@@ -53,7 +53,7 @@
   background: transparent;
   outline: none;
   resize: vertical;
-  font-family: var(--font-family-sans);
+  font-family: var(--v2-font-family-sans);
   font-style: normal;
   font-weight: 440;
   font-size: 13px;

+ 1 - 1
packages/ui/src/v2/components/textarea-v2.stories.tsx

@@ -66,7 +66,7 @@ export const Controlled = {
         <TextareaV2 value={value()} onInput={(e) => setValue(e.currentTarget.value)} placeholder="Type here…" />
         <div
           style={{
-            "font-family": "var(--font-family-sans)",
+            "font-family": "var(--v2-font-family-sans)",
             "font-size": "12px",
             color: "var(--text-text-faint)",
           }}

+ 1 - 1
packages/ui/src/v2/components/tool-error-card-v2.css

@@ -16,7 +16,7 @@
   padding: 0 0 0 10px;
   gap: 8px;
   border-left: 2px solid var(--tec-border);
-  font-family: var(--font-family-sans), var(--sans), system-ui, sans-serif;
+  font-family: var(--v2-font-family-sans), var(--sans), system-ui, sans-serif;
   font-variant-numeric: tabular-nums;
 
   [data-slot="tool-error-card-trigger"] {

+ 1 - 0
packages/ui/src/v2/styles/theme.css

@@ -94,6 +94,7 @@
     --v2-illustration-illustration-layer-03: var(--v2-grey-500);
 
     --font-family-text: "Inter", sans-serif;
+    --v2-font-family-sans: "Inter", sans-serif;
   }
 
   /* OS preference fallback (no JS needed) */