From 666b5ada4a1c25a6eb029dca6b7ff1785f32c2b0 Mon Sep 17 00:00:00 2001 From: cesnimda Date: Wed, 1 Jul 2026 20:06:50 +0200 Subject: [PATCH] feat(ui): bundle Inter + design-system preview page (/app/design) Slice 2: self-host Inter (variable) via @fontsource-variable/inter and add a living design-system reference at /app/design showing tokens, the green ramp, typography, and all primitives in both themes. Verified: frontend builds clean; prod npm audit clean. Co-Authored-By: Claude Opus 4.8 --- frontend/package-lock.json | 10 ++ frontend/package.json | 1 + frontend/src/index.css | 6 +- frontend/src/main.jsx | 3 + frontend/src/pages/DesignSystem.jsx | 177 ++++++++++++++++++++++++++++ frontend/tailwind.config.js | 1 + 6 files changed, 195 insertions(+), 3 deletions(-) create mode 100644 frontend/src/pages/DesignSystem.jsx diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e68b71a..e6b2770 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,6 +8,7 @@ "name": "inboxintel-frontend", "version": "0.1.0", "dependencies": { + "@fontsource-variable/inter": "^5.2.8", "@radix-ui/react-avatar": "^1.2.1", "@radix-ui/react-checkbox": "^1.3.6", "@radix-ui/react-dialog": "^1.1.18", @@ -764,6 +765,15 @@ "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", "license": "MIT" }, + "node_modules/@fontsource-variable/inter": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.2.8.tgz", + "integrity": "sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", diff --git a/frontend/package.json b/frontend/package.json index bf975da..e1688bb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,6 +9,7 @@ "preview": "vite preview --host" }, "dependencies": { + "@fontsource-variable/inter": "^5.2.8", "@radix-ui/react-avatar": "^1.2.1", "@radix-ui/react-checkbox": "^1.3.6", "@radix-ui/react-dialog": "^1.1.18", diff --git a/frontend/src/index.css b/frontend/src/index.css index 691a550..9f4d9ab 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -66,9 +66,9 @@ body { @apply bg-background text-foreground antialiased; - /* Prefer Inter when available (bundled in a later slice); graceful system fallback. */ - font-family: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, - Helvetica, Arial, sans-serif; + /* Inter (variable, self-hosted via @fontsource-variable/inter); system fallback. */ + font-family: 'Inter Variable', 'Inter', ui-sans-serif, system-ui, -apple-system, + 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; } /* Subtle, modern scrollbars that respect the theme. */ diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx index dbf90ae..f8b66ca 100644 --- a/frontend/src/main.jsx +++ b/frontend/src/main.jsx @@ -9,7 +9,9 @@ import Unsubscribe from './pages/Unsubscribe.jsx'; import FolderView from './pages/FolderView.jsx'; import SearchResults from './pages/SearchResults.jsx'; import Layout from './components/Layout.jsx'; +import DesignSystem from './pages/DesignSystem.jsx'; import { ToastProvider, TooltipProvider } from './components/ui'; +import '@fontsource-variable/inter'; import './index.css'; import './styles.css'; @@ -30,6 +32,7 @@ ReactDOM.createRoot(document.getElementById('root')).render( } /> } /> } /> + } /> } /> diff --git a/frontend/src/pages/DesignSystem.jsx b/frontend/src/pages/DesignSystem.jsx new file mode 100644 index 0000000..283199c --- /dev/null +++ b/frontend/src/pages/DesignSystem.jsx @@ -0,0 +1,177 @@ +import React from 'react'; +import { + Button, Badge, Input, Textarea, Switch, Skeleton, Separator, + Card, CardHeader, CardTitle, CardDescription, CardContent, + Tabs, TabsList, TabsTrigger, TabsContent, EmptyState, ThemeToggle, +} from '../components/ui'; + +/* + Design-system preview (v2). A living reference for the tokens + primitives so the + redesign can be visually verified in both themes. Route: /app/design. + Not linked in primary nav — it's a developer/design surface. +*/ + +const TOKENS = [ + ['background', 'App background'], + ['card', 'Card / surface'], + ['muted', 'Muted surface'], + ['border', 'Border'], + ['primary', 'Brand (green)'], + ['success', 'Success'], + ['warning', 'Warning'], + ['danger', 'Danger'], +]; +// Full literal class names so Tailwind's JIT includes them. +const GREEN = [ + 'bg-green-50', 'bg-green-100', 'bg-green-200', 'bg-green-300', 'bg-green-400', + 'bg-green-500', 'bg-green-600', 'bg-green-700', 'bg-green-800', 'bg-green-900', +]; +const TYPE = [ + ['text-3xl', '30px — Display'], + ['text-2xl', '24px — Heading'], + ['text-xl', '20px — Subheading'], + ['text-lg', '18px — Large'], + ['text-base', '16px — Body'], + ['text-sm', '14px — UI base'], + ['text-xs', '12px — Caption'], +]; + +function Swatch({ token, label }) { + return ( +
+
+
{label}
+
--{token}
+
+ ); +} + +function Section({ title, children }) { + return ( +
+

{title}

+ {children} +
+ ); +} + +export default function DesignSystem() { + return ( +
+
+
+

Design system

+

+ v2 tokens & primitives — green accent, warm neutrals, dark-first. Toggle the + theme to verify both. +

+
+ +
+ +
+
+ {TOKENS.map(([t, l]) => )} +
+
+ +
+
+ {GREEN.map((cls) => ( +
+ ))} +
+
+ 50500 (brand)900 +
+
+ +
+
+ {TYPE.map(([cls, label]) => ( +
+ {label} +
+ ))} +
+
+ +
+
+ + + + + + +
+
+ +
+
+ Default + Secondary + Outline + Danger +
+
+ +
+
+ +