style(ui): polished typography and switched webfonts to woff2

- Switched bundled browser font references from TTF to WOFF2 and enabled optical sizing.
- Refined heading hierarchy, text wrapping, mobile controls, and numeric alignment.
- Polished notification badges, button underlines, and ligature rendering.
This commit is contained in:
ephraimduncan
2026-07-15 10:05:37 +00:00
parent b16f979eb3
commit 8916092500
18 changed files with 36 additions and 30 deletions
+15 -9
View File
@@ -3,7 +3,7 @@
/* Inter Variable Fonts */
@font-face {
font-family: "Inter";
src: url("/fonts/inter-variablefont_opsz,wght.ttf") format("truetype-variations");
src: url("/fonts/inter-variablefont_opsz,wght.woff2") format("woff2");
font-weight: 100 900;
font-style: normal;
font-display: swap;
@@ -12,7 +12,7 @@
/* Inter Italic Variable Fonts */
@font-face {
font-family: "Inter";
src: url("/fonts/inter-italic-variablefont_opsz,wght.ttf") format("truetype-variations");
src: url("/fonts/inter-italic-variablefont_opsz,wght.woff2") format("woff2");
font-weight: 100 900;
font-style: italic;
font-display: swap;
@@ -21,7 +21,7 @@
/* Caveat Variable Font */
@font-face {
font-family: "Caveat";
src: url("/fonts/caveat-variablefont_wght.ttf") format("truetype-variations");
src: url("/fonts/caveat-variablefont_wght.woff2") format("woff2");
font-weight: 400 600;
font-style: normal;
font-display: swap;
@@ -29,8 +29,8 @@
@font-face {
font-family: "Noto Sans";
src: url("/fonts/noto-sans.ttf") format("truetype-variations");
font-weight: 100 900;
src: url("/fonts/noto-sans.woff2") format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
}
@@ -38,7 +38,7 @@
/* Korean noto sans */
@font-face {
font-family: "Noto Sans Korean";
src: url("/fonts/noto-sans-korean.ttf") format("truetype-variations");
src: url("/fonts/noto-sans-korean.woff2") format("woff2");
font-weight: 100 900;
font-style: normal;
font-display: swap;
@@ -47,7 +47,7 @@
/* Japanese noto sans */
@font-face {
font-family: "Noto Sans Japanese";
src: url("/fonts/noto-sans-japanese.ttf") format("truetype-variations");
src: url("/fonts/noto-sans-japanese.woff2") format("woff2");
font-weight: 100 900;
font-style: normal;
font-display: swap;
@@ -56,13 +56,19 @@
/* Chinese noto sans */
@font-face {
font-family: "Noto Sans Chinese";
src: url("/fonts/noto-sans-chinese.ttf") format("truetype-variations");
font-weight: 100 900;
src: url("/fonts/noto-sans-chinese.woff2") format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
}
@layer base {
html {
@apply antialiased;
font-optical-sizing: auto;
font-synthesis: none;
}
:root {
--font-sans: "Inter";
--font-signature: "Caveat";
@@ -71,7 +71,7 @@ export const Header = ({ className, ...props }: HeaderProps) => {
<InboxIcon className="h-5 w-5 flex-shrink-0 text-muted-foreground transition-colors hover:text-foreground" />
{unreadCountData && unreadCountData.count > 0 && (
<span className="absolute -top-1.5 -right-1.5 flex h-5 w-5 items-center justify-center rounded-full bg-primary font-semibold text-[10px] text-primary-foreground">
<span className="absolute -top-1.5 -right-1.5 flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1 font-semibold text-primary-foreground text-xs tabular-nums leading-none">
{unreadCountData.count > 99 ? '99+' : unreadCountData.count}
</span>
)}
@@ -94,7 +94,7 @@ export const AppNavMobile = ({ isMenuOpen, onMenuOpenChange }: AppNavMobileProps
>
{text}
{href === '/inbox' && unreadCountData && unreadCountData.count > 0 && (
<span className="flex h-6 min-w-[1.5rem] items-center justify-center rounded-full bg-primary px-1.5 font-semibold text-primary-foreground text-xs">
<span className="flex h-6 min-w-[1.5rem] items-center justify-center rounded-full bg-primary px-1.5 font-semibold text-primary-foreground text-xs tabular-nums">
{unreadCountData.count > 99 ? '99+' : unreadCountData.count}
</span>
)}
@@ -29,7 +29,7 @@ export const CardMetric = ({ icon: Icon, title, value, className, children }: Ca
</div>
{children || (
<p className="mt-auto font-semibold text-4xl text-foreground leading-8">
<p className="mt-auto font-semibold text-4xl text-foreground tabular-nums leading-8">
{typeof value === 'number' ? value.toLocaleString('en-US') : value}
</p>
)}
@@ -13,10 +13,12 @@ export const SettingsHeader = ({ children, title, subtitle, className, hideDivid
return (
<>
<div className={cn('flex flex-row items-center justify-between', className)}>
<div>
<h3 className="font-medium text-lg">{title}</h3>
<div className="min-w-0">
<h3 className="font-medium text-lg leading-tight [text-wrap:balance]">{title}</h3>
<p className="text-muted-foreground text-sm md:mt-2">{subtitle}</p>
<p className="mt-1 max-w-[65ch] text-muted-foreground text-sm leading-normal [overflow-wrap:break-word] [text-wrap:pretty] md:mt-2">
{subtitle}
</p>
</div>
{children}
@@ -143,9 +143,9 @@ export default function DocumentsPage() {
<AvatarFallback className="text-muted-foreground text-xs">{team.name.slice(0, 1)}</AvatarFallback>
</Avatar>
<h2 className="font-semibold text-4xl">
<h1 className="font-semibold text-2xl leading-tight tracking-tight md:text-3xl">
<Trans>Documents</Trans>
</h2>
</h1>
</div>
<div className="-m-1 flex flex-wrap gap-x-4 gap-y-6 overflow-hidden p-1">
@@ -172,7 +172,7 @@ export default function DocumentsPage() {
<DocumentStatus status={value} />
{value !== ExtendedDocumentStatus.ALL && (
<span className="ml-1 inline-block opacity-50">
<span className="ml-1 inline-block tabular-nums opacity-50">
{stats[value] >= STATS_COUNT_CAP ? `${STATS_COUNT_CAP.toLocaleString()}+` : stats[value]}
</span>
)}
@@ -101,7 +101,7 @@ export default function TemplatesPage() {
<AvatarFallback className="text-muted-foreground text-xs">{team.name.slice(0, 1)}</AvatarFallback>
</Avatar>
<h1 className="truncate font-semibold text-2xl md:text-3xl">
<h1 className="font-semibold text-2xl leading-tight tracking-tight md:text-3xl">
<Trans>Templates</Trans>
</h1>
</div>
@@ -131,15 +131,15 @@ export default function TemplatesPage() {
<div className="mt-8">
{activeQuery.data && activeQuery.data.count === 0 ? (
<div className="flex h-96 flex-col items-center justify-center gap-y-4 text-muted-foreground/60">
<Bird className="h-12 w-12" strokeWidth={1.5} />
<div className="flex h-96 flex-col items-center justify-center gap-y-4">
<Bird className="h-12 w-12 text-muted-foreground/60" strokeWidth={1.5} />
<div className="text-center">
<h3 className="font-semibold text-lg">
<h3 className="font-semibold text-foreground text-lg">
<Trans>We're all empty</Trans>
</h3>
<p className="mt-2 max-w-[50ch]">
<p className="mt-2 max-w-[50ch] text-muted-foreground [text-wrap:pretty]">
{isOrgView ? (
<Trans>No organisation templates are shared with your team yet.</Trans>
) : (
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.