ui: polimento geral e espaçamentos responsivos perfeitos

This commit is contained in:
2026-06-03 15:58:25 +01:00
parent 56f6d16cd1
commit 0a4de43635
10 changed files with 4087 additions and 3426 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
dist/assets/index-olys378F.css vendored Normal file

File diff suppressed because one or more lines are too long

3907
dist/assets/index-xEo-fC2P.js vendored Normal file

File diff suppressed because one or more lines are too long

24
dist/firebase-messaging-sw.js vendored Normal file
View File

@@ -0,0 +1,24 @@
importScripts('https://www.gstatic.com/firebasejs/10.8.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/10.8.0/firebase-messaging-compat.js');
firebase.initializeApp({
apiKey: "AIzaSyBBitFgNKnJ_3B0aqJgbbhGL_erufKd9lk",
authDomain: "mycloset1-864c4.firebaseapp.com",
projectId: "mycloset1-864c4",
storageBucket: "mycloset1-864c4.firebasestorage.app",
messagingSenderId: "219982610263",
appId: "1:219982610263:web:0ebe67d9cf0e7d2753c812"
});
const messaging = firebase.messaging();
messaging.onBackgroundMessage((payload) => {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
icon: '/favicon.ico'
};
self.registration.showNotification(notificationTitle, notificationOptions);
});

5
dist/index.html vendored
View File

@@ -4,8 +4,9 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MyCloset</title> <title>MyCloset</title>
<script type="module" crossorigin src="/assets/index-0fNqCu5T.js"></script> <link rel="manifest" href="/manifest.json" />
<link rel="stylesheet" crossorigin href="/assets/index-D1z9PPLp.css"> <script type="module" crossorigin src="/assets/index-xEo-fC2P.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-olys378F.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

15
dist/manifest.json vendored Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "MyCloset",
"short_name": "MyCloset",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#4F46E5",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
]
}

1
dist/sw.js vendored Normal file
View File

@@ -0,0 +1 @@
self.addEventListener('fetch', function(event) {});

37
fix_spacing.cjs Normal file
View File

@@ -0,0 +1,37 @@
const fs = require('fs');
let content = fs.readFileSync('src/App.jsx', 'utf8');
const replacements = [
{ from: /(?<!:)\bp-12\b/g, to: 'p-6 md:p-12' },
{ from: /(?<!:)\bp-10\b/g, to: 'p-6 md:p-10' },
{ from: /(?<!:)\bp-8\b/g, to: 'p-5 md:p-8' },
{ from: /(?<!:)\bgap-10\b/g, to: 'gap-6 md:gap-10' },
{ from: /(?<!:)\bgap-12\b/g, to: 'gap-6 md:gap-12' },
{ from: /(?<!:)\bgap-8\b/g, to: 'gap-4 md:gap-8' },
{ from: /(?<!:)\bmb-10\b/g, to: 'mb-6 md:mb-10' },
{ from: /(?<!:)\bmb-16\b/g, to: 'mb-8 md:mb-16' },
{ from: /(?<!:)\bmb-8\b/g, to: 'mb-5 md:mb-8' },
{ from: /(?<!:)\bmt-10\b/g, to: 'mt-6 md:mt-10' },
{ from: /(?<!:)\bmt-12\b/g, to: 'mt-6 md:mt-12' },
{ from: /(?<!:)\bmt-8\b/g, to: 'mt-5 md:mt-8' },
{ from: /(?<!:)\bpx-12\b/g, to: 'px-6 md:px-12' },
{ from: /(?<!:)\bpx-8\b/g, to: 'px-5 md:px-8' },
{ from: /(?<!:)\bpy-12\b/g, to: 'py-6 md:py-12' },
{ from: /(?<!:)\bpy-16\b/g, to: 'py-8 md:py-16' },
{ from: /(?<!:)\bspace-y-10\b/g, to: 'space-y-6 md:space-y-10' },
{ from: /(?<!:)\bspace-y-12\b/g, to: 'space-y-8 md:space-y-12' },
{ from: /(?<!:)\bspace-y-8\b/g, to: 'space-y-5 md:space-y-8' }
];
let changedContent = content;
replacements.forEach(r => {
changedContent = changedContent.replace(r.from, r.to);
});
// To be even more perfect, let's also fix rounded-[2rem] to rounded-3xl md:rounded-[2rem]
changedContent = changedContent.replace(/(?<!:)\brounded-\[2rem\]/g, 'rounded-3xl md:rounded-[2rem]');
fs.writeFileSync('src/App.jsx', changedContent);
console.log('Spacing normalized successfully.');

View File

@@ -1340,10 +1340,10 @@ export default function App() {
if (view === 'auth') { if (view === 'auth') {
return ( return (
<div className={`min-h-screen bg-gradient-to-br from-primary-100 via-white to-purple-50 dark:from-gray-950 dark:to-gray-900 flex items-center justify-center p-6 text-gray-900 ${darkMode ? 'dark' : ''}`}> <div className={`min-h-screen bg-gradient-to-br from-primary-100 via-white to-purple-50 dark:from-gray-950 dark:to-gray-900 flex items-center justify-center p-6 text-gray-900 ${darkMode ? 'dark' : ''}`}>
<Card className="max-w-md w-full p-12 border-none shadow-2xl overflow-hidden" darkMode={darkMode}> <Card className="max-w-md w-full p-6 md:p-12 border-none shadow-2xl overflow-hidden" darkMode={darkMode}>
<div key={authMode} className="animate-custom-zoom"> <div key={authMode} className="animate-custom-zoom">
<div className="text-center mb-10"> <div className="text-center mb-6 md:mb-10">
<div className="inline-flex p-5 bg-primary-600 rounded-[2rem] shadow-2xl shadow-primary-600/40 mb-6 transition-all duration-300"> <div className="inline-flex p-5 bg-primary-600 rounded-3xl md:rounded-[2rem] shadow-2xl shadow-primary-600/40 mb-6 transition-all duration-300">
{authMode === 'login' ? <Shirt className="text-white w-12 h-12" /> : <UserCircle className="text-white w-12 h-12" />} {authMode === 'login' ? <Shirt className="text-white w-12 h-12" /> : <UserCircle className="text-white w-12 h-12" />}
</div> </div>
<h1 className="text-5xl font-black tracking-tighter italic">MyCloset</h1> <h1 className="text-5xl font-black tracking-tighter italic">MyCloset</h1>
@@ -1361,19 +1361,19 @@ export default function App() {
</button> </button>
</div> </div>
)} )}
<button className="w-full py-5 bg-primary-600 text-white rounded-[2rem] font-black text-lg shadow-2xl hover:scale-[1.02] active:scale-95 transition-all"> <button className="w-full py-5 bg-primary-600 text-white rounded-3xl md:rounded-[2rem] font-black text-lg shadow-2xl hover:scale-[1.02] active:scale-95 transition-all">
{authMode === 'login' ? t('loginBtn') : t('registerBtn')} {authMode === 'login' ? t('loginBtn') : t('registerBtn')}
</button> </button>
</form> </form>
<div className="mt-10 text-center"> <div className="mt-6 md:mt-10 text-center">
<button type="button" onClick={() => setAuthMode(authMode === 'login' ? 'register' : 'login')} className="text-gray-400 font-black text-[10px] uppercase tracking-[0.3em] hover:text-primary-600 transition-colors text-inherit"> <button type="button" onClick={() => setAuthMode(authMode === 'login' ? 'register' : 'login')} className="text-gray-400 font-black text-[10px] uppercase tracking-[0.3em] hover:text-primary-600 transition-colors text-inherit">
{authMode === 'login' ? t('createAccount') : t('haveAccount')} {authMode === 'login' ? t('createAccount') : t('haveAccount')}
</button> </button>
</div> </div>
{/* Language Switcher for Auth Page */} {/* Language Switcher for Auth Page */}
<div className="mt-12 flex justify-center gap-5 pt-8 border-t border-gray-100 dark:border-gray-800/50"> <div className="mt-6 md:mt-12 flex justify-center gap-5 pt-8 border-t border-gray-100 dark:border-gray-800/50">
{[ {[
{ id: 'PT', flag: '🇵🇹' }, { id: 'PT', flag: '🇵🇹' },
{ id: 'EN', flag: '🇬🇧' }, { id: 'EN', flag: '🇬🇧' },
@@ -1399,12 +1399,12 @@ export default function App() {
{/* Modal de Forgot Password */} {/* Modal de Forgot Password */}
{showForgotPasswordModal && ( {showForgotPasswordModal && (
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowForgotPasswordModal(false)}> <div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowForgotPasswordModal(false)}>
<Card className="w-full max-w-md p-8 animate-in zoom-in-95" darkMode={darkMode} onClick={e => e.stopPropagation()}> <Card className="w-full max-w-md p-5 md:p-8 animate-in zoom-in-95" darkMode={darkMode} onClick={e => e.stopPropagation()}>
<h3 className="text-2xl font-black mb-4 text-center text-inherit">{t('forgotPassword')}</h3> <h3 className="text-2xl font-black mb-4 text-center text-inherit">{t('forgotPassword')}</h3>
<p className="text-center opacity-70 mb-8 text-sm text-inherit">{t('forgotPasswordPrompt')}</p> <p className="text-center opacity-70 mb-5 md:mb-8 text-sm text-inherit">{t('forgotPasswordPrompt')}</p>
<form onSubmit={handleForgotPasswordSubmit} className="space-y-4"> <form onSubmit={handleForgotPasswordSubmit} className="space-y-4">
<input name="resetEmail" type="email" placeholder={t('emailPlaceholder')} required value={forgotPasswordEmail} onChange={e => setForgotPasswordEmail(e.target.value)} className="w-full p-5 rounded-2xl bg-gray-50 dark:bg-gray-800 border-none focus:ring-2 focus:ring-primary-500 outline-none font-bold text-inherit" /> <input name="resetEmail" type="email" placeholder={t('emailPlaceholder')} required value={forgotPasswordEmail} onChange={e => setForgotPasswordEmail(e.target.value)} className="w-full p-5 rounded-2xl bg-gray-50 dark:bg-gray-800 border-none focus:ring-2 focus:ring-primary-500 outline-none font-bold text-inherit" />
<button type="submit" disabled={loading} className="w-full py-5 bg-primary-600 text-white rounded-[2rem] font-black text-lg shadow-2xl hover:scale-[1.02] active:scale-95 transition-all disabled:opacity-50"> <button type="submit" disabled={loading} className="w-full py-5 bg-primary-600 text-white rounded-3xl md:rounded-[2rem] font-black text-lg shadow-2xl hover:scale-[1.02] active:scale-95 transition-all disabled:opacity-50">
{loading ? t('saving') : t('sendEmailBtn')} {loading ? t('saving') : t('sendEmailBtn')}
</button> </button>
</form> </form>
@@ -1427,8 +1427,8 @@ export default function App() {
${darkMode ? 'bg-gray-900/80 border-gray-800' : 'bg-white border-gray-100'} ${darkMode ? 'bg-gray-900/80 border-gray-800' : 'bg-white border-gray-100'}
${sidebarOpen ? 'w-80 translate-x-0' : 'w-0 -translate-x-full md:w-0 md:opacity-0'} ${sidebarOpen ? 'w-80 translate-x-0' : 'w-0 -translate-x-full md:w-0 md:opacity-0'}
`}> `}>
<div className="p-10 h-full flex flex-col backdrop-blur-xl"> <div className="p-6 md:p-10 h-full flex flex-col backdrop-blur-xl">
<button onClick={() => setView('closet')} className="flex items-center gap-4 mb-16 hover:scale-[1.02] transition-transform text-left cursor-pointer w-full"> <button onClick={() => setView('closet')} className="flex items-center gap-4 mb-5 md:mb-8 md:mb-16 hover:scale-[1.02] transition-transform text-left cursor-pointer w-full">
<div className="p-3 bg-primary-600 rounded-2xl shadow-xl shadow-primary-600/30"> <div className="p-3 bg-primary-600 rounded-2xl shadow-xl shadow-primary-600/30">
<Shirt className="text-white" size={24} /> <Shirt className="text-white" size={24} />
</div> </div>
@@ -1461,7 +1461,7 @@ export default function App() {
</nav> </nav>
<div className="mt-auto pt-10 border-t border-inherit"> <div className="mt-auto pt-10 border-t border-inherit">
<div onClick={() => setView('profile')} className="w-full flex items-center gap-4 mb-8 px-2 text-left hover:bg-gray-100 dark:hover:bg-gray-800 py-3 rounded-2xl transition-all cursor-pointer"> <div onClick={() => setView('profile')} className="w-full flex items-center gap-4 mb-5 md:mb-8 px-2 text-left hover:bg-gray-100 dark:hover:bg-gray-800 py-3 rounded-2xl transition-all cursor-pointer">
<div className={`w-12 h-12 rounded-2xl shrink-0 flex items-center justify-center font-black text-white shadow-xl overflow-hidden ${darkMode ? 'bg-primary-500' : 'bg-primary-600'}`}> <div className={`w-12 h-12 rounded-2xl shrink-0 flex items-center justify-center font-black text-white shadow-xl overflow-hidden ${darkMode ? 'bg-primary-500' : 'bg-primary-600'}`}>
{userProfile?.avatar ? ( {userProfile?.avatar ? (
<img src={userProfile.avatar} className="w-full h-full object-cover" alt="Avatar" /> <img src={userProfile.avatar} className="w-full h-full object-cover" alt="Avatar" />
@@ -1540,18 +1540,18 @@ export default function App() {
</header> </header>
{/* Conteúdo Dinâmico */} {/* Conteúdo Dinâmico */}
<div className="flex-1 overflow-y-auto p-4 md:p-12 space-y-8 md:space-y-12"> <div className="flex-1 overflow-y-auto p-4 md:p-12 space-y-5 md:space-y-8 md:space-y-12">
{/* DASHBOARD */} {/* DASHBOARD */}
{view === 'dashboard' && ( {view === 'dashboard' && (
<div className="space-y-12 animate-in fade-in duration-700"> <div className="space-y-5 md:space-y-8 md:space-y-12 animate-in fade-in duration-700">
<div className="grid grid-cols-1 md:grid-cols-3 gap-8"> <div className="grid grid-cols-1 md:grid-cols-3 gap-4 md:gap-8">
{[ {[
{ label: t('readyClothes'), val: activeClothes.length, icon: Shirt, col: 'primary' }, { label: t('readyClothes'), val: activeClothes.length, icon: Shirt, col: 'primary' },
{ label: t('inLaundry'), val: laundryClothes.length, icon: Droplets, col: 'blue' }, { label: t('inLaundry'), val: laundryClothes.length, icon: Droplets, col: 'blue' },
{ label: t('myLooks'), val: looks.length, icon: Sparkles, col: 'purple' }, { label: t('myLooks'), val: looks.length, icon: Sparkles, col: 'purple' },
].map((s, i) => ( ].map((s, i) => (
<Card key={i} className="p-8 group hover:-translate-y-2" darkMode={darkMode}> <Card key={i} className="p-5 md:p-8 group hover:-translate-y-2" darkMode={darkMode}>
<div className={`w-14 h-14 rounded-2xl flex items-center justify-center mb-6 shadow-inner ${darkMode ? 'bg-gray-700 text-primary-400' : 'bg-primary-50 text-primary-600'}`}> <div className={`w-14 h-14 rounded-2xl flex items-center justify-center mb-6 shadow-inner ${darkMode ? 'bg-gray-700 text-primary-400' : 'bg-primary-50 text-primary-600'}`}>
<s.icon size={28} /> <s.icon size={28} />
</div> </div>
@@ -1561,8 +1561,8 @@ export default function App() {
))} ))}
</div> </div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8"> <div className="grid grid-cols-1 lg:grid-cols-3 gap-4 md:gap-8">
<div className="lg:col-span-2 p-10 rounded-[2rem] relative overflow-hidden shadow-2xl" style={{ backgroundColor: 'hsl(var(--primary-600))', color: 'white' }}> <div className="lg:col-span-2 p-6 md:p-10 rounded-3xl md:rounded-[2rem] relative overflow-hidden shadow-2xl" style={{ backgroundColor: 'hsl(var(--primary-600))', color: 'white' }}>
<div className="relative z-10 flex flex-col justify-between h-full"> <div className="relative z-10 flex flex-col justify-between h-full">
<div> <div>
<div className="flex items-center gap-3 mb-4"> <div className="flex items-center gap-3 mb-4">
@@ -1576,7 +1576,7 @@ export default function App() {
{weatherData ? `${t('weatherForecastDesc').replace('{max}', weatherData.maxTemp).replace('{min}', weatherData.minTemp)} ${t('weatherMsg')}` : t('weatherMsg')} {weatherData ? `${t('weatherForecastDesc').replace('{max}', weatherData.maxTemp).replace('{min}', weatherData.minTemp)} ${t('weatherMsg')}` : t('weatherMsg')}
</p> </p>
</div> </div>
<div className="mt-10 flex gap-4 items-center"> <div className="mt-6 md:mt-10 flex gap-4 items-center">
{activeClothes.filter(c => c.category === 'Tops').slice(0, 2).map(c => ( {activeClothes.filter(c => c.category === 'Tops').slice(0, 2).map(c => (
<div key={c.id} className="w-16 h-16 rounded-xl overflow-hidden border-2" style={{ borderColor: 'rgba(255,255,255,0.4)' }}> <div key={c.id} className="w-16 h-16 rounded-xl overflow-hidden border-2" style={{ borderColor: 'rgba(255,255,255,0.4)' }}>
<img src={c.imageUrl} className="w-full h-full object-cover" alt="" /> <img src={c.imageUrl} className="w-full h-full object-cover" alt="" />
@@ -1590,8 +1590,8 @@ export default function App() {
<CloudSun size={350} className="absolute -bottom-20 -right-20" style={{ color: 'rgba(255,255,255,0.1)' }} /> <CloudSun size={350} className="absolute -bottom-20 -right-20" style={{ color: 'rgba(255,255,255,0.1)' }} />
</div> </div>
<Card className="p-8" darkMode={darkMode}> <Card className="p-5 md:p-8" darkMode={darkMode}>
<h3 className="text-lg font-black tracking-tight mb-8 flex items-center gap-2 text-inherit"><PieChart size={20} /> {t('topColors')}</h3> <h3 className="text-lg font-black tracking-tight mb-5 md:mb-8 flex items-center gap-2 text-inherit"><PieChart size={20} /> {t('topColors')}</h3>
<div className="space-y-6"> <div className="space-y-6">
{colorStats.length > 0 ? colorStats.map(stat => ( {colorStats.length > 0 ? colorStats.map(stat => (
<div key={stat.color} className="space-y-2"> <div key={stat.color} className="space-y-2">
@@ -1614,13 +1614,13 @@ export default function App() {
{/* ARMÁRIO & WISHLIST */} {/* ARMÁRIO & WISHLIST */}
{(view === 'closet' || view === 'wishlist') && ( {(view === 'closet' || view === 'wishlist') && (
<div className="space-y-10 animate-in slide-in-from-bottom-8 duration-700"> <div className="space-y-6 md:space-y-10 animate-in slide-in-from-bottom-8 duration-700">
<div className="flex flex-col xl:flex-row gap-8 items-center justify-between"> <div className="flex flex-col xl:flex-row gap-4 md:gap-8 items-center justify-between">
<div className="relative w-full max-w-2xl"> <div className="relative w-full max-w-2xl">
<Search className="absolute left-6 top-1/2 -translate-y-1/2 text-gray-400" size={24} /> <Search className="absolute left-6 top-1/2 -translate-y-1/2 text-gray-400" size={24} />
<input <input
placeholder={t('searchPlaceholder')} placeholder={t('searchPlaceholder')}
className={`w-full pl-16 pr-8 py-6 rounded-[2rem] shadow-inner outline-none border-none focus:ring-4 focus:ring-primary-500/10 font-bold text-lg ${darkMode ? 'bg-gray-800' : 'bg-gray-100'}`} className={`w-full pl-16 pr-8 py-6 rounded-3xl md:rounded-[2rem] shadow-inner outline-none border-none focus:ring-4 focus:ring-primary-500/10 font-bold text-lg ${darkMode ? 'bg-gray-800' : 'bg-gray-100'}`}
onChange={(e) => setSearchTerm(e.target.value)} onChange={(e) => setSearchTerm(e.target.value)}
/> />
</div> </div>
@@ -1628,7 +1628,7 @@ export default function App() {
<div className="flex gap-3 w-full xl:w-auto"> <div className="flex gap-3 w-full xl:w-auto">
<button <button
onClick={() => setShowClosetFilters(true)} onClick={() => setShowClosetFilters(true)}
className="flex items-center gap-3 px-8 py-4 bg-primary-600 text-white rounded-[2rem] font-black uppercase text-[10px] tracking-widest shadow-xl shadow-primary-600/30 hover:scale-105 transition-all" className="flex items-center gap-3 px-5 md:px-8 py-4 bg-primary-600 text-white rounded-3xl md:rounded-[2rem] font-black uppercase text-[10px] tracking-widest shadow-xl shadow-primary-600/30 hover:scale-105 transition-all"
> >
<Filter size={18} /> {t('advancedFilters')} <Filter size={18} /> {t('advancedFilters')}
{(colorFilter || favoriteFilter || ageFilter !== 'any' || (categoryFilter !== 'Todos' && categoryFilter !== t('all'))) && ( {(colorFilter || favoriteFilter || ageFilter !== 'any' || (categoryFilter !== 'Todos' && categoryFilter !== t('all'))) && (
@@ -1667,8 +1667,8 @@ export default function App() {
<div className={ <div className={
cardSize === 'small' ? 'grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-5 2xl:grid-cols-6 gap-6' cardSize === 'small' ? 'grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-5 2xl:grid-cols-6 gap-6'
: cardSize === 'medium' ? 'grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 2xl:grid-cols-5 gap-8' : cardSize === 'medium' ? 'grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 2xl:grid-cols-5 gap-4 md:gap-8'
: 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-10' : 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-6 md:gap-10'
}> }>
{filteredClothes.map(item => { {filteredClothes.map(item => {
const styles = { const styles = {
@@ -1792,16 +1792,16 @@ export default function App() {
{/* LAVANDARIA */} {/* LAVANDARIA */}
{view === 'laundry' && ( {view === 'laundry' && (
<div className="space-y-12 animate-in fade-in duration-700"> <div className="space-y-5 md:space-y-8 md:space-y-12 animate-in fade-in duration-700">
<div className="text-center max-w-2xl mx-auto space-y-4 text-inherit"> <div className="text-center max-w-2xl mx-auto space-y-4 text-inherit">
<div className="w-20 h-20 bg-blue-100 dark:bg-blue-900/30 rounded-[2rem] flex items-center justify-center mx-auto text-blue-600 shadow-inner"> <div className="w-20 h-20 bg-blue-100 dark:bg-blue-900/30 rounded-3xl md:rounded-[2rem] flex items-center justify-center mx-auto text-blue-600 shadow-inner">
<Droplets size={40} /> <Droplets size={40} />
</div> </div>
<h3 className="text-4xl font-black tracking-tight">{t('laundryBasket')}</h3> <h3 className="text-4xl font-black tracking-tight">{t('laundryBasket')}</h3>
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 md:gap-8">
{laundryClothes.map(item => ( {laundryClothes.map(item => (
<Card key={item.id} className="p-4 flex items-center gap-4 border-blue-200 dark:border-blue-900/50" darkMode={darkMode}> <Card key={item.id} className="p-4 flex items-center gap-4 border-blue-200 dark:border-blue-900/50" darkMode={darkMode}>
<img src={item.imageUrl} className="w-16 h-16 rounded-2xl object-cover shadow-sm shrink-0" alt="" /> <img src={item.imageUrl} className="w-16 h-16 rounded-2xl object-cover shadow-sm shrink-0" alt="" />
@@ -1825,10 +1825,10 @@ export default function App() {
{/* LOOKS */} {/* LOOKS */}
{view === 'outfits' && ( {view === 'outfits' && (
<div className="space-y-12 animate-in fade-in duration-700 pb-20"> <div className="space-y-5 md:space-y-8 md:space-y-12 animate-in fade-in duration-700 pb-20">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-12"> <div className="grid grid-cols-1 lg:grid-cols-3 gap-6 md:gap-12">
<div className="lg:col-span-1 space-y-8"> <div className="lg:col-span-1 space-y-5 md:space-y-8">
<Card className="p-8 border-primary-200" darkMode={darkMode}> <Card className="p-5 md:p-8 border-primary-200" darkMode={darkMode}>
<h3 className="text-2xl font-black tracking-tighter mb-6 flex items-center gap-3 text-inherit"> <h3 className="text-2xl font-black tracking-tighter mb-6 flex items-center gap-3 text-inherit">
<Sparkles className="text-primary-600" /> {editingLook ? t('editLook') || 'Editar Outfit' : t('createNewLook')} <Sparkles className="text-primary-600" /> {editingLook ? t('editLook') || 'Editar Outfit' : t('createNewLook')}
</h3> </h3>
@@ -1908,7 +1908,7 @@ export default function App() {
</div> </div>
</div> </div>
<div className="lg:col-span-2 space-y-10"> <div className="lg:col-span-2 space-y-6 md:space-y-10">
{(() => { {(() => {
const filteredBySectionLooks = looks.filter(look => { const filteredBySectionLooks = looks.filter(look => {
const matchesSection = activeSectionFilter === 'all' || (look.sections && look.sections.includes(activeSectionFilter)); const matchesSection = activeSectionFilter === 'all' || (look.sections && look.sections.includes(activeSectionFilter));
@@ -1942,7 +1942,7 @@ export default function App() {
return item && item.status === 'laundry'; return item && item.status === 'laundry';
}); });
return ( return (
<Card key={look.id} className={`p-8 group hover:shadow-2xl transition-all border-none shadow-md ${hasLaundryPieces ? 'opacity-75' : ''}`} darkMode={darkMode}> <Card key={look.id} className={`p-5 md:p-8 group hover:shadow-2xl transition-all border-none shadow-md ${hasLaundryPieces ? 'opacity-75' : ''}`} darkMode={darkMode}>
<div className="flex justify-between items-start mb-6"> <div className="flex justify-between items-start mb-6">
<div className="text-inherit"> <div className="text-inherit">
<h4 className="text-xl font-black tracking-tight">{look.name}</h4> <h4 className="text-xl font-black tracking-tight">{look.name}</h4>
@@ -2040,11 +2040,11 @@ export default function App() {
</div> </div>
</div> </div>
{availableLooks.length > 0 ? ( {availableLooks.length > 0 ? (
<div className="grid grid-cols-1 md:grid-cols-2 gap-8"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-8">
{availableLooks.map(renderLookCard)} {availableLooks.map(renderLookCard)}
</div> </div>
) : ( ) : (
<div className="py-12 text-center opacity-20 font-black uppercase tracking-[0.3em] text-sm">{t('noLooksAvailable')}</div> <div className="py-6 md:py-12 text-center opacity-20 font-black uppercase tracking-[0.3em] text-sm">{t('noLooksAvailable')}</div>
)} )}
</div> </div>
@@ -2055,7 +2055,7 @@ export default function App() {
<div className="w-2.5 h-2.5 rounded-full bg-blue-400"></div> <div className="w-2.5 h-2.5 rounded-full bg-blue-400"></div>
<h3 className="text-2xl font-black tracking-tighter text-inherit">{t('toBeWashed')} <span className="text-sm font-bold opacity-40"> {t('unavailable')} ({laundryLooks.length})</span></h3> <h3 className="text-2xl font-black tracking-tighter text-inherit">{t('toBeWashed')} <span className="text-sm font-bold opacity-40"> {t('unavailable')} ({laundryLooks.length})</span></h3>
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-8"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-8">
{laundryLooks.map(renderLookCard)} {laundryLooks.map(renderLookCard)}
</div> </div>
</div> </div>
@@ -2222,8 +2222,8 @@ export default function App() {
{/* ADICIONAR / EDITAR */} {/* ADICIONAR / EDITAR */}
{(view === 'add' || view === 'edit') && ( {(view === 'add' || view === 'edit') && (
<div className="max-w-4xl mx-auto animate-in zoom-in-95 duration-500"> <div className="max-w-4xl mx-auto animate-in zoom-in-95 duration-500">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-start"> <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 md:gap-12 items-start">
<div className="space-y-8"> <div className="space-y-5 md:space-y-8">
<h3 className="text-5xl font-black tracking-tighter text-inherit">{editingItem ? t('edit') : t('newItem')}</h3> <h3 className="text-5xl font-black tracking-tighter text-inherit">{editingItem ? t('edit') : t('newItem')}</h3>
<Card className="aspect-[3/4] overflow-hidden shadow-2xl relative" darkMode={darkMode}> <Card className="aspect-[3/4] overflow-hidden shadow-2xl relative" darkMode={darkMode}>
{imageUrlDraft ? ( {imageUrlDraft ? (
@@ -2237,8 +2237,8 @@ export default function App() {
</Card> </Card>
</div> </div>
<Card className="p-10 shadow-2xl" darkMode={darkMode}> <Card className="p-6 md:p-10 shadow-2xl" darkMode={darkMode}>
<form onSubmit={saveItem} className="space-y-8"> <form onSubmit={saveItem} className="space-y-5 md:space-y-8">
<Input label={t('name')} name="name" defaultValue={editingItem?.name} required /> <Input label={t('name')} name="name" defaultValue={editingItem?.name} required />
<div className="space-y-2"> <div className="space-y-2">
<label className="text-[10px] font-black uppercase opacity-40 tracking-widest ml-1 text-inherit">{t('category')}</label> <label className="text-[10px] font-black uppercase opacity-40 tracking-widest ml-1 text-inherit">{t('category')}</label>
@@ -2335,7 +2335,7 @@ export default function App() {
<div className="flex gap-4 pt-6"> <div className="flex gap-4 pt-6">
<button type="button" onClick={() => { setEditingItem(null); setImageUrlDraft(''); setView('closet'); }} className="flex-1 font-black uppercase text-[10px] opacity-40 hover:opacity-100 tracking-widest transition-all text-inherit">{t('cancel')}</button> <button type="button" onClick={() => { setEditingItem(null); setImageUrlDraft(''); setView('closet'); }} className="flex-1 font-black uppercase text-[10px] opacity-40 hover:opacity-100 tracking-widest transition-all text-inherit">{t('cancel')}</button>
<button type="submit" className="flex-1 py-5 bg-primary-600 text-white rounded-[2rem] font-black uppercase tracking-widest text-[10px] shadow-2xl shadow-primary-600/40 hover:scale-[1.02] active:scale-95 transition-all"> <button type="submit" className="flex-1 py-5 bg-primary-600 text-white rounded-3xl md:rounded-[2rem] font-black uppercase tracking-widest text-[10px] shadow-2xl shadow-primary-600/40 hover:scale-[1.02] active:scale-95 transition-all">
{editingItem ? t('save') : t('register')} {editingItem ? t('save') : t('register')}
</button> </button>
</div> </div>
@@ -2347,9 +2347,9 @@ export default function App() {
{/* PERFIL */} {/* PERFIL */}
{view === 'profile' && ( {view === 'profile' && (
<div className="max-w-4xl mx-auto space-y-12 animate-in fade-in duration-700 pb-20"> <div className="max-w-4xl mx-auto space-y-5 md:space-y-8 md:space-y-12 animate-in fade-in duration-700 pb-20">
<Card className="p-10 border-primary-100 relative overflow-hidden" darkMode={darkMode}> <Card className="p-6 md:p-10 border-primary-100 relative overflow-hidden" darkMode={darkMode}>
<div className="flex items-center gap-8 relative z-10 text-inherit"> <div className="flex items-center gap-4 md:gap-8 relative z-10 text-inherit">
<div className="w-24 h-24 rounded-[2.5rem] bg-primary-600 flex items-center justify-center text-white text-4xl font-black shadow-2xl relative overflow-hidden group cursor-pointer"> <div className="w-24 h-24 rounded-[2.5rem] bg-primary-600 flex items-center justify-center text-white text-4xl font-black shadow-2xl relative overflow-hidden group cursor-pointer">
{userProfile?.avatar ? ( {userProfile?.avatar ? (
<img src={userProfile.avatar} className="w-full h-full object-cover" alt="Profile" /> <img src={userProfile.avatar} className="w-full h-full object-cover" alt="Profile" />
@@ -2383,7 +2383,7 @@ export default function App() {
</div> </div>
</Card> </Card>
<Card className="p-8" darkMode={darkMode}> <Card className="p-5 md:p-8" darkMode={darkMode}>
<h3 className="text-xl font-black mb-6 flex items-center gap-3 text-inherit"><UserCircle className="text-primary-600" /> {t('profileInfo')}</h3> <h3 className="text-xl font-black mb-6 flex items-center gap-3 text-inherit"><UserCircle className="text-primary-600" /> {t('profileInfo')}</h3>
<form key={`${userProfile?.username}-${userProfile?.fullName}-${userProfile?.dob}-${userProfile?.bio}-${userProfile?.location}`} onSubmit={saveProfile} className="space-y-6"> <form key={`${userProfile?.username}-${userProfile?.fullName}-${userProfile?.dob}-${userProfile?.bio}-${userProfile?.location}`} onSubmit={saveProfile} className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
@@ -2434,10 +2434,10 @@ export default function App() {
{/* COMUNIDADE */} {/* COMUNIDADE */}
{view === 'community' && ( {view === 'community' && (
<div className="max-w-7xl mx-auto space-y-12 animate-in fade-in duration-700 pb-20"> <div className="max-w-7xl mx-auto space-y-5 md:space-y-8 md:space-y-12 animate-in fade-in duration-700 pb-20">
{!selectedCommunityUser ? ( {!selectedCommunityUser ? (
<> <>
<div className="relative mb-8 flex gap-4"> <div className="relative mb-5 md:mb-8 flex gap-4">
<div className="relative flex-1"> <div className="relative flex-1">
<Search className="absolute left-6 top-1/2 -translate-y-1/2 opacity-40 text-inherit" size={24} /> <Search className="absolute left-6 top-1/2 -translate-y-1/2 opacity-40 text-inherit" size={24} />
<input <input
@@ -2456,7 +2456,7 @@ export default function App() {
setShowRecommended(!showRecommended); setShowRecommended(!showRecommended);
if (!showRecommended) setCommunitySearchTerm(''); if (!showRecommended) setCommunitySearchTerm('');
}} }}
className={`px-8 rounded-3xl font-black transition-all shadow-xl shadow-black/5 flex items-center justify-center gap-2 whitespace-nowrap ${showRecommended ? 'bg-primary-600 text-white' : (darkMode ? 'bg-gray-800 text-inherit hover:bg-gray-700' : 'bg-white text-inherit hover:bg-gray-50')}`} className={`px-5 md:px-8 rounded-3xl font-black transition-all shadow-xl shadow-black/5 flex items-center justify-center gap-2 whitespace-nowrap ${showRecommended ? 'bg-primary-600 text-white' : (darkMode ? 'bg-gray-800 text-inherit hover:bg-gray-700' : 'bg-white text-inherit hover:bg-gray-50')}`}
> >
<MapPin size={20} /> <MapPin size={20} />
<span className="hidden sm:inline">{t('recommended') || 'Recomendados'}</span> <span className="hidden sm:inline">{t('recommended') || 'Recomendados'}</span>
@@ -2464,7 +2464,7 @@ export default function App() {
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{communityUsers.length === 0 ? ( {communityUsers.length === 0 ? (
<div className="col-span-full text-center py-12 opacity-50 text-inherit font-black text-xl"> <div className="col-span-full text-center py-6 md:py-12 opacity-50 text-inherit font-black text-xl">
{t('noUsersFound')} {t('noUsersFound')}
</div> </div>
) : ( ) : (
@@ -2485,13 +2485,13 @@ export default function App() {
</div> </div>
</> </>
) : ( ) : (
<div className="space-y-8"> <div className="space-y-5 md:space-y-8">
<button onClick={() => { setSelectedCommunityUser(null); setShowInspectModal(false); }} className="flex items-center gap-2 opacity-60 hover:opacity-100 transition-opacity font-black text-inherit uppercase text-xs tracking-widest"> <button onClick={() => { setSelectedCommunityUser(null); setShowInspectModal(false); }} className="flex items-center gap-2 opacity-60 hover:opacity-100 transition-opacity font-black text-inherit uppercase text-xs tracking-widest">
<ChevronLeft size={16} /> Voltar <ChevronLeft size={16} /> Voltar
</button> </button>
<Card className="p-8 border-primary-100 relative overflow-hidden" darkMode={darkMode}> <Card className="p-5 md:p-8 border-primary-100 relative overflow-hidden" darkMode={darkMode}>
<div className="flex items-center gap-8 relative z-10 text-inherit"> <div className="flex items-center gap-4 md:gap-8 relative z-10 text-inherit">
<div className="w-24 h-24 rounded-[2.5rem] bg-primary-600 text-white flex items-center justify-center font-black text-4xl overflow-hidden"> <div className="w-24 h-24 rounded-[2.5rem] bg-primary-600 text-white flex items-center justify-center font-black text-4xl overflow-hidden">
{selectedCommunityUser.avatar ? <img src={selectedCommunityUser.avatar} className="w-full h-full object-cover" alt="Avatar"/> : <span>{(selectedCommunityUser.fullName?.[0] || selectedCommunityUser.username?.[0] || 'U').toUpperCase()}</span>} {selectedCommunityUser.avatar ? <img src={selectedCommunityUser.avatar} className="w-full h-full object-cover" alt="Avatar"/> : <span>{(selectedCommunityUser.fullName?.[0] || selectedCommunityUser.username?.[0] || 'U').toUpperCase()}</span>}
</div> </div>
@@ -2523,12 +2523,12 @@ export default function App() {
{showInspectModal && ( {showInspectModal && (
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowInspectModal(false)}> <div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowInspectModal(false)}>
<Card className="w-full max-w-lg p-8 animate-in zoom-in-95 relative" darkMode={darkMode} onClick={e => e.stopPropagation()}> <Card className="w-full max-w-lg p-5 md:p-8 animate-in zoom-in-95 relative" darkMode={darkMode} onClick={e => e.stopPropagation()}>
<button onClick={() => setShowInspectModal(false)} className="absolute top-6 right-6 opacity-50 hover:opacity-100 text-inherit"> <button onClick={() => setShowInspectModal(false)} className="absolute top-6 right-6 opacity-50 hover:opacity-100 text-inherit">
<X size={24} /> <X size={24} />
</button> </button>
<div className="flex items-center gap-6 mb-8 text-inherit"> <div className="flex items-center gap-6 mb-5 md:mb-8 text-inherit">
<div className="w-20 h-20 rounded-[2rem] bg-primary-600 text-white flex items-center justify-center font-black text-3xl overflow-hidden"> <div className="w-20 h-20 rounded-3xl md:rounded-[2rem] bg-primary-600 text-white flex items-center justify-center font-black text-3xl overflow-hidden">
{selectedCommunityUser.avatar ? <img src={selectedCommunityUser.avatar} className="w-full h-full object-cover" alt="Avatar"/> : <span>{(selectedCommunityUser.fullName?.[0] || selectedCommunityUser.username?.[0] || 'U').toUpperCase()}</span>} {selectedCommunityUser.avatar ? <img src={selectedCommunityUser.avatar} className="w-full h-full object-cover" alt="Avatar"/> : <span>{(selectedCommunityUser.fullName?.[0] || selectedCommunityUser.username?.[0] || 'U').toUpperCase()}</span>}
</div> </div>
<div> <div>
@@ -2575,12 +2575,12 @@ export default function App() {
{t('isPrivateUser')} {t('isPrivateUser')}
</div> </div>
) : ( ) : (
<div className="space-y-12 text-inherit"> <div className="space-y-5 md:space-y-8 md:space-y-12 text-inherit">
<div> <div>
<h3 className="text-xl font-black mb-6 uppercase tracking-widest text-[11px] opacity-50">{t('userOutfits')} ({selectedUserLooks.length})</h3> <h3 className="text-xl font-black mb-6 uppercase tracking-widest text-[11px] opacity-50">{t('userOutfits')} ({selectedUserLooks.length})</h3>
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-6"> <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-6">
{selectedUserLooks.map(look => ( {selectedUserLooks.map(look => (
<div key={look.id} className="group relative aspect-[3/4] rounded-[2rem] overflow-hidden bg-gray-100 dark:bg-gray-800 cursor-pointer shadow-lg"> <div key={look.id} className="group relative aspect-[3/4] rounded-3xl md:rounded-[2rem] overflow-hidden bg-gray-100 dark:bg-gray-800 cursor-pointer shadow-lg">
{look.items && look.items[0] && selectedUserClothes.find(c => c.id === look.items[0]) && ( {look.items && look.items[0] && selectedUserClothes.find(c => c.id === look.items[0]) && (
<img src={selectedUserClothes.find(c => c.id === look.items[0]).imageUrl} className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700" alt="Look" /> <img src={selectedUserClothes.find(c => c.id === look.items[0]).imageUrl} className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700" alt="Look" />
)} )}
@@ -2627,11 +2627,11 @@ export default function App() {
{/* DEFINIÇÕES */} {/* DEFINIÇÕES */}
{view === 'settings' && ( {view === 'settings' && (
<div className="max-w-4xl mx-auto space-y-12 animate-in fade-in duration-700 pb-20"> <div className="max-w-4xl mx-auto space-y-5 md:space-y-8 md:space-y-12 animate-in fade-in duration-700 pb-20">
{/* Preferências */} {/* Preferências */}
<div className="flex flex-col gap-8"> <div className="flex flex-col gap-4 md:gap-8">
<Card className="p-8" darkMode={darkMode}> <Card className="p-5 md:p-8" darkMode={darkMode}>
<h3 className="text-xl font-black mb-6 flex items-center gap-3 text-inherit"><Settings className="text-primary-600" /> {t('preferences')}</h3> <h3 className="text-xl font-black mb-6 flex items-center gap-3 text-inherit"><Settings className="text-primary-600" /> {t('preferences')}</h3>
<div className="space-y-6"> <div className="space-y-6">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
@@ -2770,7 +2770,7 @@ export default function App() {
</div> </div>
</Card> </Card>
<Card className="p-8" darkMode={darkMode}> <Card className="p-5 md:p-8" darkMode={darkMode}>
<h3 className="text-xl font-black mb-6 flex items-center gap-3 text-inherit"><Bell className="text-primary-600" /> {t('feedbackTitle') || 'Suporte e Feedback'}</h3> <h3 className="text-xl font-black mb-6 flex items-center gap-3 text-inherit"><Bell className="text-primary-600" /> {t('feedbackTitle') || 'Suporte e Feedback'}</h3>
<p className="opacity-60 text-sm font-medium mb-6">{t('feedbackDesc') || 'Tem alguma ideia, sugestão ou encontrou algum problema? Envie uma mensagem diretamente para nós!'}</p> <p className="opacity-60 text-sm font-medium mb-6">{t('feedbackDesc') || 'Tem alguma ideia, sugestão ou encontrou algum problema? Envie uma mensagem diretamente para nós!'}</p>
<form onSubmit={async (e) => { <form onSubmit={async (e) => {
@@ -2849,13 +2849,13 @@ export default function App() {
</div> </div>
</div> </div>
<Card className="p-10 border-red-200 bg-red-50/10" darkMode={darkMode}> <Card className="p-6 md:p-10 border-red-200 bg-red-50/10" darkMode={darkMode}>
<div className="flex flex-col md:flex-row items-center justify-between gap-8"> <div className="flex flex-col md:flex-row items-center justify-between gap-4 md:gap-8">
<div className="text-inherit"> <div className="text-inherit">
<h4 className="text-xl font-black text-red-700 flex items-center gap-3"><ShieldAlert /> {t('criticalZone')}</h4> <h4 className="text-xl font-black text-red-700 flex items-center gap-3"><ShieldAlert /> {t('criticalZone')}</h4>
<p className="opacity-60 font-bold text-sm mt-2">{t('fullCleanActions')}</p> <p className="opacity-60 font-bold text-sm mt-2">{t('fullCleanActions')}</p>
</div> </div>
<button onClick={clearAllToTrash} className="px-8 py-4 bg-red-600 text-white rounded-2xl font-black uppercase text-[10px] tracking-widest hover:bg-red-700 transition-all">{t('clearAll')}</button> <button onClick={clearAllToTrash} className="px-5 md:px-8 py-4 bg-red-600 text-white rounded-2xl font-black uppercase text-[10px] tracking-widest hover:bg-red-700 transition-all">{t('clearAll')}</button>
</div> </div>
</Card> </Card>
</div> </div>
@@ -2867,7 +2867,7 @@ export default function App() {
{/* Modal do Planeador - Escolher Outfit */} {/* Modal do Planeador - Escolher Outfit */}
{showPlannerPicker && plannerPickerDate && ( {showPlannerPicker && plannerPickerDate && (
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowPlannerPicker(false)}> <div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowPlannerPicker(false)}>
<Card className="w-full max-w-lg p-8 animate-in zoom-in-95 flex flex-col max-h-[80vh]" darkMode={darkMode} onClick={e => e.stopPropagation()}> <Card className="w-full max-w-lg p-5 md:p-8 animate-in zoom-in-95 flex flex-col max-h-[80vh]" darkMode={darkMode} onClick={e => e.stopPropagation()}>
<div className="flex items-center justify-between mb-6"> <div className="flex items-center justify-between mb-6">
<div> <div>
<h3 className="text-xl font-black text-inherit flex items-center gap-3"> <h3 className="text-xl font-black text-inherit flex items-center gap-3">
@@ -2891,7 +2891,7 @@ export default function App() {
<div className="flex-1 overflow-y-auto space-y-3 custom-scrollbar"> <div className="flex-1 overflow-y-auto space-y-3 custom-scrollbar">
{looks.length === 0 ? ( {looks.length === 0 ? (
<div className="py-12 text-center opacity-30 font-black uppercase tracking-[0.3em] text-sm">{t('noOutfitCreated')}</div> <div className="py-6 md:py-12 text-center opacity-30 font-black uppercase tracking-[0.3em] text-sm">{t('noOutfitCreated')}</div>
) : looks.map(look => { ) : looks.map(look => {
const plan = outfitPlans.find(p => p.date === plannerPickerDate); const plan = outfitPlans.find(p => p.date === plannerPickerDate);
const selectedIds = plan ? (plan.lookIds || (plan.lookId ? [plan.lookId] : [])) : []; const selectedIds = plan ? (plan.lookIds || (plan.lookId ? [plan.lookId] : [])) : [];
@@ -2938,7 +2938,7 @@ export default function App() {
{/* Modal de Notificações */} {/* Modal de Notificações */}
{showNotificationsModal && ( {showNotificationsModal && (
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowNotificationsModal(false)}> <div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowNotificationsModal(false)}>
<Card className="w-full max-w-md p-8 animate-in zoom-in-95 flex flex-col max-h-[80vh]" darkMode={darkMode} onClick={e => e.stopPropagation()}> <Card className="w-full max-w-md p-5 md:p-8 animate-in zoom-in-95 flex flex-col max-h-[80vh]" darkMode={darkMode} onClick={e => e.stopPropagation()}>
{/* Header */} {/* Header */}
<div className="flex items-center justify-between mb-6"> <div className="flex items-center justify-between mb-6">
<div> <div>
@@ -2974,7 +2974,7 @@ export default function App() {
{/* Lista */} {/* Lista */}
<div className="flex-1 overflow-y-auto space-y-3 custom-scrollbar"> <div className="flex-1 overflow-y-auto space-y-3 custom-scrollbar">
{notifications.length === 0 ? ( {notifications.length === 0 ? (
<div className="py-16 text-center flex flex-col items-center gap-4 opacity-30"> <div className="py-8 md:py-16 text-center flex flex-col items-center gap-4 opacity-30">
<Bell size={40} /> <Bell size={40} />
<span className="font-black uppercase tracking-[0.3em] text-sm">{t('noNotifications')}</span> <span className="font-black uppercase tracking-[0.3em] text-sm">{t('noNotifications')}</span>
</div> </div>
@@ -3035,8 +3035,8 @@ export default function App() {
{/* Modal de Gestão de Secções */} {/* Modal de Gestão de Secções */}
{showSectionManager && ( {showSectionManager && (
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowSectionManager(false)}> <div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowSectionManager(false)}>
<Card className="w-full max-w-lg p-8 animate-in zoom-in-95 flex flex-col max-h-[90vh]" darkMode={darkMode} onClick={e => e.stopPropagation()}> <Card className="w-full max-w-lg p-5 md:p-8 animate-in zoom-in-95 flex flex-col max-h-[90vh]" darkMode={darkMode} onClick={e => e.stopPropagation()}>
<div className="flex items-center justify-between mb-8"> <div className="flex items-center justify-between mb-5 md:mb-8">
<h3 className="text-2xl font-black text-inherit flex items-center gap-3"> <h3 className="text-2xl font-black text-inherit flex items-center gap-3">
<FolderOpen size={24} className="text-primary-600" /> {t('manageSections')} <FolderOpen size={24} className="text-primary-600" /> {t('manageSections')}
</h3> </h3>
@@ -3044,7 +3044,7 @@ export default function App() {
</div> </div>
{/* Criar nova secção */} {/* Criar nova secção */}
<div className={`flex gap-3 mb-8 p-4 rounded-2xl ${darkMode ? 'bg-gray-800' : 'bg-gray-50'}`}> <div className={`flex gap-3 mb-5 md:mb-8 p-4 rounded-2xl ${darkMode ? 'bg-gray-800' : 'bg-gray-50'}`}>
<input <input
value={newSectionName} value={newSectionName}
onChange={e => setNewSectionName(e.target.value)} onChange={e => setNewSectionName(e.target.value)}
@@ -3064,7 +3064,7 @@ export default function App() {
{/* Lista de secções */} {/* Lista de secções */}
<div className="flex-1 overflow-y-auto space-y-3 custom-scrollbar"> <div className="flex-1 overflow-y-auto space-y-3 custom-scrollbar">
{sections.length === 0 ? ( {sections.length === 0 ? (
<div className="py-12 text-center opacity-30 font-black uppercase tracking-[0.3em] text-sm">{t('noSections')}</div> <div className="py-6 md:py-12 text-center opacity-30 font-black uppercase tracking-[0.3em] text-sm">{t('noSections')}</div>
) : sections.map(sec => ( ) : sections.map(sec => (
<div key={sec.id} className={`flex items-center gap-4 p-4 rounded-2xl transition-all ${darkMode ? 'bg-gray-800' : 'bg-gray-50'}`}> <div key={sec.id} className={`flex items-center gap-4 p-4 rounded-2xl transition-all ${darkMode ? 'bg-gray-800' : 'bg-gray-50'}`}>
{editingSectionId === sec.id ? ( {editingSectionId === sec.id ? (
@@ -3108,7 +3108,7 @@ export default function App() {
))} ))}
</div> </div>
<button onClick={() => setShowSectionManager(false)} className="mt-8 w-full py-4 font-black uppercase text-[10px] tracking-widest text-gray-500 hover:text-gray-900 dark:hover:text-white transition-colors"> <button onClick={() => setShowSectionManager(false)} className="mt-5 md:mt-8 w-full py-4 font-black uppercase text-[10px] tracking-widest text-gray-500 hover:text-gray-900 dark:hover:text-white transition-colors">
{t('cancel')} {t('cancel')}
</button> </button>
</Card> </Card>
@@ -3118,13 +3118,13 @@ export default function App() {
{/* Modal de Filtros Avançados */} {/* Modal de Filtros Avançados */}
{showClosetFilters && ( {showClosetFilters && (
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowClosetFilters(false)}> <div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowClosetFilters(false)}>
<Card className="w-full max-w-lg p-8 animate-in zoom-in-95 flex flex-col max-h-[90vh]" darkMode={darkMode} onClick={e => e.stopPropagation()}> <Card className="w-full max-w-lg p-5 md:p-8 animate-in zoom-in-95 flex flex-col max-h-[90vh]" darkMode={darkMode} onClick={e => e.stopPropagation()}>
<div className="flex items-center justify-between mb-8"> <div className="flex items-center justify-between mb-5 md:mb-8">
<h3 className="text-2xl font-black text-inherit flex items-center gap-3"><Filter size={24} className="text-primary-600" /> {t('advancedFilters')}</h3> <h3 className="text-2xl font-black text-inherit flex items-center gap-3"><Filter size={24} className="text-primary-600" /> {t('advancedFilters')}</h3>
<button onClick={() => setShowClosetFilters(false)} className="p-2 bg-gray-100 dark:bg-gray-800 rounded-full hover:scale-110 transition-all text-inherit"><X size={20} /></button> <button onClick={() => setShowClosetFilters(false)} className="p-2 bg-gray-100 dark:bg-gray-800 rounded-full hover:scale-110 transition-all text-inherit"><X size={20} /></button>
</div> </div>
<div className="flex-1 overflow-y-auto space-y-8 pr-2 custom-scrollbar"> <div className="flex-1 overflow-y-auto space-y-5 md:space-y-8 pr-2 custom-scrollbar">
<div className="space-y-4"> <div className="space-y-4">
<label className="text-[10px] font-black uppercase opacity-40 tracking-widest ml-1 text-inherit">{t('closet')}</label> <label className="text-[10px] font-black uppercase opacity-40 tracking-widest ml-1 text-inherit">{t('closet')}</label>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
@@ -3167,7 +3167,7 @@ export default function App() {
</div> </div>
</div> </div>
<div className="pt-8 flex gap-4 border-t mt-8 border-gray-100 dark:border-gray-800"> <div className="pt-8 flex gap-4 border-t mt-5 md:mt-8 border-gray-100 dark:border-gray-800">
<button onClick={() => { setCategoryFilter('Todos'); setColorFilter(''); setAgeFilter('any'); setFavoriteFilter(false); }} className="flex-1 py-4 font-black uppercase text-[10px] tracking-widest text-gray-500 hover:text-gray-900 dark:hover:text-white transition-colors">{t('clearAll')}</button> <button onClick={() => { setCategoryFilter('Todos'); setColorFilter(''); setAgeFilter('any'); setFavoriteFilter(false); }} className="flex-1 py-4 font-black uppercase text-[10px] tracking-widest text-gray-500 hover:text-gray-900 dark:hover:text-white transition-colors">{t('clearAll')}</button>
<button onClick={() => setShowClosetFilters(false)} className="flex-1 py-4 bg-primary-600 text-white rounded-2xl font-black uppercase text-[10px] tracking-widest shadow-xl shadow-primary-600/30 hover:scale-105 transition-all">{t('applyFilters')}</button> <button onClick={() => setShowClosetFilters(false)} className="flex-1 py-4 bg-primary-600 text-white rounded-2xl font-black uppercase text-[10px] tracking-widest shadow-xl shadow-primary-600/30 hover:scale-105 transition-all">{t('applyFilters')}</button>
</div> </div>
@@ -3178,8 +3178,8 @@ export default function App() {
{/* Modal de Idioma */} {/* Modal de Idioma */}
{showLangModal && ( {showLangModal && (
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowLangModal(false)}> <div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-sm p-6" onClick={() => setShowLangModal(false)}>
<Card className="w-full max-w-lg p-8 animate-in zoom-in-95" darkMode={darkMode} onClick={e => e.stopPropagation()}> <Card className="w-full max-w-lg p-5 md:p-8 animate-in zoom-in-95" darkMode={darkMode} onClick={e => e.stopPropagation()}>
<h3 className="text-2xl font-black mb-8 text-center text-inherit">{t('appLanguage')}</h3> <h3 className="text-2xl font-black mb-5 md:mb-8 text-center text-inherit">{t('appLanguage')}</h3>
<div className="grid grid-cols-2 md:grid-cols-3 gap-4"> <div className="grid grid-cols-2 md:grid-cols-3 gap-4">
{[ {[
{ id: 'PT', flag: '🇵🇹', label: t('portuguese') }, { id: 'PT', flag: '🇵🇹', label: t('portuguese') },
@@ -3198,7 +3198,7 @@ export default function App() {
</button> </button>
))} ))}
</div> </div>
<button onClick={() => setShowLangModal(false)} className="w-full mt-8 py-4 uppercase font-black text-[10px] tracking-widest text-gray-500 hover:text-gray-900 dark:hover:text-white transition-colors"> <button onClick={() => setShowLangModal(false)} className="w-full mt-5 md:mt-8 py-4 uppercase font-black text-[10px] tracking-widest text-gray-500 hover:text-gray-900 dark:hover:text-white transition-colors">
{t('cancel')} {t('cancel')}
</button> </button>
</Card> </Card>
@@ -3209,11 +3209,11 @@ export default function App() {
{showSharedLookModal && sharedLookData && ( {showSharedLookModal && sharedLookData && (
<div className="fixed inset-0 z-[300] flex items-center justify-center bg-black/70 backdrop-blur-md p-6" onClick={() => { setShowSharedLookModal(false); setSharedLookData(null); }}> <div className="fixed inset-0 z-[300] flex items-center justify-center bg-black/70 backdrop-blur-md p-6" onClick={() => { setShowSharedLookModal(false); setSharedLookData(null); }}>
<div <div
className={`w-full max-w-lg rounded-[2rem] shadow-2xl overflow-hidden animate-in zoom-in-95 duration-300 ${darkMode ? 'bg-gray-900' : 'bg-white'}`} className={`w-full max-w-lg rounded-3xl md:rounded-[2rem] shadow-2xl overflow-hidden animate-in zoom-in-95 duration-300 ${darkMode ? 'bg-gray-900' : 'bg-white'}`}
onClick={e => e.stopPropagation()} onClick={e => e.stopPropagation()}
> >
{/* Header com gradiente */} {/* Header com gradiente */}
<div className="relative p-8 pb-6" style={{ background: 'linear-gradient(135deg, hsl(var(--primary-600)), hsl(var(--primary-400)))' }}> <div className="relative p-5 md:p-8 pb-6" style={{ background: 'linear-gradient(135deg, hsl(var(--primary-600)), hsl(var(--primary-400)))' }}>
<div className="absolute inset-0 opacity-20" style={{ backgroundImage: 'radial-gradient(circle at 80% 20%, white 0%, transparent 60%)' }} /> <div className="absolute inset-0 opacity-20" style={{ backgroundImage: 'radial-gradient(circle at 80% 20%, white 0%, transparent 60%)' }} />
<div className="relative z-10"> <div className="relative z-10">
<div className="flex items-center gap-3 mb-2"> <div className="flex items-center gap-3 mb-2">
@@ -3228,9 +3228,9 @@ export default function App() {
</div> </div>
{/* Peças do look */} {/* Peças do look */}
<div className={`p-8 ${darkMode ? 'bg-gray-900' : 'bg-white'}`}> <div className={`p-5 md:p-8 ${darkMode ? 'bg-gray-900' : 'bg-white'}`}>
<p className="text-[10px] font-black uppercase tracking-widest opacity-40 mb-4">{t('includedPieces')}</p> <p className="text-[10px] font-black uppercase tracking-widest opacity-40 mb-4">{t('includedPieces')}</p>
<div className="flex flex-wrap gap-3 mb-8"> <div className="flex flex-wrap gap-3 mb-5 md:mb-8">
{sharedLookData.items.map((item, idx) => ( {sharedLookData.items.map((item, idx) => (
<div key={idx} className="relative group/item"> <div key={idx} className="relative group/item">
<div className="w-20 h-20 rounded-2xl overflow-hidden border-2 border-gray-100 dark:border-gray-700 shadow-lg"> <div className="w-20 h-20 rounded-2xl overflow-hidden border-2 border-gray-100 dark:border-gray-700 shadow-lg">
@@ -3244,7 +3244,7 @@ export default function App() {
</div> </div>
{/* Descrição das peças */} {/* Descrição das peças */}
<div className={`space-y-2 mb-8 max-h-32 overflow-y-auto custom-scrollbar`}> <div className={`space-y-2 mb-5 md:mb-8 max-h-32 overflow-y-auto custom-scrollbar`}>
{sharedLookData.items.map((item, idx) => ( {sharedLookData.items.map((item, idx) => (
<div key={idx} className={`flex items-center gap-3 px-4 py-2.5 rounded-xl ${darkMode ? 'bg-gray-800' : 'bg-gray-50'}`}> <div key={idx} className={`flex items-center gap-3 px-4 py-2.5 rounded-xl ${darkMode ? 'bg-gray-800' : 'bg-gray-50'}`}>
<span className="text-xs font-black truncate flex-1">{item.name}</span> <span className="text-xs font-black truncate flex-1">{item.name}</span>
@@ -3282,10 +3282,10 @@ export default function App() {
{showDailyOutfitModal && ( {showDailyOutfitModal && (
<div className="fixed inset-0 z-[300] flex items-center justify-center bg-black/70 backdrop-blur-md p-6" onClick={() => setShowDailyOutfitModal(false)}> <div className="fixed inset-0 z-[300] flex items-center justify-center bg-black/70 backdrop-blur-md p-6" onClick={() => setShowDailyOutfitModal(false)}>
<div <div
className={`w-full max-w-lg rounded-[2rem] shadow-2xl overflow-hidden animate-in zoom-in-95 duration-300 ${darkMode ? 'bg-gray-900' : 'bg-white'}`} className={`w-full max-w-lg rounded-3xl md:rounded-[2rem] shadow-2xl overflow-hidden animate-in zoom-in-95 duration-300 ${darkMode ? 'bg-gray-900' : 'bg-white'}`}
onClick={e => e.stopPropagation()} onClick={e => e.stopPropagation()}
> >
<div className="relative p-8 pb-6 bg-gradient-to-br from-primary-600 to-primary-400"> <div className="relative p-5 md:p-8 pb-6 bg-gradient-to-br from-primary-600 to-primary-400">
<div className="absolute inset-0 opacity-20" style={{ backgroundImage: 'radial-gradient(circle at 80% 20%, white 0%, transparent 60%)' }} /> <div className="absolute inset-0 opacity-20" style={{ backgroundImage: 'radial-gradient(circle at 80% 20%, white 0%, transparent 60%)' }} />
<div className="relative z-10"> <div className="relative z-10">
<div className="flex items-center gap-3 mb-2"> <div className="flex items-center gap-3 mb-2">
@@ -3298,7 +3298,7 @@ export default function App() {
</div> </div>
</div> </div>
<div className={`p-8 ${darkMode ? 'bg-gray-900' : 'bg-white'} max-h-[60vh] overflow-y-auto custom-scrollbar`}> <div className={`p-5 md:p-8 ${darkMode ? 'bg-gray-900' : 'bg-white'} max-h-[60vh] overflow-y-auto custom-scrollbar`}>
{dailyLooks.length > 0 ? ( {dailyLooks.length > 0 ? (
<div className="space-y-6"> <div className="space-y-6">
{dailyLooks.map(look => ( {dailyLooks.map(look => (
@@ -3321,7 +3321,7 @@ export default function App() {
))} ))}
</div> </div>
) : ( ) : (
<div className="py-12 flex flex-col items-center justify-center text-center opacity-50"> <div className="py-6 md:py-12 flex flex-col items-center justify-center text-center opacity-50">
<Shirt size={48} className="mb-4 text-gray-400" /> <Shirt size={48} className="mb-4 text-gray-400" />
<p className="font-black text-lg text-inherit">{t('noOutfitPlanned')}</p> <p className="font-black text-lg text-inherit">{t('noOutfitPlanned')}</p>
<p className="text-xs mt-2 uppercase tracking-widest">{t('goToPlanning')}</p> <p className="text-xs mt-2 uppercase tracking-widest">{t('goToPlanning')}</p>
@@ -3342,10 +3342,10 @@ export default function App() {
{inspectingCommunityLook && ( {inspectingCommunityLook && (
<div className="fixed inset-0 z-[300] flex items-center justify-center bg-black/70 backdrop-blur-md p-6" onClick={() => setInspectingCommunityLook(null)}> <div className="fixed inset-0 z-[300] flex items-center justify-center bg-black/70 backdrop-blur-md p-6" onClick={() => setInspectingCommunityLook(null)}>
<div <div
className={`w-full max-w-lg rounded-[2rem] shadow-2xl overflow-hidden animate-in zoom-in-95 duration-300 ${darkMode ? 'bg-gray-900' : 'bg-white'}`} className={`w-full max-w-lg rounded-3xl md:rounded-[2rem] shadow-2xl overflow-hidden animate-in zoom-in-95 duration-300 ${darkMode ? 'bg-gray-900' : 'bg-white'}`}
onClick={e => e.stopPropagation()} onClick={e => e.stopPropagation()}
> >
<div className="relative p-8 pb-6" style={{ background: 'linear-gradient(135deg, hsl(var(--primary-600)), hsl(var(--primary-400)))' }}> <div className="relative p-5 md:p-8 pb-6" style={{ background: 'linear-gradient(135deg, hsl(var(--primary-600)), hsl(var(--primary-400)))' }}>
<div className="absolute inset-0 opacity-20" style={{ backgroundImage: 'radial-gradient(circle at 80% 20%, white 0%, transparent 60%)' }} /> <div className="absolute inset-0 opacity-20" style={{ backgroundImage: 'radial-gradient(circle at 80% 20%, white 0%, transparent 60%)' }} />
<div className="relative z-10"> <div className="relative z-10">
<div className="flex items-center justify-between mb-2"> <div className="flex items-center justify-between mb-2">
@@ -3364,9 +3364,9 @@ export default function App() {
</div> </div>
</div> </div>
<div className={`p-8 ${darkMode ? 'bg-gray-900' : 'bg-white'}`}> <div className={`p-5 md:p-8 ${darkMode ? 'bg-gray-900' : 'bg-white'}`}>
<p className="text-[10px] font-black uppercase tracking-widest opacity-40 mb-4">{t('includedPieces') || 'Peças incluídas'}</p> <p className="text-[10px] font-black uppercase tracking-widest opacity-40 mb-4">{t('includedPieces') || 'Peças incluídas'}</p>
<div className="flex flex-wrap gap-3 mb-8"> <div className="flex flex-wrap gap-3 mb-5 md:mb-8">
{(inspectingCommunityLook.items || []).map((itemId, idx) => { {(inspectingCommunityLook.items || []).map((itemId, idx) => {
const item = selectedUserClothes.find(c => c.id === itemId); const item = selectedUserClothes.find(c => c.id === itemId);
if (!item) return null; if (!item) return null;
@@ -3383,7 +3383,7 @@ export default function App() {
})} })}
</div> </div>
<div className={`space-y-2 mb-8 max-h-32 overflow-y-auto custom-scrollbar`}> <div className={`space-y-2 mb-5 md:mb-8 max-h-32 overflow-y-auto custom-scrollbar`}>
{(inspectingCommunityLook.items || []).map((itemId, idx) => { {(inspectingCommunityLook.items || []).map((itemId, idx) => {
const item = selectedUserClothes.find(c => c.id === itemId); const item = selectedUserClothes.find(c => c.id === itemId);
if (!item) return null; if (!item) return null;
@@ -3411,7 +3411,7 @@ export default function App() {
{inspectingCommunityItem && ( {inspectingCommunityItem && (
<div className="fixed inset-0 z-[300] flex items-center justify-center bg-black/70 backdrop-blur-md p-6" onClick={() => setInspectingCommunityItem(null)}> <div className="fixed inset-0 z-[300] flex items-center justify-center bg-black/70 backdrop-blur-md p-6" onClick={() => setInspectingCommunityItem(null)}>
<div <div
className={`w-full max-w-sm rounded-[2rem] shadow-2xl overflow-hidden animate-in zoom-in-95 duration-300 ${darkMode ? 'bg-gray-900' : 'bg-white'}`} className={`w-full max-w-sm rounded-3xl md:rounded-[2rem] shadow-2xl overflow-hidden animate-in zoom-in-95 duration-300 ${darkMode ? 'bg-gray-900' : 'bg-white'}`}
onClick={e => e.stopPropagation()} onClick={e => e.stopPropagation()}
> >
<div className="relative aspect-square"> <div className="relative aspect-square">
@@ -3420,7 +3420,7 @@ export default function App() {
<X size={20} /> <X size={20} />
</button> </button>
</div> </div>
<div className="p-8 text-center space-y-4"> <div className="p-5 md:p-8 text-center space-y-4">
<h3 className="text-2xl font-black text-inherit">{inspectingCommunityItem.name}</h3> <h3 className="text-2xl font-black text-inherit">{inspectingCommunityItem.name}</h3>
<div className="flex items-center justify-center gap-2 opacity-60 font-bold uppercase tracking-widest text-[10px] text-inherit"> <div className="flex items-center justify-center gap-2 opacity-60 font-bold uppercase tracking-widest text-[10px] text-inherit">
<span>{inspectingCommunityItem.category}</span> <span>{inspectingCommunityItem.category}</span>