// frontend/src/pages/dev/CardFontSample.jsx
// Standalone card header style sampler — no MainLayout, no auth required.
// View at: /dev/card-fonts
//
// Shows the stitch-reference style: Inter, uppercase, tracking-widest, icon-left.
// Each card uses a different icon to demonstrate how sections would look in practice.
import { useEffect } from 'react'
import Icon from '@/components/ui/Icon'
// ─── Shared mock body content ─────────────────────────────────────────────────
const services = [
{ name: 'API Gateway', status: 'success' },
{ name: 'Database', status: 'success' },
{ name: 'Worker Queue', status: 'warning' },
{ name: 'CDN Edge', status: 'success' },
]
const dotColor = {
success: 'var(--color-success)',
warning: 'var(--color-warning)',
}
function ServiceRow({ name, status }) {
return (
{name}{status === 'success' ? 'OK' : 'WARN'}
)
}
const CardBody = () => (
{services.map(s => )}
)
const CardFooter = () => (
Last checked 2 minutes ago
)
// ─── Card header style variants ───────────────────────────────────────────────
// All use Inter. They vary only in the title treatment (size, weight, case, spacing, color).
const specimens = [
{
id: 1,
icon: 'settings',
iconColor: 'var(--color-primary)',
label: '1 · Inter 600 · uppercase · tracking-widest · text-muted',
description: 'Closest to the stitch reference. Clean, restrained, professional.',
titleStyle: {
fontFamily: 'Inter, sans-serif',
fontSize: '0.6875rem', /* 11px */
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.12em',
color: 'var(--color-text-muted)',
},
},
{
id: 2,
icon: 'devices',
iconColor: 'var(--color-primary)',
label: '2 · Inter 700 · uppercase · tracking-widest · on-surface-variant',
description: 'Heavier weight — bolder impression while keeping the muted tone.',
titleStyle: {
fontFamily: 'Inter, sans-serif',
fontSize: '0.6875rem',
fontWeight: 700,
textTransform: 'uppercase',
letterSpacing: '0.12em',
color: 'var(--color-text-secondary)',
},
},
{
id: 3,
icon: 'dashboard',
iconColor: 'var(--color-primary)',
label: '3 · Inter 600 · uppercase · tracking-wide · primary color',
description: 'Icon and title in the same accent color — more expressive.',
titleStyle: {
fontFamily: 'Inter, sans-serif',
fontSize: '0.6875rem',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.10em',
color: 'var(--color-primary)',
},
},
{
id: 4,
icon: 'customers',
iconColor: 'var(--color-text-muted)',
label: '4 · Inter 500 · uppercase · tracking-widest · muted icon + muted title',
description: 'Both icon and title muted — very quiet, recedes into the card.',
titleStyle: {
fontFamily: 'Inter, sans-serif',
fontSize: '0.6875rem',
fontWeight: 500,
textTransform: 'uppercase',
letterSpacing: '0.14em',
color: 'var(--color-text-muted)',
},
},
{
id: 5,
icon: 'firmware',
iconColor: 'var(--color-primary)',
label: '5 · Inter 600 · uppercase · tracking-widest · 12px (slightly larger)',
description: 'Same treatment at 12px — easier to read at a glance.',
titleStyle: {
fontFamily: 'Inter, sans-serif',
fontSize: 'var(--font-size-sm)', /* 12px */
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.10em',
color: 'var(--color-text-muted)',
},
},
{
id: 6,
icon: 'mail',
iconColor: 'var(--color-primary)',
label: '6 · Inter 600 · title case · 14px · no tracking',
description: 'Title case at body size — feels more conversational.',
titleStyle: {
fontFamily: 'Inter, sans-serif',
fontSize: 'var(--font-size-base)', /* 14px */
fontWeight: 600,
textTransform: 'none',
letterSpacing: '-0.01em',
color: 'var(--color-text-primary)',
},
},
{
id: 7,
icon: 'manufacturing',
iconColor: 'var(--color-primary)',
label: '7 · Inter 500 · title case · 14px · relaxed tracking',
description: 'Medium weight at 14px — softest, most editorial option.',
titleStyle: {
fontFamily: 'Inter, sans-serif',
fontSize: 'var(--font-size-base)',
fontWeight: 500,
textTransform: 'none',
letterSpacing: '0.01em',
color: 'var(--color-text-secondary)',
},
},
{
id: 8,
icon: 'mqtt',
iconColor: 'var(--color-tertiary)',
label: '8 · Inter 700 · uppercase · tracking-widest · tertiary/aqua icon',
description: 'Accent icon in aqua — useful to visually distinguish section types.',
titleStyle: {
fontFamily: 'Inter, sans-serif',
fontSize: '0.6875rem',
fontWeight: 700,
textTransform: 'uppercase',
letterSpacing: '0.12em',
color: 'var(--color-text-muted)',
},
},
{
id: 9,
icon: 'melodies',
iconColor: 'var(--color-primary)',
label: '9 · Inter 600 · uppercase · 10px · extreme tracking',
description: 'Pushed to the limit — very spacious, laser-etched instrument-panel feel.',
titleStyle: {
fontFamily: 'Inter, sans-serif',
fontSize: '0.625rem', /* 10px */
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.20em',
color: 'var(--color-text-muted)',
},
},
{
id: 10,
icon: 'staff',
iconColor: 'var(--color-primary)',
label: '10 · Inter 600 · uppercase · 11px · no icon (icon=false)',
description: 'No icon — title only. To compare how it looks without the icon.',
noIcon: true,
titleStyle: {
fontFamily: 'Inter, sans-serif',
fontSize: '0.6875rem',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.12em',
color: 'var(--color-text-muted)',
},
},
]
// ─── Single specimen card ──────────────────────────────────────────────────────
function SpecimenCard({ s }) {
return (
{/* The card */}
{/* Header */}
{!s.noIcon && (
)}
System Status
All services operational
{/* Body */}
{/* Footer */}
{/* Label beneath card */}
{s.label}{s.description}
)
}
// ─── Page ─────────────────────────────────────────────────────────────────────
export default function CardFontSample() {
// Inter is already loaded via tokens.css (system fallback) but ensure the
// Google Fonts version is present for the exact weights we need.
useEffect(() => {
const existing = document.querySelector('link[data-card-font-sampler]')
if (existing) return
const link = document.createElement('link')
link.rel = 'stylesheet'
link.setAttribute('data-card-font-sampler', '1')
link.href = 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'
document.head.appendChild(link)
return () => {
const el = document.querySelector('link[data-card-font-sampler]')
if (el) document.head.removeChild(el)
}
}, [])
return (
{/* Page header */}
Dev Tooling · Card Header Sampler
Card Header Style Sampler
All 10 cards use Inter — the same font as the stitch reference.
Each varies title size, weight, case, letter-spacing, and icon treatment.
Pick a number and we'll apply it globally.