Upload folder using huggingface_hub
Browse files- client/src/components/HitokotoBar.tsx +8 -8
- client/src/components/Layout.tsx +17 -44
- client/src/index.css +7 -7
- client/src/pages/Dashboard.tsx +18 -18
- client/tailwind.config.js +7 -7
client/src/components/HitokotoBar.tsx
CHANGED
|
@@ -60,18 +60,18 @@ const HitokotoBar: React.FC = () => {
|
|
| 60 |
if (hidden) return null;
|
| 61 |
|
| 62 |
return (
|
| 63 |
-
<div className="fixed bottom-0
|
| 64 |
-
<div className="
|
| 65 |
-
<div className="bg-white border border-
|
| 66 |
<div className="flex items-center min-w-0">
|
| 67 |
-
<span className="mr-2 text-
|
| 68 |
<div className="min-w-0">
|
| 69 |
{loading ? (
|
| 70 |
-
<div className="text-sm text-
|
| 71 |
) : error ? (
|
| 72 |
<div className="text-sm text-red-600">{error}</div>
|
| 73 |
) : (
|
| 74 |
-
<div className="text-sm text-
|
| 75 |
{quote ? `『${quote.hitokoto}』 — ${quote.from_who || quote.from || 'Hitokoto'}` : ' '}
|
| 76 |
</div>
|
| 77 |
)}
|
|
@@ -80,14 +80,14 @@ const HitokotoBar: React.FC = () => {
|
|
| 80 |
<div className="flex items-center space-x-2 flex-shrink-0">
|
| 81 |
<button
|
| 82 |
onClick={fetchQuote}
|
| 83 |
-
className="text-xs px-2 py-1 rounded bg-
|
| 84 |
title="Next quote"
|
| 85 |
>
|
| 86 |
Next
|
| 87 |
</button>
|
| 88 |
<button
|
| 89 |
onClick={() => { setHidden(true); localStorage.setItem(LOCAL_HIDE_KEY, '1'); }}
|
| 90 |
-
className="text-xs px-2 py-1 rounded bg-
|
| 91 |
title="Hide"
|
| 92 |
>
|
| 93 |
Hide
|
|
|
|
| 60 |
if (hidden) return null;
|
| 61 |
|
| 62 |
return (
|
| 63 |
+
<div className="fixed bottom-0 right-0 z-50 w-[calc(100%-240px)] md:w-[calc(100%-240px)]">
|
| 64 |
+
<div className="ml-auto max-w-7xl px-4 sm:px-6 lg:px-8 pb-3">
|
| 65 |
+
<div className="bg-white border border-ui-bg shadow-md rounded-lg px-4 py-2 flex items-center justify-between">
|
| 66 |
<div className="flex items-center min-w-0">
|
| 67 |
+
<span className="mr-2 text-ui-navy">💬</span>
|
| 68 |
<div className="min-w-0">
|
| 69 |
{loading ? (
|
| 70 |
+
<div className="text-sm text-ui-navy/70">Loading…</div>
|
| 71 |
) : error ? (
|
| 72 |
<div className="text-sm text-red-600">{error}</div>
|
| 73 |
) : (
|
| 74 |
+
<div className="text-sm text-ui-navy truncate">
|
| 75 |
{quote ? `『${quote.hitokoto}』 — ${quote.from_who || quote.from || 'Hitokoto'}` : ' '}
|
| 76 |
</div>
|
| 77 |
)}
|
|
|
|
| 80 |
<div className="flex items-center space-x-2 flex-shrink-0">
|
| 81 |
<button
|
| 82 |
onClick={fetchQuote}
|
| 83 |
+
className="text-xs px-2 py-1 rounded bg-ui-bg hover:bg-white border border-ui-bg text-ui-navy"
|
| 84 |
title="Next quote"
|
| 85 |
>
|
| 86 |
Next
|
| 87 |
</button>
|
| 88 |
<button
|
| 89 |
onClick={() => { setHidden(true); localStorage.setItem(LOCAL_HIDE_KEY, '1'); }}
|
| 90 |
+
className="text-xs px-2 py-1 rounded bg-ui-bg hover:bg-white border border-ui-bg text-ui-navy"
|
| 91 |
title="Hide"
|
| 92 |
>
|
| 93 |
Hide
|
client/src/components/Layout.tsx
CHANGED
|
@@ -8,8 +8,6 @@ import {
|
|
| 8 |
WrenchScrewdriverIcon,
|
| 9 |
UserIcon,
|
| 10 |
ArrowRightOnRectangleIcon,
|
| 11 |
-
MagnifyingGlassIcon,
|
| 12 |
-
UserCircleIcon,
|
| 13 |
PowerIcon
|
| 14 |
} from '@heroicons/react/24/outline';
|
| 15 |
import HitokotoBar from './HitokotoBar';
|
|
@@ -137,9 +135,11 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
| 137 |
}, [user?.role]);
|
| 138 |
|
| 139 |
const handleLogout = () => {
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
|
|
|
|
|
|
| 143 |
};
|
| 144 |
|
| 145 |
let navigation = [
|
|
@@ -163,46 +163,19 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
| 163 |
}
|
| 164 |
|
| 165 |
return (
|
| 166 |
-
<div className="min-h-screen bg-
|
| 167 |
-
{/* Top Bar
|
| 168 |
-
<header className="sticky top-0 z-40 bg-white/80 backdrop-blur border-b border-
|
| 169 |
<div className="px-4 sm:px-6 lg:px-8 h-14 flex items-center justify-between">
|
| 170 |
-
<Link to="/dashboard" className="text-lg font-bold text-
|
| 171 |
-
<div
|
| 172 |
-
<form
|
| 173 |
-
onSubmit={(e) => {
|
| 174 |
-
e.preventDefault();
|
| 175 |
-
const form = e.currentTarget as HTMLFormElement;
|
| 176 |
-
const input = form.querySelector('input[name="q"]') as HTMLInputElement | null;
|
| 177 |
-
const q = (input?.value || '').trim();
|
| 178 |
-
const target = q ? `/search?q=${encodeURIComponent(q)}` : '/search';
|
| 179 |
-
window.location.href = target;
|
| 180 |
-
}}
|
| 181 |
-
>
|
| 182 |
-
<div className="relative">
|
| 183 |
-
<MagnifyingGlassIcon className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-eclipse/50" />
|
| 184 |
-
<input
|
| 185 |
-
name="q"
|
| 186 |
-
type="search"
|
| 187 |
-
placeholder="Search…"
|
| 188 |
-
className="w-full pl-10 pr-3 py-2 rounded-lg border border-primrose/60 bg-white placeholder-eclipse/40 focus:outline-none focus:ring-2 focus:ring-lyons"
|
| 189 |
-
/>
|
| 190 |
-
</div>
|
| 191 |
-
</form>
|
| 192 |
-
</div>
|
| 193 |
-
<div className="flex items-center space-x-3">
|
| 194 |
-
<div className="hidden sm:flex items-center">
|
| 195 |
-
<UserCircleIcon className="h-7 w-7 text-lyons" />
|
| 196 |
-
{user && <span className="ml-2 text-sm font-medium">{user.name}</span>}
|
| 197 |
-
</div>
|
| 198 |
-
</div>
|
| 199 |
</div>
|
| 200 |
</header>
|
| 201 |
|
| 202 |
{/* Shell: Sidebar + Content */}
|
| 203 |
<div className="flex">
|
| 204 |
{/* Sidebar */}
|
| 205 |
-
<aside className="hidden md:flex md:flex-col w-60 min-h-[calc(100vh-56px)] border-r border-
|
| 206 |
<nav className="p-3 space-y-1 flex-1">
|
| 207 |
{navigation.map((item) => {
|
| 208 |
const isActive = location.pathname === item.href;
|
|
@@ -211,7 +184,7 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
| 211 |
key={item.name}
|
| 212 |
to={item.href}
|
| 213 |
className={`flex items-center px-3 py-2 rounded-md text-sm font-medium transition-colors ${
|
| 214 |
-
isActive ? 'bg-
|
| 215 |
}`}
|
| 216 |
>
|
| 217 |
<item.icon className="h-4 w-4 mr-2" />
|
|
@@ -220,14 +193,14 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
| 220 |
);
|
| 221 |
})}
|
| 222 |
</nav>
|
| 223 |
-
<div className="p-3 border-t border-
|
| 224 |
{user ? (
|
| 225 |
-
<button onClick={handleLogout} className="w-full flex items-center justify-start px-3 py-2 rounded-md text-sm font-medium text-
|
| 226 |
<PowerIcon className="h-4 w-4 mr-2" />
|
| 227 |
Log Out
|
| 228 |
</button>
|
| 229 |
) : (
|
| 230 |
-
<Link to="/login" className="w-full flex items-center justify-start px-3 py-2 rounded-md text-sm font-medium text-
|
| 231 |
<PowerIcon className="h-4 w-4 mr-2" />
|
| 232 |
Log In
|
| 233 |
</Link>
|
|
@@ -245,8 +218,8 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
| 245 |
{isTransitioning && (
|
| 246 |
<div className="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-50">
|
| 247 |
<div className="bg-white rounded-lg shadow-lg p-4 flex items-center space-x-3">
|
| 248 |
-
<div className="animate-spin rounded-full h-6 w-6 border-b-2 border-
|
| 249 |
-
<span className="text-
|
| 250 |
</div>
|
| 251 |
</div>
|
| 252 |
)}
|
|
|
|
| 8 |
WrenchScrewdriverIcon,
|
| 9 |
UserIcon,
|
| 10 |
ArrowRightOnRectangleIcon,
|
|
|
|
|
|
|
| 11 |
PowerIcon
|
| 12 |
} from '@heroicons/react/24/outline';
|
| 13 |
import HitokotoBar from './HitokotoBar';
|
|
|
|
| 135 |
}, [user?.role]);
|
| 136 |
|
| 137 |
const handleLogout = () => {
|
| 138 |
+
try {
|
| 139 |
+
localStorage.removeItem('token');
|
| 140 |
+
localStorage.removeItem('user');
|
| 141 |
+
} catch {}
|
| 142 |
+
window.location.href = '/login';
|
| 143 |
};
|
| 144 |
|
| 145 |
let navigation = [
|
|
|
|
| 163 |
}
|
| 164 |
|
| 165 |
return (
|
| 166 |
+
<div className="min-h-screen bg-ui-bg text-ui-navy">
|
| 167 |
+
{/* Top Bar */}
|
| 168 |
+
<header className="sticky top-0 z-40 bg-white/80 backdrop-blur border-b border-ui-bg">
|
| 169 |
<div className="px-4 sm:px-6 lg:px-8 h-14 flex items-center justify-between">
|
| 170 |
+
<Link to="/dashboard" className="text-lg font-bold text-ui-navy">TransHub</Link>
|
| 171 |
+
<div />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
</div>
|
| 173 |
</header>
|
| 174 |
|
| 175 |
{/* Shell: Sidebar + Content */}
|
| 176 |
<div className="flex">
|
| 177 |
{/* Sidebar */}
|
| 178 |
+
<aside className="hidden md:flex md:flex-col w-60 min-h-[calc(100vh-56px)] border-r border-ui-bg bg-white">
|
| 179 |
<nav className="p-3 space-y-1 flex-1">
|
| 180 |
{navigation.map((item) => {
|
| 181 |
const isActive = location.pathname === item.href;
|
|
|
|
| 184 |
key={item.name}
|
| 185 |
to={item.href}
|
| 186 |
className={`flex items-center px-3 py-2 rounded-md text-sm font-medium transition-colors ${
|
| 187 |
+
isActive ? 'bg-white text-ui-navy shadow-sm' : 'text-ui-navy/80 hover:bg-ui-bg'
|
| 188 |
}`}
|
| 189 |
>
|
| 190 |
<item.icon className="h-4 w-4 mr-2" />
|
|
|
|
| 193 |
);
|
| 194 |
})}
|
| 195 |
</nav>
|
| 196 |
+
<div className="p-3 border-t border-ui-bg">
|
| 197 |
{user ? (
|
| 198 |
+
<button onClick={handleLogout} className="w-full flex items-center justify-start px-3 py-2 rounded-md text-sm font-medium text-ui-navy/80 hover:bg-ui-bg">
|
| 199 |
<PowerIcon className="h-4 w-4 mr-2" />
|
| 200 |
Log Out
|
| 201 |
</button>
|
| 202 |
) : (
|
| 203 |
+
<Link to="/login" className="w-full flex items-center justify-start px-3 py-2 rounded-md text-sm font-medium text-ui-navy/80 hover:bg-ui-bg">
|
| 204 |
<PowerIcon className="h-4 w-4 mr-2" />
|
| 205 |
Log In
|
| 206 |
</Link>
|
|
|
|
| 218 |
{isTransitioning && (
|
| 219 |
<div className="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-50">
|
| 220 |
<div className="bg-white rounded-lg shadow-lg p-4 flex items-center space-x-3">
|
| 221 |
+
<div className="animate-spin rounded-full h-6 w-6 border-b-2 border-ui-navy"></div>
|
| 222 |
+
<span className="text-ui-navy font-medium">Loading...</span>
|
| 223 |
</div>
|
| 224 |
</div>
|
| 225 |
)}
|
client/src/index.css
CHANGED
|
@@ -7,29 +7,29 @@
|
|
| 7 |
font-family: 'Inter', system-ui, sans-serif;
|
| 8 |
}
|
| 9 |
body {
|
| 10 |
-
@apply bg-
|
| 11 |
}
|
| 12 |
}
|
| 13 |
|
| 14 |
@layer components {
|
| 15 |
.btn-primary {
|
| 16 |
-
@apply bg-
|
| 17 |
}
|
| 18 |
|
| 19 |
.btn-secondary {
|
| 20 |
-
@apply bg-
|
| 21 |
}
|
| 22 |
|
| 23 |
.btn-danger {
|
| 24 |
-
@apply bg-
|
| 25 |
}
|
| 26 |
|
| 27 |
.input-field {
|
| 28 |
-
@apply w-full px-3 py-2 border border-
|
| 29 |
}
|
| 30 |
|
| 31 |
.card {
|
| 32 |
-
@apply bg-white rounded-
|
| 33 |
}
|
| 34 |
|
| 35 |
.highlight-cultural {
|
|
@@ -37,7 +37,7 @@
|
|
| 37 |
}
|
| 38 |
|
| 39 |
.text-gradient {
|
| 40 |
-
@apply bg-gradient-to-r from-
|
| 41 |
}
|
| 42 |
|
| 43 |
.font-smiley {
|
|
|
|
| 7 |
font-family: 'Inter', system-ui, sans-serif;
|
| 8 |
}
|
| 9 |
body {
|
| 10 |
+
@apply bg-ui-bg text-ui-navy;
|
| 11 |
}
|
| 12 |
}
|
| 13 |
|
| 14 |
@layer components {
|
| 15 |
.btn-primary {
|
| 16 |
+
@apply bg-ui-navy hover:bg-ui-navy/90 text-white font-medium py-2 px-4 rounded-lg transition-colors duration-200;
|
| 17 |
}
|
| 18 |
|
| 19 |
.btn-secondary {
|
| 20 |
+
@apply bg-white hover:bg-ui-bg text-ui-navy font-medium py-2 px-4 rounded-lg border border-ui-bg transition-colors duration-200;
|
| 21 |
}
|
| 22 |
|
| 23 |
.btn-danger {
|
| 24 |
+
@apply bg-red-600 hover:bg-red-700 text-white font-medium py-2 px-4 rounded-lg transition-colors duration-200;
|
| 25 |
}
|
| 26 |
|
| 27 |
.input-field {
|
| 28 |
+
@apply w-full px-3 py-2 border border-ui-bg rounded-lg focus:outline-none focus:ring-2 focus:ring-ui-navy focus:border-transparent;
|
| 29 |
}
|
| 30 |
|
| 31 |
.card {
|
| 32 |
+
@apply bg-white rounded-xl shadow-sm border border-ui-bg p-6;
|
| 33 |
}
|
| 34 |
|
| 35 |
.highlight-cultural {
|
|
|
|
| 37 |
}
|
| 38 |
|
| 39 |
.text-gradient {
|
| 40 |
+
@apply bg-gradient-to-r from-ui-navy to-ui-teal bg-clip-text text-transparent;
|
| 41 |
}
|
| 42 |
|
| 43 |
.font-smiley {
|
client/src/pages/Dashboard.tsx
CHANGED
|
@@ -113,15 +113,15 @@ const Dashboard: React.FC = () => {
|
|
| 113 |
<div className="mb-8">
|
| 114 |
<div className="flex items-center justify-between">
|
| 115 |
<div>
|
| 116 |
-
<h1 className="text-3xl font-bold text-
|
| 117 |
-
<p className="text-
|
| 118 |
Ready to practice your translation skills?
|
| 119 |
</p>
|
| 120 |
</div>
|
| 121 |
<div className="flex items-center space-x-3">
|
| 122 |
-
<span className="text-sm text-
|
| 123 |
{user.role === 'admin' && (
|
| 124 |
-
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-
|
| 125 |
Admin
|
| 126 |
</span>
|
| 127 |
)}
|
|
@@ -131,21 +131,21 @@ const Dashboard: React.FC = () => {
|
|
| 131 |
|
| 132 |
{/* Quick Actions */}
|
| 133 |
<div className="mb-8">
|
| 134 |
-
<h2 className="text-lg font-semibold text-
|
| 135 |
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
| 136 |
{actionsToShow.map((action) => (
|
| 137 |
<Link
|
| 138 |
key={action.name}
|
| 139 |
to={action.href}
|
| 140 |
-
className="bg-white rounded-xl shadow-sm border border-
|
| 141 |
>
|
| 142 |
<div className="flex items-center">
|
| 143 |
-
<div className={`p-3 rounded-lg bg-
|
| 144 |
<action.icon className="h-6 w-6 text-white" />
|
| 145 |
</div>
|
| 146 |
<div className="ml-4">
|
| 147 |
-
<h3 className="text-lg font-medium text-
|
| 148 |
-
<p className="text-
|
| 149 |
</div>
|
| 150 |
</div>
|
| 151 |
</Link>
|
|
@@ -176,23 +176,23 @@ const Dashboard: React.FC = () => {
|
|
| 176 |
)}
|
| 177 |
|
| 178 |
{/* Overview */}
|
| 179 |
-
<div className="bg-white rounded-xl shadow-sm border border-
|
| 180 |
<div className="flex items-center mb-4">
|
| 181 |
-
<ChartBarIcon className="h-6 w-6 text-
|
| 182 |
-
<h3 className="text-lg font-semibold text-
|
| 183 |
</div>
|
| 184 |
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
| 185 |
<div className="text-center">
|
| 186 |
-
<div className="text-2xl font-bold text-
|
| 187 |
-
<div className="text-sm text-
|
| 188 |
</div>
|
| 189 |
<div className="text-center">
|
| 190 |
-
<div className="text-2xl font-bold text-
|
| 191 |
-
<div className="text-sm text-
|
| 192 |
</div>
|
| 193 |
<div className="text-center">
|
| 194 |
-
<div className="text-2xl font-bold text-
|
| 195 |
-
<div className="text-sm text-
|
| 196 |
</div>
|
| 197 |
</div>
|
| 198 |
</div>
|
|
|
|
| 113 |
<div className="mb-8">
|
| 114 |
<div className="flex items-center justify-between">
|
| 115 |
<div>
|
| 116 |
+
<h1 className="text-3xl font-bold text-ui-navy">{getGreeting()}</h1>
|
| 117 |
+
<p className="text-ui-navy/70 mt-2">
|
| 118 |
Ready to practice your translation skills?
|
| 119 |
</p>
|
| 120 |
</div>
|
| 121 |
<div className="flex items-center space-x-3">
|
| 122 |
+
<span className="text-sm text-ui-navy/70">{getRoleDisplay()}</span>
|
| 123 |
{user.role === 'admin' && (
|
| 124 |
+
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-ui-gold/20 text-ui-navy border border-ui-bg">
|
| 125 |
Admin
|
| 126 |
</span>
|
| 127 |
)}
|
|
|
|
| 131 |
|
| 132 |
{/* Quick Actions */}
|
| 133 |
<div className="mb-8">
|
| 134 |
+
<h2 className="text-lg font-semibold text-ui-navy mb-4">Quick Actions</h2>
|
| 135 |
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
| 136 |
{actionsToShow.map((action) => (
|
| 137 |
<Link
|
| 138 |
key={action.name}
|
| 139 |
to={action.href}
|
| 140 |
+
className="bg-white rounded-xl shadow-sm border border-ui-bg p-6 hover:shadow-md hover:border-ui-bg transition"
|
| 141 |
>
|
| 142 |
<div className="flex items-center">
|
| 143 |
+
<div className={`p-3 rounded-lg bg-ui-teal`}>
|
| 144 |
<action.icon className="h-6 w-6 text-white" />
|
| 145 |
</div>
|
| 146 |
<div className="ml-4">
|
| 147 |
+
<h3 className="text-lg font-medium text-ui-navy">{action.name}</h3>
|
| 148 |
+
<p className="text-ui-navy/70">{action.description}</p>
|
| 149 |
</div>
|
| 150 |
</div>
|
| 151 |
</Link>
|
|
|
|
| 176 |
)}
|
| 177 |
|
| 178 |
{/* Overview */}
|
| 179 |
+
<div className="bg-white rounded-xl shadow-sm border border-ui-bg p-6">
|
| 180 |
<div className="flex items-center mb-4">
|
| 181 |
+
<ChartBarIcon className="h-6 w-6 text-ui-navy mr-3" />
|
| 182 |
+
<h3 className="text-lg font-semibold text-ui-navy">Course Overview</h3>
|
| 183 |
</div>
|
| 184 |
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
| 185 |
<div className="text-center">
|
| 186 |
+
<div className="text-2xl font-bold text-ui-navy">6</div>
|
| 187 |
+
<div className="text-sm text-ui-navy/70">Weeks</div>
|
| 188 |
</div>
|
| 189 |
<div className="text-center">
|
| 190 |
+
<div className="text-2xl font-bold text-ui-navy">2</div>
|
| 191 |
+
<div className="text-sm text-ui-navy/70">Task Types</div>
|
| 192 |
</div>
|
| 193 |
<div className="text-center">
|
| 194 |
+
<div className="text-2xl font-bold text-ui-navy">Voting</div>
|
| 195 |
+
<div className="text-sm text-ui-navy/70">Peer Review</div>
|
| 196 |
</div>
|
| 197 |
</div>
|
| 198 |
</div>
|
client/tailwind.config.js
CHANGED
|
@@ -6,13 +6,13 @@ module.exports = {
|
|
| 6 |
theme: {
|
| 7 |
extend: {
|
| 8 |
colors: {
|
| 9 |
-
//
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
},
|
| 17 |
fontFamily: {
|
| 18 |
sans: ['Inter', 'system-ui', 'sans-serif'],
|
|
|
|
| 6 |
theme: {
|
| 7 |
extend: {
|
| 8 |
colors: {
|
| 9 |
+
// Dashboard palette (sampled from provided image)
|
| 10 |
+
ui: {
|
| 11 |
+
bg: '#EDEDED', // light gray background
|
| 12 |
+
gold: '#E1AB3D', // accent badges/buttons
|
| 13 |
+
teal: '#63C6AF', // charts/highlights
|
| 14 |
+
navy: '#242B3E', // primary text/buttons
|
| 15 |
+
},
|
| 16 |
},
|
| 17 |
fontFamily: {
|
| 18 |
sans: ['Inter', 'system-ui', 'sans-serif'],
|