changes: Improve UX to fit mobile screen

This commit is contained in:
2025-10-08 23:27:54 -06:00
parent c694c15dad
commit d439640635
5 changed files with 199 additions and 112 deletions

View File

@@ -96,4 +96,48 @@
body {
@apply bg-background text-foreground;
}
/* Mobile UX Optimizations - Prevent Zoom & Unwanted Gestures */
html {
-webkit-text-size-adjust: 100%; /* Prevent font scaling in landscape */
-webkit-tap-highlight-color: transparent; /* Remove tap highlight on iOS */
touch-action: pan-y manipulation; /* Allow vertical scroll, prevent zoom gestures */
/* Use dynamic viewport height for Chrome mobile address bar */
height: 100%;
}
html, body {
/* Support for dvh (dynamic viewport height) - adjusts with Chrome address bar */
min-height: 100dvh;
}
body {
overscroll-behavior: none; /* Prevent pull-to-refresh */
-webkit-user-select: none; /* Prevent text selection on iOS */
user-select: none; /* Prevent text selection */
-webkit-touch-callout: none; /* Disable iOS callout menu */
}
/* Allow text selection only where needed */
input, textarea, [contenteditable] {
-webkit-user-select: text;
user-select: text;
}
/* Prevent double-tap zoom on buttons and interactive elements */
button, a, [role="button"] {
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
}
/* Safe Area Support for iOS Notch/Dynamic Island */
@supports (padding: env(safe-area-inset-top)) {
body {
padding-top: env(safe-area-inset-top);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
/* Don't add bottom padding - causes gap in Chrome Android */
/* Each component handles its own bottom safe area */
}
}
}

View File

@@ -13,8 +13,22 @@ const geistMono = Geist_Mono({
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
title: "Smart Store Assistant - Scan",
description: "Detector inteligente de calzado con IA avanzada",
viewport: {
width: 'device-width',
initialScale: 1,
maximumScale: 1,
userScalable: false,
viewportFit: 'cover', // Safe area support for iOS notch
},
themeColor: '#000000',
appleWebApp: {
capable: true,
statusBarStyle: 'black-translucent',
title: 'SSA Scan',
},
manifest: '/manifest.json',
};
export default function RootLayout({
@@ -23,9 +37,9 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
<html lang="en" className="dark">
<html lang="es" className="dark">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
className={`${geistSans.variable} ${geistMono.variable} antialiased select-none overscroll-none`}
>
{children}
</body>

View File

@@ -371,18 +371,26 @@ function HomePageContent() {
case 'active':
return (
<>
<video ref={videoRef} autoPlay playsInline muted onCanPlay={() => videoRef.current?.play()} className="h-full w-full object-cover" />
<video ref={videoRef} autoPlay playsInline muted onCanPlay={() => videoRef.current?.play()} className="h-full w-full object-cover sm:object-contain" />
{/* Impuls Logo - Top Left */}
<div className="absolute top-3 left-6 z-10 pointer-events-none">
<img
src="/Impuls Logo.png"
alt="Impuls Logo"
className="h-12 w-auto opacity-80"
<div className="absolute top-3 left-4 sm:left-6 z-10 pointer-events-none">
<img
src="/Impuls Logo.png"
alt="Impuls Logo"
className="h-10 sm:h-12 w-auto opacity-80"
style={{ filter: 'brightness(0) invert(1)' }}
/>
</div>
{/* Version Badge - Top Right (for symmetry) */}
<div className="absolute top-3 right-4 sm:right-6 z-10 pointer-events-none">
<div className="bg-white/10 backdrop-blur-md border border-white/20 rounded-full px-3 py-1.5 flex items-center gap-2">
<div className="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
<span className="text-white/80 text-xs font-medium">v0.0.3</span>
</div>
</div>
{/* Simple Camera Frame Overlay - Like Reference Image */}
<div className="absolute inset-0 pointer-events-none">
{/* Simple Corner Frames */}
@@ -441,39 +449,49 @@ function HomePageContent() {
`}</style>
</div>
{/* Scanning Indicator */}
{/* Scanning Indicator - Responsive with safe area */}
{isScanning && (
<div className="absolute top-4 right-4 bg-blue-600/80 backdrop-blur-sm rounded-lg px-4 py-2 text-white text-sm font-medium animate-pulse">
📸 Identificando...
<div className="absolute top-3 sm:top-4 left-1/2 transform -translate-x-1/2 bg-blue-600/90 backdrop-blur-md rounded-lg px-4 py-2 text-white text-xs sm:text-sm font-medium animate-pulse shadow-lg z-20"
style={{ marginTop: 'max(0.75rem, env(safe-area-inset-top))' }}>
<div className="flex items-center gap-2">
<div className="w-2 h-2 bg-white rounded-full animate-ping"></div>
<span>Identificando...</span>
</div>
</div>
)}
{/* Not Found Message */}
{/* Not Found Message - Responsive with safe area */}
{notFoundMessage && (
<div className="absolute top-4 left-1/2 transform -translate-x-1/2 bg-red-600/90 backdrop-blur-sm rounded-lg px-6 py-3 text-white font-medium shadow-lg animate-in fade-in slide-in-from-top-4 duration-300">
<div className="absolute top-3 sm:top-4 left-1/2 transform -translate-x-1/2 bg-red-600/90 backdrop-blur-md rounded-lg px-4 sm:px-6 py-2 sm:py-3 text-white font-medium shadow-lg animate-in fade-in slide-in-from-top-4 duration-300 z-20 max-w-[90vw]"
style={{ marginTop: 'max(0.75rem, env(safe-area-inset-top))' }}>
<div className="flex items-center gap-2">
<span className="text-xl"></span>
<span>Zapato no encontrado</span>
<span className="text-lg sm:text-xl"></span>
<span className="text-xs sm:text-base">Zapato no encontrado</span>
</div>
</div>
)}
{/* Settings Panel */}
<div className={`absolute left-0 top-0 bottom-0 w-80 bg-black/80 backdrop-blur-xl border-r border-white/20 transform transition-transform duration-500 ease-out z-40 ${
{/* Settings Panel - Responsive width with safe areas */}
<div className={`absolute left-0 top-0 bottom-0 w-full max-w-xs sm:max-w-sm bg-black/80 backdrop-blur-xl border-r border-white/20 transform transition-transform duration-500 ease-out z-40 ${
isSettingsPanelOpen ? 'translate-x-0' : '-translate-x-full'
}`}>
<div className="p-6 h-full flex flex-col">
{/* Panel Header */}
<div className="flex items-center justify-between mb-6">
<h2 className="text-xl font-bold text-white flex items-center gap-2">
<Settings size={24} className="text-blue-400" />
Configuración
<div className="p-4 sm:p-6 h-full flex flex-col"
style={{
paddingTop: 'max(1rem, env(safe-area-inset-top))',
paddingBottom: 'max(1rem, env(safe-area-inset-bottom))'
}}>
{/* Panel Header - Responsive */}
<div className="flex items-center justify-between mb-4 sm:mb-6">
<h2 className="text-lg sm:text-xl font-bold text-white flex items-center gap-2">
<Settings size={20} className="sm:w-6 sm:h-6 text-blue-400" />
<span className="truncate">Configuración</span>
</h2>
<button
onClick={() => setSettingsPanelOpen(false)}
className="text-white/60 hover:text-white transition-colors p-1"
className="text-white/60 active:text-white transition-colors p-2 min-w-[44px] min-h-[44px] flex items-center justify-center"
aria-label="Cerrar configuración"
>
<X size={20} />
</button>
</div>
@@ -520,86 +538,80 @@ function HomePageContent() {
</div>
</div>
{/* Modern Glassmorphism Dock at Bottom */}
<div className={`absolute bottom-6 left-1/2 transform -translate-x-1/2 z-50 transition-all duration-300 ${
{/* Modern Glassmorphism Dock at Bottom - Always 3 buttons for symmetry */}
<div className={`absolute left-1/2 transform -translate-x-1/2 z-50 transition-all duration-300 ${
isPopupOpen || isHistoryOpen || isSettingsPanelOpen ? 'opacity-0 translate-y-4 pointer-events-none' : 'opacity-100 translate-y-0'
}`}>
}`}
style={{
bottom: 'max(0.75rem, env(safe-area-inset-bottom, 0.75rem))'
}}>
<div className="relative">
{/* Dock Container */}
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-3xl px-8 py-4 shadow-2xl">
<div className="flex items-center space-x-6">
{/* Dock Container - Responsive padding */}
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-3xl px-4 sm:px-8 py-3 sm:py-4 shadow-2xl">
<div className="flex items-center gap-4 sm:gap-6">
{/* Settings Button */}
{/* Settings Button - Touch optimized (min 44px) */}
<button
onClick={() => setSettingsPanelOpen(!isSettingsPanelOpen)}
className='group relative'
className='group relative min-w-[44px] min-h-[44px]'
aria-label="Ajustes"
>
<div className="w-12 h-12 bg-gradient-to-br from-blue-500/30 to-purple-500/30 rounded-full flex items-center justify-center border border-white/30 hover:from-blue-500/50 hover:to-purple-500/50 transition-all duration-300 transform hover:scale-110 hover:rotate-12">
<Settings size={20} className="text-white drop-shadow-sm" />
<div className="w-11 h-11 sm:w-12 sm:h-12 bg-gradient-to-br from-blue-500/30 to-purple-500/30 rounded-full flex items-center justify-center border border-white/30 active:from-blue-500/60 active:to-purple-500/60 transition-all duration-200 active:scale-95">
<Settings size={18} className="sm:w-5 sm:h-5 text-white drop-shadow-sm" />
</div>
<div className="absolute -top-10 left-1/2 transform -translate-x-1/2 bg-black/80 text-white text-xs px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition-opacity duration-200">
Ajustes
</div>
{/* Glow Effect */}
<div className="absolute inset-0 bg-gradient-to-br from-blue-500/20 to-purple-500/20 rounded-full blur opacity-0 group-hover:opacity-100 transition-opacity duration-300 transform scale-150"></div>
{/* Glow Effect on active */}
<div className="absolute inset-0 bg-gradient-to-br from-blue-500/20 to-purple-500/20 rounded-full blur opacity-0 group-active:opacity-100 transition-opacity duration-200"></div>
</button>
{/* Main Capture Button - Larger */}
<button
onClick={handleScan}
disabled={isScanning}
className='group relative'
>
<div className={`w-16 h-16 bg-gradient-to-br rounded-full flex items-center justify-center border-2 border-white/40 transition-all duration-300 shadow-2xl ${
isScanning
? 'from-blue-500/40 to-purple-500/40 animate-pulse cursor-not-allowed'
: 'from-red-500/40 to-pink-500/40 hover:from-red-500/60 hover:to-pink-500/60 transform hover:scale-110'
}`}>
<div className="w-12 h-12 bg-white/20 rounded-full flex items-center justify-center">
<Camera size={28} className="text-white drop-shadow-lg" />
</div>
</div>
<div className="absolute -top-12 left-1/2 transform -translate-x-1/2 bg-black/80 text-white text-xs px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">
{isScanning ? 'Analizando...' : 'Detectar Zapato'}
</div>
{/* Pulsing Ring - solo cuando NO está escaneando */}
{!isScanning && (
<div className="absolute inset-0 rounded-full border-2 border-red-400/50 animate-ping"></div>
)}
{/* Glow Effect */}
<div className="absolute inset-0 bg-gradient-to-br from-red-500/30 to-pink-500/30 rounded-full blur opacity-0 group-hover:opacity-100 transition-opacity duration-300 transform scale-150"></div>
</button>
{/* Cancel Button - solo visible cuando está escaneando */}
{isScanning && (
{/* Main Capture/Cancel Button - Touch optimized */}
<div className="relative min-w-[60px] min-h-[60px]">
{/* Capture Button */}
<button
onClick={handleCancelScan}
className='group relative animate-in fade-in slide-in-from-bottom-2 duration-300'
onClick={handleScan}
disabled={isScanning}
className='group relative'
aria-label={isScanning ? 'Analizando' : 'Detectar Zapato'}
>
<div className="w-12 h-12 bg-gradient-to-br from-orange-500/40 to-red-500/40 rounded-full flex items-center justify-center border border-white/40 hover:from-orange-500/60 hover:to-red-500/60 transition-all duration-300 transform hover:scale-110">
<X size={20} className="text-white drop-shadow-sm" />
<div className={`w-14 h-14 sm:w-16 sm:h-16 bg-gradient-to-br rounded-full flex items-center justify-center border-2 border-white/40 transition-all duration-300 shadow-2xl ${
isScanning
? 'from-blue-500/40 to-purple-500/40 animate-pulse cursor-not-allowed'
: 'from-red-500/40 to-pink-500/40 active:from-red-500/60 active:to-pink-500/60 active:scale-95'
}`}>
<div className="w-10 h-10 sm:w-12 sm:h-12 bg-white/20 rounded-full flex items-center justify-center">
<Camera size={24} className="sm:w-7 sm:h-7 text-white drop-shadow-lg" />
</div>
</div>
<div className="absolute -top-10 left-1/2 transform -translate-x-1/2 bg-black/80 text-white text-xs px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">
Cancelar
</div>
{/* Glow Effect */}
<div className="absolute inset-0 bg-gradient-to-br from-orange-500/20 to-red-500/20 rounded-full blur opacity-0 group-hover:opacity-100 transition-opacity duration-300 transform scale-150"></div>
{/* Pulsing Ring - solo cuando NO está escaneando */}
{!isScanning && (
<div className="absolute inset-0 rounded-full border-2 border-red-400/50 animate-ping pointer-events-none"></div>
)}
</button>
)}
{/* History Button */}
{/* Cancel Button Overlay - appears over capture button when scanning */}
{isScanning && (
<button
onClick={handleCancelScan}
className='absolute inset-0 flex items-center justify-center animate-in fade-in zoom-in duration-300'
aria-label="Cancelar escaneo"
>
<div className="w-14 h-14 sm:w-16 sm:h-16 bg-gradient-to-br from-orange-500/90 to-red-500/90 backdrop-blur-sm rounded-full flex items-center justify-center border-2 border-white/40 active:scale-95 transition-transform duration-200 shadow-2xl">
<X size={28} className="sm:w-8 sm:h-8 text-white drop-shadow-lg" />
</div>
</button>
)}
</div>
{/* History Button - Touch optimized (min 44px) */}
<button
onClick={() => setHistoryOpen(true)}
className='group relative'
className='group relative min-w-[44px] min-h-[44px]'
aria-label="Historial"
>
<div className="w-12 h-12 bg-gradient-to-br from-green-500/30 to-emerald-500/30 rounded-full flex items-center justify-center border border-white/30 hover:from-green-500/50 hover:to-emerald-500/50 transition-all duration-300 transform hover:scale-110 hover:rotate-12">
<History size={20} className="text-white drop-shadow-sm" />
<div className="w-11 h-11 sm:w-12 sm:h-12 bg-gradient-to-br from-green-500/30 to-emerald-500/30 rounded-full flex items-center justify-center border border-white/30 active:from-green-500/60 active:to-emerald-500/60 transition-all duration-200 active:scale-95">
<History size={18} className="sm:w-5 sm:h-5 text-white drop-shadow-sm" />
</div>
<div className="absolute -top-10 left-1/2 transform -translate-x-1/2 bg-black/80 text-white text-xs px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition-opacity duration-200">
Historial
</div>
{/* Glow Effect */}
<div className="absolute inset-0 bg-gradient-to-br from-green-500/20 to-emerald-500/20 rounded-full blur opacity-0 group-hover:opacity-100 transition-opacity duration-300 transform scale-150"></div>
{/* Glow Effect on active */}
<div className="absolute inset-0 bg-gradient-to-br from-green-500/20 to-emerald-500/20 rounded-full blur opacity-0 group-active:opacity-100 transition-opacity duration-200"></div>
</button>
</div>
@@ -680,7 +692,10 @@ function HomePageContent() {
};
return (
<main className="relative h-screen w-screen bg-black overflow-hidden">
<main className="relative h-screen w-screen bg-black overflow-hidden" style={{
height: '100dvh', // Dynamic viewport height - better for mobile browsers
paddingBottom: '0' // Override body padding for this container
}}>
{renderContent()}
<ShoeResultsPopup isOpen={isPopupOpen} onOpenChange={setPopupOpen} detectedSKU={detectedSKU} />
<HistorySidebar isOpen={isHistoryOpen} onOpenChange={setHistoryOpen} history={history} onItemClick={handleHistoryItemClick} />

View File

@@ -21,13 +21,17 @@ interface HistorySidebarProps {
export default function HistorySidebar({ history, isOpen, onOpenChange, onItemClick }: HistorySidebarProps) {
return (
<Sheet open={isOpen} onOpenChange={onOpenChange}>
<SheetContent className="flex flex-col h-full bg-black/80 backdrop-blur-xl border-l border-white/20 text-white">
<SheetHeader className="border-b border-white/10 pb-6">
<SheetTitle className="text-2xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent flex items-center gap-3">
<div className="w-10 h-10 bg-gradient-to-br from-blue-500/30 to-purple-500/30 rounded-full flex items-center justify-center border border-white/30">
<History size={20} className="text-blue-400" />
<SheetContent className="flex flex-col h-full bg-black/80 backdrop-blur-xl border-l border-white/20 text-white w-full max-w-xs sm:max-w-sm"
style={{
paddingTop: 'max(1rem, env(safe-area-inset-top))',
paddingBottom: 'max(1rem, env(safe-area-inset-bottom))'
}}>
<SheetHeader className="border-b border-white/10 pb-4 sm:pb-6">
<SheetTitle className="text-xl sm:text-2xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent flex items-center gap-2 sm:gap-3">
<div className="w-8 h-8 sm:w-10 sm:h-10 bg-gradient-to-br from-blue-500/30 to-purple-500/30 rounded-full flex items-center justify-center border border-white/30 flex-shrink-0">
<History size={18} className="sm:w-5 sm:h-5 text-blue-400" />
</div>
Historial de Escaneos
<span className="truncate">Historial</span>
</SheetTitle>
</SheetHeader>
<div className="flex-1 mt-6 space-y-3 py-2 overflow-y-auto">
@@ -41,12 +45,13 @@ export default function HistorySidebar({ history, isOpen, onOpenChange, onItemCl
</div>
) : (
history.map((shoe, index) => (
<div
<button
key={`${shoe.id}-${index}`}
className="group cursor-pointer"
className="group w-full text-left"
onClick={() => onItemClick(shoe)}
aria-label={`Ver detalles de ${shoe.name}`}
>
<div className="bg-white/5 hover:bg-white/10 backdrop-blur-sm border border-white/10 hover:border-white/20 rounded-xl p-4 transition-all duration-300 transform hover:scale-[1.02] hover:shadow-xl">
<div className="bg-white/5 active:bg-white/15 backdrop-blur-sm border border-white/10 active:border-white/30 rounded-xl p-4 transition-all duration-200 active:scale-[0.98] shadow-md min-h-[60px]">
<div className="flex items-center space-x-4">
<div className="relative">
<div className="w-14 h-14 rounded-lg overflow-hidden border border-white/20 group-hover:border-white/30 transition-colors">
@@ -68,14 +73,14 @@ export default function HistorySidebar({ history, isOpen, onOpenChange, onItemCl
</div>
<p className="text-white/50 text-xs mt-1 truncate">{shoe.description}</p>
</div>
<div className="opacity-0 group-hover:opacity-100 transition-opacity duration-200">
<div className="opacity-0 group-active:opacity-100 transition-opacity duration-200">
<div className="w-6 h-6 bg-blue-500/30 rounded-full flex items-center justify-center">
<span className="text-blue-300 text-xs"></span>
</div>
</div>
</div>
</div>
</div>
</button>
))
)}
</div>

View File

@@ -62,7 +62,8 @@ export default function ShoeResultsPopup({ isOpen, onOpenChange, detectedSKU }:
<Drawer.Root open={isOpen} onOpenChange={onOpenChange}>
<Drawer.Portal>
<Drawer.Overlay className="fixed inset-0 bg-black/60 backdrop-blur-sm z-[100]" />
<Drawer.Content className="fixed bottom-0 left-0 right-0 mt-24 flex h-[90%] flex-col rounded-t-3xl bg-black/90 backdrop-blur-xl border-t-2 border-white/20 z-[101] shadow-2xl">
<Drawer.Content className="fixed bottom-0 left-0 right-0 mt-24 flex h-[90%] flex-col rounded-t-3xl bg-black/90 backdrop-blur-xl border-t-2 border-white/20 z-[101] shadow-2xl"
style={{ paddingBottom: 'env(safe-area-inset-bottom)' }}>
{/* Loading shimmer badge */}
<div className="absolute top-4 right-4 z-20">
<div className="bg-gradient-to-r from-blue-400 to-purple-500 px-3 py-1.5 rounded-full text-sm font-bold text-white animate-pulse">
@@ -105,7 +106,8 @@ export default function ShoeResultsPopup({ isOpen, onOpenChange, detectedSKU }:
<Drawer.Root open={isOpen} onOpenChange={onOpenChange}>
<Drawer.Portal>
<Drawer.Overlay className="fixed inset-0 bg-black/60 backdrop-blur-sm z-[100]" />
<Drawer.Content className="fixed bottom-0 left-0 right-0 mt-24 flex h-[90%] flex-col rounded-t-3xl bg-black/90 backdrop-blur-xl border-t-2 border-white/20 z-[101] shadow-2xl">
<Drawer.Content className="fixed bottom-0 left-0 right-0 mt-24 flex h-[90%] flex-col rounded-t-3xl bg-black/90 backdrop-blur-xl border-t-2 border-white/20 z-[101] shadow-2xl"
style={{ paddingBottom: 'env(safe-area-inset-bottom)' }}>
{/* Corner Highlight Badge */}
{highlightInfo && (
<div className="absolute top-4 right-4 z-20">
@@ -483,19 +485,26 @@ export default function ShoeResultsPopup({ isOpen, onOpenChange, detectedSKU }:
</div>
</div>
{/* Action Button */}
<div className="sticky bottom-0 w-full border-t border-white/10 bg-black/80 backdrop-blur-xl p-6">
{/* Action Button - Touch optimized with safe area */}
<div className="sticky bottom-0 w-full border-t border-white/10 bg-black/80 backdrop-blur-xl p-4 sm:p-6"
style={{ paddingBottom: 'max(1.5rem, calc(1.5rem + env(safe-area-inset-bottom)))' }}>
<div className="flex gap-3">
<Button
size="lg"
<Button
size="lg"
onClick={handleViewDetails}
className="flex-1 h-14 text-lg bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 border-0 shadow-lg shadow-blue-500/25 transform hover:scale-[1.02] transition-all duration-200"
className="flex-1 min-h-[48px] h-12 sm:h-14 text-base sm:text-lg bg-gradient-to-r from-blue-600 to-purple-600 active:from-blue-700 active:to-purple-700 border-0 shadow-lg shadow-blue-500/25 active:scale-[0.98] transition-all duration-200"
aria-label="Ver detalles completos del producto"
>
<ExternalLink className="w-5 h-5 mr-2" />
Ver Detalles Completos
<ExternalLink className="w-4 h-4 sm:w-5 sm:h-5 mr-2" />
<span className="truncate">Ver Detalles</span>
</Button>
<Button size="lg" variant="outline" className="h-14 px-6 bg-white/5 border-white/20 text-white hover:bg-white/10 hover:border-white/30">
<Button
size="lg"
variant="outline"
className="min-w-[48px] min-h-[48px] h-12 sm:h-14 px-4 sm:px-6 bg-white/5 border-white/20 text-white active:bg-white/10 active:border-white/30"
aria-label="Agregar a favoritos"
>
<span className="text-lg sm:text-xl"></span>
</Button>
</div>
</div>