update style

This commit is contained in:
root
2026-05-24 01:53:27 -04:00
parent f5292f8b6c
commit 31e06a1d61
62 changed files with 431 additions and 459 deletions
@@ -69,7 +69,7 @@ export default function AdminUsersPage() {
const ROLE_COLORS: Record<string, string> = { const ROLE_COLORS: Record<string, string> = {
SUPER_ADMIN: 'text-emerald-400 bg-emerald-950/40', SUPER_ADMIN: 'text-emerald-400 bg-emerald-950/40',
ADMIN: 'text-sky-400 bg-sky-950/40', ADMIN: 'text-sky-400 bg-sky-950/40',
SUPPORT: 'text-amber-400 bg-amber-950/40', SUPPORT: 'text-orange-400 bg-orange-950/40',
FINANCE: 'text-violet-400 bg-violet-950/40', FINANCE: 'text-violet-400 bg-violet-950/40',
VIEWER: 'text-zinc-400 bg-zinc-800', VIEWER: 'text-zinc-400 bg-zinc-800',
} }
@@ -137,7 +137,7 @@ export default function AdminUsersPage() {
</div> </div>
{showModal && ( {showModal && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm"> <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#07101e]/60 backdrop-blur-sm">
<div className="w-full max-w-md rounded-2xl border border-zinc-700 bg-zinc-900 p-8 shadow-2xl"> <div className="w-full max-w-md rounded-2xl border border-zinc-700 bg-zinc-900 p-8 shadow-2xl">
<div className="flex items-center justify-between mb-6"> <div className="flex items-center justify-between mb-6">
<h2 className="text-lg font-semibold">New admin user</h2> <h2 className="text-lg font-semibold">New admin user</h2>
@@ -16,7 +16,7 @@ const ACTION_COLORS: Record<string, string> = {
CREATE: 'text-emerald-400 bg-emerald-950/40', CREATE: 'text-emerald-400 bg-emerald-950/40',
UPDATE: 'text-sky-400 bg-sky-950/40', UPDATE: 'text-sky-400 bg-sky-950/40',
DELETE: 'text-red-400 bg-red-950/40', DELETE: 'text-red-400 bg-red-950/40',
SUSPEND: 'text-amber-400 bg-amber-950/40', SUSPEND: 'text-orange-400 bg-orange-950/40',
ACTIVATE: 'text-emerald-400 bg-emerald-950/40', ACTIVATE: 'text-emerald-400 bg-emerald-950/40',
LOGIN: 'text-zinc-400 bg-zinc-800', LOGIN: 'text-zinc-400 bg-zinc-800',
} }
@@ -56,14 +56,14 @@ interface Stats {
const SUB_STATUS_COLORS: Record<string, string> = { const SUB_STATUS_COLORS: Record<string, string> = {
ACTIVE: 'text-emerald-400 bg-emerald-900/30', ACTIVE: 'text-emerald-400 bg-emerald-900/30',
TRIALING: 'text-sky-400 bg-sky-900/30', TRIALING: 'text-sky-400 bg-sky-900/30',
PAST_DUE: 'text-amber-400 bg-amber-900/30', PAST_DUE: 'text-orange-400 bg-orange-900/30',
CANCELLED: 'text-zinc-400 bg-zinc-800', CANCELLED: 'text-zinc-400 bg-zinc-800',
UNPAID: 'text-red-400 bg-red-900/30', UNPAID: 'text-red-400 bg-red-900/30',
} }
const INVOICE_STATUS_COLORS: Record<string, string> = { const INVOICE_STATUS_COLORS: Record<string, string> = {
PAID: 'text-emerald-400 bg-emerald-900/30', PAID: 'text-emerald-400 bg-emerald-900/30',
PENDING: 'text-amber-400 bg-amber-900/30', PENDING: 'text-orange-400 bg-orange-900/30',
FAILED: 'text-red-400 bg-red-900/30', FAILED: 'text-red-400 bg-red-900/30',
REFUNDED: 'text-zinc-400 bg-zinc-800', REFUNDED: 'text-zinc-400 bg-zinc-800',
} }
@@ -302,7 +302,7 @@ export default function AdminBillingPage() {
</div> </div>
<div className="panel p-4"> <div className="panel p-4">
<p className="text-xs text-zinc-500 uppercase tracking-wider">{copy.pastDue}</p> <p className="text-xs text-zinc-500 uppercase tracking-wider">{copy.pastDue}</p>
<p className="mt-1 text-2xl font-bold text-amber-400">{stats.pastDueCount}</p> <p className="mt-1 text-2xl font-bold text-orange-400">{stats.pastDueCount}</p>
</div> </div>
<div className="panel p-4"> <div className="panel p-4">
<p className="text-xs text-zinc-500 uppercase tracking-wider">{copy.cancelled}</p> <p className="text-xs text-zinc-500 uppercase tracking-wider">{copy.cancelled}</p>
@@ -365,7 +365,7 @@ export default function AdminBillingPage() {
{sub.status} {sub.status}
</span> </span>
{sub.cancelAtPeriodEnd && ( {sub.cancelAtPeriodEnd && (
<span className="text-xs text-amber-500">{copy.cancelAtEnd}</span> <span className="text-xs text-orange-500">{copy.cancelAtEnd}</span>
)} )}
</div> </div>
</td> </td>
@@ -388,7 +388,7 @@ export default function AdminBillingPage() {
</div> </div>
{invoiceModal && ( {invoiceModal && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-4"> <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#07101e]/70 p-4">
<div className="w-full max-w-2xl rounded-2xl bg-zinc-900 border border-zinc-800 shadow-2xl flex flex-col max-h-[80vh]"> <div className="w-full max-w-2xl rounded-2xl bg-zinc-900 border border-zinc-800 shadow-2xl flex flex-col max-h-[80vh]">
<div className="flex items-center justify-between px-6 py-4 border-b border-zinc-800"> <div className="flex items-center justify-between px-6 py-4 border-b border-zinc-800">
<div> <div>
@@ -140,7 +140,7 @@ const STATUS_COLORS: Record<string, string> = {
ACTIVE: 'text-emerald-400', ACTIVE: 'text-emerald-400',
TRIALING: 'text-sky-400', TRIALING: 'text-sky-400',
SUSPENDED: 'text-red-400', SUSPENDED: 'text-red-400',
PENDING: 'text-amber-400', PENDING: 'text-orange-400',
CANCELLED: 'text-zinc-400', CANCELLED: 'text-zinc-400',
PAST_DUE: 'text-orange-400', PAST_DUE: 'text-orange-400',
} }
@@ -19,7 +19,7 @@ const STATUS_COLORS: Record<string, string> = {
ACTIVE: 'text-emerald-400 bg-emerald-900/30', ACTIVE: 'text-emerald-400 bg-emerald-900/30',
TRIALING: 'text-sky-400 bg-sky-900/30', TRIALING: 'text-sky-400 bg-sky-900/30',
SUSPENDED: 'text-red-400 bg-red-900/30', SUSPENDED: 'text-red-400 bg-red-900/30',
PENDING: 'text-amber-400 bg-amber-900/30', PENDING: 'text-orange-400 bg-orange-900/30',
CANCELLED: 'text-zinc-400 bg-zinc-800', CANCELLED: 'text-zinc-400 bg-zinc-800',
} }
@@ -34,7 +34,7 @@ function StatusBadge({ status }: { status: ContainerStatus }) {
PENDING: { label: 'Pending', className: 'bg-zinc-700 text-zinc-300' }, PENDING: { label: 'Pending', className: 'bg-zinc-700 text-zinc-300' },
CREATING: { label: 'Creating…', className: 'bg-blue-900 text-blue-300 animate-pulse' }, CREATING: { label: 'Creating…', className: 'bg-blue-900 text-blue-300 animate-pulse' },
RUNNING: { label: 'Running', className: 'bg-emerald-900 text-emerald-300' }, RUNNING: { label: 'Running', className: 'bg-emerald-900 text-emerald-300' },
STOPPED: { label: 'Stopped', className: 'bg-yellow-900 text-yellow-300' }, STOPPED: { label: 'Stopped', className: 'bg-orange-900 text-orange-300' },
RESTARTING: { label: 'Restarting…',className: 'bg-orange-900 text-orange-300 animate-pulse' }, RESTARTING: { label: 'Restarting…',className: 'bg-orange-900 text-orange-300 animate-pulse' },
REMOVING: { label: 'Removing…', className: 'bg-red-900 text-red-300 animate-pulse' }, REMOVING: { label: 'Removing…', className: 'bg-red-900 text-red-300 animate-pulse' },
ERROR: { label: 'Error', className: 'bg-red-950 text-red-400' }, ERROR: { label: 'Error', className: 'bg-red-950 text-red-400' },
@@ -71,7 +71,7 @@ function LogsModal({ companyId, companyName, onClose }: { companyId: string; com
useEffect(() => { bottomRef.current?.scrollIntoView() }, [logs]) useEffect(() => { bottomRef.current?.scrollIntoView() }, [logs])
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-4" onClick={onClose}> <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#07101e]/70 p-4" onClick={onClose}>
<div className="flex h-[80vh] w-full max-w-4xl flex-col rounded-2xl border border-zinc-700 bg-zinc-900 shadow-2xl" onClick={(e) => e.stopPropagation()}> <div className="flex h-[80vh] w-full max-w-4xl flex-col rounded-2xl border border-zinc-700 bg-zinc-900 shadow-2xl" onClick={(e) => e.stopPropagation()}>
<div className="flex items-center justify-between border-b border-zinc-700 px-5 py-4"> <div className="flex items-center justify-between border-b border-zinc-700 px-5 py-4">
<div> <div>
@@ -272,7 +272,7 @@ export default function ContainersPage() {
{[ {[
{ label: 'Total', value: stats.total, color: 'text-zinc-100' }, { label: 'Total', value: stats.total, color: 'text-zinc-100' },
{ label: 'Running', value: stats.running, color: 'text-emerald-400' }, { label: 'Running', value: stats.running, color: 'text-emerald-400' },
{ label: 'Stopped', value: stats.stopped, color: 'text-yellow-400' }, { label: 'Stopped', value: stats.stopped, color: 'text-orange-400' },
{ label: 'Error', value: stats.error, color: 'text-red-400' }, { label: 'Error', value: stats.error, color: 'text-red-400' },
].map((s) => ( ].map((s) => (
<div key={s.label} className="rounded-xl border border-zinc-800 bg-zinc-900 p-4"> <div key={s.label} className="rounded-xl border border-zinc-800 bg-zinc-900 p-4">
@@ -418,7 +418,7 @@ function ActionButton({
}) { }) {
const colorMap: Record<string, string> = { const colorMap: Record<string, string> = {
emerald: 'border-emerald-800 text-emerald-400 hover:bg-emerald-900/40', emerald: 'border-emerald-800 text-emerald-400 hover:bg-emerald-900/40',
yellow: 'border-yellow-800 text-yellow-400 hover:bg-yellow-900/40', yellow: 'border-orange-800 text-orange-400 hover:bg-orange-900/40',
blue: 'border-blue-800 text-blue-400 hover:bg-blue-900/40', blue: 'border-blue-800 text-blue-400 hover:bg-blue-900/40',
purple: 'border-purple-800 text-purple-400 hover:bg-purple-900/40', purple: 'border-purple-800 text-purple-400 hover:bg-purple-900/40',
zinc: 'border-zinc-700 text-zinc-400 hover:bg-zinc-700/40', zinc: 'border-zinc-700 text-zinc-400 hover:bg-zinc-700/40',
+9 -9
View File
@@ -50,18 +50,18 @@ export default function AdminDashboardLayout({ children }: { children: React.Rea
if (!ready) { if (!ready) {
return ( return (
<div className="flex h-screen items-center justify-center bg-[linear-gradient(180deg,#f8f5ef_0%,#f4efe6_28%,#fffdf8_58%,#ffffff_100%)] dark:bg-[linear-gradient(180deg,#14110f_0%,#17120d_35%,#0c0a09_100%)]"> <div className="flex h-screen items-center justify-center bg-[linear-gradient(180deg,#ffffff_0%,#f5f8ff_28%,#eef4ff_58%,#ffffff_100%)] dark:bg-[linear-gradient(180deg,#0a1128_0%,#0d1b38_35%,#07101e_100%)]">
<div className="h-6 w-6 animate-spin rounded-full border-2 border-amber-500 border-t-transparent" aria-label={dict.loading} /> <div className="h-6 w-6 animate-spin rounded-full border-2 border-orange-500 border-t-transparent" aria-label={dict.loading} />
</div> </div>
) )
} }
return ( return (
<div className="flex h-screen bg-[linear-gradient(180deg,#f8f5ef_0%,#f4efe6_28%,#fffdf8_58%,#ffffff_100%)] text-stone-900 transition-colors dark:bg-[linear-gradient(180deg,#14110f_0%,#17120d_35%,#0c0a09_100%)] dark:text-stone-100"> <div className="flex h-screen bg-[linear-gradient(180deg,#ffffff_0%,#f5f8ff_28%,#eef4ff_58%,#ffffff_100%)] text-stone-900 transition-colors dark:bg-[linear-gradient(180deg,#0a1128_0%,#0d1b38_35%,#07101e_100%)] dark:text-slate-100">
<aside className="flex w-60 flex-shrink-0 flex-col border-r border-stone-200/80 bg-white/78 backdrop-blur-xl transition-colors dark:border-stone-800 dark:bg-stone-950/78"> <aside className="flex w-60 flex-shrink-0 flex-col border-r border-stone-200/80 bg-white/78 backdrop-blur-xl transition-colors dark:border-blue-900 dark:bg-[#07101e]/78">
<Link href="/" className="block px-5 py-6"> <Link href="/" className="block px-5 py-6">
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-amber-700 dark:text-amber-300">{dict.admin}</p> <p className="text-xs font-semibold uppercase tracking-[0.2em] text-orange-700 dark:text-orange-300">{dict.admin}</p>
<p className="mt-0.5 text-sm font-semibold text-stone-950 dark:text-stone-100">RentalDriveGo</p> <p className="mt-0.5 text-sm font-semibold text-blue-950 dark:text-stone-100">RentalDriveGo</p>
</Link> </Link>
<nav className="flex-1 px-3 space-y-0.5"> <nav className="flex-1 px-3 space-y-0.5">
{navLinks.map((link) => { {navLinks.map((link) => {
@@ -71,7 +71,7 @@ export default function AdminDashboardLayout({ children }: { children: React.Rea
key={link.href} key={link.href}
href={link.href} href={link.href}
className={`flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-medium transition-colors ${ className={`flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-medium transition-colors ${
active ? 'bg-stone-900 text-white dark:bg-amber-400 dark:text-stone-950' : 'text-stone-500 hover:text-stone-950 hover:bg-stone-100 dark:text-stone-400 dark:hover:text-white dark:hover:bg-stone-800' active ? 'bg-orange-600 text-white dark:bg-orange-500 dark:text-white' : 'text-stone-500 hover:text-blue-900 hover:bg-stone-100 dark:text-slate-400 dark:hover:text-white dark:hover:bg-[#162038]'
}`} }`}
> >
<svg className="h-4 w-4 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}> <svg className="h-4 w-4 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
@@ -85,14 +85,14 @@ export default function AdminDashboardLayout({ children }: { children: React.Rea
<div className="px-3 py-4"> <div className="px-3 py-4">
<button <button
onClick={handleLogout} onClick={handleLogout}
className="flex w-full items-center gap-3 rounded-xl px-3 py-2.5 text-sm font-medium text-stone-500 transition-colors hover:bg-stone-100 hover:text-red-500 dark:text-stone-400 dark:hover:bg-stone-800 dark:hover:text-red-300" className="flex w-full items-center gap-3 rounded-xl px-3 py-2.5 text-sm font-medium text-stone-500 transition-colors hover:bg-stone-100 hover:text-red-500 dark:text-stone-400 dark:hover:bg-[#162038] dark:hover:text-red-300"
> >
<svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}> <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" /> <path strokeLinecap="round" strokeLinejoin="round" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
</svg> </svg>
{dict.logout} {dict.logout}
</button> </button>
<div className="mt-4 flex flex-col items-center gap-3 border-t border-stone-200/80 pt-4 dark:border-stone-800"> <div className="mt-4 flex flex-col items-center gap-3 border-t border-stone-200/80 pt-4 dark:border-blue-900">
<AdminLanguageSwitcher /> <AdminLanguageSwitcher />
<AdminThemeSwitcher /> <AdminThemeSwitcher />
</div> </div>
@@ -28,7 +28,7 @@ const STATUS_COLORS: Record<string, string> = {
ACTIVE: 'text-emerald-400 bg-emerald-900/30', ACTIVE: 'text-emerald-400 bg-emerald-900/30',
TRIALING: 'text-sky-400 bg-sky-900/30', TRIALING: 'text-sky-400 bg-sky-900/30',
SUSPENDED: 'text-red-400 bg-red-900/30', SUSPENDED: 'text-red-400 bg-red-900/30',
PENDING: 'text-amber-400 bg-amber-900/30', PENDING: 'text-orange-400 bg-orange-900/30',
CANCELLED: 'text-zinc-400 bg-zinc-800', CANCELLED: 'text-zinc-400 bg-zinc-800',
} }
@@ -415,7 +415,7 @@ export default function AdminSiteConfigPage() {
<div className="border-b border-stone-200 bg-white/90 px-5 py-4"> <div className="border-b border-stone-200 bg-white/90 px-5 py-4">
<div className="flex flex-wrap items-center justify-between gap-3"> <div className="flex flex-wrap items-center justify-between gap-3">
<div> <div>
<p className="text-xs font-bold uppercase tracking-[0.32em] text-amber-700">{activeContent.heroKicker}</p> <p className="text-xs font-bold uppercase tracking-[0.32em] text-orange-700">{activeContent.heroKicker}</p>
<p className="mt-2 text-sm text-stone-500">rentaldrivego.com</p> <p className="mt-2 text-sm text-stone-500">rentaldrivego.com</p>
</div> </div>
<div className="flex flex-wrap gap-2 text-xs font-semibold text-stone-600"> <div className="flex flex-wrap gap-2 text-xs font-semibold text-stone-600">
@@ -431,17 +431,17 @@ export default function AdminSiteConfigPage() {
<div className="space-y-10 px-5 py-6 lg:px-8"> <div className="space-y-10 px-5 py-6 lg:px-8">
{activeSections.includes('hero') ? <section className="grid gap-6 lg:grid-cols-[1.1fr_0.9fr] lg:items-center"> {activeSections.includes('hero') ? <section className="grid gap-6 lg:grid-cols-[1.1fr_0.9fr] lg:items-center">
<div> <div>
<h4 className="text-4xl font-black tracking-[-0.04em] text-stone-950">{activeContent.heroTitle}</h4> <h4 className="text-4xl font-black tracking-[-0.04em] text-blue-950">{activeContent.heroTitle}</h4>
<p className="mt-5 max-w-2xl text-base leading-8 text-stone-600">{activeContent.heroBody}</p> <p className="mt-5 max-w-2xl text-base leading-8 text-stone-600">{activeContent.heroBody}</p>
<div className="mt-8 flex flex-wrap gap-3"> <div className="mt-8 flex flex-wrap gap-3">
<span className="rounded-full bg-stone-950 px-5 py-3 text-sm font-semibold text-white">{activeContent.startTrial}</span> <span className="rounded-full bg-orange-600 px-5 py-3 text-sm font-semibold text-white">{activeContent.startTrial}</span>
<span className="rounded-full border border-stone-300 bg-white px-5 py-3 text-sm font-semibold text-stone-700">{activeContent.exploreVehicles}</span> <span className="rounded-full border border-stone-300 bg-white px-5 py-3 text-sm font-semibold text-stone-700">{activeContent.exploreVehicles}</span>
</div> </div>
</div> </div>
{activeSections.includes('surface') ? ( {activeSections.includes('surface') ? (
<div className="rounded-[1.5rem] bg-stone-950 p-6 text-white"> <div className="rounded-[1.5rem] bg-[#06132e] p-6 text-white">
<div className="flex items-center justify-between gap-3"> <div className="flex items-center justify-between gap-3">
<span className="rounded-full border border-white/15 bg-white/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-amber-200"> <span className="rounded-full border border-white/15 bg-white/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-orange-200">
{activeContent.surfaceLabel} {activeContent.surfaceLabel}
</span> </span>
<span className="rounded-full bg-emerald-400/15 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-emerald-200"> <span className="rounded-full bg-emerald-400/15 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-emerald-200">
@@ -462,9 +462,9 @@ export default function AdminSiteConfigPage() {
</section> : null} </section> : null}
{activeSections.includes('surface') && !activeSections.includes('hero') ? ( {activeSections.includes('surface') && !activeSections.includes('hero') ? (
<section className="rounded-[1.5rem] bg-stone-950 p-6 text-white"> <section className="rounded-[1.5rem] bg-[#06132e] p-6 text-white">
<div className="flex items-center justify-between gap-3"> <div className="flex items-center justify-between gap-3">
<span className="rounded-full border border-white/15 bg-white/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-amber-200"> <span className="rounded-full border border-white/15 bg-white/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-orange-200">
{activeContent.surfaceLabel} {activeContent.surfaceLabel}
</span> </span>
<span className="rounded-full bg-emerald-400/15 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-emerald-200"> <span className="rounded-full bg-emerald-400/15 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-emerald-200">
@@ -480,7 +480,7 @@ export default function AdminSiteConfigPage() {
{activeContent.pillars.map((pillar, index) => ( {activeContent.pillars.map((pillar, index) => (
<article <article
key={`${pillar.title}-${index}`} key={`${pillar.title}-${index}`}
className={`rounded-[1.5rem] border p-5 ${index === 1 ? 'border-stone-900 bg-stone-950 text-white' : 'border-stone-200 bg-white text-stone-900'}`} className={`rounded-[1.5rem] border p-5 ${index === 1 ? 'border-orange-700 bg-orange-600 text-white' : 'border-stone-200 bg-white text-stone-900'}`}
> >
<p className={`text-xs font-bold uppercase tracking-[0.24em] ${index === 1 ? 'text-stone-300' : 'text-stone-400'}`}>0{index + 1}</p> <p className={`text-xs font-bold uppercase tracking-[0.24em] ${index === 1 ? 'text-stone-300' : 'text-stone-400'}`}>0{index + 1}</p>
<h5 className="mt-3 text-xl font-black">{pillar.title}</h5> <h5 className="mt-3 text-xl font-black">{pillar.title}</h5>
@@ -492,12 +492,12 @@ export default function AdminSiteConfigPage() {
{activeSections.includes('audiences') ? <section className="grid gap-4 lg:grid-cols-2"> {activeSections.includes('audiences') ? <section className="grid gap-4 lg:grid-cols-2">
<article className="rounded-[1.5rem] border border-stone-200 bg-white p-5"> <article className="rounded-[1.5rem] border border-stone-200 bg-white p-5">
<p className="text-xs font-bold uppercase tracking-[0.24em] text-stone-500">{activeContent.companyKicker}</p> <p className="text-xs font-bold uppercase tracking-[0.24em] text-stone-500">{activeContent.companyKicker}</p>
<h5 className="mt-3 text-2xl font-black text-stone-950">{activeContent.companyTitle}</h5> <h5 className="mt-3 text-2xl font-black text-blue-950">{activeContent.companyTitle}</h5>
<p className="mt-3 text-sm leading-7 text-stone-600">{activeContent.companyBody}</p> <p className="mt-3 text-sm leading-7 text-stone-600">{activeContent.companyBody}</p>
</article> </article>
<article className="rounded-[1.5rem] border border-stone-200 bg-[#f7efe2] p-5"> <article className="rounded-[1.5rem] border border-stone-200 bg-[#f7efe2] p-5">
<p className="text-xs font-bold uppercase tracking-[0.24em] text-amber-700">{activeContent.renterKicker}</p> <p className="text-xs font-bold uppercase tracking-[0.24em] text-orange-700">{activeContent.renterKicker}</p>
<h5 className="mt-3 text-2xl font-black text-stone-950">{activeContent.renterTitle}</h5> <h5 className="mt-3 text-2xl font-black text-blue-950">{activeContent.renterTitle}</h5>
<p className="mt-3 text-sm leading-7 text-stone-700">{activeContent.renterBody}</p> <p className="mt-3 text-sm leading-7 text-stone-700">{activeContent.renterBody}</p>
</article> </article>
</section> : null} </section> : null}
@@ -509,7 +509,7 @@ export default function AdminSiteConfigPage() {
<div className="mt-5 space-y-3"> <div className="mt-5 space-y-3">
{activeContent.features.map((feature, index) => ( {activeContent.features.map((feature, index) => (
<div key={`${feature}-${index}`} className="flex items-start gap-3 rounded-[1rem] border border-stone-200 bg-white px-4 py-3"> <div key={`${feature}-${index}`} className="flex items-start gap-3 rounded-[1rem] border border-stone-200 bg-white px-4 py-3">
<span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-stone-950 text-xs font-bold text-white"> <span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-orange-600 text-xs font-bold text-white">
{index + 1} {index + 1}
</span> </span>
<p className="text-sm font-semibold leading-6 text-stone-800">{feature}</p> <p className="text-sm font-semibold leading-6 text-stone-800">{feature}</p>
@@ -520,13 +520,13 @@ export default function AdminSiteConfigPage() {
) : <div />} ) : <div />}
{activeSections.includes('steps') ? ( {activeSections.includes('steps') ? (
<article className="rounded-[1.5rem] border border-stone-200 bg-white p-5"> <article className="rounded-[1.5rem] border border-stone-200 bg-white p-5">
<p className="text-xs font-bold uppercase tracking-[0.24em] text-amber-700">{activeContent.readyKicker}</p> <p className="text-xs font-bold uppercase tracking-[0.24em] text-orange-700">{activeContent.readyKicker}</p>
<h5 className="mt-3 text-2xl font-black text-stone-950">{activeContent.stepsTitle}</h5> <h5 className="mt-3 text-2xl font-black text-blue-950">{activeContent.stepsTitle}</h5>
<div className="mt-5 space-y-3"> <div className="mt-5 space-y-3">
{activeContent.steps.map((step) => ( {activeContent.steps.map((step) => (
<div key={step.step} className="rounded-[1rem] border border-stone-200 bg-stone-50 p-4"> <div key={step.step} className="rounded-[1rem] border border-stone-200 bg-stone-50 p-4">
<p className="text-xs font-bold uppercase tracking-[0.24em] text-stone-500">{activeContent.stepLabel} {step.step}</p> <p className="text-xs font-bold uppercase tracking-[0.24em] text-stone-500">{activeContent.stepLabel} {step.step}</p>
<h6 className="mt-2 text-lg font-black text-stone-950">{step.title}</h6> <h6 className="mt-2 text-lg font-black text-blue-950">{step.title}</h6>
<p className="mt-2 text-sm leading-7 text-stone-600">{step.body}</p> <p className="mt-2 text-sm leading-7 text-stone-600">{step.body}</p>
</div> </div>
))} ))}
@@ -535,13 +535,13 @@ export default function AdminSiteConfigPage() {
) : <div />} ) : <div />}
</section> : null} </section> : null}
{activeSections.includes('closing') ? <section className="rounded-[1.5rem] bg-stone-950 px-6 py-7 text-white"> {activeSections.includes('closing') ? <section className="rounded-[1.5rem] bg-[#06132e] px-6 py-7 text-white">
<p className="text-xs font-bold uppercase tracking-[0.28em] text-amber-300">{activeContent.readyKicker}</p> <p className="text-xs font-bold uppercase tracking-[0.28em] text-orange-300">{activeContent.readyKicker}</p>
<h5 className="mt-4 max-w-3xl text-3xl font-black tracking-[-0.04em]">{activeContent.readyTitle}</h5> <h5 className="mt-4 max-w-3xl text-3xl font-black tracking-[-0.04em]">{activeContent.readyTitle}</h5>
<p className="mt-4 max-w-2xl text-sm leading-8 text-stone-300">{activeContent.readyBody}</p> <p className="mt-4 max-w-2xl text-sm leading-8 text-stone-300">{activeContent.readyBody}</p>
<div className="mt-6 flex flex-wrap gap-3"> <div className="mt-6 flex flex-wrap gap-3">
<span className="rounded-full border border-white/20 px-5 py-3 text-sm font-semibold">{activeContent.viewPricing}</span> <span className="rounded-full border border-white/20 px-5 py-3 text-sm font-semibold">{activeContent.viewPricing}</span>
<span className="rounded-full bg-amber-300 px-5 py-3 text-sm font-semibold text-stone-950">{activeContent.createWorkspace}</span> <span className="rounded-full bg-orange-300 px-5 py-3 text-sm font-semibold text-blue-950">{activeContent.createWorkspace}</span>
</div> </div>
</section> : null} </section> : null}
</div> </div>
+3 -3
View File
@@ -35,7 +35,7 @@ export default function AdminForgotPasswordPage() {
<main className="flex flex-1 items-center justify-center px-4"> <main className="flex flex-1 items-center justify-center px-4">
<div className="w-full max-w-md"> <div className="w-full max-w-md">
<div className="mb-8 text-center"> <div className="mb-8 text-center">
<Link href="/" className="text-xs font-semibold uppercase tracking-[0.2em] text-amber-700 dark:text-amber-300">RentalDriveGo</Link> <Link href="/" className="text-xs font-semibold uppercase tracking-[0.2em] text-orange-700 dark:text-orange-300">RentalDriveGo</Link>
<h1 className="mt-3 text-3xl font-black tracking-tight">Forgot password</h1> <h1 className="mt-3 text-3xl font-black tracking-tight">Forgot password</h1>
<p className="mt-1 text-sm text-zinc-400">Enter your admin email to receive a reset link.</p> <p className="mt-1 text-sm text-zinc-400">Enter your admin email to receive a reset link.</p>
</div> </div>
@@ -64,13 +64,13 @@ export default function AdminForgotPasswordPage() {
value={email} value={email}
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setEmail(e.target.value)}
placeholder="admin@rentaldrivego.com" placeholder="admin@rentaldrivego.com"
className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm text-stone-900 placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-amber-500 dark:border-stone-700 dark:bg-stone-950/80 dark:text-stone-100 dark:placeholder:text-stone-500" className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm text-stone-900 placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-orange-500 dark:border-blue-800 dark:bg-[#07101e]/80 dark:text-stone-100 dark:placeholder:text-stone-500"
/> />
</div> </div>
<button <button
type="submit" type="submit"
disabled={loading} disabled={loading}
className="inline-flex w-full justify-center rounded-full bg-stone-900 px-6 py-3 text-sm font-semibold text-white transition hover:bg-stone-700 disabled:opacity-50 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300" className="inline-flex w-full justify-center rounded-full bg-stone-900 px-6 py-3 text-sm font-semibold text-white transition hover:bg-orange-700 disabled:opacity-50 dark:bg-orange-400 dark:text-white dark:hover:bg-orange-300"
> >
{loading ? 'Sending…' : 'Send reset link'} {loading ? 'Sending…' : 'Send reset link'}
</button> </button>
+28 -25
View File
@@ -11,9 +11,9 @@ html.dark {
} }
body { body {
@apply text-stone-900 antialiased transition-colors dark:text-stone-100; @apply text-blue-950 antialiased transition-colors dark:text-slate-100;
background-image: background-image:
linear-gradient(180deg, #f8f5ef 0%, #f4efe6 28%, #fffdf8 58%, #ffffff 100%); linear-gradient(180deg, #ffffff 0%, #f5f8ff 28%, #eef4ff 58%, #ffffff 100%);
} }
.shell { .shell {
@@ -21,19 +21,19 @@ body {
} }
.panel { .panel {
@apply rounded-[1.75rem] border shadow-[0_30px_80px_rgba(28,25,23,0.08)] backdrop-blur transition-colors dark:shadow-[0_30px_80px_rgba(0,0,0,0.26)]; @apply rounded-[1.75rem] border shadow-[0_30px_80px_rgba(28,25,23,0.08)] backdrop-blur transition-colors dark:shadow-[0_30px_80px_rgba(0,0,0,0.36)];
border-color: rgb(231 229 228 / 0.8); border-color: rgb(231 229 228 / 0.8);
background-color: rgb(255 255 255 / 0.82); background-color: rgb(255 255 255 / 0.82);
} }
html.dark body { html.dark body {
background-image: background-image:
linear-gradient(180deg, #14110f 0%, #17120d 35%, #0c0a09 100%); linear-gradient(180deg, #0a1128 0%, #0d1b38 35%, #07101e 100%);
} }
html.dark .panel { html.dark .panel {
border-color: rgb(41 37 36 / 0.96); border-color: rgb(30 60 140 / 0.40);
background-color: rgb(28 25 23 / 0.72); background-color: rgb(11 25 55 / 0.72);
} }
@layer utilities { @layer utilities {
@@ -41,89 +41,92 @@ html.dark .panel {
color: rgb(28 25 23); color: rgb(28 25 23);
} }
/* ── Dark mode: zinc classes → deep navy blue ─────────────── */
.bg-zinc-950 { .bg-zinc-950 {
background-color: rgb(12 10 9); background-color: rgb(6 13 30);
} }
.bg-zinc-950\/90 { .bg-zinc-950\/90 {
background-color: rgb(28 25 23 / 0.9); background-color: rgb(6 13 30 / 0.9);
} }
.bg-zinc-900 { .bg-zinc-900 {
background-color: rgb(28 25 23); background-color: rgb(11 25 55);
} }
.bg-zinc-800, .bg-zinc-800,
.bg-zinc-800\/50 { .bg-zinc-800\/50 {
background-color: rgb(41 37 36); background-color: rgb(20 42 90);
} }
.border-zinc-800, .border-zinc-800,
.border-zinc-700 { .border-zinc-700 {
border-color: rgb(68 64 60); border-color: rgb(30 60 130);
} }
.text-zinc-100, .text-zinc-100,
.text-zinc-200 { .text-zinc-200 {
color: rgb(250 250 249); color: rgb(241 245 249);
} }
.text-zinc-500 { .text-zinc-500 {
color: rgb(168 162 158); color: rgb(148 163 184);
} }
.text-zinc-400, .text-zinc-400,
.text-zinc-300 { .text-zinc-300 {
color: rgb(120 113 108); color: rgb(100 116 139);
} }
.hover\:bg-zinc-800:hover, .hover\:bg-zinc-800:hover,
.hover\:bg-zinc-800\/50:hover { .hover\:bg-zinc-800\/50:hover {
background-color: rgb(68 64 60); background-color: rgb(30 55 115);
} }
.hover\:text-zinc-200:hover { .hover\:text-zinc-200:hover {
color: rgb(250 250 249); color: rgb(241 245 249);
} }
/* ── Primary action (emerald class → orange) ──────────────── */
.text-emerald-400 { .text-emerald-400 {
color: rgb(252 211 77); color: rgb(251 146 60);
} }
.bg-emerald-600 { .bg-emerald-600 {
background-color: rgb(28 25 23); background-color: rgb(234 88 12);
} }
.hover\:bg-emerald-500:hover { .hover\:bg-emerald-500:hover {
background-color: rgb(68 64 60); background-color: rgb(194 65 12);
} }
.dark .bg-emerald-600 { .dark .bg-emerald-600 {
background-color: rgb(251 191 36); background-color: rgb(249 115 22);
} }
.dark .hover\:bg-emerald-500:hover { .dark .hover\:bg-emerald-500:hover {
background-color: rgb(252 211 77); background-color: rgb(251 146 60);
} }
.bg-emerald-900\/30, .bg-emerald-900\/30,
.bg-emerald-950\/40, .bg-emerald-950\/40,
.bg-emerald-950\/50 { .bg-emerald-950\/50 {
background-color: rgb(120 53 15 / 0.32); background-color: rgb(154 52 18 / 0.22);
} }
.border-emerald-500 { .border-emerald-500 {
border-color: rgb(245 158 11); border-color: rgb(249 115 22);
} }
.focus\:ring-emerald-500:focus { .focus\:ring-emerald-500:focus {
--tw-ring-color: rgb(217 119 6 / 0.45); --tw-ring-color: rgb(234 88 12 / 0.45);
} }
.hover\:bg-emerald-900\/50:hover { .hover\:bg-emerald-900\/50:hover {
background-color: rgb(146 64 14 / 0.42); background-color: rgb(154 52 18 / 0.35);
} }
/* ── Light mode: zinc classes → white / stone-light ──────── */
.light .bg-zinc-950 { .light .bg-zinc-950 {
background-color: rgb(255 253 248); background-color: rgb(255 253 248);
} }
+5 -5
View File
@@ -77,7 +77,7 @@ function AdminResetPasswordContent() {
<button <button
type="button" type="button"
onClick={() => router.push('/login')} onClick={() => router.push('/login')}
className="mt-2 inline-flex w-full justify-center rounded-full bg-stone-900 px-6 py-3 text-sm font-semibold text-white transition hover:bg-stone-700 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300" className="mt-2 inline-flex w-full justify-center rounded-full bg-stone-900 px-6 py-3 text-sm font-semibold text-white transition hover:bg-orange-700 dark:bg-orange-400 dark:text-white dark:hover:bg-orange-300"
> >
Sign in Sign in
</button> </button>
@@ -101,7 +101,7 @@ function AdminResetPasswordContent() {
value={password} value={password}
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
placeholder="••••••••" placeholder="••••••••"
className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm text-stone-900 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-amber-500 dark:border-stone-700 dark:bg-stone-950/80 dark:text-stone-100" className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm text-stone-900 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-orange-500 dark:border-blue-800 dark:bg-[#07101e]/80 dark:text-stone-100"
/> />
</div> </div>
<div> <div>
@@ -113,13 +113,13 @@ function AdminResetPasswordContent() {
value={confirm} value={confirm}
onChange={(e) => setConfirm(e.target.value)} onChange={(e) => setConfirm(e.target.value)}
placeholder="••••••••" placeholder="••••••••"
className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm text-stone-900 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-amber-500 dark:border-stone-700 dark:bg-stone-950/80 dark:text-stone-100" className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm text-stone-900 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-orange-500 dark:border-blue-800 dark:bg-[#07101e]/80 dark:text-stone-100"
/> />
</div> </div>
<button <button
type="submit" type="submit"
disabled={loading} disabled={loading}
className="inline-flex w-full justify-center rounded-full bg-stone-900 px-6 py-3 text-sm font-semibold text-white transition hover:bg-stone-700 disabled:opacity-50 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300" className="inline-flex w-full justify-center rounded-full bg-stone-900 px-6 py-3 text-sm font-semibold text-white transition hover:bg-orange-700 disabled:opacity-50 dark:bg-orange-400 dark:text-white dark:hover:bg-orange-300"
> >
{loading ? 'Resetting…' : 'Reset password'} {loading ? 'Resetting…' : 'Reset password'}
</button> </button>
@@ -140,7 +140,7 @@ function AdminResetShell({ children }: { children: React.ReactNode }) {
<main className="flex flex-1 items-center justify-center px-4"> <main className="flex flex-1 items-center justify-center px-4">
<div className="w-full max-w-md"> <div className="w-full max-w-md">
<div className="mb-8 text-center"> <div className="mb-8 text-center">
<Link href="/" className="text-xs font-semibold uppercase tracking-[0.2em] text-amber-700 dark:text-amber-300">RentalDriveGo</Link> <Link href="/" className="text-xs font-semibold uppercase tracking-[0.2em] text-orange-700 dark:text-orange-300">RentalDriveGo</Link>
<h1 className="mt-3 text-3xl font-black tracking-tight">Reset password</h1> <h1 className="mt-3 text-3xl font-black tracking-tight">Reset password</h1>
</div> </div>
<div className="panel p-8">{children}</div> <div className="panel p-8">{children}</div>
+4 -4
View File
@@ -167,7 +167,7 @@ export function AdminLanguageSwitcher() {
if (embedded) return null if (embedded) return null
return ( return (
<div className="flex items-center gap-1 rounded-full border border-stone-200/80 bg-white/95 px-2 py-1 shadow-sm transition-colors dark:border-stone-700 dark:bg-stone-900/85"> <div className="flex items-center gap-1 rounded-full border border-stone-200/80 bg-white/95 px-2 py-1 shadow-sm transition-colors dark:border-blue-800 dark:bg-[#0d1b38]/85">
<span className="px-2 text-[11px] font-semibold uppercase tracking-[0.16em] text-stone-500 dark:text-stone-400">{dict.language}</span> <span className="px-2 text-[11px] font-semibold uppercase tracking-[0.16em] text-stone-500 dark:text-stone-400">{dict.language}</span>
{(['en', 'fr', 'ar'] as AdminLanguage[]).map((value) => { {(['en', 'fr', 'ar'] as AdminLanguage[]).map((value) => {
const active = value === language const active = value === language
@@ -178,7 +178,7 @@ export function AdminLanguageSwitcher() {
type="button" type="button"
onClick={() => setLanguage(value)} onClick={() => setLanguage(value)}
className={`rounded-full px-3 py-1.5 text-xs font-semibold transition ${ className={`rounded-full px-3 py-1.5 text-xs font-semibold transition ${
active ? 'bg-stone-900 text-white dark:bg-amber-400 dark:text-stone-950' : 'text-stone-600 hover:bg-stone-100 dark:text-stone-300 dark:hover:bg-stone-800' active ? 'bg-blue-900 text-white dark:bg-orange-400 dark:text-white' : 'text-stone-600 hover:bg-stone-100 dark:text-stone-300 dark:hover:bg-[#162038]'
}`} }`}
> >
<span className="inline-flex items-center gap-1.5"> <span className="inline-flex items-center gap-1.5">
@@ -203,7 +203,7 @@ export function AdminThemeSwitcher() {
if (embedded) return null if (embedded) return null
return ( return (
<div className="flex items-center gap-1 rounded-full border border-stone-200/80 bg-white/95 px-2 py-1 shadow-sm transition-colors dark:border-stone-700 dark:bg-stone-900/85"> <div className="flex items-center gap-1 rounded-full border border-stone-200/80 bg-white/95 px-2 py-1 shadow-sm transition-colors dark:border-blue-800 dark:bg-[#0d1b38]/85">
{(['light', 'dark'] as AdminTheme[]).map((value) => { {(['light', 'dark'] as AdminTheme[]).map((value) => {
const active = value === theme const active = value === theme
return ( return (
@@ -212,7 +212,7 @@ export function AdminThemeSwitcher() {
type="button" type="button"
onClick={() => setTheme(value)} onClick={() => setTheme(value)}
className={`rounded-full px-3 py-1.5 text-xs font-semibold transition ${ className={`rounded-full px-3 py-1.5 text-xs font-semibold transition ${
active ? 'bg-stone-900 text-white dark:bg-amber-400 dark:text-stone-950' : 'text-stone-600 hover:bg-stone-100 dark:text-stone-300 dark:hover:bg-stone-800' active ? 'bg-blue-900 text-white dark:bg-orange-400 dark:text-white' : 'text-stone-600 hover:bg-stone-100 dark:text-stone-300 dark:hover:bg-[#162038]'
}`} }`}
> >
{value === 'light' ? dict.light : dict.dark} {value === 'light' ? dict.light : dict.dark}
+2 -2
View File
@@ -28,11 +28,11 @@ export default function PublicFooter() {
}[language] }[language]
return ( return (
<footer className="border-t border-stone-200/80 bg-white/72 px-4 py-4 backdrop-blur-xl transition-colors dark:border-stone-800 dark:bg-stone-950/72"> <footer className="border-t border-stone-200/80 bg-white/72 px-4 py-4 backdrop-blur-xl transition-colors dark:border-blue-900 dark:bg-[#07101e]/72">
<div className="mx-auto flex max-w-6xl flex-col items-center justify-between gap-3 lg:flex-row"> <div className="mx-auto flex max-w-6xl flex-col items-center justify-between gap-3 lg:flex-row">
<div className="flex items-center gap-3 text-xs font-medium uppercase tracking-[0.16em] text-stone-400 dark:text-stone-500"> <div className="flex items-center gap-3 text-xs font-medium uppercase tracking-[0.16em] text-stone-400 dark:text-stone-500">
<p>{dict.preferences}</p> <p>{dict.preferences}</p>
<span className="inline-flex items-center gap-1 rounded-full border border-stone-200/80 bg-white/95 px-2.5 py-1 text-stone-700 dark:border-stone-700 dark:bg-stone-900/85 dark:text-stone-200"> <span className="inline-flex items-center gap-1 rounded-full border border-stone-200/80 bg-white/95 px-2.5 py-1 text-stone-700 dark:border-blue-800 dark:bg-[#0d1b38]/85 dark:text-stone-200">
<span aria-hidden="true">{currentLanguage.flag}</span> <span aria-hidden="true">{currentLanguage.flag}</span>
<span>{currentLanguage.shortLabel}</span> <span>{currentLanguage.shortLabel}</span>
</span> </span>
+4 -4
View File
@@ -28,18 +28,18 @@ export default function PublicHeader() {
}[language] }[language]
return ( return (
<header className="sticky top-0 z-30 border-b border-stone-200/80 bg-white/78 backdrop-blur-xl transition-colors dark:border-stone-800 dark:bg-stone-950/76"> <header className="sticky top-0 z-30 border-b border-stone-200/80 bg-white/78 backdrop-blur-xl transition-colors dark:border-blue-900 dark:bg-[#07101e]/76">
<div className="mx-auto flex max-w-6xl items-center justify-between gap-4 px-4 py-4"> <div className="mx-auto flex max-w-6xl items-center justify-between gap-4 px-4 py-4">
<Link href="/" className="flex items-center gap-3"> <Link href="/" className="flex items-center gap-3">
<span className="text-xs font-semibold uppercase tracking-[0.24em] text-amber-700 dark:text-amber-300">RentalDriveGo</span> <span className="text-xs font-semibold uppercase tracking-[0.24em] text-orange-700 dark:text-orange-300">RentalDriveGo</span>
<span className="hidden text-sm font-semibold text-stone-500 dark:text-stone-400 sm:inline">{dict.admin}</span> <span className="hidden text-sm font-semibold text-stone-500 dark:text-stone-400 sm:inline">{dict.admin}</span>
</Link> </Link>
<nav className="flex items-center gap-2"> <nav className="flex items-center gap-2">
<span className="inline-flex min-w-[3.5rem] items-center justify-center gap-1 rounded-full border border-stone-200/80 bg-white/95 px-2.5 py-2 text-xs font-semibold text-stone-700 dark:border-stone-700 dark:bg-stone-900/85 dark:text-stone-200"> <span className="inline-flex min-w-[3.5rem] items-center justify-center gap-1 rounded-full border border-stone-200/80 bg-white/95 px-2.5 py-2 text-xs font-semibold text-stone-700 dark:border-blue-800 dark:bg-[#0d1b38]/85 dark:text-stone-200">
<span aria-hidden="true">{currentLanguage.flag}</span> <span aria-hidden="true">{currentLanguage.flag}</span>
<span>{currentLanguage.shortLabel}</span> <span>{currentLanguage.shortLabel}</span>
</span> </span>
<Link href="/login" className="rounded-full bg-stone-900 px-4 py-2 text-sm font-semibold text-white transition hover:bg-stone-700 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300"> <Link href="/login" className="rounded-full bg-blue-900 px-4 py-2 text-sm font-semibold text-white transition hover:bg-orange-700 dark:bg-orange-400 dark:text-white dark:hover:bg-orange-300">
{dict.signIn} {dict.signIn}
</Link> </Link>
</nav> </nav>
+1 -1
View File
@@ -5,7 +5,7 @@ import PublicHeader from '@/components/PublicHeader'
export default function PublicShell({ children }: { children: React.ReactNode }) { export default function PublicShell({ children }: { children: React.ReactNode }) {
return ( return (
<div className="flex min-h-screen flex-col bg-[linear-gradient(180deg,#f8f5ef_0%,#f4efe6_28%,#fffdf8_58%,#ffffff_100%)] text-stone-900 transition-colors dark:bg-[linear-gradient(180deg,#14110f_0%,#17120d_35%,#0c0a09_100%)] dark:text-stone-100"> <div className="flex min-h-screen flex-col bg-[linear-gradient(180deg,#ffffff_0%,#f5f8ff_28%,#eef4ff_58%,#ffffff_100%)] text-blue-950 transition-colors dark:bg-[linear-gradient(180deg,#0a1128_0%,#0d1b38_35%,#07101e_100%)] dark:text-slate-100">
<PublicHeader /> <PublicHeader />
<div className="flex flex-1 flex-col">{children}</div> <div className="flex flex-1 flex-col">{children}</div>
<PublicFooter /> <PublicFooter />
@@ -45,7 +45,7 @@ type ManualPaymentMethod = 'CASH' | 'CHECK' | 'BANK_TRANSFER' | 'CARD' | 'PAYPAL
const PAYMENT_STATUS_BADGE: Record<string, string> = { const PAYMENT_STATUS_BADGE: Record<string, string> = {
UNPAID: 'bg-rose-100 text-rose-700', UNPAID: 'bg-rose-100 text-rose-700',
PAID: 'bg-emerald-100 text-emerald-700', PAID: 'bg-emerald-100 text-emerald-700',
PARTIAL: 'bg-amber-100 text-amber-700', PARTIAL: 'bg-orange-100 text-orange-700',
PENDING: 'bg-sky-100 text-sky-700', PENDING: 'bg-sky-100 text-sky-700',
REFUNDED: 'bg-slate-100 text-slate-700', REFUNDED: 'bg-slate-100 text-slate-700',
FAILED: 'bg-rose-100 text-rose-700', FAILED: 'bg-rose-100 text-rose-700',
@@ -53,7 +53,7 @@ const PAYMENT_STATUS_BADGE: Record<string, string> = {
} }
const PAYMENT_EVENT_BADGE: Record<string, string> = { const PAYMENT_EVENT_BADGE: Record<string, string> = {
PENDING: 'bg-amber-100 text-amber-700', PENDING: 'bg-orange-100 text-orange-700',
SUCCEEDED: 'bg-emerald-100 text-emerald-700', SUCCEEDED: 'bg-emerald-100 text-emerald-700',
FAILED: 'bg-rose-100 text-rose-700', FAILED: 'bg-rose-100 text-rose-700',
REFUNDED: 'bg-slate-100 text-slate-700', REFUNDED: 'bg-slate-100 text-slate-700',
@@ -506,7 +506,7 @@ export default function BillingPage() {
) : null} ) : null}
</td> </td>
<td className="px-6 py-4 text-right text-sm font-semibold text-emerald-700">{formatCurrency(row.paidAmount, 'MAD')}</td> <td className="px-6 py-4 text-right text-sm font-semibold text-emerald-700">{formatCurrency(row.paidAmount, 'MAD')}</td>
<td className="px-6 py-4 text-right text-sm font-semibold text-amber-700">{formatCurrency(row.balanceDue, 'MAD')}</td> <td className="px-6 py-4 text-right text-sm font-semibold text-orange-700">{formatCurrency(row.balanceDue, 'MAD')}</td>
<td className="px-6 py-4 text-sm"> <td className="px-6 py-4 text-sm">
<span className={`inline-flex rounded-full px-2.5 py-0.5 text-xs font-medium ${PAYMENT_STATUS_BADGE[row.paymentStatus] ?? 'bg-slate-100 text-slate-700'}`}> <span className={`inline-flex rounded-full px-2.5 py-0.5 text-xs font-medium ${PAYMENT_STATUS_BADGE[row.paymentStatus] ?? 'bg-slate-100 text-slate-700'}`}>
{translateStatus(row.paymentStatus, copy.paymentStatusLabels)} {translateStatus(row.paymentStatus, copy.paymentStatusLabels)}
@@ -566,7 +566,7 @@ export default function BillingPage() {
</div> </div>
{paymentModalRow ? ( {paymentModalRow ? (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/30 backdrop-blur-sm" onClick={(event) => { <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#07101e]/30 backdrop-blur-sm" onClick={(event) => {
if (event.target === event.currentTarget && !submittingPayment) setPaymentModalRow(null) if (event.target === event.currentTarget && !submittingPayment) setPaymentModalRow(null)
}}> }}>
<div className="w-full max-w-lg rounded-3xl bg-white p-6 shadow-2xl"> <div className="w-full max-w-lg rounded-3xl bg-white p-6 shadow-2xl">
@@ -476,7 +476,7 @@ export default function FleetDetailPage() {
{tab === 'maintenance' && ( {tab === 'maintenance' && (
<> <>
<Wrench className="w-4 h-4" /> {vd.tabMaintenance} <Wrench className="w-4 h-4" /> {vd.tabMaintenance}
{maintenanceLogs.length === 0 && <span className="ml-1 inline-flex h-4 w-4 items-center justify-center rounded-full bg-amber-100 text-amber-700 text-[10px] font-bold">!</span>} {maintenanceLogs.length === 0 && <span className="ml-1 inline-flex h-4 w-4 items-center justify-center rounded-full bg-orange-100 text-orange-700 text-[10px] font-bold">!</span>}
</> </>
)} )}
{tab === 'calendar' && <><CalendarDays className="w-4 h-4" /> {vd.tabCalendar}</>} {tab === 'calendar' && <><CalendarDays className="w-4 h-4" /> {vd.tabCalendar}</>}
@@ -513,7 +513,7 @@ export default function FleetDetailPage() {
<img src={src} alt={`new photo ${i + 1}`} className="object-cover w-full h-full" /> <img src={src} alt={`new photo ${i + 1}`} className="object-cover w-full h-full" />
<button <button
onClick={() => removeNewPhoto(i)} onClick={() => removeNewPhoto(i)}
className="absolute top-2 right-2 p-1.5 bg-black/60 text-white rounded-lg opacity-0 group-hover:opacity-100 transition-opacity" className="absolute top-2 right-2 p-1.5 bg-[#07101e]/60 text-white rounded-lg opacity-0 group-hover:opacity-100 transition-opacity"
> >
<X className="w-3.5 h-3.5" /> <X className="w-3.5 h-3.5" />
</button> </button>
@@ -88,7 +88,7 @@ function MaintenanceModal({ vehicleId, vehicleName, open, onClose, onSaved }: Ma
if (!open) return null if (!open) return null
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40" onClick={(e) => { if (e.target === e.currentTarget) handleClose() }}> <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#07101e]/40" onClick={(e) => { if (e.target === e.currentTarget) handleClose() }}>
<div className="bg-white rounded-2xl shadow-xl w-full max-w-md mx-4 p-6"> <div className="bg-white rounded-2xl shadow-xl w-full max-w-md mx-4 p-6">
<h2 className="text-lg font-semibold text-slate-900 mb-1">{f.logMaintenance}</h2> <h2 className="text-lg font-semibold text-slate-900 mb-1">{f.logMaintenance}</h2>
<p className="text-sm text-slate-500 mb-5">{f.maintenanceSubtitle(vehicleName)}</p> <p className="text-sm text-slate-500 mb-5">{f.maintenanceSubtitle(vehicleName)}</p>
@@ -210,7 +210,7 @@ function StatusDropdown({ vehicleId, status, onStatusChange }: {
<span className={`inline-block w-2 h-2 rounded-full flex-shrink-0 ${ <span className={`inline-block w-2 h-2 rounded-full flex-shrink-0 ${
s === 'AVAILABLE' ? 'bg-green-500' : s === 'AVAILABLE' ? 'bg-green-500' :
s === 'RENTED' ? 'bg-blue-500' : s === 'RENTED' ? 'bg-blue-500' :
s === 'MAINTENANCE' ? 'bg-amber-500' : 'bg-red-500' s === 'MAINTENANCE' ? 'bg-orange-500' : 'bg-red-500'
}`} /> }`} />
{f.statusLabels[s]} {f.statusLabels[s]}
</button> </button>
@@ -333,7 +333,7 @@ function AddVehicleModal({ open, onClose, onSaved }: AddVehicleModalProps) {
const presetModels = form.make && MODELS_BY_MAKE[form.make] ? MODELS_BY_MAKE[form.make] : null const presetModels = form.make && MODELS_BY_MAKE[form.make] ? MODELS_BY_MAKE[form.make] : null
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40" onClick={(e) => { if (e.target === e.currentTarget) handleClose() }}> <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#07101e]/40" onClick={(e) => { if (e.target === e.currentTarget) handleClose() }}>
<div className="bg-white rounded-2xl shadow-xl w-full max-w-lg mx-4 p-6 max-h-[90vh] overflow-y-auto"> <div className="bg-white rounded-2xl shadow-xl w-full max-w-lg mx-4 p-6 max-h-[90vh] overflow-y-auto">
<h2 className="text-lg font-semibold text-slate-900 mb-5">{f.addNewVehicle}</h2> <h2 className="text-lg font-semibold text-slate-900 mb-5">{f.addNewVehicle}</h2>
{error && ( {error && (
@@ -485,7 +485,7 @@ function AddVehicleModal({ open, onClose, onSaved }: AddVehicleModalProps) {
<button <button
type="button" type="button"
onClick={() => removePhoto(i)} onClick={() => removePhoto(i)}
className="absolute top-1 right-1 p-0.5 bg-black/60 text-white rounded-full opacity-0 group-hover:opacity-100 transition-opacity" className="absolute top-1 right-1 p-0.5 bg-[#07101e]/60 text-white rounded-full opacity-0 group-hover:opacity-100 transition-opacity"
> >
<X className="w-3 h-3" /> <X className="w-3 h-3" />
</button> </button>
@@ -540,7 +540,7 @@ export default function OffersPage() {
{/* Create / Edit Modal */} {/* Create / Edit Modal */}
{modalOpen && ( {modalOpen && (
<div className="fixed inset-0 z-50 flex items-start justify-center overflow-y-auto bg-black/50 p-4"> <div className="fixed inset-0 z-50 flex items-start justify-center overflow-y-auto bg-[#07101e]/50 p-4">
<div className="relative w-full max-w-2xl my-8 card p-6" dir={isRtl ? 'rtl' : 'ltr'}> <div className="relative w-full max-w-2xl my-8 card p-6" dir={isRtl ? 'rtl' : 'ltr'}>
<h3 className="text-lg font-semibold text-slate-900 mb-5"> <h3 className="text-lg font-semibold text-slate-900 mb-5">
{editing ? t.editOffer : t.createOffer} {editing ? t.editOffer : t.createOffer}
@@ -778,7 +778,7 @@ export default function OffersPage() {
{/* Delete confirmation */} {/* Delete confirmation */}
{deleteTarget && ( {deleteTarget && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4"> <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#07101e]/50 p-4">
<div className="card p-6 w-full max-w-sm" dir={isRtl ? 'rtl' : 'ltr'}> <div className="card p-6 w-full max-w-sm" dir={isRtl ? 'rtl' : 'ltr'}>
<h3 className="text-base font-semibold text-slate-900 mb-2">{t.deleteOffer}</h3> <h3 className="text-base font-semibold text-slate-900 mb-2">{t.deleteOffer}</h3>
<p className="text-sm text-slate-600 mb-5">{t.confirmDelete}</p> <p className="text-sm text-slate-600 mb-5">{t.confirmDelete}</p>
@@ -25,7 +25,7 @@ interface OnlineReservation {
} }
const STATUS_STYLE: Record<string, string> = { const STATUS_STYLE: Record<string, string> = {
DRAFT: 'bg-amber-100 text-amber-800', DRAFT: 'bg-orange-100 text-orange-800',
CONFIRMED: 'bg-emerald-100 text-emerald-700', CONFIRMED: 'bg-emerald-100 text-emerald-700',
CANCELLED: 'bg-rose-100 text-rose-700', CANCELLED: 'bg-rose-100 text-rose-700',
ACTIVE: 'bg-blue-100 text-blue-700', ACTIVE: 'bg-blue-100 text-blue-700',
@@ -45,7 +45,7 @@ const STATUS_LABEL: Record<string, string> = {
function DeclineModal({ onConfirm, onCancel, loading }: { onConfirm: (reason: string) => void; onCancel: () => void; loading: boolean }) { function DeclineModal({ onConfirm, onCancel, loading }: { onConfirm: (reason: string) => void; onCancel: () => void; loading: boolean }) {
const [reason, setReason] = useState('') const [reason, setReason] = useState('')
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4" onClick={onCancel}> <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#07101e]/40 p-4" onClick={onCancel}>
<div className="w-full max-w-sm rounded-2xl bg-white p-6 shadow-xl" onClick={(e) => e.stopPropagation()}> <div className="w-full max-w-sm rounded-2xl bg-white p-6 shadow-xl" onClick={(e) => e.stopPropagation()}>
<h3 className="text-base font-semibold text-slate-900">Decline reservation</h3> <h3 className="text-base font-semibold text-slate-900">Decline reservation</h3>
<p className="mt-1 text-sm text-slate-500">Optionally provide a reason it will be visible in the reservation record.</p> <p className="mt-1 text-sm text-slate-500">Optionally provide a reason it will be visible in the reservation record.</p>
@@ -183,7 +183,7 @@ export default function OnlineReservationsPage() {
<Globe className="h-5 w-5 text-blue-600" /> <Globe className="h-5 w-5 text-blue-600" />
<h2 className="text-xl font-semibold text-slate-900">{copy.title}</h2> <h2 className="text-xl font-semibold text-slate-900">{copy.title}</h2>
{pending.length > 0 && ( {pending.length > 0 && (
<span className="rounded-full bg-amber-500 px-2.5 py-0.5 text-xs font-bold text-white">{pending.length}</span> <span className="rounded-full bg-orange-500 px-2.5 py-0.5 text-xs font-bold text-white">{pending.length}</span>
)} )}
</div> </div>
<p className="mt-1 text-sm text-slate-500">{copy.subtitle}</p> <p className="mt-1 text-sm text-slate-500">{copy.subtitle}</p>
@@ -201,7 +201,7 @@ export default function OnlineReservationsPage() {
<section> <section>
<h3 className="mb-3 flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-slate-500"> <h3 className="mb-3 flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-slate-500">
<Clock className="h-4 w-4" /> {copy.pendingApproval} <Clock className="h-4 w-4" /> {copy.pendingApproval}
{pending.length > 0 && <span className="ml-1 text-amber-600">({pending.length})</span>} {pending.length > 0 && <span className="ml-1 text-orange-600">({pending.length})</span>}
</h3> </h3>
{loading ? ( {loading ? (
@@ -238,7 +238,7 @@ function ReservationCard({ r, acting, onConfirm, onDecline }: {
}) { }) {
const days = r.totalDays const days = r.totalDays
return ( return (
<div className="card overflow-hidden border-l-4 border-l-amber-400"> <div className="card overflow-hidden border-l-4 border-l-orange-400">
<div className="p-5"> <div className="p-5">
<div className="flex flex-wrap items-start justify-between gap-4"> <div className="flex flex-wrap items-start justify-between gap-4">
{/* Left: customer + vehicle + dates */} {/* Left: customer + vehicle + dates */}
@@ -80,7 +80,7 @@ function SubscriptionBanner({
message: trialEndsAt ? trialEndsMsg(localeDate) : trialActiveMsg, message: trialEndsAt ? trialEndsMsg(localeDate) : trialActiveMsg,
}, },
PAST_DUE: { PAST_DUE: {
bg: 'bg-amber-50 border-amber-200 text-amber-800', bg: 'bg-orange-50 border-orange-200 text-orange-800',
icon: <AlertTriangle className="w-4 h-4" />, icon: <AlertTriangle className="w-4 h-4" />,
message: pastDueMsg, message: pastDueMsg,
}, },
@@ -197,8 +197,8 @@ export default function DashboardPage() {
change={kpis.revenueChange} change={kpis.revenueChange}
vsLastMonthLabel={d.vsLastMonth} vsLastMonthLabel={d.vsLastMonth}
icon={DollarSign} icon={DollarSign}
iconColor="text-amber-600" iconColor="text-orange-600"
iconBg="bg-amber-50" iconBg="bg-orange-50"
/> />
) : null} ) : null}
<StatCard <StatCard
@@ -625,7 +625,7 @@ export default function ReservationDetailPage() {
{reservation.pricingRulesApplied.map((rule) => ( {reservation.pricingRulesApplied.map((rule) => (
<div key={`${rule.name}-${rule.amount}`} className="flex items-center justify-between rounded-xl border border-slate-200 px-4 py-3 text-sm"> <div key={`${rule.name}-${rule.amount}`} className="flex items-center justify-between rounded-xl border border-slate-200 px-4 py-3 text-sm">
<span className="text-slate-700">{rule.name}</span> <span className="text-slate-700">{rule.name}</span>
<span className={rule.amount < 0 ? 'font-semibold text-emerald-700' : 'font-semibold text-amber-700'}> <span className={rule.amount < 0 ? 'font-semibold text-emerald-700' : 'font-semibold text-orange-700'}>
{rule.amount < 0 ? '-' : '+'}{formatCurrency(Math.abs(rule.amount), 'MAD')} {rule.amount < 0 ? '-' : '+'}{formatCurrency(Math.abs(rule.amount), 'MAD')}
</span> </span>
</div> </div>
@@ -676,7 +676,7 @@ export default function ReservationDetailPage() {
</span> </span>
)} )}
</div> </div>
{driver.approvalNote && <p className="mt-2 text-xs text-amber-700">{driver.approvalNote}</p>} {driver.approvalNote && <p className="mt-2 text-xs text-orange-700">{driver.approvalNote}</p>}
</div> </div>
))} ))}
{reservation.additionalDrivers.length === 0 && ( {reservation.additionalDrivers.length === 0 && (
@@ -496,9 +496,9 @@ export default function NewReservationPage() {
))} ))}
</select> </select>
{vehicles.length === 0 ? ( {vehicles.length === 0 ? (
<span className="text-xs text-amber-700">{copy.noVehicles}</span> <span className="text-xs text-orange-700">{copy.noVehicles}</span>
) : availableVehicles.length === 0 ? ( ) : availableVehicles.length === 0 ? (
<span className="text-xs text-amber-700"> <span className="text-xs text-orange-700">
{language === 'fr' {language === 'fr'
? 'Des véhicules existent dans la flotte, mais aucun nest marqué Disponible.' ? 'Des véhicules existent dans la flotte, mais aucun nest marqué Disponible.'
: language === 'ar' : language === 'ar'
@@ -43,14 +43,14 @@ interface EmployeeProfile {
const STATUS_BADGE: Record<string, string> = { const STATUS_BADGE: Record<string, string> = {
TRIALING: 'bg-sky-100 text-sky-700', TRIALING: 'bg-sky-100 text-sky-700',
ACTIVE: 'bg-green-100 text-green-700', ACTIVE: 'bg-green-100 text-green-700',
PAST_DUE: 'bg-amber-100 text-amber-700', PAST_DUE: 'bg-orange-100 text-orange-700',
CANCELLED: 'bg-slate-100 text-slate-600', CANCELLED: 'bg-slate-100 text-slate-600',
UNPAID: 'bg-red-100 text-red-700', UNPAID: 'bg-red-100 text-red-700',
} }
const INVOICE_STATUS: Record<string, string> = { const INVOICE_STATUS: Record<string, string> = {
PAID: 'bg-green-100 text-green-700', PAID: 'bg-green-100 text-green-700',
PENDING: 'bg-amber-100 text-amber-700', PENDING: 'bg-orange-100 text-orange-700',
FAILED: 'bg-red-100 text-red-700', FAILED: 'bg-red-100 text-red-700',
REFUNDED: 'bg-slate-100 text-slate-600', REFUNDED: 'bg-slate-100 text-slate-600',
} }
@@ -352,7 +352,7 @@ export default function SubscriptionPage() {
{subscription.currentPeriodEnd && ` · ${copy.renews} ${new Date(subscription.currentPeriodEnd).toLocaleDateString()}`} {subscription.currentPeriodEnd && ` · ${copy.renews} ${new Date(subscription.currentPeriodEnd).toLocaleDateString()}`}
</p> </p>
{subscription.cancelAtPeriodEnd && ( {subscription.cancelAtPeriodEnd && (
<p className="mt-2 text-sm font-medium text-amber-700"> <p className="mt-2 text-sm font-medium text-orange-700">
{copy.cancelScheduled}{' '} {copy.cancelScheduled}{' '}
<button onClick={handleResume} disabled={cancelling} className="underline">{copy.undo}</button> <button onClick={handleResume} disabled={cancelling} className="underline">{copy.undo}</button>
</p> </p>
@@ -374,7 +374,7 @@ export default function SubscriptionPage() {
{/* Plan selector + checkout */} {/* Plan selector + checkout */}
<div className="card p-6 space-y-6"> <div className="card p-6 space-y-6">
{!providerAvailability.amanpay && !providerAvailability.paypal ? ( {!providerAvailability.amanpay && !providerAvailability.paypal ? (
<div className="rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-700"> <div className="rounded-xl border border-orange-200 bg-orange-50 px-4 py-3 text-sm text-orange-700">
{copy.noProviderConfigured} {copy.noProviderConfigured}
</div> </div>
) : null} ) : null}
@@ -40,7 +40,7 @@ const AVATAR_BG: string[] = [
'bg-violet-100 dark:bg-violet-900/40 text-violet-700 dark:text-violet-300', 'bg-violet-100 dark:bg-violet-900/40 text-violet-700 dark:text-violet-300',
'bg-blue-100 dark:bg-blue-900/40 text-blue-700 dark:text-blue-300', 'bg-blue-100 dark:bg-blue-900/40 text-blue-700 dark:text-blue-300',
'bg-teal-100 dark:bg-teal-900/40 text-teal-700 dark:text-teal-300', 'bg-teal-100 dark:bg-teal-900/40 text-teal-700 dark:text-teal-300',
'bg-amber-100 dark:bg-amber-900/40 text-amber-700 dark:text-amber-300', 'bg-orange-100 dark:bg-orange-900/40 text-orange-700 dark:text-orange-300',
'bg-pink-100 dark:bg-pink-900/40 text-pink-700 dark:text-pink-300', 'bg-pink-100 dark:bg-pink-900/40 text-pink-700 dark:text-pink-300',
] ]
@@ -72,7 +72,7 @@ function RoleBadge({ role, language }: { role: string; language: 'en' | 'fr' | '
function StatusBadge({ member, language }: { member: TeamMember; language: 'en' | 'fr' | 'ar' }) { function StatusBadge({ member, language }: { member: TeamMember; language: 'en' | 'fr' | 'ar' }) {
if (member.invitationStatus === 'pending') { if (member.invitationStatus === 'pending') {
return ( return (
<span className="text-xs px-2 py-0.5 rounded-full border bg-amber-50 dark:bg-amber-950/30 text-amber-700 dark:text-amber-400 border-amber-100 dark:border-amber-900/50"> <span className="text-xs px-2 py-0.5 rounded-full border bg-orange-50 dark:bg-orange-950/30 text-orange-700 dark:text-orange-400 border-orange-100 dark:border-orange-900/50">
{language === 'fr' ? 'Invitation en attente' : language === 'ar' ? 'دعوة قيد الانتظار' : 'Pending invite'} {language === 'fr' ? 'Invitation en attente' : language === 'ar' ? 'دعوة قيد الانتظار' : 'Pending invite'}
</span> </span>
) )
@@ -4,7 +4,7 @@ import { DashboardLanguageSwitcher, DashboardThemeSwitcher } from '@/components/
export default function DashboardLayout({ children }: { children: React.ReactNode }) { export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return ( return (
<div className="flex min-h-screen bg-[linear-gradient(180deg,#f8f5ef_0%,#f4efe6_28%,#fffdf8_58%,#ffffff_100%)] transition-colors dark:bg-[linear-gradient(180deg,#14110f_0%,#17120d_35%,#0c0a09_100%)] print:block print:min-h-0 print:bg-white"> <div className="flex min-h-screen bg-[linear-gradient(180deg,#f8f5ef_0%,#f4efe6_28%,#fffdf8_58%,#ffffff_100%)] transition-colors dark:bg-[linear-gradient(180deg,#0a1128_0%,#0d1b38_35%,#07101e_100%)] print:block print:min-h-0 print:bg-white">
<div className="print:hidden"> <div className="print:hidden">
<Sidebar /> <Sidebar />
</div> </div>
@@ -13,7 +13,7 @@ export default function DashboardLayout({ children }: { children: React.ReactNod
<TopBar /> <TopBar />
</div> </div>
<main className="flex-1 overflow-y-auto p-6 print:p-0 print:overflow-visible">{children}</main> <main className="flex-1 overflow-y-auto p-6 print:p-0 print:overflow-visible">{children}</main>
<footer className="border-t border-stone-200/80 bg-white/72 px-6 py-4 backdrop-blur-xl transition-colors dark:border-stone-800 dark:bg-stone-950/72 print:hidden"> <footer className="border-t border-stone-200/80 bg-white/72 px-6 py-4 backdrop-blur-xl transition-colors dark:border-blue-900 dark:bg-[#07101e]/72 print:hidden">
<div className="flex flex-col items-center justify-between gap-3 lg:flex-row"> <div className="flex flex-col items-center justify-between gap-3 lg:flex-row">
<p className="text-xs font-medium uppercase tracking-[0.16em] text-stone-400 dark:text-stone-500"> <p className="text-xs font-medium uppercase tracking-[0.16em] text-stone-400 dark:text-stone-500">
Workspace preferences Workspace preferences
@@ -85,7 +85,7 @@ export default function ForgotPasswordPageClient({ embedded = false }: { embedde
width={104} width={104}
height={104} height={104}
priority priority
className="h-24 w-24 rounded-[1.75rem] border border-stone-200 bg-white p-1.5 shadow-sm transition-colors dark:border-stone-700 dark:bg-stone-900" className="h-24 w-24 rounded-[1.75rem] border border-stone-200 bg-white p-1.5 shadow-sm transition-colors dark:border-blue-800 dark:bg-[#0d1b38]"
/> />
</a> </a>
</div> </div>
@@ -93,7 +93,7 @@ export default function ForgotPasswordPageClient({ embedded = false }: { embedde
<p className="mt-2 text-sm text-stone-500 dark:text-stone-400">{dict.subtitle}</p> <p className="mt-2 text-sm text-stone-500 dark:text-stone-400">{dict.subtitle}</p>
</div> </div>
<section className="rounded-[2rem] border border-stone-200 bg-white p-8 shadow-sm transition-colors dark:border-stone-800 dark:bg-stone-900"> <section className="rounded-[2rem] border border-stone-200 bg-white p-8 shadow-sm transition-colors dark:border-blue-900 dark:bg-[#0d1b38]">
{sent ? ( {sent ? (
<div className="space-y-4 text-center"> <div className="space-y-4 text-center">
<div className="mx-auto flex h-14 w-14 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-950/50"> <div className="mx-auto flex h-14 w-14 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-950/50">
@@ -130,7 +130,7 @@ export default function ForgotPasswordPageClient({ embedded = false }: { embedde
</form> </form>
)} )}
<div className="mt-6 border-t border-stone-200 pt-6 text-center text-sm text-stone-500 dark:border-stone-800 dark:text-stone-400"> <div className="mt-6 border-t border-stone-200 pt-6 text-center text-sm text-stone-500 dark:border-blue-900 dark:text-stone-400">
<Link href="/sign-in" className="font-semibold text-stone-900 underline decoration-stone-300 underline-offset-4 dark:text-stone-100 dark:decoration-stone-700"> <Link href="/sign-in" className="font-semibold text-stone-900 underline decoration-stone-300 underline-offset-4 dark:text-stone-100 dark:decoration-stone-700">
{dict.backToLogin} {dict.backToLogin}
</Link> </Link>
+23 -59
View File
@@ -13,8 +13,8 @@ html.dark {
:root { :root {
--primary: #2563eb; --primary: #2563eb;
--primary-hover: #1d4ed8; --primary-hover: #1d4ed8;
--accent: #f59e0b; --accent: #f97316;
--sidebar-bg: #0f172a; --sidebar-bg: #0a1128;
--sidebar-text: #94a3b8; --sidebar-text: #94a3b8;
--sidebar-active: #ffffff; --sidebar-active: #ffffff;
} }
@@ -25,9 +25,9 @@ html.dark {
} }
body { body {
@apply text-stone-900 antialiased transition-colors dark:text-stone-100; @apply text-blue-950 antialiased transition-colors dark:text-slate-100;
background-image: background-image:
linear-gradient(180deg, #f8f5ef 0%, #f4efe6 28%, #fffdf8 58%, #ffffff 100%); linear-gradient(180deg, #ffffff 0%, #f5f8ff 28%, #eef4ff 58%, #ffffff 100%);
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
@@ -37,16 +37,16 @@ html.dark {
html.dark body { html.dark body {
background-image: background-image:
linear-gradient(180deg, #14110f 0%, #17120d 35%, #0c0a09 100%); linear-gradient(180deg, #0a1128 0%, #0d1b38 35%, #07101e 100%);
} }
@layer components { @layer components {
.btn-primary { .btn-primary {
@apply inline-flex items-center gap-2 rounded-full bg-stone-950 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-stone-800 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300; @apply inline-flex items-center gap-2 rounded-full bg-orange-600 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-orange-700 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-orange-500 dark:hover:bg-orange-400;
} }
.btn-secondary { .btn-secondary {
@apply inline-flex items-center gap-2 rounded-full border border-stone-300 bg-white/85 px-5 py-2.5 text-sm font-semibold text-stone-700 transition hover:border-stone-950 hover:text-stone-950 dark:border-stone-700 dark:bg-stone-950/30 dark:text-stone-200 dark:hover:border-stone-200 dark:hover:text-white; @apply inline-flex items-center gap-2 rounded-full border border-stone-300 bg-white/85 px-5 py-2.5 text-sm font-semibold text-stone-700 transition hover:border-blue-900 hover:text-blue-900 dark:border-blue-800 dark:bg-blue-950/20 dark:text-blue-100 dark:hover:border-blue-400 dark:hover:text-white;
} }
.btn-danger { .btn-danger {
@@ -54,18 +54,18 @@ html.dark body {
} }
.input-field { .input-field {
@apply w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm text-stone-900 transition-colors placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-amber-500 dark:border-stone-700 dark:bg-stone-950/80 dark:text-stone-100 dark:placeholder:text-stone-500; @apply w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm text-stone-900 transition-colors placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-orange-500 dark:border-blue-900 dark:bg-blue-950/50 dark:text-slate-100 dark:placeholder:text-slate-500 dark:focus:ring-orange-400;
} }
.card { .card {
@apply rounded-[1.75rem] border shadow-[0_30px_80px_rgba(28,25,23,0.08)] backdrop-blur transition-colors dark:shadow-[0_30px_80px_rgba(0,0,0,0.26)]; @apply rounded-[1.75rem] border shadow-[0_30px_80px_rgba(28,25,23,0.08)] backdrop-blur transition-colors dark:shadow-[0_30px_80px_rgba(0,0,0,0.36)];
border-color: rgb(231 229 228 / 0.8); border-color: rgb(231 229 228 / 0.8);
background-color: rgb(255 255 255 / 0.82); background-color: rgb(255 255 255 / 0.82);
} }
html.dark .card { html.dark .card {
border-color: rgb(41 37 36 / 0.96); border-color: rgb(30 60 140 / 0.40);
background-color: rgb(28 25 23 / 0.72); background-color: rgb(11 25 55 / 0.72);
} }
.badge-green { .badge-green {
@@ -73,7 +73,7 @@ html.dark body {
} }
.badge-blue { .badge-blue {
@apply inline-flex items-center rounded-full bg-amber-100 px-2.5 py-0.5 text-xs font-medium text-amber-700 dark:bg-amber-950/40 dark:text-amber-300; @apply inline-flex items-center rounded-full bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-700 dark:bg-blue-950/40 dark:text-blue-300;
} }
.badge-amber { .badge-amber {
@@ -85,7 +85,7 @@ html.dark body {
} }
.badge-gray { .badge-gray {
@apply inline-flex items-center rounded-full bg-stone-100 px-2.5 py-0.5 text-xs font-medium text-stone-600 dark:bg-stone-800 dark:text-stone-300; @apply inline-flex items-center rounded-full bg-stone-100 px-2.5 py-0.5 text-xs font-medium text-stone-600 dark:bg-blue-950/40 dark:text-slate-300;
} }
.badge-purple { .badge-purple {
@@ -106,82 +106,46 @@ html.dark body {
@layer utilities { @layer utilities {
.dark .bg-slate-50 { .dark .bg-slate-50 {
background-color: rgb(12 10 9); background-color: rgb(7 16 46);
} }
.dark .bg-white { .dark .bg-white {
background-color: rgb(28 25 23); background-color: rgb(11 25 55);
} }
.dark .bg-white\/90 { .dark .bg-white\/90 {
background-color: rgb(28 25 23 / 0.9); background-color: rgb(11 25 55 / 0.9);
} }
.dark .border-slate-200, .dark .border-slate-200,
.dark .border-stone-200 { .dark .border-stone-200 {
border-color: rgb(41 37 36); border-color: rgb(30 60 140 / 0.50);
} }
.dark .text-slate-900 { .dark .text-slate-900 {
color: rgb(250 250 249); color: rgb(241 245 249);
} }
.dark .text-slate-700 { .dark .text-slate-700 {
color: rgb(231 229 228); color: rgb(203 213 225);
} }
.dark .text-slate-600, .dark .text-slate-600,
.dark .text-stone-500 { .dark .text-stone-500 {
color: rgb(168 162 158); color: rgb(148 163 184);
} }
.dark .text-slate-500, .dark .text-slate-500,
.dark .text-slate-400, .dark .text-slate-400,
.dark .text-stone-400 { .dark .text-stone-400 {
color: rgb(120 113 108); color: rgb(100 116 139);
} }
.dark .hover\:bg-slate-100:hover { .dark .hover\:bg-slate-100:hover {
background-color: rgb(41 37 36); background-color: rgb(20 42 90);
} }
.dark .hover\:text-slate-900:hover { .dark .hover\:text-slate-900:hover {
color: rgb(250 250 249); color: rgb(241 245 249);
}
.bg-blue-600 {
background-color: rgb(217 119 6);
}
.hover\:bg-blue-700:hover {
background-color: rgb(180 83 9);
}
.bg-blue-500 {
background-color: rgb(245 158 11);
}
.bg-blue-50 {
background-color: rgb(255 251 235);
}
.text-blue-600 {
color: rgb(180 83 9);
}
.text-blue-800 {
color: rgb(154 52 18);
}
.border-blue-200 {
border-color: rgb(253 230 138);
}
.ring-blue-400 {
--tw-ring-color: rgb(251 191 36 / 0.6);
}
.focus\:ring-blue-500:focus {
--tw-ring-color: rgb(217 119 6 / 0.45);
} }
} }
@@ -175,7 +175,7 @@ function ResetPasswordContent({ embedded = false }: { embedded?: boolean }) {
</button> </button>
</form> </form>
<div className="mt-6 border-t border-stone-200 pt-6 text-center text-sm text-stone-500 dark:border-stone-800 dark:text-stone-400"> <div className="mt-6 border-t border-stone-200 pt-6 text-center text-sm text-stone-500 dark:border-blue-900 dark:text-stone-400">
<Link href="/sign-in" className="font-semibold text-stone-900 underline decoration-stone-300 underline-offset-4 dark:text-stone-100 dark:decoration-stone-700"> <Link href="/sign-in" className="font-semibold text-stone-900 underline decoration-stone-300 underline-offset-4 dark:text-stone-100 dark:decoration-stone-700">
{dict.backToLogin} {dict.backToLogin}
</Link> </Link>
@@ -200,11 +200,11 @@ function ResetShell({
<main className="flex min-h-[calc(100vh-80px)] items-center justify-center px-4 py-12"> <main className="flex min-h-[calc(100vh-80px)] items-center justify-center px-4 py-12">
<div className="w-full max-w-md"> <div className="w-full max-w-md">
<div className="mb-8 text-center"> <div className="mb-8 text-center">
<span className="text-xs font-semibold uppercase tracking-[0.24em] text-amber-700 dark:text-amber-400">RentalDriveGo</span> <span className="text-xs font-semibold uppercase tracking-[0.24em] text-orange-700 dark:text-orange-400">RentalDriveGo</span>
<h1 className="mt-3 text-3xl font-black tracking-tight text-stone-900 dark:text-stone-100">{title}</h1> <h1 className="mt-3 text-3xl font-black tracking-tight text-stone-900 dark:text-stone-100">{title}</h1>
{subtitle && <p className="mt-2 text-sm text-stone-500 dark:text-stone-400">{subtitle}</p>} {subtitle && <p className="mt-2 text-sm text-stone-500 dark:text-stone-400">{subtitle}</p>}
</div> </div>
<section className="rounded-[2rem] border border-stone-200 bg-white p-8 shadow-sm transition-colors dark:border-stone-800 dark:bg-stone-900"> <section className="rounded-[2rem] border border-stone-200 bg-white p-8 shadow-sm transition-colors dark:border-blue-900 dark:bg-[#0d1b38]">
{children} {children}
</section> </section>
</div> </div>
@@ -149,14 +149,14 @@ export default function SignInPageClient({ embedded = false }: { embedded?: bool
width={104} width={104}
height={104} height={104}
priority priority
className="h-24 w-24 rounded-[1.75rem] border border-stone-200/80 bg-white/85 p-1.5 shadow-sm transition-colors dark:border-stone-700 dark:bg-stone-900/80" className="h-24 w-24 rounded-[1.75rem] border border-stone-200/80 bg-white/85 p-1.5 shadow-sm transition-colors dark:border-blue-800 dark:bg-[#0d1b38]/80"
/> />
</a> </a>
</div> </div>
<p className="mt-5 text-xs font-bold uppercase tracking-[0.28em] text-amber-700 dark:text-amber-300"> <p className="mt-5 text-xs font-bold uppercase tracking-[0.28em] text-orange-700 dark:text-orange-300">
RentalDriveGo RentalDriveGo
</p> </p>
<h1 className="mt-3 text-3xl font-black tracking-[-0.03em] text-stone-950 dark:text-stone-50"> <h1 className="mt-3 text-3xl font-black tracking-[-0.03em] text-blue-950 dark:text-stone-50">
{dict.brandName} {dict.brandName}
</h1> </h1>
<p className="mt-2 text-sm text-stone-600 dark:text-stone-300"> <p className="mt-2 text-sm text-stone-600 dark:text-stone-300">
@@ -168,7 +168,7 @@ export default function SignInPageClient({ embedded = false }: { embedded?: bool
key={lang} key={lang}
type="button" type="button"
onClick={() => setLanguage(lang)} onClick={() => setLanguage(lang)}
className={`rounded-full px-3 py-1 text-xs font-semibold uppercase tracking-wider transition-colors text-amber-700 dark:text-amber-300 ${ className={`rounded-full px-3 py-1 text-xs font-semibold uppercase tracking-wider transition-colors text-orange-700 dark:text-orange-300 ${
language === lang language === lang
? 'ring-1 ring-current opacity-100' ? 'ring-1 ring-current opacity-100'
: 'opacity-45 hover:opacity-80' : 'opacity-45 hover:opacity-80'
@@ -180,7 +180,7 @@ export default function SignInPageClient({ embedded = false }: { embedded?: bool
</div> </div>
</div> </div>
<section className="rounded-[2rem] border border-stone-200/80 bg-white/82 p-8 shadow-[0_30px_80px_rgba(28,25,23,0.08)] backdrop-blur transition-colors dark:border-stone-800 dark:bg-stone-900/78 dark:shadow-[0_30px_80px_rgba(0,0,0,0.26)]"> <section className="rounded-[2rem] border border-stone-200/80 bg-white/82 p-8 shadow-[0_30px_80px_rgba(28,25,23,0.08)] backdrop-blur transition-colors dark:border-blue-900 dark:bg-[#0d1b38]/78 dark:shadow-[0_30px_80px_rgba(0,0,0,0.26)]">
<LocalSignInForm dict={dict} /> <LocalSignInForm dict={dict} />
</section> </section>
</div> </div>
@@ -331,7 +331,7 @@ function LocalSignInForm({
value={email} value={email}
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setEmail(e.target.value)}
placeholder="owner@company.com" placeholder="owner@company.com"
className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm text-stone-900 transition-colors placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-amber-500 dark:border-stone-700 dark:bg-stone-950/80 dark:text-stone-100 dark:placeholder:text-stone-500" className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm text-stone-900 transition-colors placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-orange-500 dark:border-blue-800 dark:bg-[#07101e]/80 dark:text-stone-100 dark:placeholder:text-stone-500"
/> />
</div> </div>
@@ -344,7 +344,7 @@ function LocalSignInForm({
value={password} value={password}
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
placeholder="••••••••" placeholder="••••••••"
className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 pr-10 text-sm text-stone-900 transition-colors placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-amber-500 dark:border-stone-700 dark:bg-stone-950/80 dark:text-stone-100 dark:placeholder:text-stone-500" className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 pr-10 text-sm text-stone-900 transition-colors placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-orange-500 dark:border-blue-800 dark:bg-[#07101e]/80 dark:text-stone-100 dark:placeholder:text-stone-500"
/> />
<button <button
type="button" type="button"
@@ -369,7 +369,7 @@ function LocalSignInForm({
<button <button
type="submit" type="submit"
disabled={loading} disabled={loading}
className="inline-flex w-full justify-center rounded-full bg-stone-950 px-6 py-3 text-sm font-semibold text-white transition hover:bg-stone-800 disabled:cursor-not-allowed disabled:opacity-60 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300" className="inline-flex w-full justify-center rounded-full bg-stone-950 px-6 py-3 text-sm font-semibold text-white transition hover:bg-stone-800 disabled:cursor-not-allowed disabled:opacity-60 dark:bg-orange-400 dark:text-white dark:hover:bg-orange-300"
> >
{loading ? dict.signingIn : dict.signIn} {loading ? dict.signingIn : dict.signIn}
</button> </button>
@@ -382,7 +382,7 @@ function LocalSignInForm({
</form> </form>
) : ( ) : (
<form onSubmit={handleTotp} className="space-y-5"> <form onSubmit={handleTotp} className="space-y-5">
<div className="rounded-[1.5rem] border border-stone-200/80 bg-stone-50/90 px-4 py-4 text-center text-sm text-stone-600 dark:border-stone-700 dark:bg-stone-950/50 dark:text-stone-300"> <div className="rounded-[1.5rem] border border-stone-200/80 bg-stone-50/90 px-4 py-4 text-center text-sm text-stone-600 dark:border-blue-800 dark:bg-[#07101e]/50 dark:text-stone-300">
{dict.enterCode} {dict.enterCode}
</div> </div>
@@ -397,14 +397,14 @@ function LocalSignInForm({
value={totpCode} value={totpCode}
onChange={(e) => setTotpCode(e.target.value.replace(/\D/g, ''))} onChange={(e) => setTotpCode(e.target.value.replace(/\D/g, ''))}
placeholder="000000" placeholder="000000"
className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-center text-xl tracking-[0.45em] text-stone-900 transition-colors placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-amber-500 dark:border-stone-700 dark:bg-stone-950/80 dark:text-stone-100 dark:placeholder:text-stone-500" className="w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-center text-xl tracking-[0.45em] text-stone-900 transition-colors placeholder:text-stone-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-orange-500 dark:border-blue-800 dark:bg-[#07101e]/80 dark:text-stone-100 dark:placeholder:text-stone-500"
/> />
</div> </div>
<button <button
type="submit" type="submit"
disabled={loading} disabled={loading}
className="inline-flex w-full justify-center rounded-full bg-stone-950 px-6 py-3 text-sm font-semibold text-white transition hover:bg-stone-800 disabled:cursor-not-allowed disabled:opacity-60 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300" className="inline-flex w-full justify-center rounded-full bg-stone-950 px-6 py-3 text-sm font-semibold text-white transition hover:bg-stone-800 disabled:cursor-not-allowed disabled:opacity-60 dark:bg-orange-400 dark:text-white dark:hover:bg-orange-300"
> >
{loading ? dict.verifying : dict.verify} {loading ? dict.verifying : dict.verify}
</button> </button>
@@ -426,7 +426,7 @@ export default function SignUpPage() {
<span className="font-semibold text-slate-900"> {completedSignup.email}</span>. <span className="font-semibold text-slate-900"> {completedSignup.email}</span>.
</p> </p>
{completedSignup.emailWarning ? ( {completedSignup.emailWarning ? (
<div className="mt-6 rounded-2xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800"> <div className="mt-6 rounded-2xl border border-orange-200 bg-orange-50 px-4 py-3 text-sm text-orange-800">
{completedSignup.emailWarning} {completedSignup.emailWarning}
</div> </div>
) : null} ) : null}
@@ -1513,7 +1513,7 @@ export function DashboardLanguageSwitcher() {
} }
return ( return (
<div className="flex items-center gap-1 rounded-full border border-stone-200/80 bg-white/95 px-2 py-1 shadow-sm transition-colors dark:border-stone-700 dark:bg-stone-900/85"> <div className="flex items-center gap-1 rounded-full border border-stone-200/80 bg-white/95 px-2 py-1 shadow-sm transition-colors dark:border-blue-800 dark:bg-[#0d1b38]/85">
<span className="px-2 text-[11px] font-semibold uppercase tracking-[0.16em] text-stone-500 dark:text-stone-400"> <span className="px-2 text-[11px] font-semibold uppercase tracking-[0.16em] text-stone-500 dark:text-stone-400">
{dict.language} {dict.language}
</span> </span>
@@ -1526,8 +1526,8 @@ export function DashboardLanguageSwitcher() {
onClick={() => handleLanguageChange(value)} onClick={() => handleLanguageChange(value)}
className={`rounded-full px-3 py-1.5 text-xs font-semibold transition ${ className={`rounded-full px-3 py-1.5 text-xs font-semibold transition ${
active active
? 'bg-stone-900 text-white dark:bg-amber-400 dark:text-stone-950' ? 'bg-blue-900 text-white dark:bg-orange-400 dark:text-white'
: 'text-stone-600 hover:bg-stone-100 dark:text-stone-300 dark:hover:bg-stone-800' : 'text-stone-600 hover:bg-stone-100 dark:text-stone-300 dark:hover:bg-[#162038]'
}`} }`}
> >
{value.toUpperCase()} {value.toUpperCase()}
@@ -1549,7 +1549,7 @@ export function DashboardThemeSwitcher() {
if (embedded) return null if (embedded) return null
return ( return (
<div className="flex items-center gap-1 rounded-full border border-stone-200/80 bg-white/95 px-2 py-1 shadow-sm transition-colors dark:border-stone-700 dark:bg-stone-900/85"> <div className="flex items-center gap-1 rounded-full border border-stone-200/80 bg-white/95 px-2 py-1 shadow-sm transition-colors dark:border-blue-800 dark:bg-[#0d1b38]/85">
{(['light', 'dark'] as DashboardTheme[]).map((value) => { {(['light', 'dark'] as DashboardTheme[]).map((value) => {
const active = value === theme const active = value === theme
return ( return (
@@ -1559,8 +1559,8 @@ export function DashboardThemeSwitcher() {
onClick={() => setTheme(value)} onClick={() => setTheme(value)}
className={`rounded-full px-3 py-1.5 text-xs font-semibold transition ${ className={`rounded-full px-3 py-1.5 text-xs font-semibold transition ${
active active
? 'bg-stone-900 text-white dark:bg-amber-400 dark:text-stone-950' ? 'bg-blue-900 text-white dark:bg-orange-400 dark:text-white'
: 'text-stone-600 hover:bg-stone-100 dark:text-stone-300 dark:hover:bg-stone-800' : 'text-stone-600 hover:bg-stone-100 dark:text-stone-300 dark:hover:bg-[#162038]'
}`} }`}
> >
{value === 'light' ? dict.light : dict.dark} {value === 'light' ? dict.light : dict.dark}
@@ -22,7 +22,7 @@ interface Props {
const EVENT_STYLES: Record<EventType, { bg: string; text: string; border: string; dot: string }> = { const EVENT_STYLES: Record<EventType, { bg: string; text: string; border: string; dot: string }> = {
RESERVATION: { bg: 'bg-blue-100', text: 'text-blue-800', border: 'border-blue-300', dot: 'bg-blue-500' }, RESERVATION: { bg: 'bg-blue-100', text: 'text-blue-800', border: 'border-blue-300', dot: 'bg-blue-500' },
MAINTENANCE: { bg: 'bg-amber-100', text: 'text-amber-800', border: 'border-amber-300', dot: 'bg-amber-500' }, MAINTENANCE: { bg: 'bg-orange-100', text: 'text-orange-800', border: 'border-orange-300', dot: 'bg-orange-500' },
BLOCK: { bg: 'bg-red-100', text: 'text-red-800', border: 'border-red-300', dot: 'bg-red-500' }, BLOCK: { bg: 'bg-red-100', text: 'text-red-800', border: 'border-red-300', dot: 'bg-red-500' },
} }
@@ -212,7 +212,7 @@ export default function VehicleCalendar({ vehicleId }: Props) {
{/* Legend */} {/* Legend */}
<div className="flex flex-wrap gap-4 text-xs text-slate-600"> <div className="flex flex-wrap gap-4 text-xs text-slate-600">
<span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-full bg-blue-500 inline-block" />{c.legendReserved}</span> <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-full bg-blue-500 inline-block" />{c.legendReserved}</span>
<span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-full bg-amber-500 inline-block" />{c.legendMaintenance}</span> <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-full bg-orange-500 inline-block" />{c.legendMaintenance}</span>
<span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-full bg-red-500 inline-block" />{c.legendBlocked}</span> <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-full bg-red-500 inline-block" />{c.legendBlocked}</span>
<span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-full bg-emerald-500 inline-block" />{c.legendAvailable}</span> <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-full bg-emerald-500 inline-block" />{c.legendAvailable}</span>
</div> </div>
@@ -336,7 +336,7 @@ export default function VehicleCalendar({ vehicleId }: Props) {
{/* Add Block Modal */} {/* Add Block Modal */}
{showModal && ( {showModal && (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/40 backdrop-blur-sm" onClick={closeModal}> <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-[#07101e]/40 backdrop-blur-sm" onClick={closeModal}>
<div className="bg-white rounded-2xl shadow-2xl w-full max-w-md p-6 space-y-4" onClick={(e) => e.stopPropagation()}> <div className="bg-white rounded-2xl shadow-2xl w-full max-w-md p-6 space-y-4" onClick={(e) => e.stopPropagation()}>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h4 className="text-base font-semibold text-slate-900">{c.modalTitle}</h4> <h4 className="text-base font-semibold text-slate-900">{c.modalTitle}</h4>
@@ -357,7 +357,7 @@ export default function VehicleCalendar({ vehicleId }: Props) {
</button> </button>
<button <button
onClick={() => setBlockType('MAINTENANCE')} onClick={() => setBlockType('MAINTENANCE')}
className={`flex-1 flex items-center justify-center gap-2 py-2 rounded-lg border text-sm font-medium transition-colors ${blockType === 'MAINTENANCE' ? 'bg-amber-50 border-amber-300 text-amber-700' : 'border-slate-200 text-slate-600 hover:bg-slate-50'}`} className={`flex-1 flex items-center justify-center gap-2 py-2 rounded-lg border text-sm font-medium transition-colors ${blockType === 'MAINTENANCE' ? 'bg-orange-50 border-orange-300 text-orange-700' : 'border-slate-200 text-slate-600 hover:bg-slate-50'}`}
> >
<Wrench className="w-3.5 h-3.5" /> {c.maintenanceBlock} <Wrench className="w-3.5 h-3.5" /> {c.maintenanceBlock}
</button> </button>
@@ -111,7 +111,7 @@ export default function PublicFooter() {
}, []) }, [])
return ( return (
<footer className="border-t border-stone-200/80 bg-white/72 px-4 py-8 text-stone-600 backdrop-blur-xl transition-colors dark:border-stone-800 dark:bg-stone-950/72 dark:text-stone-300"> <footer className="border-t border-stone-200/80 bg-white/72 px-4 py-8 text-stone-600 backdrop-blur-xl transition-colors dark:border-blue-900 dark:bg-[#07101e]/72 dark:text-stone-300">
<div className="mx-auto flex max-w-7xl flex-col items-center gap-5 px-0 text-center sm:px-2 lg:px-0"> <div className="mx-auto flex max-w-7xl flex-col items-center gap-5 px-0 text-center sm:px-2 lg:px-0">
<nav className="flex flex-wrap items-center justify-center gap-y-3 text-sm"> <nav className="flex flex-wrap items-center justify-center gap-y-3 text-sm">
{footerContent.primary.map((item, index) => ( {footerContent.primary.map((item, index) => (
@@ -135,7 +135,7 @@ export default function PublicFooter() {
<button <button
type="button" type="button"
onClick={() => setLocaleMenuOpen((open) => !open)} onClick={() => setLocaleMenuOpen((open) => !open)}
className="inline-flex items-center gap-2 text-amber-700 transition hover:text-stone-950 dark:text-amber-300 dark:hover:text-stone-100" className="inline-flex items-center gap-2 text-orange-700 transition hover:text-blue-900 dark:text-orange-300 dark:hover:text-stone-100"
aria-expanded={localeMenuOpen} aria-expanded={localeMenuOpen}
aria-haspopup="menu" aria-haspopup="menu"
> >
@@ -144,7 +144,7 @@ export default function PublicFooter() {
<ChevronDown className={`h-4 w-4 transition-transform ${localeMenuOpen ? 'rotate-180' : ''}`} /> <ChevronDown className={`h-4 w-4 transition-transform ${localeMenuOpen ? 'rotate-180' : ''}`} />
</button> </button>
{localeMenuOpen ? ( {localeMenuOpen ? (
<div className="absolute left-1/2 top-full z-20 mt-3 w-56 -translate-x-1/2 overflow-hidden rounded-2xl border border-stone-200 bg-white/95 text-left shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-stone-800 dark:bg-stone-950/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)]"> <div className="absolute left-1/2 top-full z-20 mt-3 w-56 -translate-x-1/2 overflow-hidden rounded-2xl border border-stone-200 bg-white/95 text-left shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-blue-900 dark:bg-[#07101e]/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)]">
{availableLocaleOptions.map((option) => ( {availableLocaleOptions.map((option) => (
<button <button
key={option.value} key={option.value}
@@ -153,7 +153,7 @@ export default function PublicFooter() {
setLanguage(option.value) setLanguage(option.value)
setLocaleMenuOpen(false) setLocaleMenuOpen(false)
}} }}
className="flex w-full items-center gap-3 px-4 py-3 text-sm text-stone-700 transition hover:bg-stone-100 hover:text-stone-950 dark:text-stone-200 dark:hover:bg-stone-900 dark:hover:text-white" className="flex w-full items-center gap-3 px-4 py-3 text-sm text-stone-700 transition hover:bg-stone-100 hover:text-blue-900 dark:text-stone-200 dark:hover:bg-[#0d1b38] dark:hover:text-white"
> >
<span aria-hidden="true" className="text-base leading-none">{option.flag}</span> <span aria-hidden="true" className="text-base leading-none">{option.flag}</span>
<span>{option.label}</span> <span>{option.label}</span>
@@ -173,7 +173,7 @@ export default function PublicFooter() {
} }
function FooterNavItem({ item }: { item: FooterItem }) { function FooterNavItem({ item }: { item: FooterItem }) {
const className = 'px-3 text-stone-600 transition hover:text-stone-950 dark:text-stone-300 dark:hover:text-white' const className = 'px-3 text-stone-600 transition hover:text-blue-900 dark:text-stone-300 dark:hover:text-white'
if (item.href) { if (item.href) {
return ( return (
@@ -105,9 +105,9 @@ export default function PublicHeader() {
const signUpHref = `/sign-up?${signUpParams.toString()}` const signUpHref = `/sign-up?${signUpParams.toString()}`
return ( return (
<header className="sticky top-0 z-30 border-b border-stone-200/80 bg-white/78 backdrop-blur-xl shadow-[0_10px_30px_rgba(15,23,42,0.06)] transition-colors dark:border-stone-800 dark:bg-stone-950/76 dark:shadow-[0_10px_30px_rgba(0,0,0,0.28)]"> <header className="sticky top-0 z-30 border-b border-stone-200/80 bg-white/78 backdrop-blur-xl shadow-[0_10px_30px_rgba(15,23,42,0.06)] transition-colors dark:border-blue-900 dark:bg-[#07101e]/76 dark:shadow-[0_10px_30px_rgba(0,0,0,0.28)]">
<div className="mx-auto flex max-w-7xl flex-col gap-1.5 px-4 py-1.5 sm:px-6 lg:flex-row lg:items-center lg:justify-between lg:gap-3 lg:px-8 lg:py-2"> <div className="mx-auto flex max-w-7xl flex-col gap-1.5 px-4 py-1.5 sm:px-6 lg:flex-row lg:items-center lg:justify-between lg:gap-3 lg:px-8 lg:py-2">
<a href={marketplaceUrl} className="flex items-center gap-1.5 text-[11px] font-bold uppercase tracking-[0.14em] text-stone-900 dark:text-stone-100 sm:text-sm sm:tracking-[0.2em]"> <a href={marketplaceUrl} className="flex items-center gap-1.5 text-[11px] font-bold uppercase tracking-[0.14em] text-blue-950 dark:text-slate-100 sm:text-sm sm:tracking-[0.2em]">
<Image <Image
src={DASHBOARD_LOGO_SRC} src={DASHBOARD_LOGO_SRC}
alt="RentalDriveGo" alt="RentalDriveGo"
@@ -121,26 +121,26 @@ export default function PublicHeader() {
<div className="flex flex-col gap-1.5 lg:flex-row lg:items-center lg:gap-3"> <div className="flex flex-col gap-1.5 lg:flex-row lg:items-center lg:gap-3">
<nav className="flex items-center gap-0.5 overflow-x-auto"> <nav className="flex items-center gap-0.5 overflow-x-auto">
<a href={marketplaceUrl} className="rounded-full px-2.5 py-1 text-[12px] font-medium text-stone-600 transition hover:bg-stone-100 hover:text-stone-900 dark:text-stone-300 dark:hover:bg-stone-800 dark:hover:text-stone-100 sm:px-4 sm:py-2 sm:text-sm"> <a href={marketplaceUrl} className="rounded-full px-2.5 py-1 text-[12px] font-medium text-stone-600 transition hover:bg-stone-100 hover:text-blue-900 dark:text-stone-300 dark:hover:bg-[#162038] dark:hover:text-stone-100 sm:px-4 sm:py-2 sm:text-sm">
{dict.home} {dict.home}
</a> </a>
<a href={`${marketplaceUrl}/explore`} className="rounded-full px-2.5 py-1 text-[12px] font-medium text-stone-600 transition hover:bg-stone-100 hover:text-stone-900 dark:text-stone-300 dark:hover:bg-stone-800 dark:hover:text-stone-100 sm:px-4 sm:py-2 sm:text-sm"> <a href={`${marketplaceUrl}/explore`} className="rounded-full px-2.5 py-1 text-[12px] font-medium text-stone-600 transition hover:bg-stone-100 hover:text-blue-900 dark:text-stone-300 dark:hover:bg-[#162038] dark:hover:text-stone-100 sm:px-4 sm:py-2 sm:text-sm">
{dict.marketplace} {dict.marketplace}
</a> </a>
<a href={signInHref} className="rounded-full px-2.5 py-1 text-[12px] font-medium text-stone-600 transition hover:bg-stone-100 hover:text-stone-900 dark:text-stone-300 dark:hover:bg-stone-800 dark:hover:text-stone-100 sm:px-4 sm:py-2 sm:text-sm"> <a href={signInHref} className="rounded-full px-2.5 py-1 text-[12px] font-medium text-stone-600 transition hover:bg-stone-100 hover:text-blue-900 dark:text-stone-300 dark:hover:bg-[#162038] dark:hover:text-stone-100 sm:px-4 sm:py-2 sm:text-sm">
{dict.signIn} {dict.signIn}
</a> </a>
<Link href={signUpHref} className="ml-1 rounded-full bg-stone-900 px-3 py-1 text-[12px] font-semibold text-white transition hover:bg-stone-700 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300 sm:ml-2 sm:px-5 sm:py-2 sm:text-sm"> <Link href={signUpHref} className="ml-1 rounded-full bg-blue-900 px-3 py-1 text-[12px] font-semibold text-white transition hover:bg-orange-700 dark:bg-orange-400 dark:text-white dark:hover:bg-orange-300 sm:ml-2 sm:px-5 sm:py-2 sm:text-sm">
{dict.createAccount} {dict.createAccount}
</Link> </Link>
</nav> </nav>
<div className="shrink-0"> <div className="shrink-0">
<div className="flex items-center self-start rounded-full border border-stone-200/80 bg-white/95 p-0.5 shadow-sm dark:border-stone-700 dark:bg-stone-900/85 sm:self-auto sm:p-1"> <div className="flex items-center self-start rounded-full border border-stone-200/80 bg-white/95 p-0.5 shadow-sm dark:border-blue-800 dark:bg-[#0d1b38]/85 sm:self-auto sm:p-1">
<div ref={localeMenuRef} className="relative"> <div ref={localeMenuRef} className="relative">
<button <button
type="button" type="button"
onClick={toggleLocaleMenu} onClick={toggleLocaleMenu}
className="inline-flex min-w-[4.75rem] items-center justify-center gap-1.5 rounded-full px-2.5 py-1.5 text-[11px] font-semibold text-stone-700 transition hover:bg-stone-100 dark:text-stone-200 dark:hover:bg-stone-800 sm:min-w-[5.25rem] sm:px-3 sm:py-2 sm:text-xs" className="inline-flex min-w-[4.75rem] items-center justify-center gap-1.5 rounded-full px-2.5 py-1.5 text-[11px] font-semibold text-stone-700 transition hover:bg-stone-100 dark:text-stone-200 dark:hover:bg-[#162038] sm:min-w-[5.25rem] sm:px-3 sm:py-2 sm:text-xs"
aria-expanded={localeMenuOpen} aria-expanded={localeMenuOpen}
aria-haspopup="menu" aria-haspopup="menu"
> >
@@ -149,7 +149,7 @@ export default function PublicHeader() {
<ChevronDown className={`h-3.5 w-3.5 transition-transform ${localeMenuOpen ? 'rotate-180' : ''}`} /> <ChevronDown className={`h-3.5 w-3.5 transition-transform ${localeMenuOpen ? 'rotate-180' : ''}`} />
</button> </button>
{localeMenuOpen ? ( {localeMenuOpen ? (
<div className={`absolute top-full z-30 mt-2 w-48 max-w-[calc(100vw-2rem)] overflow-hidden rounded-2xl border border-stone-200 bg-white/95 text-left shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-stone-800 dark:bg-stone-950/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)] ${localeMenuPositionClass}`}> <div className={`absolute top-full z-30 mt-2 w-48 max-w-[calc(100vw-2rem)] overflow-hidden rounded-2xl border border-stone-200 bg-white/95 text-left shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-blue-900 dark:bg-[#07101e]/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)] ${localeMenuPositionClass}`}>
{availableLanguages.map((option) => ( {availableLanguages.map((option) => (
<button <button
key={option.value} key={option.value}
@@ -158,7 +158,7 @@ export default function PublicHeader() {
setLanguage(option.value) setLanguage(option.value)
setLocaleMenuOpen(false) setLocaleMenuOpen(false)
}} }}
className="flex w-full items-center gap-3 px-4 py-3 text-sm text-stone-700 transition hover:bg-stone-100 hover:text-stone-950 dark:text-stone-200 dark:hover:bg-stone-900 dark:hover:text-white" className="flex w-full items-center gap-3 px-4 py-3 text-sm text-stone-700 transition hover:bg-stone-100 hover:text-blue-900 dark:text-stone-200 dark:hover:bg-[#0d1b38] dark:hover:text-white"
> >
<span aria-hidden="true">{option.flag}</span> <span aria-hidden="true">{option.flag}</span>
<span>{option.shortLabel}</span> <span>{option.shortLabel}</span>
@@ -172,17 +172,17 @@ export default function PublicHeader() {
<button <button
type="button" type="button"
onClick={toggleThemeMenu} onClick={toggleThemeMenu}
className="inline-flex items-center gap-1.5 rounded-full px-2 py-1 transition hover:bg-stone-100 dark:hover:bg-stone-800 sm:px-2.5 sm:py-1.5" className="inline-flex items-center gap-1.5 rounded-full px-2 py-1 transition hover:bg-stone-100 dark:hover:bg-[#162038] sm:px-2.5 sm:py-1.5"
aria-expanded={themeMenuOpen} aria-expanded={themeMenuOpen}
aria-haspopup="menu" aria-haspopup="menu"
> >
<span className="rounded-full bg-stone-900 px-3 py-1 text-[11px] font-semibold text-white dark:bg-amber-400 dark:text-stone-950 sm:px-3.5 sm:py-1.5 sm:text-xs"> <span className="rounded-full bg-blue-900 px-3 py-1 text-[11px] font-semibold text-white dark:bg-orange-400 dark:text-white sm:px-3.5 sm:py-1.5 sm:text-xs">
{currentTheme.label} {currentTheme.label}
</span> </span>
<ChevronDown className={`h-3.5 w-3.5 text-stone-500 transition-transform dark:text-stone-400 ${themeMenuOpen ? 'rotate-180' : ''}`} /> <ChevronDown className={`h-3.5 w-3.5 text-stone-500 transition-transform dark:text-stone-400 ${themeMenuOpen ? 'rotate-180' : ''}`} />
</button> </button>
{themeMenuOpen ? ( {themeMenuOpen ? (
<div className={`absolute top-full z-30 mt-2 w-44 max-w-[calc(100vw-2rem)] overflow-hidden rounded-2xl border border-stone-200 bg-white/95 text-left shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-stone-800 dark:bg-stone-950/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)] ${localeMenuPositionClass}`}> <div className={`absolute top-full z-30 mt-2 w-44 max-w-[calc(100vw-2rem)] overflow-hidden rounded-2xl border border-stone-200 bg-white/95 text-left shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-blue-900 dark:bg-[#07101e]/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)] ${localeMenuPositionClass}`}>
{themeOptions {themeOptions
.filter((option) => option.value !== theme) .filter((option) => option.value !== theme)
.map((option) => ( .map((option) => (
@@ -193,7 +193,7 @@ export default function PublicHeader() {
setTheme(option.value) setTheme(option.value)
setThemeMenuOpen(false) setThemeMenuOpen(false)
}} }}
className="flex w-full items-center justify-between px-4 py-3 text-sm text-stone-700 transition hover:bg-stone-100 hover:text-stone-950 dark:text-stone-200 dark:hover:bg-stone-900 dark:hover:text-white" className="flex w-full items-center justify-between px-4 py-3 text-sm text-stone-700 transition hover:bg-stone-100 hover:text-blue-900 dark:text-stone-200 dark:hover:bg-[#0d1b38] dark:hover:text-white"
> >
<span>{option.label}</span> <span>{option.label}</span>
</button> </button>
@@ -11,7 +11,7 @@ export default function PublicShell({
embedded?: boolean embedded?: boolean
}) { }) {
return ( return (
<div className="flex min-h-screen flex-col bg-[linear-gradient(180deg,#f8f5ef_0%,#f4efe6_28%,#fffdf8_58%,#ffffff_100%)] text-stone-900 transition-colors dark:bg-[linear-gradient(180deg,#14110f_0%,#17120d_35%,#0c0a09_100%)] dark:text-stone-100"> <div className="flex min-h-screen flex-col bg-[linear-gradient(180deg,#ffffff_0%,#f5f8ff_28%,#eef4ff_58%,#ffffff_100%)] text-blue-950 transition-colors dark:bg-[linear-gradient(180deg,#0a1128_0%,#0d1b38_35%,#07101e_100%)] dark:text-slate-100">
{embedded ? null : <PublicHeader />} {embedded ? null : <PublicHeader />}
<div className="flex flex-1 flex-col">{children}</div> <div className="flex flex-1 flex-col">{children}</div>
{embedded ? null : <PublicFooter />} {embedded ? null : <PublicFooter />}
@@ -169,7 +169,7 @@ export default function Sidebar() {
{/* Mobile backdrop */} {/* Mobile backdrop */}
{open && ( {open && (
<div <div
className="fixed inset-0 z-30 bg-black/50 lg:hidden" className="fixed inset-0 z-30 bg-[#07101e]/50 lg:hidden"
onClick={() => setOpen(false)} onClick={() => setOpen(false)}
/> />
)} )}
@@ -180,7 +180,7 @@ export default function Sidebar() {
onClick={() => setOpen(true)} onClick={() => setOpen(true)}
aria-label="Open sidebar" aria-label="Open sidebar"
className={[ className={[
'fixed top-1/2 z-50 flex h-14 w-6 -translate-y-1/2 items-center justify-center bg-stone-950 text-white shadow-lg lg:hidden', 'fixed top-1/2 z-50 flex h-14 w-6 -translate-y-1/2 items-center justify-center bg-[#0a1128] text-white shadow-lg lg:hidden',
isRtl ? 'right-0 rounded-l-lg' : 'left-0 rounded-r-lg', isRtl ? 'right-0 rounded-l-lg' : 'left-0 rounded-r-lg',
].join(' ')} ].join(' ')}
> >
@@ -190,19 +190,19 @@ export default function Sidebar() {
<aside <aside
className={[ className={[
'fixed inset-y-0 z-40 flex w-64 flex-col border-r border-stone-800/80 bg-stone-950/94 backdrop-blur-xl transition-transform duration-300', 'fixed inset-y-0 z-40 flex w-64 flex-col border-r border-blue-900/50 bg-[#0a1128]/94 backdrop-blur-xl transition-transform duration-300',
isRtl ? 'right-0' : 'left-0', isRtl ? 'right-0' : 'left-0',
'lg:translate-x-0', 'lg:translate-x-0',
open ? 'translate-x-0' : (isRtl ? 'translate-x-full' : '-translate-x-full'), open ? 'translate-x-0' : (isRtl ? 'translate-x-full' : '-translate-x-full'),
].join(' ')} ].join(' ')}
> >
<a href={marketplaceUrl} target="_top" className="flex items-center gap-3 border-b border-stone-800/80 px-6 py-5"> <a href={marketplaceUrl} target="_top" className="flex items-center gap-3 border-b border-blue-900/50 px-6 py-5">
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center overflow-hidden rounded-lg bg-amber-400"> <div className="flex h-8 w-8 flex-shrink-0 items-center justify-center overflow-hidden rounded-lg bg-orange-400">
{brand?.logoUrl ? ( {brand?.logoUrl ? (
// eslint-disable-next-line @next/next/no-img-element // eslint-disable-next-line @next/next/no-img-element
<img src={brand.logoUrl} alt={brand.displayName} className="h-8 w-8 object-cover" /> <img src={brand.logoUrl} alt={brand.displayName} className="h-8 w-8 object-cover" />
) : ( ) : (
<Car className="h-4 w-4 text-stone-950" /> <Car className="h-4 w-4 text-blue-950" />
)} )}
</div> </div>
<span className="truncate text-sm font-bold tracking-wide text-white"> <span className="truncate text-sm font-bold tracking-wide text-white">
@@ -220,7 +220,7 @@ export default function Sidebar() {
href={item.href} href={item.href}
className={[ className={[
'flex items-center gap-3 rounded-2xl px-3 py-2.5 text-sm font-medium transition-colors', 'flex items-center gap-3 rounded-2xl px-3 py-2.5 text-sm font-medium transition-colors',
active ? 'bg-amber-400 text-stone-950' : 'text-stone-400 hover:bg-stone-800 hover:text-white', active ? 'bg-orange-500 text-white' : 'text-slate-400 hover:bg-[#162038] hover:text-white',
].join(' ')} ].join(' ')}
> >
<Icon className="h-4 w-4 flex-shrink-0" /> <Icon className="h-4 w-4 flex-shrink-0" />
@@ -230,19 +230,19 @@ export default function Sidebar() {
})} })}
</nav> </nav>
<div className="border-t border-stone-800/80 px-3 py-4"> <div className="border-t border-blue-900/50 px-3 py-4">
<div className="flex items-center gap-3 rounded-2xl px-3 py-2"> <div className="flex items-center gap-3 rounded-2xl px-3 py-2">
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-amber-400 text-xs font-semibold text-stone-950"> <div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-orange-500 text-xs font-semibold text-white">
{user.initials} {user.initials}
</div> </div>
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
<p className="truncate text-sm font-medium text-white">{user.displayName}</p> <p className="truncate text-sm font-medium text-white">{user.displayName}</p>
<p className="truncate text-xs text-stone-400">{user.subtitle}</p> <p className="truncate text-xs text-slate-400">{user.subtitle}</p>
</div> </div>
</div> </div>
<button <button
onClick={signOut} onClick={signOut}
className="mt-2 flex w-full items-center gap-3 rounded-2xl px-3 py-2 text-sm text-stone-400 transition-colors hover:bg-stone-800 hover:text-white" className="mt-2 flex w-full items-center gap-3 rounded-2xl px-3 py-2 text-sm text-slate-400 transition-colors hover:bg-[#162038] hover:text-white"
> >
<LogOut className="h-4 w-4" /> <LogOut className="h-4 w-4" />
{dict.signOut} {dict.signOut}
@@ -254,7 +254,7 @@ export default function Sidebar() {
onClick={() => setOpen(false)} onClick={() => setOpen(false)}
aria-label="Close sidebar" aria-label="Close sidebar"
className={[ className={[
'absolute top-1/2 z-10 flex h-14 w-5 -translate-y-1/2 items-center justify-center bg-stone-950 text-white shadow-lg lg:hidden', 'absolute top-1/2 z-10 flex h-14 w-5 -translate-y-1/2 items-center justify-center bg-[#0a1128] text-white shadow-lg lg:hidden',
isRtl ? '-left-5 rounded-l-lg' : '-right-5 rounded-r-lg', isRtl ? '-left-5 rounded-l-lg' : '-right-5 rounded-r-lg',
].join(' ')} ].join(' ')}
> >
@@ -143,14 +143,14 @@ export default function TopBar() {
} }
return ( return (
<header className="flex h-16 items-center justify-between border-b border-stone-200/80 bg-white/78 px-6 backdrop-blur-xl transition-colors dark:border-stone-800 dark:bg-stone-950/76"> <header className="flex h-16 items-center justify-between border-b border-stone-200/80 bg-white/78 px-6 backdrop-blur-xl transition-colors dark:border-blue-900 dark:bg-[#07101e]/76">
<h1 className="text-lg font-semibold text-stone-950 dark:text-stone-50">{title}</h1> <h1 className="text-lg font-semibold text-blue-950 dark:text-stone-50">{title}</h1>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="relative"> <div className="relative">
<button <button
onClick={() => setShowNotifs(!showNotifs)} onClick={() => setShowNotifs(!showNotifs)}
className="relative rounded-2xl p-2 text-stone-500 transition-colors hover:bg-stone-100 hover:text-stone-700 dark:text-stone-400 dark:hover:bg-stone-800 dark:hover:text-stone-100" className="relative rounded-2xl p-2 text-stone-500 transition-colors hover:bg-stone-100 hover:text-stone-700 dark:text-stone-400 dark:hover:bg-[#162038] dark:hover:text-stone-100"
> >
<Bell className="h-5 w-5" /> <Bell className="h-5 w-5" />
{unreadCount > 0 ? ( {unreadCount > 0 ? (
@@ -161,13 +161,13 @@ export default function TopBar() {
</button> </button>
{showNotifs ? ( {showNotifs ? (
<div className="absolute right-0 top-full z-50 mt-2 w-80 rounded-[1.75rem] border border-stone-200/80 bg-white/95 p-4 shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-stone-800 dark:bg-stone-950/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)]"> <div className="absolute right-0 top-full z-50 mt-2 w-80 rounded-[1.75rem] border border-stone-200/80 bg-white/95 p-4 shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-blue-900 dark:bg-[#07101e]/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)]">
<div className="mb-2 flex items-center justify-between gap-2"> <div className="mb-2 flex items-center justify-between gap-2">
<p className="text-sm font-medium text-stone-950 dark:text-stone-100">{dict.notifications}</p> <p className="text-sm font-medium text-blue-950 dark:text-stone-100">{dict.notifications}</p>
<button <button
type="button" type="button"
onClick={() => openNotificationsInbox()} onClick={() => openNotificationsInbox()}
className="text-xs font-medium text-amber-700 hover:text-stone-950 dark:text-amber-300 dark:hover:text-white" className="text-xs font-medium text-orange-700 hover:text-blue-900 dark:text-orange-300 dark:hover:text-white"
> >
View all View all
</button> </button>
@@ -187,11 +187,11 @@ export default function TopBar() {
type="button" type="button"
onClick={() => openNotificationsInbox(notification.id)} onClick={() => openNotificationsInbox(notification.id)}
className={[ className={[
'w-full rounded-2xl px-3 py-2 text-left transition-colors hover:bg-stone-100 dark:hover:bg-stone-800', 'w-full rounded-2xl px-3 py-2 text-left transition-colors hover:bg-stone-100 dark:hover:bg-[#162038]',
notification.readAt ? 'opacity-80' : '', notification.readAt ? 'opacity-80' : '',
].join(' ')} ].join(' ')}
> >
<p className="truncate text-sm font-medium text-stone-950 dark:text-stone-100"> <p className="truncate text-sm font-medium text-blue-950 dark:text-stone-100">
{notification.title} {notification.title}
</p> </p>
<p className="truncate text-xs text-stone-500 dark:text-stone-400"> <p className="truncate text-xs text-stone-500 dark:text-stone-400">
@@ -205,7 +205,7 @@ export default function TopBar() {
) : null} ) : null}
</div> </div>
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-amber-400 text-xs font-semibold text-stone-950"> <div className="flex h-8 w-8 items-center justify-center rounded-full bg-orange-400 text-xs font-semibold text-blue-950">
{userInitials} {userInitials}
</div> </div>
</div> </div>
@@ -177,7 +177,7 @@ export default function EditMemberModal({
return ( return (
<div <div
className="fixed inset-0 z-50 flex items-center justify-center bg-black/30 backdrop-blur-sm" className="fixed inset-0 z-50 flex items-center justify-center bg-[#07101e]/30 backdrop-blur-sm"
onClick={(e) => { if (e.target === e.currentTarget && !busy) onClose() }} onClick={(e) => { if (e.target === e.currentTarget && !busy) onClose() }}
> >
<div <div
@@ -197,7 +197,7 @@ export default function EditMemberModal({
</div> </div>
<div className="ml-auto"> <div className="ml-auto">
{isPending && ( {isPending && (
<span className="text-xs px-2 py-1 rounded-full bg-amber-50 dark:bg-amber-950/30 text-amber-700 dark:text-amber-400 border border-amber-100 dark:border-amber-900/50"> <span className="text-xs px-2 py-1 rounded-full bg-orange-50 dark:bg-orange-950/30 text-orange-700 dark:text-orange-400 border border-orange-100 dark:border-orange-900/50">
{t.pendingInvite} {t.pendingInvite}
</span> </span>
)} )}
@@ -136,7 +136,7 @@ export default function InviteModal({ open, onClose, onInvite }: Props) {
return ( return (
<div <div
className="fixed inset-0 z-50 flex items-center justify-center bg-black/30 backdrop-blur-sm" className="fixed inset-0 z-50 flex items-center justify-center bg-[#07101e]/30 backdrop-blur-sm"
onClick={(e) => { if (e.target === e.currentTarget) onClose() }} onClick={(e) => { if (e.target === e.currentTarget) onClose() }}
> >
<div <div
@@ -151,9 +151,9 @@ function AccessCell({ access, label, limitedNote }: { access: Access; label: { f
return ( return (
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5">
<div className="w-3.5 h-3.5 flex-shrink-0 flex items-center justify-center"> <div className="w-3.5 h-3.5 flex-shrink-0 flex items-center justify-center">
<div className="w-2.5 h-0.5 rounded bg-amber-500" /> <div className="w-2.5 h-0.5 rounded bg-orange-500" />
</div> </div>
<span className="text-xs text-amber-700 dark:text-amber-400">{limitedNote || label.limited}</span> <span className="text-xs text-orange-700 dark:text-orange-400">{limitedNote || label.limited}</span>
</div> </div>
) )
} }
@@ -16,8 +16,8 @@ export default function StatCard({
change, change,
vsLastMonthLabel = 'vs last month', vsLastMonthLabel = 'vs last month',
icon: Icon, icon: Icon,
iconColor = 'text-amber-700 dark:text-amber-300', iconColor = 'text-orange-700 dark:text-orange-300',
iconBg = 'bg-amber-50 dark:bg-amber-950/30', iconBg = 'bg-orange-50 dark:bg-orange-950/30',
}: StatCardProps) { }: StatCardProps) {
const isPositive = change !== undefined && change >= 0 const isPositive = change !== undefined && change >= 0
const isNegative = change !== undefined && change < 0 const isNegative = change !== undefined && change < 0
@@ -27,7 +27,7 @@ export default function StatCard({
<div className="flex items-start justify-between"> <div className="flex items-start justify-between">
<div> <div>
<p className="text-sm font-medium text-stone-500 dark:text-stone-400">{title}</p> <p className="text-sm font-medium text-stone-500 dark:text-stone-400">{title}</p>
<p className="mt-1 text-2xl font-bold text-stone-950 dark:text-stone-50">{value}</p> <p className="mt-1 text-2xl font-bold text-blue-950 dark:text-stone-50">{value}</p>
{change !== undefined && ( {change !== undefined && (
<div className="mt-2 flex items-center gap-1"> <div className="mt-2 flex items-center gap-1">
<span <span
@@ -52,9 +52,9 @@ export default function HomeContent() {
<div className="shell relative py-10 sm:py-14 lg:py-20"> <div className="shell relative py-10 sm:py-14 lg:py-20">
<div className={`grid gap-8 ${hasSection('hero') && hasSection('surface') ? 'lg:grid-cols-[minmax(0,1.15fr)_24rem] lg:items-stretch xl:grid-cols-[minmax(0,1.2fr)_28rem]' : ''}`}> <div className={`grid gap-8 ${hasSection('hero') && hasSection('surface') ? 'lg:grid-cols-[minmax(0,1.15fr)_24rem] lg:items-stretch xl:grid-cols-[minmax(0,1.2fr)_28rem]' : ''}`}>
{hasSection('hero') ? ( {hasSection('hero') ? (
<div className="rounded-[2rem] border border-stone-200/80 bg-white/80 p-7 shadow-[0_30px_80px_rgba(28,25,23,0.08)] backdrop-blur dark:border-stone-800 dark:bg-stone-900/70"> <div className="rounded-[2rem] border border-stone-200/80 bg-white/80 p-7 shadow-[0_30px_80px_rgba(28,25,23,0.08)] backdrop-blur dark:border-blue-900 dark:bg-[#0d1b38]/70">
<p className="text-xs font-bold uppercase tracking-[0.32em] text-amber-700 dark:text-amber-300">{dict.heroKicker}</p> <p className="text-xs font-bold uppercase tracking-[0.32em] text-orange-700 dark:text-orange-300">{dict.heroKicker}</p>
<h1 className="mt-5 max-w-4xl text-5xl font-black leading-none tracking-[-0.04em] text-stone-950 dark:text-stone-50 sm:text-6xl lg:text-7xl"> <h1 className="mt-5 max-w-4xl text-5xl font-black leading-none tracking-[-0.04em] text-blue-950 dark:text-stone-50 sm:text-6xl lg:text-7xl">
{dict.heroTitle} {dict.heroTitle}
</h1> </h1>
<p className="mt-6 max-w-2xl text-base leading-8 text-stone-600 dark:text-stone-300 sm:text-lg"> <p className="mt-6 max-w-2xl text-base leading-8 text-stone-600 dark:text-stone-300 sm:text-lg">
@@ -64,13 +64,13 @@ export default function HomeContent() {
<div className="mt-8 flex flex-wrap gap-3"> <div className="mt-8 flex flex-wrap gap-3">
<a <a
href={starterSignupHref} href={starterSignupHref}
className="rounded-full bg-stone-950 px-6 py-3 text-sm font-semibold text-white transition hover:bg-stone-800 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300" className="rounded-full bg-orange-600 px-6 py-3 text-sm font-semibold text-white transition hover:bg-orange-700 dark:bg-orange-500 dark:hover:bg-orange-400"
> >
{dict.startTrial} {dict.startTrial}
</a> </a>
<a <a
href="/explore" href="/explore"
className="rounded-full border border-stone-300 bg-white/85 px-6 py-3 text-sm font-semibold text-stone-700 transition hover:border-stone-950 hover:text-stone-950 dark:border-stone-700 dark:bg-stone-950/30 dark:text-stone-200 dark:hover:border-stone-200 dark:hover:text-white" className="rounded-full border border-stone-300 bg-white/85 px-6 py-3 text-sm font-semibold text-stone-700 transition hover:border-blue-900 hover:text-blue-900 dark:border-blue-800 dark:bg-[#07101e]/30 dark:text-stone-200 dark:hover:border-stone-200 dark:hover:text-white"
> >
{dict.exploreVehicles} {dict.exploreVehicles}
</a> </a>
@@ -78,7 +78,7 @@ export default function HomeContent() {
<div className="mt-10 grid gap-3 sm:grid-cols-3"> <div className="mt-10 grid gap-3 sm:grid-cols-3">
{dict.metrics.map(({ value, label }) => ( {dict.metrics.map(({ value, label }) => (
<div key={value} className="rounded-[1.5rem] border border-stone-200/80 bg-stone-50/90 p-4 dark:border-stone-800 dark:bg-stone-950/50"> <div key={value} className="rounded-[1.5rem] border border-stone-200/80 bg-stone-50/90 p-4 dark:border-blue-900 dark:bg-[#07101e]/50">
<p className="text-xs font-bold tracking-[0.28em] text-stone-400 dark:text-stone-500">{value}</p> <p className="text-xs font-bold tracking-[0.28em] text-stone-400 dark:text-stone-500">{value}</p>
<p className="mt-3 text-sm font-semibold leading-6 text-stone-900 dark:text-stone-100">{label}</p> <p className="mt-3 text-sm font-semibold leading-6 text-stone-900 dark:text-stone-100">{label}</p>
</div> </div>
@@ -88,11 +88,11 @@ export default function HomeContent() {
) : null} ) : null}
{hasSection('surface') ? ( {hasSection('surface') ? (
<div className="relative overflow-hidden rounded-[2rem] border border-stone-200/80 bg-stone-950 p-6 text-white shadow-[0_30px_80px_rgba(28,25,23,0.18)] dark:border-stone-700"> <div className="relative overflow-hidden rounded-[2rem] border border-blue-900/60 bg-[#06132e] p-6 text-white shadow-[0_30px_80px_rgba(6,19,46,0.40)] dark:border-blue-800">
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top_right,rgba(245,158,11,0.34),transparent_28%),radial-gradient(circle_at_bottom_left,rgba(20,184,166,0.25),transparent_32%)]" /> <div className="absolute inset-0 bg-[radial-gradient(circle_at_top_right,rgba(249,115,22,0.30),transparent_28%),radial-gradient(circle_at_bottom_left,rgba(96,165,250,0.22),transparent_32%)]" />
<div className="relative"> <div className="relative">
<div className="flex items-center justify-between gap-3"> <div className="flex items-center justify-between gap-3">
<span className="rounded-full border border-white/15 bg-white/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-amber-200"> <span className="rounded-full border border-white/15 bg-white/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-orange-200">
{dict.surfaceLabel} {dict.surfaceLabel}
</span> </span>
<span className="rounded-full bg-emerald-400/15 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-emerald-200"> <span className="rounded-full bg-emerald-400/15 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.22em] text-emerald-200">
@@ -111,12 +111,12 @@ export default function HomeContent() {
].map(([step, label]) => ( ].map(([step, label]) => (
<div key={step} className="flex items-center justify-between rounded-[1.25rem] border border-white/10 bg-white/5 px-4 py-4"> <div key={step} className="flex items-center justify-between rounded-[1.25rem] border border-white/10 bg-white/5 px-4 py-4">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<span className="flex h-10 w-10 items-center justify-center rounded-full bg-white text-xs font-bold text-stone-950"> <span className="flex h-10 w-10 items-center justify-center rounded-full bg-white text-xs font-bold text-blue-950">
{step} {step}
</span> </span>
<p className="text-sm font-semibold text-white">{label}</p> <p className="text-sm font-semibold text-white">{label}</p>
</div> </div>
<span className="text-lg text-amber-300">+</span> <span className="text-lg text-orange-300">+</span>
</div> </div>
))} ))}
</div> </div>
@@ -126,14 +126,14 @@ export default function HomeContent() {
</div> </div>
{hasSection('audiences') ? <div className="mt-8 grid gap-4 lg:grid-cols-[1.15fr_0.85fr]"> {hasSection('audiences') ? <div className="mt-8 grid gap-4 lg:grid-cols-[1.15fr_0.85fr]">
<article className="rounded-[2rem] border border-stone-200/80 bg-white/80 p-7 backdrop-blur dark:border-stone-800 dark:bg-stone-900/60"> <article className="rounded-[2rem] border border-stone-200/80 bg-white/80 p-7 backdrop-blur dark:border-blue-900 dark:bg-[#0d1b38]/60">
<p className="text-xs font-bold uppercase tracking-[0.24em] text-stone-500 dark:text-stone-400">{dict.companyKicker}</p> <p className="text-xs font-bold uppercase tracking-[0.24em] text-stone-500 dark:text-stone-400">{dict.companyKicker}</p>
<h2 className="mt-4 text-2xl font-black tracking-[-0.03em] text-stone-950 dark:text-stone-50 sm:text-3xl">{dict.companyTitle}</h2> <h2 className="mt-4 text-2xl font-black tracking-[-0.03em] text-blue-950 dark:text-stone-50 sm:text-3xl">{dict.companyTitle}</h2>
<p className="mt-4 max-w-3xl text-sm leading-7 text-stone-600 dark:text-stone-300">{dict.companyBody}</p> <p className="mt-4 max-w-3xl text-sm leading-7 text-stone-600 dark:text-stone-300">{dict.companyBody}</p>
</article> </article>
<article className="rounded-[2rem] border border-stone-200/80 bg-[#f7efe2] p-7 dark:border-stone-800 dark:bg-[#1d1712]"> <article className="rounded-[2rem] border border-stone-200/80 bg-[#f7efe2] p-7 dark:border-blue-900 dark:bg-[#1d1712]">
<p className="text-xs font-bold uppercase tracking-[0.24em] text-amber-700 dark:text-amber-300">{dict.renterKicker}</p> <p className="text-xs font-bold uppercase tracking-[0.24em] text-orange-700 dark:text-orange-300">{dict.renterKicker}</p>
<h2 className="mt-4 text-2xl font-black tracking-[-0.03em] text-stone-950 dark:text-stone-50 sm:text-3xl">{dict.renterTitle}</h2> <h2 className="mt-4 text-2xl font-black tracking-[-0.03em] text-blue-950 dark:text-stone-50 sm:text-3xl">{dict.renterTitle}</h2>
<p className="mt-4 text-sm leading-7 text-stone-700 dark:text-stone-300">{dict.renterBody}</p> <p className="mt-4 text-sm leading-7 text-stone-700 dark:text-stone-300">{dict.renterBody}</p>
</article> </article>
</div> : null} </div> : null}
@@ -147,8 +147,8 @@ export default function HomeContent() {
key={title} key={title}
className={`rounded-[2rem] border p-7 shadow-sm ${ className={`rounded-[2rem] border p-7 shadow-sm ${
index === 1 index === 1
? 'border-stone-900 bg-stone-950 text-white dark:border-amber-300 dark:bg-amber-300 dark:text-stone-950' ? 'border-orange-700 bg-orange-600 text-white dark:border-orange-500 dark:bg-orange-500 dark:text-white'
: 'border-stone-200 bg-white dark:border-stone-800 dark:bg-stone-900' : 'border-stone-200 bg-white dark:border-blue-900 dark:bg-[#0d1b38]'
}`} }`}
> >
<p <p
@@ -174,12 +174,12 @@ export default function HomeContent() {
{(hasSection('features') || hasSection('steps')) ? <section className="shell py-10"> {(hasSection('features') || hasSection('steps')) ? <section className="shell py-10">
<div className="grid gap-6 lg:grid-cols-[0.9fr_1.1fr]"> <div className="grid gap-6 lg:grid-cols-[0.9fr_1.1fr]">
{hasSection('features') ? ( {hasSection('features') ? (
<div className="rounded-[2rem] border border-stone-200 bg-[linear-gradient(160deg,#fffdf8_0%,#f1ebe1_100%)] p-8 dark:border-stone-800 dark:bg-[linear-gradient(160deg,#17120d_0%,#221a14_100%)]"> <div className="rounded-[2rem] border border-stone-200 bg-[linear-gradient(160deg,#f5f8ff_0%,#edf2ff_100%)] p-8 dark:border-blue-900 dark:bg-[linear-gradient(160deg,#0c1830_0%,#10203e_100%)]">
<p className="text-xs font-bold uppercase tracking-[0.24em] text-stone-500 dark:text-stone-400">{dict.featureLabel}</p> <p className="text-xs font-bold uppercase tracking-[0.24em] text-stone-500 dark:text-stone-400">{dict.featureLabel}</p>
<div className="mt-6 space-y-3"> <div className="mt-6 space-y-3">
{dict.features.map((item, index) => ( {dict.features.map((item, index) => (
<div key={item} className="flex items-start gap-4 rounded-[1.25rem] border border-stone-200/80 bg-white/85 px-4 py-4 dark:border-stone-700 dark:bg-stone-950/40"> <div key={item} className="flex items-start gap-4 rounded-[1.25rem] border border-stone-200/80 bg-white/85 px-4 py-4 dark:border-blue-800 dark:bg-[#07101e]/40">
<span className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-stone-950 text-xs font-bold text-white dark:bg-amber-300 dark:text-stone-950"> <span className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-orange-600 text-xs font-bold text-white dark:bg-orange-500 dark:text-white">
{index + 1} {index + 1}
</span> </span>
<p className="text-sm font-semibold leading-6 text-stone-800 dark:text-stone-100">{item}</p> <p className="text-sm font-semibold leading-6 text-stone-800 dark:text-stone-100">{item}</p>
@@ -190,21 +190,21 @@ export default function HomeContent() {
) : <div />} ) : <div />}
{hasSection('steps') ? ( {hasSection('steps') ? (
<div className="rounded-[2rem] border border-stone-200 bg-white p-8 shadow-sm dark:border-stone-800 dark:bg-stone-900"> <div className="rounded-[2rem] border border-stone-200 bg-white p-8 shadow-sm dark:border-blue-900 dark:bg-[#0d1b38]">
<div className="flex items-end justify-between gap-4"> <div className="flex items-end justify-between gap-4">
<div> <div>
<p className="text-xs font-bold uppercase tracking-[0.24em] text-amber-700 dark:text-amber-300">{dict.readyKicker}</p> <p className="text-xs font-bold uppercase tracking-[0.24em] text-orange-700 dark:text-orange-300">{dict.readyKicker}</p>
<h2 className="mt-4 text-3xl font-black tracking-[-0.03em] text-stone-950 dark:text-stone-50">{dict.stepsTitle}</h2> <h2 className="mt-4 text-3xl font-black tracking-[-0.03em] text-blue-950 dark:text-stone-50">{dict.stepsTitle}</h2>
</div> </div>
</div> </div>
<div className="mt-8 space-y-4"> <div className="mt-8 space-y-4">
{dict.steps.map(({ step, title, body }) => ( {dict.steps.map(({ step, title, body }) => (
<article key={step} className="rounded-[1.5rem] border border-stone-200 bg-stone-50 p-5 dark:border-stone-800 dark:bg-stone-950"> <article key={step} className="rounded-[1.5rem] border border-stone-200 bg-stone-50 p-5 dark:border-blue-900 dark:bg-[#07101e]">
<p className="text-xs font-bold uppercase tracking-[0.24em] text-stone-500 dark:text-stone-400"> <p className="text-xs font-bold uppercase tracking-[0.24em] text-stone-500 dark:text-stone-400">
{dict.stepLabel} {step} {dict.stepLabel} {step}
</p> </p>
<h3 className="mt-3 text-lg font-black text-stone-950 dark:text-stone-50">{title}</h3> <h3 className="mt-3 text-lg font-black text-blue-950 dark:text-stone-50">{title}</h3>
<p className="mt-3 text-sm leading-7 text-stone-600 dark:text-stone-300">{body}</p> <p className="mt-3 text-sm leading-7 text-stone-600 dark:text-stone-300">{body}</p>
</article> </article>
))} ))}
@@ -215,10 +215,10 @@ export default function HomeContent() {
</section> : null} </section> : null}
{hasSection('closing') ? <section className="shell pb-16 pt-6 sm:pb-20"> {hasSection('closing') ? <section className="shell pb-16 pt-6 sm:pb-20">
<div className="overflow-hidden rounded-[2rem] border border-stone-200 bg-stone-950 px-8 py-10 text-white dark:border-stone-700"> <div className="overflow-hidden rounded-[2rem] border border-blue-900/60 bg-[#06132e] px-8 py-10 text-white dark:border-blue-800">
<div className="grid gap-8 lg:grid-cols-[1fr_auto] lg:items-end"> <div className="grid gap-8 lg:grid-cols-[1fr_auto] lg:items-end">
<div> <div>
<p className="text-xs font-bold uppercase tracking-[0.28em] text-amber-300">{dict.readyKicker}</p> <p className="text-xs font-bold uppercase tracking-[0.28em] text-orange-300">{dict.readyKicker}</p>
<h2 className="mt-4 max-w-3xl text-4xl font-black leading-tight tracking-[-0.04em] sm:text-5xl">{dict.readyTitle}</h2> <h2 className="mt-4 max-w-3xl text-4xl font-black leading-tight tracking-[-0.04em] sm:text-5xl">{dict.readyTitle}</h2>
<p className="mt-5 max-w-2xl text-sm leading-8 text-stone-300 sm:text-base">{dict.readyBody}</p> <p className="mt-5 max-w-2xl text-sm leading-8 text-stone-300 sm:text-base">{dict.readyBody}</p>
</div> </div>
@@ -226,13 +226,13 @@ export default function HomeContent() {
<div className="flex flex-wrap gap-3 lg:justify-end"> <div className="flex flex-wrap gap-3 lg:justify-end">
<a <a
href="/pricing" href="/pricing"
className="rounded-full border border-white/20 px-6 py-3 text-sm font-semibold text-white transition hover:bg-white hover:text-stone-950" className="rounded-full border border-white/20 px-6 py-3 text-sm font-semibold text-white transition hover:bg-white hover:text-blue-900"
> >
{dict.viewPricing} {dict.viewPricing}
</a> </a>
<a <a
href={starterSignupHref} href={starterSignupHref}
className="rounded-full bg-amber-300 px-6 py-3 text-sm font-semibold text-stone-950 transition hover:bg-amber-200" className="rounded-full bg-orange-300 px-6 py-3 text-sm font-semibold text-blue-950 transition hover:bg-orange-200"
> >
{dict.createWorkspace} {dict.createWorkspace}
</a> </a>
@@ -23,8 +23,8 @@ function toUtcDateTime(date: string, time: string) {
return `${date}T${time || '10:00'}:00.000Z` return `${date}T${time || '10:00'}:00.000Z`
} }
const inputBase = 'w-full border-0 bg-white dark:bg-stone-800 px-4 py-4 text-sm text-stone-900 dark:text-stone-100 outline-none placeholder:text-stone-400 dark:placeholder:text-stone-500' const inputBase = 'w-full border-0 bg-white dark:bg-[#162038] px-4 py-4 text-sm text-stone-900 dark:text-stone-100 outline-none placeholder:text-stone-400 dark:placeholder:text-stone-500'
const selectBase = 'w-full border-0 bg-white dark:bg-stone-800 py-4 text-sm text-stone-900 dark:text-stone-100 outline-none' const selectBase = 'w-full border-0 bg-white dark:bg-[#162038] py-4 text-sm text-stone-900 dark:text-stone-100 outline-none'
export default function ExploreSearchForm({ export default function ExploreSearchForm({
pickupLocation, pickupLocation,
@@ -98,11 +98,11 @@ export default function ExploreSearchForm({
} }
return ( return (
<div className="mt-8 rounded-[1.75rem] bg-white dark:bg-stone-900 p-5 text-stone-900 dark:text-stone-100 shadow-[0_24px_80px_rgba(0,0,0,0.16)]"> <div className="mt-8 rounded-[1.75rem] bg-white dark:bg-[#0d1b38] p-5 text-stone-900 dark:text-stone-100 shadow-[0_24px_80px_rgba(0,0,0,0.16)]">
<h2 className="text-3xl font-black tracking-tight text-stone-900 dark:text-stone-100">{dict.searchTitle}</h2> <h2 className="text-3xl font-black tracking-tight text-stone-900 dark:text-stone-100">{dict.searchTitle}</h2>
<form onSubmit={handleSubmit} className="mt-5 space-y-4"> <form onSubmit={handleSubmit} className="mt-5 space-y-4">
<div className="grid gap-px overflow-hidden rounded-[1.35rem] border border-stone-200 dark:border-stone-700 bg-stone-200 dark:bg-stone-700 md:grid-cols-2"> <div className="grid gap-px overflow-hidden rounded-[1.35rem] border border-stone-200 dark:border-blue-800 bg-stone-200 dark:bg-stone-700 md:grid-cols-2">
<label className="flex items-center gap-3 bg-white dark:bg-stone-800 px-4"> <label className="flex items-center gap-3 bg-white dark:bg-[#162038] px-4">
<MapPin className="h-5 w-5 text-stone-300 dark:text-stone-500" /> <MapPin className="h-5 w-5 text-stone-300 dark:text-stone-500" />
<select <select
name="pickupLocation" name="pickupLocation"
@@ -116,7 +116,7 @@ export default function ExploreSearchForm({
))} ))}
</select> </select>
</label> </label>
<label className="flex items-center gap-3 bg-white dark:bg-stone-800 px-4"> <label className="flex items-center gap-3 bg-white dark:bg-[#162038] px-4">
<MapPin className="h-5 w-5 text-stone-300 dark:text-stone-500" /> <MapPin className="h-5 w-5 text-stone-300 dark:text-stone-500" />
<select <select
name="dropoffLocation" name="dropoffLocation"
@@ -132,8 +132,8 @@ export default function ExploreSearchForm({
</label> </label>
</div> </div>
<div className="grid gap-px overflow-hidden rounded-[1.35rem] border border-stone-200 dark:border-stone-700 bg-stone-200 dark:bg-stone-700 md:grid-cols-4"> <div className="grid gap-px overflow-hidden rounded-[1.35rem] border border-stone-200 dark:border-blue-800 bg-stone-200 dark:bg-stone-700 md:grid-cols-4">
<label className="flex items-center gap-3 bg-white dark:bg-stone-800 px-4"> <label className="flex items-center gap-3 bg-white dark:bg-[#162038] px-4">
<CalendarDays className="h-5 w-5 text-stone-500 dark:text-stone-400" /> <CalendarDays className="h-5 w-5 text-stone-500 dark:text-stone-400" />
<div className="flex w-full flex-col py-3"> <div className="flex w-full flex-col py-3">
<span className="text-xs font-semibold uppercase tracking-[0.14em] text-stone-400 dark:text-stone-500">{dict.pickupDate}</span> <span className="text-xs font-semibold uppercase tracking-[0.14em] text-stone-400 dark:text-stone-500">{dict.pickupDate}</span>
@@ -147,7 +147,7 @@ export default function ExploreSearchForm({
/> />
</div> </div>
</label> </label>
<label className="flex items-center gap-3 bg-white dark:bg-stone-800 px-4"> <label className="flex items-center gap-3 bg-white dark:bg-[#162038] px-4">
<Clock3 className="h-5 w-5 text-stone-500 dark:text-stone-400" /> <Clock3 className="h-5 w-5 text-stone-500 dark:text-stone-400" />
<div className="flex w-full flex-col py-3"> <div className="flex w-full flex-col py-3">
<span className="text-xs font-semibold uppercase tracking-[0.14em] text-stone-400 dark:text-stone-500">{dict.hour}</span> <span className="text-xs font-semibold uppercase tracking-[0.14em] text-stone-400 dark:text-stone-500">{dict.hour}</span>
@@ -160,7 +160,7 @@ export default function ExploreSearchForm({
/> />
</div> </div>
</label> </label>
<label className="flex items-center gap-3 bg-white dark:bg-stone-800 px-4"> <label className="flex items-center gap-3 bg-white dark:bg-[#162038] px-4">
<CalendarDays className="h-5 w-5 text-stone-500 dark:text-stone-400" /> <CalendarDays className="h-5 w-5 text-stone-500 dark:text-stone-400" />
<div className="flex w-full flex-col py-3"> <div className="flex w-full flex-col py-3">
<span className="text-xs font-semibold uppercase tracking-[0.14em] text-stone-400 dark:text-stone-500">{dict.returnDate}</span> <span className="text-xs font-semibold uppercase tracking-[0.14em] text-stone-400 dark:text-stone-500">{dict.returnDate}</span>
@@ -174,7 +174,7 @@ export default function ExploreSearchForm({
/> />
</div> </div>
</label> </label>
<label className="flex items-center gap-3 bg-white dark:bg-stone-800 px-4"> <label className="flex items-center gap-3 bg-white dark:bg-[#162038] px-4">
<Clock3 className="h-5 w-5 text-stone-500 dark:text-stone-400" /> <Clock3 className="h-5 w-5 text-stone-500 dark:text-stone-400" />
<div className="flex w-full flex-col py-3"> <div className="flex w-full flex-col py-3">
<span className="text-xs font-semibold uppercase tracking-[0.14em] text-stone-400 dark:text-stone-500">{dict.hour}</span> <span className="text-xs font-semibold uppercase tracking-[0.14em] text-stone-400 dark:text-stone-500">{dict.hour}</span>
@@ -189,8 +189,8 @@ export default function ExploreSearchForm({
</label> </label>
</div> </div>
<div className="relative z-10 grid gap-px overflow-visible rounded-[1.35rem] border border-stone-200 dark:border-stone-700 bg-stone-200 dark:bg-stone-700 lg:grid-cols-[1.1fr_1.1fr_1.35fr]"> <div className="relative z-10 grid gap-px overflow-visible rounded-[1.35rem] border border-stone-200 dark:border-blue-800 bg-stone-200 dark:bg-stone-700 lg:grid-cols-[1.1fr_1.1fr_1.35fr]">
<label className="flex items-center gap-3 rounded-t-[1.35rem] bg-white dark:bg-stone-800 px-4 lg:rounded-l-[1.35rem] lg:rounded-tr-none"> <label className="flex items-center gap-3 rounded-t-[1.35rem] bg-white dark:bg-[#162038] px-4 lg:rounded-l-[1.35rem] lg:rounded-tr-none">
<TicketPercent className="h-5 w-5 text-stone-300 dark:text-stone-500" /> <TicketPercent className="h-5 w-5 text-stone-300 dark:text-stone-500" />
<input <input
name="promoCode" name="promoCode"
@@ -200,7 +200,7 @@ export default function ExploreSearchForm({
className={`${inputBase} pl-2`} className={`${inputBase} pl-2`}
/> />
</label> </label>
<label className="flex items-center justify-between gap-3 bg-white dark:bg-stone-800 px-4 py-3"> <label className="flex items-center justify-between gap-3 bg-white dark:bg-[#162038] px-4 py-3">
<div className="flex min-w-0 items-center gap-3"> <div className="flex min-w-0 items-center gap-3">
<span className="text-sm font-semibold text-stone-600 dark:text-stone-300">{dict.myAge}</span> <span className="text-sm font-semibold text-stone-600 dark:text-stone-300">{dict.myAge}</span>
<select <select
@@ -228,16 +228,16 @@ export default function ExploreSearchForm({
<Info className="h-5 w-5" /> <Info className="h-5 w-5" />
</button> </button>
{ageHelpOpen ? ( {ageHelpOpen ? (
<div className="absolute bottom-[calc(100%+0.85rem)] right-0 z-30 w-72 rounded-2xl border border-amber-300 dark:border-amber-600 bg-white dark:bg-stone-900 px-4 py-3 text-left text-sm leading-6 text-stone-700 dark:text-stone-200 shadow-[0_16px_40px_rgba(0,0,0,0.14)]"> <div className="absolute bottom-[calc(100%+0.85rem)] right-0 z-30 w-72 rounded-2xl border border-orange-300 dark:border-orange-600 bg-white dark:bg-[#0d1b38] px-4 py-3 text-left text-sm leading-6 text-stone-700 dark:text-stone-200 shadow-[0_16px_40px_rgba(0,0,0,0.14)]">
{dict.ageDescription} {dict.ageDescription}
<span className="absolute right-6 top-full h-3 w-3 -translate-y-1/2 rotate-45 border-b border-r border-amber-300 dark:border-amber-600 bg-white dark:bg-stone-900" /> <span className="absolute right-6 top-full h-3 w-3 -translate-y-1/2 rotate-45 border-b border-r border-orange-300 dark:border-orange-600 bg-white dark:bg-[#0d1b38]" />
</div> </div>
) : null} ) : null}
</div> </div>
</label> </label>
<button <button
type="submit" type="submit"
className="min-h-[76px] rounded-b-[1.35rem] bg-stone-900 px-6 text-sm font-black uppercase tracking-[0.08em] text-white transition hover:bg-stone-700 dark:bg-amber-400 dark:text-stone-900 dark:hover:bg-amber-300 lg:rounded-b-none lg:rounded-r-[1.35rem]" className="min-h-[76px] rounded-b-[1.35rem] bg-stone-900 px-6 text-sm font-black uppercase tracking-[0.08em] text-white transition hover:bg-orange-700 dark:bg-orange-400 dark:text-stone-900 dark:hover:bg-orange-300 lg:rounded-b-none lg:rounded-r-[1.35rem]"
> >
{dict.search} {dict.search}
</button> </button>
@@ -65,7 +65,7 @@ export default function ExploreVehicleGrid({ vehicles, dict }: { vehicles: Vehic
<div className="mt-4 grid gap-5 md:grid-cols-2 xl:grid-cols-3"> <div className="mt-4 grid gap-5 md:grid-cols-2 xl:grid-cols-3">
{vehicles.map((vehicle) => ( {vehicles.map((vehicle) => (
<article key={vehicle.id} className="card overflow-hidden"> <article key={vehicle.id} className="card overflow-hidden">
<div className="aspect-[16/10] bg-stone-100 dark:bg-stone-800"> <div className="aspect-[16/10] bg-stone-100 dark:bg-[#162038]">
{vehicle.photos[0] ? ( {vehicle.photos[0] ? (
// eslint-disable-next-line @next/next/no-img-element // eslint-disable-next-line @next/next/no-img-element
<img src={vehicle.photos[0]} alt={`${vehicle.make} ${vehicle.model}`} className="h-full w-full object-cover" /> <img src={vehicle.photos[0]} alt={`${vehicle.make} ${vehicle.model}`} className="h-full w-full object-cover" />
@@ -94,7 +94,7 @@ export default function ExploreVehicleGrid({ vehicles, dict }: { vehicles: Vehic
</div> </div>
<Link <Link
href={`/explore/${vehicle.company.slug}/vehicles/${vehicle.id}`} href={`/explore/${vehicle.company.slug}/vehicles/${vehicle.id}`}
className="rounded-full bg-stone-900 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-stone-700 dark:bg-white dark:text-stone-900 dark:hover:bg-stone-100" className="rounded-full bg-stone-900 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-orange-700 dark:bg-white dark:text-stone-900 dark:hover:bg-stone-100"
> >
{dict.viewVehicle} {dict.viewVehicle}
</Link> </Link>
@@ -85,11 +85,11 @@ export default async function CompanyProfilePage({ params }: { params: { slug: s
<main className="site-page"> <main className="site-page">
<div className="site-section"> <div className="site-section">
<section className="card p-8"> <section className="card p-8">
<p className="text-sm uppercase tracking-[0.18em] text-amber-700 dark:text-amber-400">{dict.unavailable}</p> <p className="text-sm uppercase tracking-[0.18em] text-orange-700 dark:text-orange-400">{dict.unavailable}</p>
<h1 className="mt-3 text-3xl font-black text-stone-900 dark:text-stone-100">{dict.unavailableTitle}</h1> <h1 className="mt-3 text-3xl font-black text-stone-900 dark:text-stone-100">{dict.unavailableTitle}</h1>
<p className="mt-3 text-stone-600 dark:text-stone-400">{dict.unavailableBody}</p> <p className="mt-3 text-stone-600 dark:text-stone-400">{dict.unavailableBody}</p>
<div className="mt-6"> <div className="mt-6">
<Link href="/explore" className="rounded-full bg-stone-900 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-stone-700 dark:bg-white dark:text-stone-900 dark:hover:bg-stone-100">{dict.backToExplore}</Link> <Link href="/explore" className="rounded-full bg-stone-900 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-orange-700 dark:bg-white dark:text-stone-900 dark:hover:bg-stone-100">{dict.backToExplore}</Link>
</div> </div>
</section> </section>
</div> </div>
@@ -101,7 +101,7 @@ export default async function CompanyProfilePage({ params }: { params: { slug: s
<main className="site-page"> <main className="site-page">
<div className="site-section space-y-8"> <div className="site-section space-y-8">
<section className="card p-8"> <section className="card p-8">
<p className="text-sm uppercase tracking-[0.18em] text-amber-700 dark:text-amber-400">{company.brand?.publicCity ?? dict.partner}</p> <p className="text-sm uppercase tracking-[0.18em] text-orange-700 dark:text-orange-400">{company.brand?.publicCity ?? dict.partner}</p>
<h1 className="mt-3 text-4xl font-black text-stone-900 dark:text-stone-100">{company.brand?.displayName ?? company.name}</h1> <h1 className="mt-3 text-4xl font-black text-stone-900 dark:text-stone-100">{company.brand?.displayName ?? company.name}</h1>
<p className="mt-3 text-stone-600 dark:text-stone-400">{company.brand?.publicCountry ?? ''}</p> <p className="mt-3 text-stone-600 dark:text-stone-400">{company.brand?.publicCountry ?? ''}</p>
<div className="mt-6 flex flex-wrap gap-3 text-sm text-stone-500 dark:text-stone-400"> <div className="mt-6 flex flex-wrap gap-3 text-sm text-stone-500 dark:text-stone-400">
@@ -117,7 +117,7 @@ export default async function CompanyProfilePage({ params }: { params: { slug: s
{company.offers.map((offer) => ( {company.offers.map((offer) => (
<div key={offer.id} className="card p-5"> <div key={offer.id} className="card p-5">
<p className="text-sm font-semibold text-stone-900 dark:text-stone-100">{offer.title}</p> <p className="text-sm font-semibold text-stone-900 dark:text-stone-100">{offer.title}</p>
<p className="mt-2 text-3xl font-black text-amber-700 dark:text-amber-400">{offer.discountValue}%</p> <p className="mt-2 text-3xl font-black text-orange-700 dark:text-orange-400">{offer.discountValue}%</p>
<p className="mt-2 text-sm text-stone-500 dark:text-stone-400">{dict.validUntil} {new Date(offer.validUntil).toLocaleDateString()}</p> <p className="mt-2 text-sm text-stone-500 dark:text-stone-400">{dict.validUntil} {new Date(offer.validUntil).toLocaleDateString()}</p>
</div> </div>
))} ))}
@@ -130,7 +130,7 @@ export default async function CompanyProfilePage({ params }: { params: { slug: s
<div className="mt-4 grid gap-5 md:grid-cols-2 xl:grid-cols-3"> <div className="mt-4 grid gap-5 md:grid-cols-2 xl:grid-cols-3">
{company.vehicles.map((vehicle) => ( {company.vehicles.map((vehicle) => (
<article key={vehicle.id} className="card overflow-hidden"> <article key={vehicle.id} className="card overflow-hidden">
<div className="aspect-[16/10] bg-stone-100 dark:bg-stone-800"> <div className="aspect-[16/10] bg-stone-100 dark:bg-[#162038]">
{vehicle.photos[0] ? ( {vehicle.photos[0] ? (
// eslint-disable-next-line @next/next/no-img-element // eslint-disable-next-line @next/next/no-img-element
<img src={vehicle.photos[0]} alt={`${vehicle.make} ${vehicle.model}`} className="h-full w-full object-cover" /> <img src={vehicle.photos[0]} alt={`${vehicle.make} ${vehicle.model}`} className="h-full w-full object-cover" />
@@ -146,7 +146,7 @@ export default async function CompanyProfilePage({ params }: { params: { slug: s
)} )}
<div className="mt-4 flex items-end justify-between"> <div className="mt-4 flex items-end justify-between">
<p className="text-xl font-black text-stone-900 dark:text-stone-100">{formatCurrency(vehicle.dailyRate, 'MAD')}</p> <p className="text-xl font-black text-stone-900 dark:text-stone-100">{formatCurrency(vehicle.dailyRate, 'MAD')}</p>
<Link href={`/explore/${params.slug}/vehicles/${vehicle.id}`} className="rounded-full bg-stone-900 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-stone-700 dark:bg-white dark:text-stone-900 dark:hover:bg-stone-100">{dict.viewVehicle}</Link> <Link href={`/explore/${params.slug}/vehicles/${vehicle.id}`} className="rounded-full bg-stone-900 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-orange-700 dark:bg-white dark:text-stone-900 dark:hover:bg-stone-100">{dict.viewVehicle}</Link>
</div> </div>
</div> </div>
</article> </article>
@@ -110,12 +110,12 @@ export default async function VehicleDetailPage({ params }: { params: { slug: st
<main className="site-page"> <main className="site-page">
<div className="site-section"> <div className="site-section">
<section className="card p-8"> <section className="card p-8">
<p className="text-sm uppercase tracking-[0.18em] text-amber-700 dark:text-amber-400">{dict.unavailable}</p> <p className="text-sm uppercase tracking-[0.18em] text-orange-700 dark:text-orange-400">{dict.unavailable}</p>
<h1 className="mt-3 text-3xl font-black text-stone-900 dark:text-stone-100">{dict.unavailableTitle}</h1> <h1 className="mt-3 text-3xl font-black text-stone-900 dark:text-stone-100">{dict.unavailableTitle}</h1>
<p className="mt-3 text-stone-600 dark:text-stone-400">{dict.unavailableBody}</p> <p className="mt-3 text-stone-600 dark:text-stone-400">{dict.unavailableBody}</p>
<div className="mt-6 flex gap-3"> <div className="mt-6 flex gap-3">
<Link href={`/explore/${params.slug}`} className="rounded-full bg-stone-900 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-stone-700 dark:bg-white dark:text-stone-900 dark:hover:bg-stone-100">{dict.backToFleet}</Link> <Link href={`/explore/${params.slug}`} className="rounded-full bg-stone-900 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-orange-700 dark:bg-white dark:text-stone-900 dark:hover:bg-stone-100">{dict.backToFleet}</Link>
<Link href="/explore" className="rounded-full border border-stone-200 px-5 py-2.5 text-sm font-semibold text-stone-700 transition hover:border-stone-400 dark:border-stone-700 dark:text-stone-300 dark:hover:border-stone-500">{dict.backToExplore}</Link> <Link href="/explore" className="rounded-full border border-stone-200 px-5 py-2.5 text-sm font-semibold text-stone-700 transition hover:border-stone-400 dark:border-blue-800 dark:text-stone-300 dark:hover:border-stone-500">{dict.backToExplore}</Link>
</div> </div>
</section> </section>
</div> </div>
@@ -149,12 +149,12 @@ export default async function VehicleDetailPage({ params }: { params: { slug: st
{/* Hero photo */} {/* Hero photo */}
{heroPhoto ? ( {heroPhoto ? (
<div className="overflow-hidden rounded-3xl bg-stone-100 dark:bg-stone-800 aspect-[16/9]"> <div className="overflow-hidden rounded-3xl bg-stone-100 dark:bg-[#162038] aspect-[16/9]">
{/* eslint-disable-next-line @next/next/no-img-element */} {/* eslint-disable-next-line @next/next/no-img-element */}
<img src={heroPhoto} alt={`${vehicle.make} ${vehicle.model}`} className="h-full w-full object-cover" /> <img src={heroPhoto} alt={`${vehicle.make} ${vehicle.model}`} className="h-full w-full object-cover" />
</div> </div>
) : ( ) : (
<div className="overflow-hidden rounded-3xl bg-stone-100 dark:bg-stone-800 aspect-[16/9] flex items-center justify-center text-sm text-stone-400">{dict.noPhotos}</div> <div className="overflow-hidden rounded-3xl bg-stone-100 dark:bg-[#162038] aspect-[16/9] flex items-center justify-center text-sm text-stone-400">{dict.noPhotos}</div>
)} )}
{/* Gallery */} {/* Gallery */}
@@ -163,7 +163,7 @@ export default async function VehicleDetailPage({ params }: { params: { slug: st
<p className="mb-3 text-xs font-semibold uppercase tracking-[0.16em] text-stone-400 dark:text-stone-500">{dict.photos}</p> <p className="mb-3 text-xs font-semibold uppercase tracking-[0.16em] text-stone-400 dark:text-stone-500">{dict.photos}</p>
<div className="grid grid-cols-2 gap-3 sm:grid-cols-3"> <div className="grid grid-cols-2 gap-3 sm:grid-cols-3">
{galleryPhotos.map((photo, index) => ( {galleryPhotos.map((photo, index) => (
<div key={`${photo}-${index}`} className="overflow-hidden rounded-2xl bg-stone-100 dark:bg-stone-800 aspect-[4/3]"> <div key={`${photo}-${index}`} className="overflow-hidden rounded-2xl bg-stone-100 dark:bg-[#162038] aspect-[4/3]">
{/* eslint-disable-next-line @next/next/no-img-element */} {/* eslint-disable-next-line @next/next/no-img-element */}
<img src={photo} alt={`${vehicle.make} ${vehicle.model} ${index + 2}`} className="h-full w-full object-cover" /> <img src={photo} alt={`${vehicle.make} ${vehicle.model} ${index + 2}`} className="h-full w-full object-cover" />
</div> </div>
@@ -205,11 +205,11 @@ export default async function VehicleDetailPage({ params }: { params: { slug: st
</dl> </dl>
{vehicle.features.length > 0 && ( {vehicle.features.length > 0 && (
<div className="pt-2 border-t border-stone-100 dark:border-stone-800"> <div className="pt-2 border-t border-stone-100 dark:border-blue-900">
<p className="text-xs font-medium uppercase tracking-[0.14em] text-stone-400 dark:text-stone-500 mb-3">{dict.features}</p> <p className="text-xs font-medium uppercase tracking-[0.14em] text-stone-400 dark:text-stone-500 mb-3">{dict.features}</p>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
{vehicle.features.map((feature) => ( {vehicle.features.map((feature) => (
<span key={feature} className="rounded-full bg-stone-100 dark:bg-stone-800 px-3 py-1 text-xs font-medium text-stone-700 dark:text-stone-300">{feature}</span> <span key={feature} className="rounded-full bg-stone-100 dark:bg-[#162038] px-3 py-1 text-xs font-medium text-stone-700 dark:text-stone-300">{feature}</span>
))} ))}
</div> </div>
</div> </div>
@@ -223,7 +223,7 @@ export default async function VehicleDetailPage({ params }: { params: { slug: st
<p className="text-sm text-stone-500 dark:text-stone-400">{vehicle.company.brand?.displayName ?? dict.rentalCompany}</p> <p className="text-sm text-stone-500 dark:text-stone-400">{vehicle.company.brand?.displayName ?? dict.rentalCompany}</p>
<div className="flex flex-wrap gap-3"> <div className="flex flex-wrap gap-3">
{vehicle.company.brand?.publicPhone && ( {vehicle.company.brand?.publicPhone && (
<a href={`tel:${vehicle.company.brand.publicPhone}`} className="inline-flex items-center gap-2 rounded-full border border-stone-300 dark:border-stone-700 px-4 py-2 text-sm font-semibold text-stone-700 dark:text-stone-300 hover:bg-stone-100 dark:hover:bg-stone-800 transition"> <a href={`tel:${vehicle.company.brand.publicPhone}`} className="inline-flex items-center gap-2 rounded-full border border-stone-300 dark:border-blue-800 px-4 py-2 text-sm font-semibold text-stone-700 dark:text-stone-300 hover:bg-stone-100 dark:hover:bg-[#162038] transition">
{dict.phone}: {vehicle.company.brand.publicPhone} {dict.phone}: {vehicle.company.brand.publicPhone}
</a> </a>
)} )}
@@ -249,7 +249,7 @@ export default async function VehicleDetailPage({ params }: { params: { slug: st
</p> </p>
{!vehicle.availability && ( {!vehicle.availability && (
<div className="rounded-2xl border border-amber-200 bg-amber-50 dark:border-amber-800 dark:bg-amber-950/40 px-4 py-3 text-sm text-amber-800 dark:text-amber-300"> <div className="rounded-2xl border border-orange-200 bg-orange-50 dark:border-orange-800 dark:bg-orange-950/40 px-4 py-3 text-sm text-orange-800 dark:text-orange-300">
{availabilityDate ? `${dict.availableFrom} ${availabilityDate}` : dict.unavailableNoDate} {availabilityDate ? `${dict.availableFrom} ${availabilityDate}` : dict.unavailableNoDate}
</div> </div>
)} )}
@@ -264,7 +264,7 @@ export default async function VehicleDetailPage({ params }: { params: { slug: st
<Link <Link
href={`/explore/${params.slug}`} href={`/explore/${params.slug}`}
className="block rounded-full border border-stone-300 dark:border-stone-700 px-6 py-3 text-center text-sm font-semibold text-stone-700 dark:text-stone-300 hover:bg-stone-100 dark:hover:bg-stone-800 transition" className="block rounded-full border border-stone-300 dark:border-blue-800 px-6 py-3 text-center text-sm font-semibold text-stone-700 dark:text-stone-300 hover:bg-stone-100 dark:hover:bg-[#162038] transition"
> >
{dict.backToFleet} {dict.backToFleet}
</Link> </Link>
@@ -240,7 +240,7 @@ export default async function ExplorePage({ searchParams }: { searchParams?: Rec
<main className="site-page"> <main className="site-page">
<div className="site-section space-y-10"> <div className="site-section space-y-10">
<section className="site-panel-contrast bg-[linear-gradient(135deg,#1c1917,#57534e)] dark:bg-[linear-gradient(135deg,#0c0a09,#292524)] px-8 py-12"> <section className="site-panel-contrast bg-[linear-gradient(135deg,#1c1917,#57534e)] dark:bg-[linear-gradient(135deg,#0c0a09,#292524)] px-8 py-12">
<p className="site-kicker text-amber-300 dark:text-amber-300">{dict.kicker}</p> <p className="site-kicker text-orange-300 dark:text-orange-300">{dict.kicker}</p>
<h1 className="mt-4 text-4xl font-black tracking-tight">{dict.title}</h1> <h1 className="mt-4 text-4xl font-black tracking-tight">{dict.title}</h1>
<p className="mt-4 max-w-2xl text-stone-300">{dict.body}</p> <p className="mt-4 max-w-2xl text-stone-300">{dict.body}</p>
<ExploreSearchForm <ExploreSearchForm
@@ -264,8 +264,8 @@ export default async function ExplorePage({ searchParams }: { searchParams?: Rec
</div> </div>
<div className="mt-4 grid gap-4 md:grid-cols-2 xl:grid-cols-4"> <div className="mt-4 grid gap-4 md:grid-cols-2 xl:grid-cols-4">
{offers.map((offer) => ( {offers.map((offer) => (
<Link key={offer.id} href={`/explore/${offer.company.brand?.subdomain ?? ''}#offers`} className="card p-5 hover:border-amber-300 dark:hover:border-amber-500 transition-colors"> <Link key={offer.id} href={`/explore/${offer.company.brand?.subdomain ?? ''}#offers`} className="card p-5 hover:border-orange-300 dark:hover:border-orange-500 transition-colors">
<p className="text-xs uppercase tracking-[0.18em] text-amber-700 dark:text-amber-400">{offer.company.brand?.displayName ?? dict.company}</p> <p className="text-xs uppercase tracking-[0.18em] text-orange-700 dark:text-orange-400">{offer.company.brand?.displayName ?? dict.company}</p>
<h3 className="mt-3 text-lg font-semibold text-stone-900 dark:text-stone-100">{offer.title}</h3> <h3 className="mt-3 text-lg font-semibold text-stone-900 dark:text-stone-100">{offer.title}</h3>
<p className="mt-3 text-3xl font-black text-stone-900 dark:text-stone-100">{offer.discountValue}%</p> <p className="mt-3 text-3xl font-black text-stone-900 dark:text-stone-100">{offer.discountValue}%</p>
<p className="mt-2 text-sm text-stone-500 dark:text-stone-400">{dict.validUntil} {new Date(offer.validUntil).toLocaleDateString()}</p> <p className="mt-2 text-sm text-stone-500 dark:text-stone-400">{dict.validUntil} {new Date(offer.validUntil).toLocaleDateString()}</p>
@@ -281,7 +281,7 @@ export default async function ExplorePage({ searchParams }: { searchParams?: Rec
<h2 className="text-2xl font-bold text-stone-900 dark:text-stone-100">{dict.browseByCategory}</h2> <h2 className="text-2xl font-bold text-stone-900 dark:text-stone-100">{dict.browseByCategory}</h2>
<div className="mt-4 flex flex-wrap gap-3"> <div className="mt-4 flex flex-wrap gap-3">
{dict.categories.map((categoryName, index) => ( {dict.categories.map((categoryName, index) => (
<Link key={CATEGORY_VALUES[index] ?? categoryName} href={`/explore?category=${CATEGORY_VALUES[index]}`} className="rounded-full border border-stone-200 bg-white px-4 py-2 text-sm font-semibold text-stone-700 transition hover:border-stone-400 dark:border-stone-700 dark:bg-stone-900 dark:text-stone-300 dark:hover:border-stone-500"> <Link key={CATEGORY_VALUES[index] ?? categoryName} href={`/explore?category=${CATEGORY_VALUES[index]}`} className="rounded-full border border-stone-200 bg-white px-4 py-2 text-sm font-semibold text-stone-700 transition hover:border-stone-400 dark:border-blue-800 dark:bg-[#0d1b38] dark:text-stone-300 dark:hover:border-stone-500">
{categoryName} {categoryName}
</Link> </Link>
))} ))}
@@ -295,7 +295,7 @@ export default async function ExplorePage({ searchParams }: { searchParams?: Rec
</div> </div>
<div className="mt-4 grid gap-4 md:grid-cols-2 xl:grid-cols-4"> <div className="mt-4 grid gap-4 md:grid-cols-2 xl:grid-cols-4">
{companies.map((company) => ( {companies.map((company) => (
<Link key={company.id} href={`/explore/${company.brand?.subdomain ?? ''}`} className="card p-5 hover:border-amber-300 dark:hover:border-amber-500 transition-colors"> <Link key={company.id} href={`/explore/${company.brand?.subdomain ?? ''}`} className="card p-5 hover:border-orange-300 dark:hover:border-orange-500 transition-colors">
<p className="text-xs uppercase tracking-[0.18em] text-stone-500 dark:text-stone-400">{company.brand?.publicCity ?? dict.marketplacePartner}</p> <p className="text-xs uppercase tracking-[0.18em] text-stone-500 dark:text-stone-400">{company.brand?.publicCity ?? dict.marketplacePartner}</p>
<h3 className="mt-3 text-lg font-semibold text-stone-900 dark:text-stone-100">{company.brand?.displayName ?? dict.rentalCompany}</h3> <h3 className="mt-3 text-lg font-semibold text-stone-900 dark:text-stone-100">{company.brand?.displayName ?? dict.rentalCompany}</h3>
<p className="mt-2 text-sm text-stone-500 dark:text-stone-400">{dict.rating} {company.brand?.marketplaceRating?.toFixed(1) ?? dict.new}</p> <p className="mt-2 text-sm text-stone-500 dark:text-stone-400">{dict.rating} {company.brand?.marketplaceRating?.toFixed(1) ?? dict.new}</p>
@@ -140,7 +140,7 @@ export default function PricingClient() {
{/* Toggles */} {/* Toggles */}
<div className="flex flex-col items-center gap-6 sm:flex-row sm:justify-center"> <div className="flex flex-col items-center gap-6 sm:flex-row sm:justify-center">
{/* Billing toggle */} {/* Billing toggle */}
<div className="flex items-center gap-1 rounded-full border border-stone-200 bg-white p-1 shadow-sm dark:border-stone-700 dark:bg-stone-900"> <div className="flex items-center gap-1 rounded-full border border-stone-200 bg-white p-1 shadow-sm dark:border-blue-800 dark:bg-[#0d1b38]">
{(['monthly', 'annual'] as Billing[]).map((b) => ( {(['monthly', 'annual'] as Billing[]).map((b) => (
<button <button
key={b} key={b}
@@ -153,7 +153,7 @@ export default function PricingClient() {
> >
{b === 'monthly' ? dict.monthly : dict.annual} {b === 'monthly' ? dict.monthly : dict.annual}
{b === 'annual' && billing !== 'annual' && ( {b === 'annual' && billing !== 'annual' && (
<span className="ml-2 rounded-full bg-amber-100 px-2 py-0.5 text-[10px] font-bold text-amber-700 dark:bg-amber-950/50 dark:text-amber-400"> <span className="ml-2 rounded-full bg-orange-100 px-2 py-0.5 text-[10px] font-bold text-orange-700 dark:bg-orange-950/50 dark:text-orange-400">
-{savings}% -{savings}%
</span> </span>
)} )}
@@ -162,14 +162,14 @@ export default function PricingClient() {
</div> </div>
{/* Currency toggle */} {/* Currency toggle */}
<div className="flex items-center gap-1 rounded-full border border-stone-200 bg-white p-1 shadow-sm dark:border-stone-700 dark:bg-stone-900"> <div className="flex items-center gap-1 rounded-full border border-stone-200 bg-white p-1 shadow-sm dark:border-blue-800 dark:bg-[#0d1b38]">
{(['MAD', 'USD', 'EUR'] as Currency[]).map((c) => ( {(['MAD', 'USD', 'EUR'] as Currency[]).map((c) => (
<button <button
key={c} key={c}
onClick={() => setCurrency(c)} onClick={() => setCurrency(c)}
className={`rounded-full px-4 py-2 text-sm font-semibold transition-colors ${ className={`rounded-full px-4 py-2 text-sm font-semibold transition-colors ${
currency === c currency === c
? 'bg-amber-500 text-white dark:bg-amber-400 dark:text-stone-900' ? 'bg-orange-500 text-white dark:bg-orange-400 dark:text-stone-900'
: 'text-stone-600 hover:text-stone-900 dark:text-stone-400 dark:hover:text-stone-100' : 'text-stone-600 hover:text-stone-900 dark:text-stone-400 dark:hover:text-stone-100'
}`} }`}
> >
@@ -180,7 +180,7 @@ export default function PricingClient() {
</div> </div>
{billing === 'annual' && ( {billing === 'annual' && (
<p className="text-center text-sm font-medium text-amber-700 dark:text-amber-400"> <p className="text-center text-sm font-medium text-orange-700 dark:text-orange-400">
{dict.youSave} {savings}% {dict.withAnnual} {dict.youSave} {savings}% {dict.withAnnual}
</p> </p>
)} )}
@@ -199,18 +199,18 @@ export default function PricingClient() {
key={plan.key} key={plan.key}
className={`card relative flex flex-col overflow-hidden ${ className={`card relative flex flex-col overflow-hidden ${
plan.highlight plan.highlight
? 'border-amber-400 ring-2 ring-amber-400 ring-offset-2 dark:ring-offset-stone-950' ? 'border-orange-400 ring-2 ring-orange-400 ring-offset-2 dark:ring-offset-[#07101e]'
: '' : ''
}`} }`}
> >
{plan.highlight && ( {plan.highlight && (
<div className="bg-amber-500 dark:bg-amber-400 py-1.5 text-center text-xs font-bold uppercase tracking-widest text-white dark:text-stone-900"> <div className="bg-orange-500 dark:bg-orange-400 py-1.5 text-center text-xs font-bold uppercase tracking-widest text-white dark:text-stone-900">
{dict.mostPopular} {dict.mostPopular}
</div> </div>
)} )}
<div className="flex flex-1 flex-col p-8"> <div className="flex flex-1 flex-col p-8">
<p className="text-xs font-bold uppercase tracking-[0.2em] text-amber-700 dark:text-amber-400"> <p className="text-xs font-bold uppercase tracking-[0.2em] text-orange-700 dark:text-orange-400">
{plan.name} {plan.name}
</p> </p>
<p className="mt-1 text-sm text-stone-500 dark:text-stone-400">{plan.tagline}</p> <p className="mt-1 text-sm text-stone-500 dark:text-stone-400">{plan.tagline}</p>
@@ -240,7 +240,7 @@ export default function PricingClient() {
{plan.features.map((f) => ( {plan.features.map((f) => (
<li key={f} className="flex items-start gap-2.5 text-sm text-stone-700 dark:text-stone-300"> <li key={f} className="flex items-start gap-2.5 text-sm text-stone-700 dark:text-stone-300">
<svg <svg
className="mt-0.5 h-4 w-4 shrink-0 text-amber-500 dark:text-amber-400" className="mt-0.5 h-4 w-4 shrink-0 text-orange-500 dark:text-orange-400"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
strokeWidth={2.5} strokeWidth={2.5}
@@ -257,8 +257,8 @@ export default function PricingClient() {
href={`${dashboardUrl}/sign-up?plan=${plan.key}&billing=${billing.toUpperCase()}&currency=${currency}`} href={`${dashboardUrl}/sign-up?plan=${plan.key}&billing=${billing.toUpperCase()}&currency=${currency}`}
className={`mt-10 block rounded-full px-6 py-3 text-center text-sm font-semibold transition-colors ${ className={`mt-10 block rounded-full px-6 py-3 text-center text-sm font-semibold transition-colors ${
plan.highlight plan.highlight
? 'bg-amber-500 text-white hover:bg-amber-600 dark:bg-amber-400 dark:text-stone-900 dark:hover:bg-amber-300' ? 'bg-orange-500 text-white hover:bg-orange-600 dark:bg-orange-400 dark:text-stone-900 dark:hover:bg-orange-300'
: 'bg-stone-900 text-white hover:bg-stone-700 dark:bg-white dark:text-stone-900 dark:hover:bg-stone-100' : 'bg-stone-900 text-white hover:bg-orange-700 dark:bg-white dark:text-stone-900 dark:hover:bg-stone-100'
}`} }`}
> >
{dict.getStarted} {dict.getStarted}
@@ -33,7 +33,7 @@ function StarRating({ value, onChange, label }: { value: number; onChange: (v: n
<Star <Star
className={`h-8 w-8 transition-colors ${ className={`h-8 w-8 transition-colors ${
n <= (hovered || value) n <= (hovered || value)
? 'fill-amber-400 text-amber-400' ? 'fill-orange-400 text-orange-400'
: 'fill-stone-200 text-stone-200 dark:fill-stone-700 dark:text-stone-700' : 'fill-stone-200 text-stone-200 dark:fill-stone-700 dark:text-stone-700'
}`} }`}
/> />
@@ -150,12 +150,12 @@ function ReviewPageContent() {
<main className="site-page flex min-h-screen items-center justify-center p-6"> <main className="site-page flex min-h-screen items-center justify-center p-6">
<div className="card w-full max-w-lg overflow-hidden"> <div className="card w-full max-w-lg overflow-hidden">
{/* Header */} {/* Header */}
<div className="flex items-center gap-4 border-b border-stone-200 dark:border-stone-800 p-6"> <div className="flex items-center gap-4 border-b border-stone-200 dark:border-blue-900 p-6">
{info?.vehiclePhoto ? ( {info?.vehiclePhoto ? (
// eslint-disable-next-line @next/next/no-img-element // eslint-disable-next-line @next/next/no-img-element
<img src={info.vehiclePhoto} alt={info.vehicle} className="h-16 w-24 flex-shrink-0 rounded-xl object-cover" /> <img src={info.vehiclePhoto} alt={info.vehicle} className="h-16 w-24 flex-shrink-0 rounded-xl object-cover" />
) : ( ) : (
<div className="h-16 w-24 flex-shrink-0 rounded-xl bg-stone-100 dark:bg-stone-800" /> <div className="h-16 w-24 flex-shrink-0 rounded-xl bg-stone-100 dark:bg-[#162038]" />
)} )}
<div className="min-w-0"> <div className="min-w-0">
<p className="truncate text-xs uppercase tracking-widest text-stone-400 dark:text-stone-500">{info?.companyName}</p> <p className="truncate text-xs uppercase tracking-widest text-stone-400 dark:text-stone-500">{info?.companyName}</p>
@@ -176,7 +176,7 @@ function ReviewPageContent() {
value={comment} value={comment}
onChange={(e) => setComment(e.target.value)} onChange={(e) => setComment(e.target.value)}
placeholder="Tell us about your rental experience…" placeholder="Tell us about your rental experience…"
className="w-full resize-none rounded-xl border border-stone-200 dark:border-stone-700 bg-white dark:bg-stone-900 px-4 py-3 text-sm text-stone-900 dark:text-stone-100 placeholder:text-stone-400 dark:placeholder:text-stone-500 focus:outline-none focus:ring-2 focus:ring-stone-900 dark:focus:ring-stone-400" className="w-full resize-none rounded-xl border border-stone-200 dark:border-blue-800 bg-white dark:bg-[#0d1b38] px-4 py-3 text-sm text-stone-900 dark:text-stone-100 placeholder:text-stone-400 dark:placeholder:text-stone-500 focus:outline-none focus:ring-2 focus:ring-stone-900 dark:focus:ring-stone-400"
/> />
</div> </div>
@@ -187,7 +187,7 @@ function ReviewPageContent() {
<button <button
type="submit" type="submit"
disabled={submitState === 'submitting'} disabled={submitState === 'submitting'}
className="w-full rounded-full bg-stone-900 py-3 text-sm font-semibold text-white transition-colors hover:bg-stone-700 disabled:opacity-60 dark:bg-white dark:text-stone-900 dark:hover:bg-stone-100" className="w-full rounded-full bg-stone-900 py-3 text-sm font-semibold text-white transition-colors hover:bg-orange-700 disabled:opacity-60 dark:bg-white dark:text-stone-900 dark:hover:bg-stone-100"
> >
{submitState === 'submitting' ? 'Submitting' : 'Submit review'} {submitState === 'submitting' ? 'Submitting' : 'Submit review'}
</button> </button>
+31 -26
View File
@@ -3,7 +3,12 @@
@tailwind utilities; @tailwind utilities;
body { body {
@apply bg-stone-50 text-stone-900 antialiased transition-colors dark:bg-stone-950 dark:text-stone-100; @apply bg-white text-blue-950 antialiased transition-colors dark:text-slate-100;
}
html.dark body {
background-image:
linear-gradient(180deg, #0a1128 0%, #0d1b38 35%, #07101e 100%);
} }
.shell { .shell {
@@ -11,38 +16,38 @@ body {
} }
.card { .card {
@apply rounded-[2rem] border p-0 shadow-[0_30px_80px_rgba(28,25,23,0.08)] backdrop-blur transition-colors dark:shadow-[0_30px_80px_rgba(0,0,0,0.26)]; @apply rounded-[2rem] border p-0 shadow-[0_30px_80px_rgba(28,25,23,0.08)] backdrop-blur transition-colors dark:shadow-[0_30px_80px_rgba(0,0,0,0.36)];
border-color: rgb(231 229 228 / 0.8); border-color: rgb(231 229 228 / 0.8);
background-color: rgb(255 255 255 / 0.82); background-color: rgb(255 255 255 / 0.82);
} }
html.dark .card { html.dark .card {
border-color: rgb(41 37 36 / 0.96); border-color: rgb(30 60 140 / 0.40);
background-color: rgb(28 25 23 / 0.72); background-color: rgb(11 25 55 / 0.72);
} }
.site-page { .site-page {
@apply min-h-screen overflow-hidden text-stone-900; @apply min-h-screen overflow-hidden text-blue-950;
background-image: background-image:
linear-gradient(180deg, #f8f5ef 0%, #f4efe6 28%, #fffdf8 58%, #ffffff 100%); linear-gradient(180deg, #ffffff 0%, #f5f8ff 28%, #eef4ff 58%, #ffffff 100%);
} }
html.dark .site-page { html.dark .site-page {
@apply text-stone-100; @apply text-slate-100;
background-image: background-image:
linear-gradient(180deg, #14110f 0%, #17120d 35%, #0c0a09 100%); linear-gradient(180deg, #0a1128 0%, #0d1b38 35%, #07101e 100%);
} }
.site-glow { .site-glow {
background-image: background-image:
radial-gradient(circle at top left, rgba(217, 119, 6, 0.24), transparent 34%), radial-gradient(circle at top left, rgba(234, 88, 12, 0.24), transparent 34%),
radial-gradient(circle at top right, rgba(15, 118, 110, 0.18), transparent 26%); radial-gradient(circle at top right, rgba(59, 130, 246, 0.18), transparent 26%);
} }
html.dark .site-glow { html.dark .site-glow {
background-image: background-image:
radial-gradient(circle at top left, rgba(251, 191, 36, 0.16), transparent 34%), radial-gradient(circle at top left, rgba(251, 146, 60, 0.22), transparent 34%),
radial-gradient(circle at top right, rgba(45, 212, 191, 0.14), transparent 26%); radial-gradient(circle at top right, rgba(96, 165, 250, 0.18), transparent 26%);
} }
.site-section { .site-section {
@@ -56,48 +61,48 @@ html.dark .site-glow {
} }
html.dark .site-panel { html.dark .site-panel {
border-color: rgb(41 37 36 / 0.96); border-color: rgb(30 60 140 / 0.40);
background-color: rgb(28 25 23 / 0.72); background-color: rgb(11 25 55 / 0.72);
box-shadow: 0 30px 80px rgba(0, 0, 0, 0.26); box-shadow: 0 30px 80px rgba(0, 0, 0, 0.36);
} }
.site-panel-muted { .site-panel-muted {
@apply rounded-[2rem] border p-7 transition-colors sm:p-8; @apply rounded-[2rem] border p-7 transition-colors sm:p-8;
border-color: rgb(231 229 228 / 0.8); border-color: rgb(231 229 228 / 0.8);
background-image: linear-gradient(160deg, #fffdf8 0%, #f1ebe1 100%); background-image: linear-gradient(160deg, #f5f8ff 0%, #edf2ff 100%);
} }
html.dark .site-panel-muted { html.dark .site-panel-muted {
border-color: rgb(41 37 36 / 0.96); border-color: rgb(30 60 140 / 0.40);
background-image: linear-gradient(160deg, #17120d 0%, #221a14 100%); background-image: linear-gradient(160deg, #0c1830 0%, #10203e 100%);
} }
.site-panel-contrast { .site-panel-contrast {
@apply rounded-[2rem] border p-7 text-white shadow-[0_30px_80px_rgba(28,25,23,0.18)] transition-colors sm:p-8; @apply rounded-[2rem] border p-7 text-white shadow-[0_30px_80px_rgba(28,25,23,0.18)] transition-colors sm:p-8;
border-color: rgb(231 229 228 / 0.8); border-color: rgb(14 40 90 / 0.8);
background-color: rgb(12 10 9); background-color: rgb(6 13 30);
} }
html.dark .site-panel-contrast { html.dark .site-panel-contrast {
border-color: rgb(68 64 60); border-color: rgb(30 64 175);
} }
.site-kicker { .site-kicker {
@apply text-xs font-bold uppercase tracking-[0.28em] text-amber-700 dark:text-amber-300; @apply text-xs font-bold uppercase tracking-[0.28em] text-orange-600 dark:text-orange-400;
} }
.site-title { .site-title {
@apply mt-4 text-4xl font-black tracking-[-0.04em] text-stone-950 dark:text-stone-50 sm:text-5xl; @apply mt-4 text-4xl font-black tracking-[-0.04em] text-blue-950 dark:text-white sm:text-5xl;
} }
.site-lead { .site-lead {
@apply mt-5 text-base leading-8 text-stone-600 dark:text-stone-300 sm:text-lg; @apply mt-5 text-base leading-8 text-stone-600 dark:text-slate-300 sm:text-lg;
} }
.site-link-primary { .site-link-primary {
@apply rounded-full bg-stone-950 px-6 py-3 text-sm font-semibold text-white transition hover:bg-stone-800 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300; @apply rounded-full bg-orange-600 px-6 py-3 text-sm font-semibold text-white transition hover:bg-orange-700 dark:bg-orange-500 dark:hover:bg-orange-400;
} }
.site-link-secondary { .site-link-secondary {
@apply rounded-full border border-stone-300 bg-white/85 px-6 py-3 text-sm font-semibold text-stone-700 transition hover:border-stone-950 hover:text-stone-950 dark:border-stone-700 dark:bg-stone-950/30 dark:text-stone-200 dark:hover:border-stone-200 dark:hover:text-white; @apply rounded-full border border-stone-300 bg-white/85 px-6 py-3 text-sm font-semibold text-stone-700 transition hover:border-blue-900 hover:text-blue-900 dark:border-blue-800 dark:bg-blue-950/30 dark:text-blue-100 dark:hover:border-blue-400 dark:hover:text-white;
} }
@@ -162,7 +162,7 @@ export default function RenterDashboardPage() {
<p className="text-sm text-rose-600">{errorMsg}</p> <p className="text-sm text-rose-600">{errorMsg}</p>
<Link <Link
href="/explore" href="/explore"
className="mt-4 inline-flex rounded-full bg-stone-900 px-6 py-2.5 text-sm font-semibold text-white" className="mt-4 inline-flex rounded-full bg-orange-600 px-6 py-2.5 text-sm font-semibold text-white"
> >
{dict.backToExplore} {dict.backToExplore}
</Link> </Link>
@@ -177,10 +177,10 @@ export default function RenterDashboardPage() {
<div className="shell space-y-8"> <div className="shell space-y-8">
<div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between"> <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<div> <div>
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-amber-700"> <p className="text-xs font-semibold uppercase tracking-[0.2em] text-orange-700">
{dict.renterDashboard} {dict.renterDashboard}
</p> </p>
<h1 className="mt-1 text-3xl font-black tracking-tight text-stone-900"> <h1 className="mt-1 text-3xl font-black tracking-tight text-blue-900">
{dict.welcome} {profile?.firstName} {dict.welcome} {profile?.firstName}
</h1> </h1>
</div> </div>
@@ -198,8 +198,8 @@ export default function RenterDashboardPage() {
{ href: '/renter/saved-companies', label: dict.cards[1][0], copy: dict.cards[1][1] }, { href: '/renter/saved-companies', label: dict.cards[1][0], copy: dict.cards[1][1] },
{ href: '/renter/notifications', label: dict.cards[2][0], copy: dict.cards[2][1] }, { href: '/renter/notifications', label: dict.cards[2][0], copy: dict.cards[2][1] },
].map((item) => ( ].map((item) => (
<Link key={item.href} href={item.href} className="card p-5 hover:border-amber-300 transition-colors"> <Link key={item.href} href={item.href} className="card p-5 hover:border-orange-300 transition-colors">
<p className="text-sm font-semibold text-stone-900">{item.label}</p> <p className="text-sm font-semibold text-blue-900">{item.label}</p>
<p className="mt-2 text-sm leading-6 text-stone-500">{item.copy}</p> <p className="mt-2 text-sm leading-6 text-stone-500">{item.copy}</p>
</Link> </Link>
))} ))}
@@ -207,7 +207,7 @@ export default function RenterDashboardPage() {
{/* Profile card */} {/* Profile card */}
<section className="card p-8"> <section className="card p-8">
<h2 className="text-lg font-bold text-stone-900">{dict.yourProfile}</h2> <h2 className="text-lg font-bold text-blue-900">{dict.yourProfile}</h2>
<div className="mt-6 grid gap-6 sm:grid-cols-2 lg:grid-cols-4"> <div className="mt-6 grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
{[ {[
{ label: dict.firstName, value: profile?.firstName }, { label: dict.firstName, value: profile?.firstName },
@@ -219,7 +219,7 @@ export default function RenterDashboardPage() {
<p className="text-xs font-semibold uppercase tracking-[0.16em] text-stone-400"> <p className="text-xs font-semibold uppercase tracking-[0.16em] text-stone-400">
{label} {label}
</p> </p>
<p className="mt-1.5 text-sm font-medium text-stone-900 break-all"> <p className="mt-1.5 text-sm font-medium text-blue-900 break-all">
{value} {value}
</p> </p>
</div> </div>
@@ -230,7 +230,7 @@ export default function RenterDashboardPage() {
{/* Saved companies */} {/* Saved companies */}
<section> <section>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h2 className="text-2xl font-bold text-stone-900">{dict.savedCompanies}</h2> <h2 className="text-2xl font-bold text-blue-900">{dict.savedCompanies}</h2>
<p className="text-sm text-stone-500"> <p className="text-sm text-stone-500">
{savedCompanies.length === 0 {savedCompanies.length === 0
? dict.noneSaved ? dict.noneSaved
@@ -258,7 +258,7 @@ export default function RenterDashboardPage() {
</p> </p>
<Link <Link
href="/explore" href="/explore"
className="rounded-full bg-stone-900 px-6 py-2.5 text-sm font-semibold text-white hover:bg-stone-700" className="rounded-full bg-orange-600 px-6 py-2.5 text-sm font-semibold text-white hover:bg-orange-700"
> >
{dict.startExploring} {dict.startExploring}
</Link> </Link>
@@ -269,7 +269,7 @@ export default function RenterDashboardPage() {
<Link <Link
key={company.id} key={company.id}
href={`/explore/${company.brand?.subdomain ?? company.id}`} href={`/explore/${company.brand?.subdomain ?? company.id}`}
className="card flex items-center gap-4 p-5 hover:border-amber-300 transition-colors" className="card flex items-center gap-4 p-5 hover:border-orange-300 transition-colors"
> >
{company.brand?.logoUrl ? ( {company.brand?.logoUrl ? (
// eslint-disable-next-line @next/next/no-img-element // eslint-disable-next-line @next/next/no-img-element
@@ -279,12 +279,12 @@ export default function RenterDashboardPage() {
className="h-10 w-10 rounded-lg object-contain" className="h-10 w-10 rounded-lg object-contain"
/> />
) : ( ) : (
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-amber-100 text-amber-700 font-bold text-sm"> <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-orange-100 text-orange-700 font-bold text-sm">
{company.brand?.displayName?.charAt(0) ?? '?'} {company.brand?.displayName?.charAt(0) ?? '?'}
</div> </div>
)} )}
<div className="min-w-0"> <div className="min-w-0">
<p className="truncate font-semibold text-stone-900"> <p className="truncate font-semibold text-blue-900">
{company.brand?.displayName ?? dict.rentalCompany} {company.brand?.displayName ?? dict.rentalCompany}
</p> </p>
<p className="mt-0.5 text-xs text-stone-400"> <p className="mt-0.5 text-xs text-stone-400">
@@ -102,7 +102,7 @@ export default function RenterNotificationsPage() {
return ( return (
<div className="shell space-y-6"> <div className="shell space-y-6">
<div className="flex flex-wrap items-center justify-between gap-4"> <div className="flex flex-wrap items-center justify-between gap-4">
<h1 className="text-3xl font-black tracking-tight text-stone-900">{dict.title}</h1> <h1 className="text-3xl font-black tracking-tight text-blue-900">{dict.title}</h1>
<button <button
type="button" type="button"
onClick={markAllRead} onClick={markAllRead}
@@ -126,8 +126,8 @@ export default function RenterNotificationsPage() {
<article key={notification.id} className="card p-6"> <article key={notification.id} className="card p-6">
<div className="flex flex-wrap items-center justify-between gap-3"> <div className="flex flex-wrap items-center justify-between gap-3">
<div> <div>
<p className="text-xs font-semibold uppercase tracking-[0.16em] text-amber-700">{notification.type.replaceAll('_', ' ')}</p> <p className="text-xs font-semibold uppercase tracking-[0.16em] text-orange-700">{notification.type.replaceAll('_', ' ')}</p>
<h2 className="mt-2 text-lg font-bold text-stone-900">{notification.title}</h2> <h2 className="mt-2 text-lg font-bold text-blue-900">{notification.title}</h2>
</div> </div>
{notification.readAt ? ( {notification.readAt ? (
<span className="rounded-full bg-stone-100 px-3 py-1 text-xs font-semibold text-stone-600">{dict.read}</span> <span className="rounded-full bg-stone-100 px-3 py-1 text-xs font-semibold text-stone-600">{dict.read}</span>
@@ -136,7 +136,7 @@ export default function RenterNotificationsPage() {
type="button" type="button"
onClick={() => markRead(notification.id)} onClick={() => markRead(notification.id)}
disabled={updating} disabled={updating}
className="rounded-full bg-amber-100 px-3 py-1 text-xs font-semibold text-amber-800" className="rounded-full bg-orange-100 px-3 py-1 text-xs font-semibold text-orange-800"
> >
{dict.markRead} {dict.markRead}
</button> </button>
@@ -145,7 +145,7 @@ export default function RenterProfilePage() {
return ( return (
<div className="shell space-y-6"> <div className="shell space-y-6">
<div className="card p-8"> <div className="card p-8">
<h1 className="text-3xl font-black tracking-tight text-stone-900">{dict.yourProfile}</h1> <h1 className="text-3xl font-black tracking-tight text-blue-900">{dict.yourProfile}</h1>
<div className="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-3"> <div className="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
<EditableField label={dict.firstName} value={profile?.firstName ?? ''} onChange={(value) => setProfile((current) => current ? { ...current, firstName: value } : current)} /> <EditableField label={dict.firstName} value={profile?.firstName ?? ''} onChange={(value) => setProfile((current) => current ? { ...current, firstName: value } : current)} />
<EditableField label={dict.lastName} value={profile?.lastName ?? ''} onChange={(value) => setProfile((current) => current ? { ...current, lastName: value } : current)} /> <EditableField label={dict.lastName} value={profile?.lastName ?? ''} onChange={(value) => setProfile((current) => current ? { ...current, lastName: value } : current)} />
@@ -186,7 +186,7 @@ export default function RenterProfilePage() {
setSaving(false) setSaving(false)
} }
}} }}
className="rounded-full bg-stone-900 px-5 py-2 text-sm font-semibold text-white" className="rounded-full bg-orange-600 px-5 py-2 text-sm font-semibold text-white"
> >
{saving ? dict.saving : dict.saveProfile} {saving ? dict.saving : dict.saveProfile}
</button> </button>
@@ -202,7 +202,7 @@ export default function RenterProfilePage() {
<div className="card p-8"> <div className="card p-8">
<div className="flex flex-wrap items-center justify-between gap-4"> <div className="flex flex-wrap items-center justify-between gap-4">
<div> <div>
<h2 className="text-2xl font-bold text-stone-900">{dict.notificationPrefs}</h2> <h2 className="text-2xl font-bold text-blue-900">{dict.notificationPrefs}</h2>
<p className="mt-2 text-sm text-stone-600">{dict.notificationBody}</p> <p className="mt-2 text-sm text-stone-600">{dict.notificationBody}</p>
</div> </div>
<button <button
@@ -222,7 +222,7 @@ export default function RenterProfilePage() {
setSaving(false) setSaving(false)
} }
}} }}
className="rounded-full bg-stone-900 px-5 py-2 text-sm font-semibold text-white" className="rounded-full bg-orange-600 px-5 py-2 text-sm font-semibold text-white"
> >
{saving ? dict.saving : dict.savePreferences} {saving ? dict.saving : dict.savePreferences}
</button> </button>
@@ -242,7 +242,7 @@ export default function RenterProfilePage() {
<tbody> <tbody>
{RENTER_EVENTS.map((eventName) => ( {RENTER_EVENTS.map((eventName) => (
<tr key={eventName} className="border-t border-stone-100"> <tr key={eventName} className="border-t border-stone-100">
<td className="px-4 py-3 font-medium text-stone-900">{eventName.replaceAll('_', ' ')}</td> <td className="px-4 py-3 font-medium text-blue-900">{eventName.replaceAll('_', ' ')}</td>
{RENTER_CHANNELS.map((channel) => ( {RENTER_CHANNELS.map((channel) => (
<td key={`${eventName}-${channel}`} className="px-4 py-3 text-center"> <td key={`${eventName}-${channel}`} className="px-4 py-3 text-center">
<input <input
@@ -254,7 +254,7 @@ export default function RenterProfilePage() {
[`${eventName}:${channel}`]: event.target.checked, [`${eventName}:${channel}`]: event.target.checked,
})) }))
} }
className="h-4 w-4 rounded border-stone-300 text-amber-600" className="h-4 w-4 rounded border-stone-300 text-orange-600"
/> />
</td> </td>
))} ))}
@@ -272,7 +272,7 @@ function Field({ label, value }: { label: string; value?: string | null }) {
return ( return (
<div> <div>
<p className="text-xs font-semibold uppercase tracking-[0.16em] text-stone-400">{label}</p> <p className="text-xs font-semibold uppercase tracking-[0.16em] text-stone-400">{label}</p>
<p className="mt-2 text-sm font-medium text-stone-900 break-all">{value}</p> <p className="mt-2 text-sm font-medium text-blue-900 break-all">{value}</p>
</div> </div>
) )
} }
@@ -284,7 +284,7 @@ function EditableField({ label, value, onChange }: { label: string; value: strin
<input <input
value={value} value={value}
onChange={(event) => onChange(event.target.value)} onChange={(event) => onChange(event.target.value)}
className="mt-2 w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm font-medium text-stone-900" className="mt-2 w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm font-medium text-blue-900"
/> />
</label> </label>
) )
@@ -297,7 +297,7 @@ function SelectField({ label, value, options, onChange }: { label: string; value
<select <select
value={value} value={value}
onChange={(event) => onChange(event.target.value)} onChange={(event) => onChange(event.target.value)}
className="mt-2 w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm font-medium text-stone-900" className="mt-2 w-full rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm font-medium text-blue-900"
> >
{options.map((option) => ( {options.map((option) => (
<option key={option} value={option}> <option key={option} value={option}>
@@ -60,7 +60,7 @@ export default function RenterSavedCompaniesPage() {
return ( return (
<div className="shell space-y-6"> <div className="shell space-y-6">
<h1 className="text-3xl font-black tracking-tight text-stone-900">{dict.title}</h1> <h1 className="text-3xl font-black tracking-tight text-blue-900">{dict.title}</h1>
{loading ? <div className="card p-8 text-sm text-stone-500">{dict.loading}</div> : null} {loading ? <div className="card p-8 text-sm text-stone-500">{dict.loading}</div> : null}
{!loading && errorMsg ? <div className="card p-8 text-sm text-rose-600">{errorMsg}</div> : null} {!loading && errorMsg ? <div className="card p-8 text-sm text-rose-600">{errorMsg}</div> : null}
@@ -68,7 +68,7 @@ export default function RenterSavedCompaniesPage() {
{!loading && !errorMsg && companies.length === 0 ? ( {!loading && !errorMsg && companies.length === 0 ? (
<div className="card p-10 text-center"> <div className="card p-10 text-center">
<p className="text-sm text-stone-500">{dict.empty}</p> <p className="text-sm text-stone-500">{dict.empty}</p>
<Link href="/explore" className="mt-5 inline-flex rounded-full bg-stone-900 px-6 py-2.5 text-sm font-semibold text-white"> <Link href="/explore" className="mt-5 inline-flex rounded-full bg-orange-600 px-6 py-2.5 text-sm font-semibold text-white">
{dict.browse} {dict.browse}
</Link> </Link>
</div> </div>
@@ -80,18 +80,18 @@ export default function RenterSavedCompaniesPage() {
<Link <Link
key={company.id} key={company.id}
href={`/explore/${company.brand?.subdomain ?? company.id}`} href={`/explore/${company.brand?.subdomain ?? company.id}`}
className="card flex items-center gap-4 p-5 hover:border-amber-300 transition-colors" className="card flex items-center gap-4 p-5 hover:border-orange-300 transition-colors"
> >
{company.brand?.logoUrl ? ( {company.brand?.logoUrl ? (
// eslint-disable-next-line @next/next/no-img-element // eslint-disable-next-line @next/next/no-img-element
<img src={company.brand.logoUrl} alt={company.brand.displayName} className="h-11 w-11 rounded-xl object-contain" /> <img src={company.brand.logoUrl} alt={company.brand.displayName} className="h-11 w-11 rounded-xl object-contain" />
) : ( ) : (
<div className="flex h-11 w-11 items-center justify-center rounded-xl bg-amber-100 text-sm font-bold text-amber-700"> <div className="flex h-11 w-11 items-center justify-center rounded-xl bg-orange-100 text-sm font-bold text-orange-700">
{company.brand?.displayName?.charAt(0) ?? '?'} {company.brand?.displayName?.charAt(0) ?? '?'}
</div> </div>
)} )}
<div className="min-w-0"> <div className="min-w-0">
<p className="truncate text-sm font-semibold text-stone-900">{company.brand?.displayName ?? dict.rentalCompany}</p> <p className="truncate text-sm font-semibold text-blue-900">{company.brand?.displayName ?? dict.rentalCompany}</p>
<p className="mt-1 truncate text-xs text-stone-400">{company.brand?.subdomain ?? company.id}</p> <p className="mt-1 truncate text-xs text-stone-400">{company.brand?.subdomain ?? company.id}</p>
</div> </div>
</Link> </Link>
@@ -158,7 +158,7 @@ export default function BookingForm({ vehicleId, companySlug, dailyRate }: Props
required required
value={firstName} value={firstName}
onChange={(e) => setFirstName(e.target.value)} onChange={(e) => setFirstName(e.target.value)}
className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-stone-700 dark:bg-stone-800 dark:text-stone-100 dark:focus:border-stone-500" className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-blue-800 dark:bg-[#162038] dark:text-stone-100 dark:focus:border-stone-500"
/> />
</div> </div>
<div className="space-y-1"> <div className="space-y-1">
@@ -167,7 +167,7 @@ export default function BookingForm({ vehicleId, companySlug, dailyRate }: Props
required required
value={lastName} value={lastName}
onChange={(e) => setLastName(e.target.value)} onChange={(e) => setLastName(e.target.value)}
className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-stone-700 dark:bg-stone-800 dark:text-stone-100 dark:focus:border-stone-500" className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-blue-800 dark:bg-[#162038] dark:text-stone-100 dark:focus:border-stone-500"
/> />
</div> </div>
</div> </div>
@@ -179,7 +179,7 @@ export default function BookingForm({ vehicleId, companySlug, dailyRate }: Props
type="email" type="email"
value={email} value={email}
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setEmail(e.target.value)}
className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-stone-700 dark:bg-stone-800 dark:text-stone-100 dark:focus:border-stone-500" className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-blue-800 dark:bg-[#162038] dark:text-stone-100 dark:focus:border-stone-500"
/> />
</div> </div>
@@ -190,7 +190,7 @@ export default function BookingForm({ vehicleId, companySlug, dailyRate }: Props
type="tel" type="tel"
value={phone} value={phone}
onChange={(e) => setPhone(e.target.value)} onChange={(e) => setPhone(e.target.value)}
className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-stone-700 dark:bg-stone-800 dark:text-stone-100 dark:focus:border-stone-500" className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-blue-800 dark:bg-[#162038] dark:text-stone-100 dark:focus:border-stone-500"
/> />
</div> </div>
@@ -203,7 +203,7 @@ export default function BookingForm({ vehicleId, companySlug, dailyRate }: Props
value={startDate} value={startDate}
min={new Date().toISOString().slice(0, 10)} min={new Date().toISOString().slice(0, 10)}
onChange={(e) => setStartDate(e.target.value)} onChange={(e) => setStartDate(e.target.value)}
className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-stone-700 dark:bg-stone-800 dark:text-stone-100 dark:focus:border-stone-500" className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-blue-800 dark:bg-[#162038] dark:text-stone-100 dark:focus:border-stone-500"
/> />
</div> </div>
<div className="space-y-1"> <div className="space-y-1">
@@ -214,7 +214,7 @@ export default function BookingForm({ vehicleId, companySlug, dailyRate }: Props
value={endDate} value={endDate}
min={startDate || new Date().toISOString().slice(0, 10)} min={startDate || new Date().toISOString().slice(0, 10)}
onChange={(e) => setEndDate(e.target.value)} onChange={(e) => setEndDate(e.target.value)}
className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-stone-700 dark:bg-stone-800 dark:text-stone-100 dark:focus:border-stone-500" className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-blue-800 dark:bg-[#162038] dark:text-stone-100 dark:focus:border-stone-500"
/> />
</div> </div>
</div> </div>
@@ -235,14 +235,14 @@ export default function BookingForm({ vehicleId, companySlug, dailyRate }: Props
value={notes} value={notes}
onChange={(e) => setNotes(e.target.value)} onChange={(e) => setNotes(e.target.value)}
rows={3} rows={3}
className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-stone-700 dark:bg-stone-800 dark:text-stone-100 dark:focus:border-stone-500" className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-blue-800 dark:bg-[#162038] dark:text-stone-100 dark:focus:border-stone-500"
/> />
</div> </div>
<button <button
type="submit" type="submit"
disabled={submitting} disabled={submitting}
className="w-full rounded-full bg-stone-900 px-6 py-3 text-center text-sm font-semibold text-white transition hover:bg-stone-700 disabled:opacity-60 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300" className="w-full rounded-full bg-stone-900 px-6 py-3 text-center text-sm font-semibold text-white transition hover:bg-orange-700 disabled:opacity-60 dark:bg-orange-400 dark:text-white dark:hover:bg-orange-300"
> >
{submitting ? t.submitting : t.submit} {submitting ? t.submitting : t.submit}
</button> </button>
@@ -37,7 +37,7 @@ function renderParagraphText(paragraph: string) {
<span key={`${part}-${index}`}> <span key={`${part}-${index}`}>
<a <a
href={href} href={href}
className="text-amber-700 underline decoration-amber-300 underline-offset-4 transition hover:text-stone-950 dark:text-amber-300 dark:hover:text-stone-100" className="text-orange-700 underline decoration-orange-300 underline-offset-4 transition hover:text-blue-900 dark:text-orange-300 dark:hover:text-stone-100"
> >
{href} {href}
</a> </a>
@@ -62,7 +62,7 @@ export default function FooterContentPage({ slug, forcedLanguage }: { slug: Foot
<main className="site-page"> <main className="site-page">
<div className="site-section mx-auto max-w-4xl"> <div className="site-section mx-auto max-w-4xl">
<section className="site-panel overflow-hidden p-0"> <section className="site-panel overflow-hidden p-0">
<div className="site-panel-muted rounded-none border-0 border-b border-stone-100/80 px-6 py-10 sm:px-10 sm:py-14 dark:border-stone-800"> <div className="site-panel-muted rounded-none border-0 border-b border-stone-100/80 px-6 py-10 sm:px-10 sm:py-14 dark:border-blue-900">
<p className="site-kicker"> <p className="site-kicker">
{meta.kicker} {meta.kicker}
</p> </p>
@@ -91,8 +91,8 @@ export default function FooterContentPage({ slug, forcedLanguage }: { slug: Foot
</section> </section>
))} ))}
<div className="rounded-3xl border border-amber-200 bg-amber-50 px-6 py-5 dark:border-amber-800 dark:bg-amber-950/30"> <div className="rounded-3xl border border-orange-200 bg-orange-50 px-6 py-5 dark:border-orange-800 dark:bg-orange-950/30">
<p className="text-sm font-semibold uppercase tracking-[0.18em] text-amber-800 dark:text-amber-400"> <p className="text-sm font-semibold uppercase tracking-[0.18em] text-orange-800 dark:text-orange-400">
{meta.cta} {meta.cta}
</p> </p>
<p className="mt-2 text-base leading-7 text-stone-700 dark:text-stone-300">{meta.support}</p> <p className="mt-2 text-base leading-7 text-stone-700 dark:text-stone-300">{meta.support}</p>
@@ -47,7 +47,7 @@ export default function MarketplaceFooter({
}, []) }, [])
return ( return (
<footer className="border-t border-stone-200/80 bg-white/72 px-4 py-8 text-stone-600 backdrop-blur-xl transition-colors dark:border-stone-800 dark:bg-stone-950/72 dark:text-stone-300"> <footer className="border-t border-stone-200/80 bg-white/72 px-4 py-8 text-stone-600 backdrop-blur-xl transition-colors dark:border-blue-900 dark:bg-[#07101e]/72 dark:text-stone-300">
<div className="shell flex flex-col items-center gap-5 text-center"> <div className="shell flex flex-col items-center gap-5 text-center">
<nav className="flex flex-wrap items-center justify-center gap-y-3 text-sm"> <nav className="flex flex-wrap items-center justify-center gap-y-3 text-sm">
{primaryItems.map((item, index) => ( {primaryItems.map((item, index) => (
@@ -80,7 +80,7 @@ export default function MarketplaceFooter({
<ChevronDown className={`h-4 w-4 transition-transform ${localeMenuOpen ? 'rotate-180' : ''}`} /> <ChevronDown className={`h-4 w-4 transition-transform ${localeMenuOpen ? 'rotate-180' : ''}`} />
</button> </button>
{localeMenuOpen ? ( {localeMenuOpen ? (
<div className="absolute left-1/2 top-full z-20 mt-3 w-56 -translate-x-1/2 overflow-hidden rounded-2xl border border-stone-200 bg-white/95 text-left shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-stone-800 dark:bg-stone-950/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)]"> <div className="absolute left-1/2 top-full z-20 mt-3 w-56 -translate-x-1/2 overflow-hidden rounded-2xl border border-stone-200 bg-white/95 text-left shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-blue-900 dark:bg-[#07101e]/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)]">
{localeOptions.map((option) => ( {localeOptions.map((option) => (
<button <button
key={option.value} key={option.value}
@@ -89,7 +89,7 @@ export default function MarketplaceFooter({
onSelectLanguage(option.value) onSelectLanguage(option.value)
setLocaleMenuOpen(false) setLocaleMenuOpen(false)
}} }}
className="flex w-full items-center gap-3 px-4 py-3 text-sm text-stone-700 transition hover:bg-stone-100 hover:text-stone-950 dark:text-stone-200 dark:hover:bg-stone-900 dark:hover:text-white" className="flex w-full items-center gap-3 px-4 py-3 text-sm text-stone-700 transition hover:bg-stone-100 hover:text-blue-900 dark:text-stone-200 dark:hover:bg-[#0d1b38] dark:hover:text-white"
> >
<span aria-hidden="true" className="text-base leading-none">{option.flag}</span> <span aria-hidden="true" className="text-base leading-none">{option.flag}</span>
<span>{option.label}</span> <span>{option.label}</span>
@@ -109,7 +109,7 @@ export default function MarketplaceFooter({
} }
function FooterNavItem({ item }: { item: FooterItem }) { function FooterNavItem({ item }: { item: FooterItem }) {
const className = 'px-3 text-stone-600 transition hover:text-stone-950 dark:text-stone-300 dark:hover:text-white' const className = 'px-3 text-stone-600 transition hover:text-blue-900 dark:text-stone-300 dark:hover:text-white'
if (item.href) { if (item.href) {
return ( return (
@@ -82,7 +82,7 @@ export default function MarketplaceHeader({
} }
return ( return (
<header className="sticky top-0 z-50 border-b border-stone-200/80 bg-white/78 backdrop-blur-xl shadow-[0_10px_30px_rgba(15,23,42,0.08)] transition-colors dark:border-stone-800 dark:bg-stone-950/76 dark:shadow-[0_10px_30px_rgba(0,0,0,0.32)]"> <header className="sticky top-0 z-50 border-b border-stone-200/80 bg-white/78 backdrop-blur-xl shadow-[0_10px_30px_rgba(15,23,42,0.08)] transition-colors dark:border-blue-900 dark:bg-[#07101e]/76 dark:shadow-[0_10px_30px_rgba(0,0,0,0.32)]">
<div className="shell flex min-h-14 flex-col gap-1.5 py-1.5 lg:flex-row lg:items-center lg:justify-between lg:gap-3 lg:py-2"> <div className="shell flex min-h-14 flex-col gap-1.5 py-1.5 lg:flex-row lg:items-center lg:justify-between lg:gap-3 lg:py-2">
<div className="flex items-center justify-between gap-3"> <div className="flex items-center justify-between gap-3">
<Link href="/" className="flex items-center gap-1.5 text-[11px] font-bold uppercase tracking-[0.14em] text-stone-900 dark:text-stone-100 sm:text-sm sm:tracking-[0.2em]"> <Link href="/" className="flex items-center gap-1.5 text-[11px] font-bold uppercase tracking-[0.14em] text-stone-900 dark:text-stone-100 sm:text-sm sm:tracking-[0.2em]">
@@ -102,28 +102,28 @@ export default function MarketplaceHeader({
<nav className="flex items-center gap-0.5 overflow-x-auto"> <nav className="flex items-center gap-0.5 overflow-x-auto">
<Link <Link
href="/" href="/"
className="rounded-full px-2.5 py-1 text-[12px] font-medium text-stone-600 transition hover:bg-stone-100 hover:text-stone-900 dark:text-stone-300 dark:hover:bg-stone-800 dark:hover:text-stone-100 sm:px-4 sm:py-2 sm:text-sm" className="rounded-full px-2.5 py-1 text-[12px] font-medium text-stone-600 transition hover:bg-stone-100 hover:text-stone-900 dark:text-stone-300 dark:hover:bg-[#162038] dark:hover:text-stone-100 sm:px-4 sm:py-2 sm:text-sm"
> >
{dict.marketplace} {dict.marketplace}
</Link> </Link>
<Link <Link
href="/explore" href="/explore"
className="rounded-full px-2.5 py-1 text-[12px] font-medium text-stone-600 transition hover:bg-stone-100 hover:text-stone-900 dark:text-stone-300 dark:hover:bg-stone-800 dark:hover:text-stone-100 sm:px-4 sm:py-2 sm:text-sm" className="rounded-full px-2.5 py-1 text-[12px] font-medium text-stone-600 transition hover:bg-stone-100 hover:text-stone-900 dark:text-stone-300 dark:hover:bg-[#162038] dark:hover:text-stone-100 sm:px-4 sm:py-2 sm:text-sm"
> >
{dict.explore} {dict.explore}
</Link> </Link>
<Link <Link
href="/sign-in" href="/sign-in"
className="rounded-full px-2.5 py-1 text-[12px] font-medium text-stone-600 transition hover:bg-stone-100 hover:text-stone-900 dark:text-stone-300 dark:hover:bg-stone-800 dark:hover:text-stone-100 sm:px-4 sm:py-2 sm:text-sm" className="rounded-full px-2.5 py-1 text-[12px] font-medium text-stone-600 transition hover:bg-stone-100 hover:text-stone-900 dark:text-stone-300 dark:hover:bg-[#162038] dark:hover:text-stone-100 sm:px-4 sm:py-2 sm:text-sm"
> >
{dict.signIn} {dict.signIn}
</Link> </Link>
{companyName ? ( {companyName ? (
<Link <Link
href={`${dashboardUrl}/dashboard`} href={`${dashboardUrl}/dashboard`}
className="ml-1 flex items-center gap-1.5 rounded-full bg-stone-900 px-3 py-1 text-[12px] font-semibold text-white transition hover:bg-stone-700 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300 sm:ml-2 sm:gap-2 sm:px-4 sm:py-2 sm:text-sm" className="ml-1 flex items-center gap-1.5 rounded-full bg-orange-600 px-3 py-1 text-[12px] font-semibold text-white transition hover:bg-orange-700 dark:bg-orange-500 dark:hover:bg-orange-400 sm:ml-2 sm:gap-2 sm:px-4 sm:py-2 sm:text-sm"
> >
<span className="inline-flex h-5 w-5 items-center justify-center rounded-full bg-white/20 text-[10px] font-black dark:bg-stone-950/20"> <span className="inline-flex h-5 w-5 items-center justify-center rounded-full bg-white/20 text-[10px] font-black dark:bg-[#07101e]/20">
{companyName.charAt(0).toUpperCase()} {companyName.charAt(0).toUpperCase()}
</span> </span>
{companyName} {companyName}
@@ -131,18 +131,18 @@ export default function MarketplaceHeader({
) : ( ) : (
<Link <Link
href={`${dashboardUrl}/sign-up`} href={`${dashboardUrl}/sign-up`}
className="ml-1 rounded-full bg-stone-900 px-3 py-1 text-[12px] font-semibold text-white transition hover:bg-stone-700 dark:bg-amber-400 dark:text-stone-950 dark:hover:bg-amber-300 sm:ml-2 sm:px-5 sm:py-2 sm:text-sm" className="ml-1 rounded-full bg-orange-600 px-3 py-1 text-[12px] font-semibold text-white transition hover:bg-orange-700 dark:bg-orange-500 dark:hover:bg-orange-400 sm:ml-2 sm:px-5 sm:py-2 sm:text-sm"
> >
{dict.ownerSignIn} {dict.ownerSignIn}
</Link> </Link>
)} )}
</nav> </nav>
<div className="flex items-center self-start rounded-full border border-stone-200/80 bg-white/95 p-0.5 shadow-sm dark:border-stone-700 dark:bg-stone-900/85 sm:self-auto sm:p-1"> <div className="flex items-center self-start rounded-full border border-stone-200/80 bg-white/95 p-0.5 shadow-sm dark:border-blue-800 dark:bg-[#0d1b38]/85 sm:self-auto sm:p-1">
<div ref={localeMenuRef} className="relative"> <div ref={localeMenuRef} className="relative">
<button <button
type="button" type="button"
onClick={toggleLocaleMenu} onClick={toggleLocaleMenu}
className="inline-flex min-w-[4.75rem] items-center justify-center gap-1.5 rounded-full px-2.5 py-1.5 text-[11px] font-semibold text-stone-700 transition hover:bg-stone-100 dark:text-stone-200 dark:hover:bg-stone-800 sm:min-w-[5.25rem] sm:px-3 sm:py-2 sm:text-xs" className="inline-flex min-w-[4.75rem] items-center justify-center gap-1.5 rounded-full px-2.5 py-1.5 text-[11px] font-semibold text-stone-700 transition hover:bg-stone-100 dark:text-stone-200 dark:hover:bg-[#162038] sm:min-w-[5.25rem] sm:px-3 sm:py-2 sm:text-xs"
aria-expanded={localeMenuOpen} aria-expanded={localeMenuOpen}
aria-haspopup="menu" aria-haspopup="menu"
> >
@@ -151,7 +151,7 @@ export default function MarketplaceHeader({
<ChevronDown className={`h-3.5 w-3.5 transition-transform ${localeMenuOpen ? 'rotate-180' : ''}`} /> <ChevronDown className={`h-3.5 w-3.5 transition-transform ${localeMenuOpen ? 'rotate-180' : ''}`} />
</button> </button>
{localeMenuOpen ? ( {localeMenuOpen ? (
<div className={`absolute top-full z-30 mt-2 w-44 max-w-[calc(100vw-2rem)] overflow-hidden rounded-2xl border border-stone-200 bg-white/95 text-left shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-stone-800 dark:bg-stone-950/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)] ${localeMenuPositionClass}`}> <div className={`absolute top-full z-30 mt-2 w-44 max-w-[calc(100vw-2rem)] overflow-hidden rounded-2xl border border-stone-200 bg-white/95 text-left shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-blue-900 dark:bg-[#07101e]/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)] ${localeMenuPositionClass}`}>
{localeOptions.map((option) => ( {localeOptions.map((option) => (
<button <button
key={option.value} key={option.value}
@@ -160,7 +160,7 @@ export default function MarketplaceHeader({
onSelectLanguage(option.value) onSelectLanguage(option.value)
setLocaleMenuOpen(false) setLocaleMenuOpen(false)
}} }}
className="flex w-full items-center gap-3 px-4 py-3 text-sm text-stone-700 transition hover:bg-stone-100 hover:text-stone-950 dark:text-stone-200 dark:hover:bg-stone-900 dark:hover:text-white" className="flex w-full items-center gap-3 px-4 py-3 text-sm text-stone-700 transition hover:bg-stone-100 hover:text-blue-900 dark:text-stone-200 dark:hover:bg-[#0d1b38] dark:hover:text-white"
> >
<span aria-hidden="true">{option.flag}</span> <span aria-hidden="true">{option.flag}</span>
<span>{option.shortLabel}</span> <span>{option.shortLabel}</span>
@@ -174,17 +174,17 @@ export default function MarketplaceHeader({
<button <button
type="button" type="button"
onClick={toggleThemeMenu} onClick={toggleThemeMenu}
className="inline-flex items-center gap-1.5 rounded-full px-2 py-1 transition hover:bg-stone-100 dark:hover:bg-stone-800 sm:px-2.5 sm:py-1.5" className="inline-flex items-center gap-1.5 rounded-full px-2 py-1 transition hover:bg-stone-100 dark:hover:bg-[#162038] sm:px-2.5 sm:py-1.5"
aria-expanded={themeMenuOpen} aria-expanded={themeMenuOpen}
aria-haspopup="menu" aria-haspopup="menu"
> >
<span className="rounded-full bg-stone-900 px-3 py-1 text-[11px] font-semibold text-white dark:bg-amber-400 dark:text-stone-950 sm:px-3.5 sm:py-1.5 sm:text-xs"> <span className="rounded-full bg-stone-900 px-3 py-1 text-[11px] font-semibold text-white dark:bg-orange-400 dark:text-white sm:px-3.5 sm:py-1.5 sm:text-xs">
{currentTheme.label} {currentTheme.label}
</span> </span>
<ChevronDown className={`h-3.5 w-3.5 text-stone-500 transition-transform dark:text-stone-400 ${themeMenuOpen ? 'rotate-180' : ''}`} /> <ChevronDown className={`h-3.5 w-3.5 text-stone-500 transition-transform dark:text-stone-400 ${themeMenuOpen ? 'rotate-180' : ''}`} />
</button> </button>
{themeMenuOpen ? ( {themeMenuOpen ? (
<div className={`absolute top-full z-30 mt-2 w-44 max-w-[calc(100vw-2rem)] overflow-hidden rounded-2xl border border-stone-200 bg-white/95 text-left shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-stone-800 dark:bg-stone-950/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)] ${localeMenuPositionClass}`}> <div className={`absolute top-full z-30 mt-2 w-44 max-w-[calc(100vw-2rem)] overflow-hidden rounded-2xl border border-stone-200 bg-white/95 text-left shadow-[0_20px_60px_rgba(0,0,0,0.12)] backdrop-blur dark:border-blue-900 dark:bg-[#07101e]/95 dark:shadow-[0_20px_60px_rgba(0,0,0,0.35)] ${localeMenuPositionClass}`}>
{themeOptions {themeOptions
.filter((option) => option.value !== theme) .filter((option) => option.value !== theme)
.map((option) => ( .map((option) => (
@@ -195,7 +195,7 @@ export default function MarketplaceHeader({
setTheme(option.value) setTheme(option.value)
setThemeMenuOpen(false) setThemeMenuOpen(false)
}} }}
className="flex w-full items-center justify-between px-4 py-3 text-sm text-stone-700 transition hover:bg-stone-100 hover:text-stone-950 dark:text-stone-200 dark:hover:bg-stone-900 dark:hover:text-white" className="flex w-full items-center justify-between px-4 py-3 text-sm text-stone-700 transition hover:bg-stone-100 hover:text-blue-900 dark:text-stone-200 dark:hover:bg-[#0d1b38] dark:hover:text-white"
> >
<span>{option.label}</span> <span>{option.label}</span>
</button> </button>
+13 -13
View File
@@ -103,7 +103,7 @@ export default function RenterShell({ children }: { children: React.ReactNode })
<div className="site-page flex min-h-screen"> <div className="site-page flex min-h-screen">
{open && ( {open && (
<div <div
className="fixed inset-0 z-30 bg-black/50 lg:hidden" className="fixed inset-0 z-30 bg-[#07101e]/50 lg:hidden"
onClick={() => setOpen(false)} onClick={() => setOpen(false)}
/> />
)} )}
@@ -113,7 +113,7 @@ export default function RenterShell({ children }: { children: React.ReactNode })
onClick={() => setOpen(true)} onClick={() => setOpen(true)}
aria-label="Open sidebar" aria-label="Open sidebar"
className={[ className={[
'fixed top-1/2 z-50 -translate-y-1/2 flex items-center justify-center w-6 h-14 bg-stone-900 text-white shadow-lg lg:hidden', 'fixed top-1/2 z-50 -translate-y-1/2 flex items-center justify-center w-6 h-14 bg-[#0d1b38] text-white shadow-lg lg:hidden',
isRtl ? 'right-0 rounded-l-lg' : 'left-0 rounded-r-lg', isRtl ? 'right-0 rounded-l-lg' : 'left-0 rounded-r-lg',
].join(' ')} ].join(' ')}
> >
@@ -123,14 +123,14 @@ export default function RenterShell({ children }: { children: React.ReactNode })
<aside <aside
className={[ className={[
'fixed inset-y-0 z-40 flex w-64 flex-col bg-stone-900 transition-transform duration-300', 'fixed inset-y-0 z-40 flex w-64 flex-col bg-[#0d1b38] transition-transform duration-300',
isRtl ? 'right-0' : 'left-0', isRtl ? 'right-0' : 'left-0',
'lg:translate-x-0', 'lg:translate-x-0',
open ? 'translate-x-0' : isRtl ? 'translate-x-full' : '-translate-x-full', open ? 'translate-x-0' : isRtl ? 'translate-x-full' : '-translate-x-full',
].join(' ')} ].join(' ')}
> >
<div className="flex items-center gap-3 border-b border-stone-800 px-6 py-5"> <div className="flex items-center gap-3 border-b border-blue-900/50 px-6 py-5">
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-amber-500 overflow-hidden"> <div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-orange-500 overflow-hidden">
<Car className="h-4 w-4 text-white" /> <Car className="h-4 w-4 text-white" />
</div> </div>
<span className="truncate text-sm font-bold tracking-wide text-white"> <span className="truncate text-sm font-bold tracking-wide text-white">
@@ -149,8 +149,8 @@ export default function RenterShell({ children }: { children: React.ReactNode })
className={[ className={[
'flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors', 'flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors',
active active
? 'bg-amber-500 text-white' ? 'bg-orange-500 text-white'
: 'text-stone-400 hover:bg-stone-800 hover:text-white', : 'text-slate-400 hover:bg-[#162038] hover:text-white',
].join(' ')} ].join(' ')}
> >
<Icon className="h-4 w-4 flex-shrink-0" /> <Icon className="h-4 w-4 flex-shrink-0" />
@@ -162,7 +162,7 @@ export default function RenterShell({ children }: { children: React.ReactNode })
<div className="border-t border-stone-800 px-3 py-4"> <div className="border-t border-stone-800 px-3 py-4">
<div className="flex items-center gap-3 rounded-lg px-3 py-2"> <div className="flex items-center gap-3 rounded-lg px-3 py-2">
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-amber-500 text-xs font-semibold text-white"> <div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-orange-500 text-xs font-semibold text-white">
{userInitials} {userInitials}
</div> </div>
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
@@ -176,7 +176,7 @@ export default function RenterShell({ children }: { children: React.ReactNode })
</div> </div>
<button <button
onClick={signOut} onClick={signOut}
className="mt-2 flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm text-stone-400 transition-colors hover:bg-stone-800 hover:text-white" className="mt-2 flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm text-slate-400 transition-colors hover:bg-[#162038] hover:text-white"
> >
<LogOut className="h-4 w-4" /> <LogOut className="h-4 w-4" />
{dict.signOut} {dict.signOut}
@@ -187,7 +187,7 @@ export default function RenterShell({ children }: { children: React.ReactNode })
onClick={() => setOpen(false)} onClick={() => setOpen(false)}
aria-label="Close sidebar" aria-label="Close sidebar"
className={[ className={[
'absolute top-1/2 z-10 -translate-y-1/2 flex items-center justify-center w-5 h-14 bg-stone-900 text-white shadow-lg lg:hidden', 'absolute top-1/2 z-10 -translate-y-1/2 flex items-center justify-center w-5 h-14 bg-[#0d1b38] text-white shadow-lg lg:hidden',
isRtl ? '-left-5 rounded-l-lg' : '-right-5 rounded-r-lg', isRtl ? '-left-5 rounded-l-lg' : '-right-5 rounded-r-lg',
].join(' ')} ].join(' ')}
> >
@@ -201,9 +201,9 @@ export default function RenterShell({ children }: { children: React.ReactNode })
isRtl ? 'lg:mr-64' : 'lg:ml-64', isRtl ? 'lg:mr-64' : 'lg:ml-64',
].join(' ')} ].join(' ')}
> >
<header className="flex h-16 items-center justify-between border-b border-stone-200/80 bg-white/80 px-6 backdrop-blur transition-colors dark:border-stone-800 dark:bg-stone-900/70"> <header className="flex h-16 items-center justify-between border-b border-stone-200/80 bg-white/80 px-6 backdrop-blur transition-colors dark:border-blue-900 dark:bg-[#0d1b38]/70">
<h1 className="text-lg font-semibold text-stone-900 dark:text-stone-100">{pageTitle}</h1> <h1 className="text-lg font-semibold text-stone-900 dark:text-stone-100">{pageTitle}</h1>
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-amber-500 text-xs font-semibold text-white"> <div className="flex h-8 w-8 items-center justify-center rounded-full bg-orange-500 text-xs font-semibold text-white">
{userInitials} {userInitials}
</div> </div>
</header> </header>
@@ -212,7 +212,7 @@ export default function RenterShell({ children }: { children: React.ReactNode })
{children} {children}
</main> </main>
<footer className="border-t border-stone-200/80 bg-white/80 px-6 py-4 backdrop-blur transition-colors dark:border-stone-800 dark:bg-stone-900/70"> <footer className="border-t border-stone-200/80 bg-white/80 px-6 py-4 backdrop-blur transition-colors dark:border-blue-900 dark:bg-[#0d1b38]/70">
<p className="text-center text-xs text-stone-400 dark:text-stone-500"> <p className="text-center text-xs text-stone-400 dark:text-stone-500">
&copy; {new Date().getFullYear()} RentalDriveGo. {dict.rights} &copy; {new Date().getFullYear()} RentalDriveGo. {dict.rights}
</p> </p>
@@ -91,7 +91,7 @@ export default function WorkspaceFrame({ target }: { target: FrameId }) {
<iframe <iframe
title={config.label} title={config.label}
src={src} src={src}
className="w-full border-0 bg-white dark:bg-stone-950" className="w-full border-0 bg-white dark:bg-[#07101e]"
style={{ height: FRAME_HEIGHT }} style={{ height: FRAME_HEIGHT }}
/> />
) : ( ) : (
@@ -84,8 +84,8 @@ export default function WorkspaceTabs() {
return ( return (
<main className={`min-h-screen transition-colors ${ <main className={`min-h-screen transition-colors ${
theme === 'dark' theme === 'dark'
? 'bg-[radial-gradient(circle_at_top,#451a03,transparent_28%),linear-gradient(180deg,#0c0a09,#111827)]' ? 'bg-[radial-gradient(circle_at_top,rgba(234,88,12,0.20),transparent_28%),linear-gradient(180deg,#07101e,#0d1b38)]'
: 'bg-[radial-gradient(circle_at_top,#fef3c7,transparent_28%),linear-gradient(180deg,#fafaf9,white)]' : 'bg-[radial-gradient(circle_at_top,rgba(234,88,12,0.08),transparent_28%),linear-gradient(180deg,#f5f8ff,white)]'
}`}> }`}>
<div className="shell py-16 sm:py-20"> <div className="shell py-16 sm:py-20">
<div className="max-w-4xl"> <div className="max-w-4xl">
@@ -97,18 +97,18 @@ export default function WorkspaceTabs() {
width={72} width={72}
height={72} height={72}
className={`h-16 w-16 rounded-2xl object-contain p-1 shadow-sm ${ className={`h-16 w-16 rounded-2xl object-contain p-1 shadow-sm ${
theme === 'dark' ? 'border border-amber-500/40 bg-stone-900' : 'border border-amber-200 bg-white' theme === 'dark' ? 'border border-orange-500/40 bg-[#0d1b38]' : 'border border-orange-200 bg-white'
}`} }`}
/> />
</Link> </Link>
<p className={`text-sm font-semibold uppercase tracking-[0.24em] ${ <p className={`text-sm font-semibold uppercase tracking-[0.24em] ${
theme === 'dark' ? 'text-amber-300' : 'text-amber-700' theme === 'dark' ? 'text-orange-300' : 'text-orange-700'
}`}> }`}>
{copy.badge} {copy.badge}
</p> </p>
</div> </div>
<h1 className={`mt-5 text-4xl font-black tracking-tight sm:text-6xl ${ <h1 className={`mt-5 text-4xl font-black tracking-tight sm:text-6xl ${
theme === 'dark' ? 'text-stone-100' : 'text-stone-900' theme === 'dark' ? 'text-slate-100' : 'text-blue-900'
}`}> }`}>
{copy.title} {copy.title}
</h1> </h1>
@@ -121,19 +121,19 @@ export default function WorkspaceTabs() {
<section className={`mt-10 overflow-hidden rounded-[2rem] border shadow-xl transition-colors ${ <section className={`mt-10 overflow-hidden rounded-[2rem] border shadow-xl transition-colors ${
theme === 'dark' theme === 'dark'
? 'border-stone-800 bg-stone-900 shadow-black/20' ? 'border-blue-900 bg-[#0d1b38] shadow-black/20'
: 'border-stone-200 bg-white shadow-stone-200/40' : 'border-stone-200 bg-white shadow-stone-200/40'
}`}> }`}>
<div className={`px-6 py-6 ${theme === 'dark' ? 'border-b border-stone-800' : 'border-b border-stone-200'}`}> <div className={`px-6 py-6 ${theme === 'dark' ? 'border-b border-stone-800' : 'border-b border-stone-200'}`}>
<p className={`text-xs font-semibold uppercase tracking-[0.18em] ${ <p className={`text-xs font-semibold uppercase tracking-[0.18em] ${
theme === 'dark' ? 'text-amber-300' : 'text-amber-700' theme === 'dark' ? 'text-orange-300' : 'text-orange-700'
}`}> }`}>
{copy.sectionBadge} {copy.sectionBadge}
</p> </p>
<div className="mt-3 flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between"> <div className="mt-3 flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
<div className="max-w-3xl"> <div className="max-w-3xl">
<h2 className={`text-2xl font-black tracking-tight ${ <h2 className={`text-2xl font-black tracking-tight ${
theme === 'dark' ? 'text-stone-100' : 'text-stone-900' theme === 'dark' ? 'text-slate-100' : 'text-blue-900'
}`}> }`}>
{copy.sectionTitle} {copy.sectionTitle}
</h2> </h2>
@@ -154,8 +154,8 @@ export default function WorkspaceTabs() {
href="/explore" href="/explore"
className={`rounded-full px-5 py-2.5 text-sm font-semibold transition ${ className={`rounded-full px-5 py-2.5 text-sm font-semibold transition ${
theme === 'dark' theme === 'dark'
? 'bg-amber-400 text-stone-950 hover:bg-amber-300' ? 'bg-orange-400 text-blue-950 hover:bg-orange-300'
: 'bg-stone-900 text-white hover:bg-stone-700' : 'bg-[#0d1b38] text-white hover:bg-[#162038]'
}`} }`}
> >
{copy.exploreVehicles} {copy.exploreVehicles}
@@ -164,7 +164,7 @@ export default function WorkspaceTabs() {
href="/pricing" href="/pricing"
className={`rounded-full border px-5 py-2.5 text-sm font-semibold transition ${ className={`rounded-full border px-5 py-2.5 text-sm font-semibold transition ${
theme === 'dark' theme === 'dark'
? 'border-stone-700 text-stone-200 hover:border-stone-500 hover:bg-stone-800' ? 'border-blue-800 text-slate-200 hover:border-blue-600 hover:bg-[#162038]'
: 'border-stone-300 text-stone-700 hover:border-stone-400 hover:bg-stone-50' : 'border-stone-300 text-stone-700 hover:border-stone-400 hover:bg-stone-50'
}`} }`}
> >
@@ -175,10 +175,10 @@ export default function WorkspaceTabs() {
</div> </div>
<div className={`grid gap-6 px-6 py-8 lg:grid-cols-[1.4fr_0.9fr] ${ <div className={`grid gap-6 px-6 py-8 lg:grid-cols-[1.4fr_0.9fr] ${
theme === 'dark' ? 'bg-stone-950' : 'bg-stone-50' theme === 'dark' ? 'bg-[#07101e]' : 'bg-stone-50'
}`}> }`}>
<div className="rounded-[1.5rem] bg-[linear-gradient(135deg,#1c1917,#44403c)] p-8 text-white"> <div className="rounded-[1.5rem] bg-[linear-gradient(135deg,#06132e,#0d1b38)] p-8 text-white">
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-amber-300">{copy.nowServing}</p> <p className="text-xs font-semibold uppercase tracking-[0.24em] text-orange-300">{copy.nowServing}</p>
<h3 className="mt-4 text-3xl font-black tracking-tight"> <h3 className="mt-4 text-3xl font-black tracking-tight">
{copy.promoTitle} {copy.promoTitle}
</h3> </h3>
@@ -189,13 +189,13 @@ export default function WorkspaceTabs() {
<div className="grid gap-4"> <div className="grid gap-4">
<div className={`rounded-[1.5rem] border p-5 ${ <div className={`rounded-[1.5rem] border p-5 ${
theme === 'dark' ? 'border-stone-800 bg-stone-900' : 'border-stone-200 bg-white' theme === 'dark' ? 'border-blue-900 bg-[#0d1b38]' : 'border-stone-200 bg-white'
}`}> }`}>
<p className={`text-xs font-semibold uppercase tracking-[0.18em] ${ <p className={`text-xs font-semibold uppercase tracking-[0.18em] ${
theme === 'dark' ? 'text-stone-400' : 'text-stone-500' theme === 'dark' ? 'text-stone-400' : 'text-stone-500'
}`}>{copy.customerPaths}</p> }`}>{copy.customerPaths}</p>
<div className="mt-4 flex flex-wrap gap-3"> <div className="mt-4 flex flex-wrap gap-3">
<Link href="/explore" className="rounded-full bg-amber-500 px-4 py-2 text-sm font-semibold text-white"> <Link href="/explore" className="rounded-full bg-orange-500 px-4 py-2 text-sm font-semibold text-white">
{copy.exploreVehicles} {copy.exploreVehicles}
</Link> </Link>
<Link className={`rounded-full border px-4 py-2 text-sm font-semibold ${ <Link className={`rounded-full border px-4 py-2 text-sm font-semibold ${
@@ -212,7 +212,7 @@ export default function WorkspaceTabs() {
</div> </div>
<div className={`rounded-[1.5rem] border p-5 ${ <div className={`rounded-[1.5rem] border p-5 ${
theme === 'dark' ? 'border-stone-800 bg-stone-900' : 'border-stone-200 bg-white' theme === 'dark' ? 'border-blue-900 bg-[#0d1b38]' : 'border-stone-200 bg-white'
}`}> }`}>
<p className={`text-xs font-semibold uppercase tracking-[0.18em] ${ <p className={`text-xs font-semibold uppercase tracking-[0.18em] ${
theme === 'dark' ? 'text-stone-400' : 'text-stone-500' theme === 'dark' ? 'text-stone-400' : 'text-stone-500'