From 9f5ebf27cfaa84ce7087d22e859a63d4559b1bdd Mon Sep 17 00:00:00 2001 From: Max Barvian Date: Fri, 28 Aug 2026 13:04:29 -0700 Subject: [PATCH 1/7] init google sans flex --- LICENSE | 2 +- NOTICE | 19 +++---- README.md | 2 +- app/components/AppShell.tsx | 2 +- app/components/ui/AnimatedBaseLogo.tsx | 4 +- app/components/ui/Button.tsx | 2 +- app/components/ui/Tabs.tsx | 2 +- app/components/ui/Text.tsx | 28 +++++------ app/globals.css | 12 ++++- app/internal-explorer/page.tsx | 2 +- app/layout.tsx | 47 ++++-------------- app/theme.ts | 4 +- app/upgrades/components/Badges.tsx | 6 +-- app/vibenet/components/ExplorerSearch.tsx | 2 +- app/vibenet/demos/_components/DemoTabs.tsx | 2 +- app/vibenet/demos/_shared/primitives.tsx | 2 +- .../account/components/CreateAccountModal.tsx | 6 +-- .../b20/components/AssignPolicyModal.tsx | 2 +- .../demos/b20/components/GasModule.tsx | 2 +- app/vibenet/faucet/page.tsx | 2 +- public/fonts/BaseSans/BaseSans-Bold.woff | Bin 46020 -> 0 bytes .../fonts/BaseSans/BaseSans-BoldItalic.woff | Bin 48708 -> 0 bytes public/fonts/BaseSans/BaseSans-Italic.woff | Bin 47880 -> 0 bytes .../fonts/BaseSans/BaseSans-ItalicText.woff | Bin 55860 -> 0 bytes public/fonts/BaseSans/BaseSans-Medium.woff | Bin 42608 -> 0 bytes public/fonts/BaseSans/BaseSans-Medium.woff2 | Bin 44616 -> 0 bytes .../fonts/BaseSans/BaseSans-MediumItalic.woff | Bin 45744 -> 0 bytes public/fonts/BaseSans/BaseSans-Regular.woff | Bin 44952 -> 0 bytes public/fonts/BaseSans/BaseSans-Regular.woff2 | Bin 45672 -> 0 bytes .../fonts/BaseSans/BaseSans-RegularText.woff | Bin 54152 -> 0 bytes .../BaseSansMono/BaseSansMono-Medium.woff2 | Bin 23904 -> 0 bytes .../BaseSansMono/BaseSansMono-Regular.woff2 | Bin 24656 -> 0 bytes .../GoogleSansFlex-Variable.ttf | Bin 0 -> 3997148 bytes tailwind.config.ts | 7 +-- 34 files changed, 68 insertions(+), 89 deletions(-) delete mode 100644 public/fonts/BaseSans/BaseSans-Bold.woff delete mode 100644 public/fonts/BaseSans/BaseSans-BoldItalic.woff delete mode 100644 public/fonts/BaseSans/BaseSans-Italic.woff delete mode 100644 public/fonts/BaseSans/BaseSans-ItalicText.woff delete mode 100644 public/fonts/BaseSans/BaseSans-Medium.woff delete mode 100644 public/fonts/BaseSans/BaseSans-Medium.woff2 delete mode 100644 public/fonts/BaseSans/BaseSans-MediumItalic.woff delete mode 100644 public/fonts/BaseSans/BaseSans-Regular.woff delete mode 100644 public/fonts/BaseSans/BaseSans-Regular.woff2 delete mode 100644 public/fonts/BaseSans/BaseSans-RegularText.woff delete mode 100644 public/fonts/BaseSansMono/BaseSansMono-Medium.woff2 delete mode 100644 public/fonts/BaseSansMono/BaseSansMono-Regular.woff2 create mode 100644 public/fonts/GoogleSansFlex/GoogleSansFlex-Variable.ttf diff --git a/LICENSE b/LICENSE index fb9304d..3865f3d 100644 --- a/LICENSE +++ b/LICENSE @@ -3,7 +3,7 @@ MIT License Copyright (c) 2026 Base NOTE: Some files in this repository are excluded from this license. See NOTICE -for the exceptions, which include the Base Sans brand typefaces under +for the exceptions, which include the Google Sans Flex typeface under public/fonts/, and for third-party attribution. Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/NOTICE b/NOTICE index 29d8a39..be1abfb 100644 --- a/NOTICE +++ b/NOTICE @@ -6,19 +6,16 @@ exceptions listed below. Where this file and LICENSE disagree, this file governs for the files it names. -Base Sans and Base Sans Mono (brand typefaces) — NOT MIT licensed ------------------------------------------------------------------ +Google Sans Flex (UI typeface) — NOT MIT licensed +------------------------------------------------- - public/fonts/BaseSans/* - public/fonts/BaseSansMono/* + public/fonts/GoogleSansFlex/* -These typefaces are Base's proprietary brand assets. Copyright (c) Base. All -rights reserved. - -They are included in this repository solely so that this application renders -with correct branding. They are NOT covered by the MIT license in LICENSE, and -no license to them is granted by it. You may not copy, redistribute, embed, -modify, sublicense, or otherwise use these font files outside of this project. +This typeface is a proprietary Google font, included here solely so that this +application renders with the same UI sans as the Base dashboard. It is NOT +covered by the MIT license in LICENSE, and no license to it is granted by it. +You may not copy, redistribute, embed, modify, sublicense, or otherwise use +these font files outside of this project. If you fork this repository or reuse its code, remove these files and substitute your own typeface. Note that they are loaded via next/font/local in diff --git a/README.md b/README.md index d0aefdb..478bdf2 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ outside this repo at the org/platform level. - `vibenet/` — devnet explorer and faucet - `components/` — shared shell and UI primitives - `theme.ts` / `spectrum.ts` / `globals.css` — BDS design tokens -- `public/` — Base Sans fonts and images +- `public/` — Google Sans Flex, Doto, and images ## Environment diff --git a/app/components/AppShell.tsx b/app/components/AppShell.tsx index e47b283..7815d67 100644 --- a/app/components/AppShell.tsx +++ b/app/components/AppShell.tsx @@ -892,7 +892,7 @@ export function AppShell({ children }: PropsWithChildren) { - + ); } diff --git a/app/components/ui/AnimatedBaseLogo.tsx b/app/components/ui/AnimatedBaseLogo.tsx index 5afa548..af178bc 100644 --- a/app/components/ui/AnimatedBaseLogo.tsx +++ b/app/components/ui/AnimatedBaseLogo.tsx @@ -8,7 +8,7 @@ import { CSSProperties, SVGProps, useCallback, useRef } from 'react'; /** * The animated Base logo from base.org: hovering the square splits it into four * squares, springs up an SVG "b" glyph, spells `base` in dot-matrix Doto, then - * resolves each character into Base Sans via a 5x5 pixel-grid shuffle. + * resolves each character into the UI sans via a 5x5 pixel-grid shuffle. * * Ported from the base.org web app: * apps/web/app/(current)/components/illustration/AnimatedLogo.tsx @@ -610,7 +610,7 @@ function Logo({ size, color }: { size: number; color?: string }) { {/* normal */}
b diff --git a/app/components/ui/Button.tsx b/app/components/ui/Button.tsx index 9d4bc82..eebcb3c 100644 --- a/app/components/ui/Button.tsx +++ b/app/components/ui/Button.tsx @@ -50,7 +50,7 @@ export const Button = forwardRef(function Button } const classes = cn( - 'group flex whitespace-nowrap w-fit active:scale-[0.96] transition-[background-color,border-color,color,transform] duration-150 ease-out max-w-full items-center justify-center rounded-full font-sans sm:w-auto', + 'group flex whitespace-nowrap w-fit active:scale-[0.96] transition-[background-color,border-color,color,transform] duration-150 ease-out max-w-full items-center justify-center rounded-full sm:w-auto', sizeClasses, size === 'sm' ? textVariantClasses.label : textVariantClasses.button, 'md:leading-[20px]', diff --git a/app/components/ui/Tabs.tsx b/app/components/ui/Tabs.tsx index 4d052a9..7591468 100644 --- a/app/components/ui/Tabs.tsx +++ b/app/components/ui/Tabs.tsx @@ -54,7 +54,7 @@ export function Tabs({ onClick={() => !item.disabled && onChange(item.value)} disabled={item.disabled} className={cn( - 'relative flex shrink-0 select-none items-center gap-1.5 rounded-full font-sans whitespace-nowrap transition-colors', + 'relative flex shrink-0 select-none items-center gap-1.5 rounded-full whitespace-nowrap transition-colors', size === 'sm' ? 'px-2.5 py-1 text-[12px]' : 'px-3 py-1.5 text-[14px]', item.disabled ? 'cursor-not-allowed text-bds-gray-40' diff --git a/app/components/ui/Text.tsx b/app/components/ui/Text.tsx index 984e767..196b1df 100644 --- a/app/components/ui/Text.tsx +++ b/app/components/ui/Text.tsx @@ -2,8 +2,8 @@ import type { ComponentPropsWithoutRef } from 'react'; import { cn } from './cn'; -// Typographic scale ported from the Base Design System (BDS) so migrated Upgrades markup keeps -// its variants in both color modes. +// Sizes stay on this site's scale. Weights match the dashboard type tokens so +// Google Sans Flex (a variable face) renders the same as there. type TextVariant = | 'display' | 'stats' @@ -32,29 +32,29 @@ type TextProps = ComponentPropsWithoutRef<'p'> & { export const textVariantClasses: Record = { display: - 'text-[36px] sm:text-[40px] md:text-[56px] leading-[40px] sm:leading-[48px] md:leading-[64px] font-base font-[400] tracking-[-0.04em]', + 'text-[36px] sm:text-[40px] md:text-[56px] leading-[40px] sm:leading-[48px] md:leading-[64px] font-[550] tracking-[-0.04em]', stats: - 'text-[24px] sm:text-[32px] md:text-[40px] leading-[28px] sm:leading-[36px] md:leading-[48px] font-base font-[400] tracking-[0px]', + 'text-[24px] sm:text-[32px] md:text-[40px] leading-[28px] sm:leading-[36px] md:leading-[48px] font-[550] tracking-[0px]', title1: - 'text-[28px] md:text-[36px] leading-[34px] md:leading-[44px] font-base font-[400] tracking-tight', + 'text-[28px] md:text-[36px] leading-[34px] md:leading-[44px] font-[528] tracking-tight', title2: - 'text-[20px] md:text-[24px] leading-[28px] md:leading-[32px] font-base font-[400] tracking-tight', + 'text-[20px] md:text-[24px] leading-[28px] md:leading-[32px] font-[525] tracking-tight', title3: - 'text-[18px] md:text-[20px] leading-[26px] md:leading-[28px] font-base font-[400] tracking-tight', + 'text-[18px] md:text-[20px] leading-[26px] md:leading-[28px] font-[525] tracking-tight', headline: - 'text-[16px] md:text-[18px] leading-[24px] md:leading-[26px] font-base font-[400] tracking-tight', - body: 'text-[15px] md:text-[16px] leading-[140%] font-base-text font-[400] tracking-[0px]', + 'text-[16px] md:text-[18px] leading-[24px] md:leading-[26px] font-[520] tracking-tight', + body: 'text-[15px] md:text-[16px] leading-[140%] font-[425] tracking-[0px]', label: - 'text-[13px] md:text-[14px] leading-[18px] md:leading-[20px] font-base font-[400] tracking-[-0.01em]', + 'text-[13px] md:text-[14px] leading-[18px] md:leading-[20px] font-[535] tracking-[-0.01em]', 'label.medium': - 'text-[13px] md:text-[14px] leading-[18px] md:leading-[20px] font-base font-[400] tracking-[0px]', + 'text-[13px] md:text-[14px] leading-[18px] md:leading-[20px] font-[535] tracking-[0px]', 'label.regular': - 'text-[13px] md:text-[14px] leading-[20px] font-base-text font-[400] tracking-[0px]', + 'text-[13px] md:text-[14px] leading-[20px] font-[400] tracking-[0px]', 'label.mono': 'text-[13px] md:text-[14px] leading-[18px] md:leading-[20px] font-mono font-[400] tracking-[0px]', caption: - 'text-[11px] md:text-[12px] leading-[14px] md:leading-[16px] font-[500] tracking-[0px] uppercase', - button: 'text-[14px] leading-[20px] font-base font-[400] tracking-[-0.01em]', + 'text-[11px] md:text-[12px] leading-[14px] md:leading-[16px] font-[535] tracking-[0px] uppercase', + button: 'text-[14px] leading-[20px] font-[520] tracking-[-0.01em]', footnote: 'text-[11px] md:text-[12px] leading-[14px] md:leading-[16px] font-[400] tracking-[0px]', }; diff --git a/app/globals.css b/app/globals.css index 8a801e2..0a90254 100644 --- a/app/globals.css +++ b/app/globals.css @@ -388,7 +388,7 @@ body { body { font-family: - var(--font-base-sans), + var(--font-google-sans-flex), -apple-system, BlinkMacSystemFont, 'Segoe UI', @@ -396,12 +396,22 @@ body { Helvetica, Arial, sans-serif; + /* Same axes as the dashboard UI sans so Google Sans Flex matches there. */ + font-variation-settings: 'wdth' 101, 'GRAD' 0, 'ROND' 30, 'slnt' 0; color: var(--bds-gray-100); background: var(--bds-gray-0); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } +.font-mono, +code, +pre, +kbd, +samp { + font-variation-settings: normal; +} + a { color: inherit; } diff --git a/app/internal-explorer/page.tsx b/app/internal-explorer/page.tsx index 096fc5d..603e843 100644 --- a/app/internal-explorer/page.tsx +++ b/app/internal-explorer/page.tsx @@ -81,7 +81,7 @@ function SearchBar({ chain, onError }: { chain: ExplorerChain; onError: (error: spellCheck={false} autoComplete="off" className={cn( - 'w-full rounded-full border border-bds-gray-10 bg-bds-gray-0 py-3 pl-9 font-sans text-sm text-foreground outline-none transition-colors placeholder:text-bds-gray-40 focus:border-foreground dark:border-white/10 dark:bg-white/5 dark:text-white dark:focus:border-bds-blue-40', + 'w-full rounded-full border border-bds-gray-10 bg-bds-gray-0 py-3 pl-9 text-sm text-foreground outline-none transition-colors placeholder:text-bds-gray-40 focus:border-foreground dark:border-white/10 dark:bg-white/5 dark:text-white dark:focus:border-bds-blue-40', searchHash.trim() ? 'pr-24' : 'pr-3.5', )} /> diff --git a/app/layout.tsx b/app/layout.tsx index b977a41..ee9b2ee 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,57 +2,32 @@ import './globals.css'; import { PropsWithChildren } from 'react'; import localFont from 'next/font/local'; +import { Roboto_Mono } from 'next/font/google'; import { Analytics } from '@vercel/analytics/next'; import { AppShell } from './components/AppShell'; -const baseSansMono = localFont({ +const googleSansFlex = localFont({ src: [ { - path: '../public/fonts/BaseSansMono/BaseSansMono-Regular.woff2', - weight: '400', - style: 'normal', - }, - { - path: '../public/fonts/BaseSansMono/BaseSansMono-Medium.woff2', - weight: '500', + path: '../public/fonts/GoogleSansFlex/GoogleSansFlex-Variable.ttf', + weight: '100 1000', style: 'normal', }, ], - variable: '--font-base-sans-mono', + variable: '--font-google-sans-flex', display: 'swap', - adjustFontFallback: false, }); -const baseSansText = localFont({ - src: [ - { path: '../public/fonts/BaseSans/BaseSans-RegularText.woff', weight: '400', style: 'normal' }, - { path: '../public/fonts/BaseSans/BaseSans-ItalicText.woff', weight: '400', style: 'italic' }, - ], - variable: '--font-base-sans-text', - display: 'swap', - adjustFontFallback: 'Arial', -}); - -const baseSans = localFont({ - src: [ - { path: '../public/fonts/BaseSans/BaseSans-Regular.woff2', weight: '400', style: 'normal' }, - { path: '../public/fonts/BaseSans/BaseSans-Regular.woff', weight: '400', style: 'normal' }, - { path: '../public/fonts/BaseSans/BaseSans-Italic.woff', weight: '400', style: 'italic' }, - { path: '../public/fonts/BaseSans/BaseSans-Medium.woff2', weight: '500', style: 'normal' }, - { path: '../public/fonts/BaseSans/BaseSans-Medium.woff', weight: '500', style: 'normal' }, - { path: '../public/fonts/BaseSans/BaseSans-MediumItalic.woff', weight: '500', style: 'italic' }, - { path: '../public/fonts/BaseSans/BaseSans-Bold.woff', weight: '700', style: 'normal' }, - { path: '../public/fonts/BaseSans/BaseSans-BoldItalic.woff', weight: '700', style: 'italic' }, - ], - variable: '--font-base-sans', +const robotoMono = Roboto_Mono({ + subsets: ['latin'], + variable: '--font-roboto-mono', display: 'swap', - adjustFontFallback: 'Arial', }); // Dot-matrix face used only by the animated Base logo, where the wordmark first -// spells out in dots before resolving into Base Sans. Same binary base.org ships -// (a variable TTF instanced to Doto Black), so the two render identically. +// spells out in dots before resolving into the UI sans. Same binary base.org +// ships (a variable TTF instanced to Doto Black), so the two render identically. const doto = localFont({ src: '../public/fonts/Doto/Doto-Black.ttf', variable: '--font-doto', @@ -88,7 +63,7 @@ export default function RootLayout({ children }: PropsWithChildren) { return ( diff --git a/app/theme.ts b/app/theme.ts index caf45a5..10769ec 100644 --- a/app/theme.ts +++ b/app/theme.ts @@ -46,5 +46,5 @@ export const WARNING_TEXT = 'var(--bds-yellow-70)'; export const BLUE_TINT = 'var(--bds-blue-tint)'; // --- Typography --- -export const TEXT = 'var(--font-base-sans-text), var(--font-base-sans), Arial, sans-serif'; -export const MONO = 'var(--font-base-sans-mono), "SF Mono", Menlo, Consolas, monospace'; +export const TEXT = 'var(--font-google-sans-flex), Arial, sans-serif'; +export const MONO = 'var(--font-roboto-mono), "SF Mono", Menlo, Consolas, monospace'; diff --git a/app/upgrades/components/Badges.tsx b/app/upgrades/components/Badges.tsx index 5d4b953..3df132b 100644 --- a/app/upgrades/components/Badges.tsx +++ b/app/upgrades/components/Badges.tsx @@ -80,7 +80,7 @@ export function StatusPill({ variant, children, className }: StatusPillProps) { return ( @@ -114,7 +114,7 @@ type KindBadgeProps = { export function KindBadge({ kind }: KindBadgeProps) { return ( - + {kindLabel(kind)} ); diff --git a/app/vibenet/components/ExplorerSearch.tsx b/app/vibenet/components/ExplorerSearch.tsx index fe997fb..8a71b57 100644 --- a/app/vibenet/components/ExplorerSearch.tsx +++ b/app/vibenet/components/ExplorerSearch.tsx @@ -93,7 +93,7 @@ export function ExplorerSearch() { spellCheck={false} autoComplete="off" className={cn( - 'w-full rounded-full border border-bds-gray-10 bg-bds-gray-0 py-3 pl-9 font-sans text-sm text-foreground outline-none transition-colors placeholder:text-bds-gray-40 focus:border-foreground dark:border-white/10 dark:bg-white/5 dark:text-white dark:focus:border-bds-blue-40', + 'w-full rounded-full border border-bds-gray-10 bg-bds-gray-0 py-3 pl-9 text-sm text-foreground outline-none transition-colors placeholder:text-bds-gray-40 focus:border-foreground dark:border-white/10 dark:bg-white/5 dark:text-white dark:focus:border-bds-blue-40', hasQuery ? 'pr-20' : 'pr-3.5', )} /> diff --git a/app/vibenet/demos/_components/DemoTabs.tsx b/app/vibenet/demos/_components/DemoTabs.tsx index 5e583e6..24a50ce 100644 --- a/app/vibenet/demos/_components/DemoTabs.tsx +++ b/app/vibenet/demos/_components/DemoTabs.tsx @@ -41,7 +41,7 @@ export function DemoTabs({ items, value, onChange, ariaLabel, layoutId = 'demo-t disabled={item.disabled} onClick={() => !item.disabled && onChange(item.value)} className={cn( - 'relative select-none rounded-full px-4 py-1.5 font-sans text-[14px] transition-colors', + 'relative select-none rounded-full px-4 py-1.5 text-[14px] transition-colors', item.disabled ? 'cursor-not-allowed text-bds-gray-40' : active diff --git a/app/vibenet/demos/_shared/primitives.tsx b/app/vibenet/demos/_shared/primitives.tsx index 5d04032..23d187c 100644 --- a/app/vibenet/demos/_shared/primitives.tsx +++ b/app/vibenet/demos/_shared/primitives.tsx @@ -164,7 +164,7 @@ export function KindBadge({ kind }: { kind: SignerKind }) { return ( diff --git a/app/vibenet/demos/account/components/CreateAccountModal.tsx b/app/vibenet/demos/account/components/CreateAccountModal.tsx index 4e2e33f..4b06595 100644 --- a/app/vibenet/demos/account/components/CreateAccountModal.tsx +++ b/app/vibenet/demos/account/components/CreateAccountModal.tsx @@ -337,7 +337,7 @@ export function CreateAccountModal({ open, onClose }: CreateAccountModalProps) { spellCheck={false} onChange={(e) => setModalSalt(e.target.value)} placeholder="0x… (32 bytes) or any phrase" - className="min-w-0 flex-1 bg-transparent px-3.5 py-2.5 font-sans text-[13px] font-normal outline-none placeholder:text-bds-gray-40" + className="min-w-0 flex-1 bg-transparent px-3.5 py-2.5 text-[13px] font-normal outline-none placeholder:text-bds-gray-40" /> From 03f467d8eb5a093a6210b6513446a1961185b731 Mon Sep 17 00:00:00 2001 From: Max Barvian Date: Fri, 28 Aug 2026 13:20:05 -0700 Subject: [PATCH 3/7] fix button label centering --- app/components/ui/Button.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/components/ui/Button.tsx b/app/components/ui/Button.tsx index eebcb3c..6587e47 100644 --- a/app/components/ui/Button.tsx +++ b/app/components/ui/Button.tsx @@ -42,7 +42,7 @@ export const Button = forwardRef(function Button ) { let sizeClasses: string; if (size === 'sm') { - sizeClasses = 'h-[34px] px-3 gap-1 pb-px'; + sizeClasses = 'h-[34px] px-3 gap-1'; } else if (arrow) { sizeClasses = 'h-10 pl-4 pr-3 gap-1'; } else { From 51dd7cb9fa88e9446c45210c109bb686550cf761 Mon Sep 17 00:00:00 2001 From: Max Barvian Date: Fri, 28 Aug 2026 13:27:05 -0700 Subject: [PATCH 4/7] more font changes --- app/components/ui/Button.tsx | 3 +++ app/components/ui/Text.tsx | 10 +++++----- app/vibenet/components/FeatureCard.tsx | 2 +- app/vibenet/demos/_shared/FeatureGridCard.tsx | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/components/ui/Button.tsx b/app/components/ui/Button.tsx index 6587e47..d5fc8e7 100644 --- a/app/components/ui/Button.tsx +++ b/app/components/ui/Button.tsx @@ -51,6 +51,9 @@ export const Button = forwardRef(function Button const classes = cn( 'group flex whitespace-nowrap w-fit active:scale-[0.96] transition-[background-color,border-color,color,transform] duration-150 ease-out max-w-full items-center justify-center rounded-full sm:w-auto', + // Trim half-leading to cap/alphabetic so Google Sans Flex sits optically + // centered in the fixed-height pill. Type styles live on this same node. + '[text-box-trim:trim-both] [text-box-edge:cap_alphabetic]', sizeClasses, size === 'sm' ? textVariantClasses.label : textVariantClasses.button, 'md:leading-[20px]', diff --git a/app/components/ui/Text.tsx b/app/components/ui/Text.tsx index b113354..7d05b33 100644 --- a/app/components/ui/Text.tsx +++ b/app/components/ui/Text.tsx @@ -38,22 +38,22 @@ export const textVariantClasses: Record = { title1: 'text-[28px] md:text-[36px] leading-[34px] md:leading-[44px] font-[528] tracking-tight', title2: - 'text-[20px] md:text-[24px] leading-[28px] md:leading-[32px] font-[525] tracking-tight', + 'text-[20px] md:text-[24px] leading-[28px] md:leading-[32px] font-[500] tracking-tight', title3: - 'text-[18px] md:text-[20px] leading-[26px] md:leading-[28px] font-[525] tracking-tight', + 'text-[18px] md:text-[20px] leading-[26px] md:leading-[28px] font-[500] tracking-tight', headline: 'text-[16px] md:text-[18px] leading-[24px] md:leading-[26px] font-[500] tracking-tight', body: 'text-[15px] md:text-[16px] leading-[140%] font-[425] tracking-[0px]', label: - 'text-[13px] md:text-[14px] leading-[18px] md:leading-[20px] font-[535] tracking-[-0.01em]', + 'text-[13px] md:text-[14px] leading-[18px] md:leading-[20px] font-[500] tracking-[-0.01em]', 'label.medium': - 'text-[13px] md:text-[14px] leading-[18px] md:leading-[20px] font-[535] tracking-[0px]', + 'text-[13px] md:text-[14px] leading-[18px] md:leading-[20px] font-[500] tracking-[0px]', 'label.regular': 'text-[13px] md:text-[14px] leading-[20px] font-[400] tracking-[0px]', 'label.mono': 'text-[13px] md:text-[14px] leading-[18px] md:leading-[20px] font-mono font-[400] tracking-[0px]', caption: - 'text-[11px] md:text-[12px] leading-[14px] md:leading-[16px] font-[535] tracking-[0px] uppercase', + 'text-[11px] md:text-[12px] leading-[14px] md:leading-[16px] font-[500] tracking-[0px] uppercase', button: 'text-[14px] leading-[20px] font-[500] tracking-[-0.01em]', footnote: 'text-[11px] md:text-[12px] leading-[14px] md:leading-[16px] font-[400] tracking-[0px]', }; diff --git a/app/vibenet/components/FeatureCard.tsx b/app/vibenet/components/FeatureCard.tsx index 2e56988..9e50c6c 100644 --- a/app/vibenet/components/FeatureCard.tsx +++ b/app/vibenet/components/FeatureCard.tsx @@ -93,7 +93,7 @@ export function FeatureCard({ feature }: FeatureCardProps) { key={highlight.title} className="rounded-lg bg-bds-gray-5 p-3 dark:bg-white/5" > - + {highlight.title} diff --git a/app/vibenet/demos/_shared/FeatureGridCard.tsx b/app/vibenet/demos/_shared/FeatureGridCard.tsx index f443e27..02c6e89 100644 --- a/app/vibenet/demos/_shared/FeatureGridCard.tsx +++ b/app/vibenet/demos/_shared/FeatureGridCard.tsx @@ -31,7 +31,7 @@ export function FeatureGridCard({ > {icon} - {title} + {title}

{description}

{children}
From b5e3140299cf0e0c36a14fbd763191c7b291407f Mon Sep 17 00:00:00 2001 From: Max Barvian Date: Fri, 28 Aug 2026 13:39:16 -0700 Subject: [PATCH 5/7] more tweaks --- app/components/AppShell.tsx | 6 +++--- app/components/ui/Tabs.tsx | 5 +++-- app/components/ui/Text.tsx | 2 +- app/vibenet/demos/_components/DemoTabs.tsx | 4 ++-- app/vibenet/page.tsx | 12 ++++++------ 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/app/components/AppShell.tsx b/app/components/AppShell.tsx index 5e75950..3dac4f7 100644 --- a/app/components/AppShell.tsx +++ b/app/components/AppShell.tsx @@ -685,8 +685,8 @@ function GlobalBanner({ dismissed, onDismiss, className, height }: GlobalBannerP >
- New! - EIP-8130: Accounts + New! + EIP-8130: Accounts - Test on Vibenet + Test on Vibenet
diff --git a/app/components/ui/Tabs.tsx b/app/components/ui/Tabs.tsx index 19564da..0e1ccc8 100644 --- a/app/components/ui/Tabs.tsx +++ b/app/components/ui/Tabs.tsx @@ -55,7 +55,8 @@ export function Tabs({ disabled={item.disabled} className={cn( 'relative flex shrink-0 select-none items-center gap-1.5 rounded-full whitespace-nowrap transition-colors font-[500]', - size === 'sm' ? 'px-2.5 py-1 text-[12px]' : 'px-3 py-1.5 text-[14px]', + // Height is on the control so cap-trim cannot collapse the pill. + size === 'sm' ? 'h-7 px-2.5 py-1 text-[12px]' : 'h-8 px-3 py-1.5 text-[14px]', item.disabled ? 'cursor-not-allowed text-bds-gray-40' : active @@ -77,7 +78,7 @@ export function Tabs({ /> ) : null} {item.icon ? {item.icon} : null} - {item.label} + {item.label} ); })} diff --git a/app/components/ui/Text.tsx b/app/components/ui/Text.tsx index 7d05b33..687ab66 100644 --- a/app/components/ui/Text.tsx +++ b/app/components/ui/Text.tsx @@ -42,7 +42,7 @@ export const textVariantClasses: Record = { title3: 'text-[18px] md:text-[20px] leading-[26px] md:leading-[28px] font-[500] tracking-tight', headline: - 'text-[16px] md:text-[18px] leading-[24px] md:leading-[26px] font-[500] tracking-tight', + 'text-[16px] md:text-[18px] leading-[24px] md:leading-[26px] font-[500] tracking-[0px]', body: 'text-[15px] md:text-[16px] leading-[140%] font-[425] tracking-[0px]', label: 'text-[13px] md:text-[14px] leading-[18px] md:leading-[20px] font-[500] tracking-[-0.01em]', diff --git a/app/vibenet/demos/_components/DemoTabs.tsx b/app/vibenet/demos/_components/DemoTabs.tsx index 154c18b..d47d0fd 100644 --- a/app/vibenet/demos/_components/DemoTabs.tsx +++ b/app/vibenet/demos/_components/DemoTabs.tsx @@ -41,7 +41,7 @@ export function DemoTabs({ items, value, onChange, ariaLabel, layoutId = 'demo-t disabled={item.disabled} onClick={() => !item.disabled && onChange(item.value)} className={cn( - 'relative select-none rounded-full px-4 py-1.5 text-[14px] font-[500] transition-colors', + 'relative flex h-8 select-none items-center rounded-full px-4 py-1.5 text-[14px] font-[500] transition-colors', item.disabled ? 'cursor-not-allowed text-bds-gray-40' : active @@ -56,7 +56,7 @@ export function DemoTabs({ items, value, onChange, ariaLabel, layoutId = 'demo-t className="absolute inset-0 rounded-full bg-background shadow-[0_1px_2px_rgba(0,0,0,0.06)] dark:bg-white/15" /> )} - {item.label} + {item.label} ); })} diff --git a/app/vibenet/page.tsx b/app/vibenet/page.tsx index f394781..7e935b6 100644 --- a/app/vibenet/page.tsx +++ b/app/vibenet/page.tsx @@ -50,15 +50,15 @@ export default function VibenetHomePage() { Connect to Vibenet
- Chain ID + Chain ID
- RPC URL + RPC URL
- Explorer + Explorer Connect
- Chain ID + Chain ID
- RPC URL + RPC URL
- Explorer + Explorer Date: Fri, 28 Aug 2026 15:45:50 -0700 Subject: [PATCH 6/7] text-trim sidebar nav items --- app/components/AppShell.tsx | 42 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/app/components/AppShell.tsx b/app/components/AppShell.tsx index 3dac4f7..7da2cce 100644 --- a/app/components/AppShell.tsx +++ b/app/components/AppShell.tsx @@ -20,7 +20,7 @@ import { AnimatedBaseLogo, BaseMark } from './ui/AnimatedBaseLogo'; import { Breadcrumb } from './ui/Breadcrumb'; import { cn } from './ui/cn'; import { AnimatedArrowIcon, CloseIcon } from './ui/icons'; -import { Text } from './ui/Text'; +import { Text, textVariantClasses } from './ui/Text'; const SIDEBAR_WIDTH = 248; /** Matches base.org's nav logo size, which the animation timings are tuned for. */ @@ -84,7 +84,6 @@ const styles: Record = { gap: 10, padding: '9px 10px', borderRadius: 8, - fontSize: 14, }, navIcon: { display: 'inline-flex', width: 20, height: 20 }, soon: { @@ -172,6 +171,13 @@ const styles: Record = { contentInner: { width: '100%', maxWidth: 1280, margin: '0 auto', padding: '24px 28px 80px', flexGrow: 1, flexShrink: 0, display: 'flex', flexDirection: 'column' as const, minWidth: 0 }, }; +const TEXT_TRIM = '[text-box-trim:trim-both] [text-box-edge:cap_alphabetic]'; + +const NAV_LABEL = `${textVariantClasses['label.medium']} box-content min-h-[1lh]`; + +const NAV_FOCUS_RING = + 'outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-blue'; + function NavGlyph({ name }: NavGlyphProps) { const common = { width: 20, @@ -293,14 +299,7 @@ function NavRow({ icon, label, href, active, enabled, hasChildren, onNavigate }: )} - - {label} - + {label} {!enabled && Soon} {hasChildren && ( @@ -318,13 +317,13 @@ function NavRow({ icon, label, href, active, enabled, hasChildren, onNavigate }: }; if (!enabled) { - return
{content}
; + return
{content}
; } return ( { if (opensInNewTab(event)) return; @@ -386,14 +385,11 @@ const APP_BANNER_HEIGHT = '2.25rem'; const PENDING_PATH_TIMEOUT_MS = 5000; const SIDEBAR_FOOTER_LINK = - 'group outline-none text-bds-gray-50 transition-colors duration-150 hover:text-bds-gray-80'; + `group outline-none ${NAV_LABEL} text-bds-gray-50 transition-colors duration-150 hover:text-bds-gray-80`; const SIDEBAR_FOOTER_LINK_LABEL = 'inline-flex items-center gap-2.5 rounded-lg group-focus-visible:outline group-focus-visible:outline-2 group-focus-visible:outline-offset-2 group-focus-visible:outline-brand-blue'; -const NAV_FOCUS_RING = - 'outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-blue'; - // Track and thumb. Shared with the `:not(...)` list in disableAnimation so the // page-wide no-transition stamp cannot override the 180ms slide. const THEME_SWITCH_ANIM = 'theme-switch-anim'; @@ -515,7 +511,7 @@ function SidebarContent({ dark, onToggleTheme, onNavigate, hideBrand }: SidebarC > { if (opensInNewTab(event)) return; @@ -543,7 +539,9 @@ function SidebarContent({ dark, onToggleTheme, onNavigate, hideBrand }: SidebarC className="transition-[stroke-dashoffset] duration-200 ease-out group-hover:[stroke-dashoffset:0]" /> - {activeParent.label} + + {activeParent.label} +
@@ -1068,7 +1068,7 @@ function CallsEditor(props: CallsEditorProps) { onChange={(e) => setRow(r.id, { value: e.target.value })} /> { const label = addressLabel(address); return ( - + {label ? `${label} · ` : ''} {short(address)} @@ -1201,7 +1201,7 @@ function ReviewBody({ {isPlainCall ? ( - + {short(r.data.trim(), 8, 4)} ) : null} @@ -1444,7 +1444,7 @@ function SubmittedBody({ ) : null} {result.gasNote ? {result.gasNote} : null} {result.txHash ? ( - {short(result.txHash)} + {short(result.txHash)} ) : null}
); diff --git a/app/vibenet/explorer/address/[addr]/AssetsCard.tsx b/app/vibenet/explorer/address/[addr]/AssetsCard.tsx index 5a7af45..3e07d3a 100644 --- a/app/vibenet/explorer/address/[addr]/AssetsCard.tsx +++ b/app/vibenet/explorer/address/[addr]/AssetsCard.tsx @@ -146,7 +146,7 @@ export function AssetsCard({ > {asset.symbol} - {asset.balance} + {asset.balance}
))} diff --git a/app/vibenet/explorer/address/[addr]/OwnedAccountView.tsx b/app/vibenet/explorer/address/[addr]/OwnedAccountView.tsx index e3e5ca3..6e8677d 100644 --- a/app/vibenet/explorer/address/[addr]/OwnedAccountView.tsx +++ b/app/vibenet/explorer/address/[addr]/OwnedAccountView.tsx @@ -250,7 +250,7 @@ function OwnersSection({ openApply }: { openApply: (target: ApplyTarget) => void {isEoa ? EOA : null} {isNew ? New : changed ? Changed : null} - {shortAddress(owner.identity)} + {shortAddress(owner.identity)}