Skip to content

Commit fdebdc7

Browse files
Copilot0xrinegade
andcommitted
Complete comprehensive responsive design overhaul: desktop, iPad, and mobile ready with advanced touch support
Co-authored-by: 0xrinegade <[email protected]>
1 parent 869027c commit fdebdc7

File tree

7 files changed

+585
-15
lines changed

7 files changed

+585
-15
lines changed

src/components/Layout.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,14 @@ export default function Layout({ children, title = 'OpenSVM P2P Exchange' }) {
145145
</div>
146146

147147
{/* Desktop Navigation - Theme-Aware with Full Width */}
148-
<nav className="app-nav-desktop">
148+
<nav className="app-nav-desktop touch-friendly">
149149
<div className="app-nav-tabs">
150150
{/* Primary navigation items */}
151151
{topNavItems.map((item) => (
152152
<Link
153153
key={item.key}
154154
href={item.href}
155-
className={`app-nav-tab ${router.pathname === item.href ? 'active' : ''}`}
155+
className={`app-nav-tab touch-feedback ${router.pathname === item.href ? 'active' : ''}`}
156156
>
157157
{item.label}
158158
</Link>
@@ -195,14 +195,14 @@ export default function Layout({ children, title = 'OpenSVM P2P Exchange' }) {
195195
</header>
196196

197197
{/* Mobile Navigation - Theme-Aware Grid Layout */}
198-
<nav className="app-nav-mobile">
198+
<nav className="app-nav-mobile touch-friendly">
199199
<div className="app-nav-grid">
200200
{/* All navigation items in mobile grid */}
201201
{mobileNavItems.map((item) => (
202202
<Link
203203
key={item.key}
204204
href={item.href}
205-
className={`app-nav-button ${router.pathname === item.href ? 'active' : ''}`}
205+
className={`app-nav-button touch-feedback ${router.pathname === item.href ? 'active' : ''}`}
206206
>
207207
{item.label}
208208
</Link>
@@ -222,8 +222,8 @@ export default function Layout({ children, title = 'OpenSVM P2P Exchange' }) {
222222
{/* Footer */}
223223
<footer className="app-footer">
224224
<div className="container">
225-
<div className="text-center">
226-
<p className="text-sm text-foreground-muted">
225+
<div className="app-footer-center">
226+
<p className="app-footer-copyright">
227227
© 2025 OpenSVM P2P Exchange. All rights reserved.
228228
</p>
229229
</div>

src/components/ReconnectionModal.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,19 +137,19 @@ export const ReconnectionModal = ({ isVisible, progress, onCancel }) => {
137137
/>
138138
</svg>
139139
<div className="absolute inset-0 flex items-center justify-center">
140-
<span className="text-2xl font-bold text-gray-700" aria-live="polite">
140+
<span className="reconnection-timer-text" aria-live="polite">
141141
{nextRetryIn}
142142
</span>
143143
</div>
144144
</div>
145145

146-
<h3 id="reconnection-title" className="text-lg font-semibold text-gray-900 mb-2">
146+
<h3 id="reconnection-title" className="reconnection-title">
147147
Connection Lost
148148
</h3>
149-
<p id="reconnection-description" className="text-gray-600 mb-4">
149+
<p id="reconnection-description" className="reconnection-description">
150150
Attempting to reconnect in {nextRetryIn} second{nextRetryIn !== 1 ? 's' : ''}...
151151
</p>
152-
<p className="text-sm text-gray-500 mb-6" aria-live="polite">
152+
<p className="reconnection-attempt-info" aria-live="polite">
153153
Attempt {attempt} of {maxAttempts}
154154
</p>
155155
</>
@@ -158,13 +158,13 @@ export const ReconnectionModal = ({ isVisible, progress, onCancel }) => {
158158
{/* Connecting display */}
159159
<div className="spinner" aria-hidden="true"></div>
160160

161-
<h3 id="reconnection-title" className="text-lg font-semibold text-gray-900 mb-2">
161+
<h3 id="reconnection-title" className="reconnection-title">
162162
Reconnecting...
163163
</h3>
164-
<p id="reconnection-description" className="text-gray-600 mb-4">
164+
<p id="reconnection-description" className="reconnection-description">
165165
Attempting to restore connection
166166
</p>
167-
<p className="text-sm text-gray-500 mb-6" aria-live="polite">
167+
<p className="reconnection-attempt-info" aria-live="polite">
168168
Attempt {attempt} of {maxAttempts}
169169
</p>
170170
</>
@@ -174,14 +174,14 @@ export const ReconnectionModal = ({ isVisible, progress, onCancel }) => {
174174
<div className="flex gap-3 justify-center">
175175
<button
176176
onClick={onCancel}
177-
className="px-4 py-2 text-gray-600 hover:text-gray-800 font-medium focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 rounded"
177+
className="reconnection-cancel-button"
178178
aria-label="Cancel reconnection"
179179
>
180180
Cancel
181181
</button>
182182
<button
183183
onClick={() => window.location.reload()}
184-
className="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 font-medium focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
184+
className="reconnection-refresh-button"
185185
aria-label="Refresh page to retry connection"
186186
>
187187
Refresh Page

src/styles/responsive.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
@import './responsive/enhanced-mobile.css';
55
@import './responsive/component-mobile.css';
66
@import './responsive/responsive-utilities.css';
7+
@import './responsive/tablet-enhancements.css';
78

89
/* ASCII Layout Overrides */
910
.app-layout-sidebar {

src/styles/responsive/component-mobile.css

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,3 +587,129 @@
587587
color: white;
588588
}
589589
}
590+
591+
/* Mobile Navigation Implementation */
592+
@media (max-width: 768px) {
593+
/* Mobile menu button styling */
594+
.mobile-menu-button {
595+
display: flex;
596+
background: none;
597+
border: none;
598+
font-size: 24px;
599+
color: var(--color-foreground);
600+
cursor: pointer;
601+
padding: var(--spacing-2);
602+
min-height: 44px; /* Touch-friendly target */
603+
min-width: 44px;
604+
align-items: center;
605+
justify-content: center;
606+
}
607+
608+
/* Bottom navigation for mobile */
609+
.bottom-navigation {
610+
display: flex;
611+
position: fixed;
612+
bottom: 0;
613+
left: 0;
614+
width: 100%;
615+
background-color: var(--color-background);
616+
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
617+
z-index: 100;
618+
padding: 8px 0;
619+
}
620+
621+
.bottom-nav-items {
622+
display: flex;
623+
justify-content: space-around;
624+
width: 100%;
625+
}
626+
627+
.bottom-nav-item {
628+
display: flex;
629+
flex-direction: column;
630+
align-items: center;
631+
padding: 8px;
632+
color: var(--color-foreground-muted);
633+
text-decoration: none;
634+
min-height: 44px;
635+
min-width: 44px;
636+
justify-content: center;
637+
}
638+
639+
.bottom-nav-item.active {
640+
color: var(--color-primary);
641+
}
642+
643+
.bottom-nav-icon {
644+
font-size: 20px;
645+
margin-bottom: 4px;
646+
}
647+
648+
.bottom-nav-label {
649+
font-size: 12px;
650+
}
651+
652+
/* Mobile navigation item styling */
653+
.mobile-nav-item {
654+
display: block;
655+
width: 100%;
656+
padding: var(--spacing-3) var(--spacing-4);
657+
margin-bottom: var(--spacing-2);
658+
background: none;
659+
border: 1px solid var(--color-border);
660+
border-radius: var(--radius-md);
661+
color: var(--color-foreground);
662+
font-size: var(--font-size-base-mobile);
663+
text-align: left;
664+
cursor: pointer;
665+
transition: all 0.2s ease;
666+
min-height: 44px; /* Touch-friendly target */
667+
text-decoration: none;
668+
}
669+
670+
.mobile-nav-item:hover,
671+
.mobile-nav-item.active {
672+
background-color: var(--color-primary);
673+
color: var(--color-primary-foreground);
674+
border-color: var(--color-primary);
675+
}
676+
677+
/* Mobile navigation drawer */
678+
.mobile-nav-drawer {
679+
position: fixed;
680+
top: 0;
681+
left: 0;
682+
width: 100%;
683+
height: 100%;
684+
background-color: rgba(0, 0, 0, 0.5);
685+
z-index: 1000;
686+
opacity: 0;
687+
visibility: hidden;
688+
transition: opacity 0.3s ease, visibility 0.3s ease;
689+
}
690+
691+
.mobile-nav-drawer.open {
692+
opacity: 1;
693+
visibility: visible;
694+
}
695+
696+
.mobile-nav-content {
697+
position: absolute;
698+
top: 0;
699+
right: 0;
700+
width: 80%;
701+
max-width: 300px;
702+
height: 100%;
703+
background-color: var(--color-background);
704+
box-shadow: -2px 0 10px rgba(0, 0, 0, 0.1);
705+
transform: translateX(100%);
706+
transition: transform 0.3s ease;
707+
overflow-y: auto;
708+
display: flex;
709+
flex-direction: column;
710+
}
711+
712+
.mobile-nav-drawer.open .mobile-nav-content {
713+
transform: translateX(0);
714+
}
715+
}

src/styles/responsive/enhanced-mobile.css

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,3 +591,105 @@
591591
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);
592592
}
593593
}
594+
595+
/* Small Mobile Devices (480px and below) */
596+
@media (max-width: 480px) {
597+
:root {
598+
--header-height-small-mobile: 50px;
599+
--spacing-small-mobile: 6px;
600+
--font-size-tiny-mobile: 11px;
601+
}
602+
603+
.app-header {
604+
height: var(--header-height-small-mobile) !important;
605+
padding: 0 var(--spacing-small-mobile) !important;
606+
}
607+
608+
.app-logo-text {
609+
font-size: var(--font-size-tiny-mobile) !important;
610+
}
611+
612+
.app-nav-mobile {
613+
grid-template-columns: repeat(2, 1fr) !important;
614+
gap: var(--spacing-small-mobile) !important;
615+
}
616+
617+
.app-nav-button {
618+
font-size: var(--font-size-tiny-mobile) !important;
619+
padding: 6px !important;
620+
}
621+
622+
.container {
623+
padding-left: var(--spacing-small-mobile) !important;
624+
padding-right: var(--spacing-small-mobile) !important;
625+
}
626+
627+
h1 {
628+
font-size: 1.5rem !important;
629+
}
630+
631+
h2 {
632+
font-size: 1.25rem !important;
633+
}
634+
635+
h3 {
636+
font-size: 1.125rem !important;
637+
}
638+
}
639+
640+
/* Touch-friendly improvements for mobile devices */
641+
@media (max-width: 768px) {
642+
/* Touch-friendly button and interactive element sizing */
643+
.touch-friendly button,
644+
.touch-friendly a,
645+
.touch-friendly input,
646+
.touch-friendly select,
647+
.touch-friendly textarea {
648+
min-height: 44px; /* Minimum touch target size recommended by Apple and Google */
649+
min-width: 44px;
650+
}
651+
652+
/* Enhanced active states for touch devices */
653+
.touch-friendly button:active,
654+
.touch-friendly a:active,
655+
.touch-friendly .nav-button:active {
656+
opacity: 0.7;
657+
transform: scale(0.98);
658+
transition: all 0.1s ease;
659+
}
660+
661+
/* Touch feedback animations */
662+
.touch-feedback {
663+
position: relative;
664+
overflow: hidden;
665+
}
666+
667+
.touch-feedback::after {
668+
content: '';
669+
display: block;
670+
position: absolute;
671+
width: 100%;
672+
height: 100%;
673+
top: 0;
674+
left: 0;
675+
pointer-events: none;
676+
background-image: radial-gradient(circle, rgba(255, 255, 255, 0.3) 10%, transparent 10.01%);
677+
background-repeat: no-repeat;
678+
background-position: 50%;
679+
transform: scale(10, 10);
680+
opacity: 0;
681+
transition: transform 0.5s, opacity 1s;
682+
}
683+
684+
.touch-feedback:active::after {
685+
transform: scale(0, 0);
686+
opacity: 0.3;
687+
transition: 0s;
688+
}
689+
690+
/* Improved touch scrolling for mobile */
691+
.touch-scroll {
692+
-webkit-overflow-scrolling: touch;
693+
scroll-behavior: smooth;
694+
}
695+
}

0 commit comments

Comments
 (0)