feat: enhance responsive design for glass panel and configurator section
This commit is contained in:
parent
0793a650fb
commit
b9444979f2
@ -200,22 +200,57 @@ html {
|
|||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.layout-container {
|
.layout-container {
|
||||||
flex-direction: column !important;
|
flex-direction: column-reverse !important;
|
||||||
|
height: 100dvh !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.glass-panel-responsive {
|
.glass-panel-responsive {
|
||||||
position: fixed !important;
|
order: unset !important;
|
||||||
bottom: 0 !important;
|
position: relative !important;
|
||||||
left: 0 !important;
|
bottom: auto !important;
|
||||||
right: 0 !important;
|
left: auto !important;
|
||||||
|
right: auto !important;
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
height: 50vh !important;
|
height: 55dvh !important;
|
||||||
border-left: none !important;
|
max-height: 55dvh !important;
|
||||||
border-right: none !important;
|
border-right: none !important;
|
||||||
|
border-left: none !important;
|
||||||
border-top: 1px solid var(--color-border) !important;
|
border-top: 1px solid var(--color-border) !important;
|
||||||
box-shadow: 0 -4px 40px rgba(0, 0, 0, 0.08) !important;
|
box-shadow: 0 -4px 30px rgba(0, 0, 0, 0.06) !important;
|
||||||
border-radius: 1rem 1rem 0 0 !important;
|
border-radius: 1rem 1rem 0 0 !important;
|
||||||
|
overflow-y: auto !important;
|
||||||
|
overflow-x: hidden !important;
|
||||||
z-index: 50;
|
z-index: 50;
|
||||||
|
padding-bottom: env(safe-area-inset-bottom, 0px) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expanded (fullscreen) state overrides */
|
||||||
|
.glass-panel-responsive.panel-expanded {
|
||||||
|
position: fixed !important;
|
||||||
|
top: 0 !important;
|
||||||
|
left: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100dvh !important;
|
||||||
|
max-height: 100dvh !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-top: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
z-index: 200 !important;
|
||||||
|
overflow-y: auto !important;
|
||||||
|
-webkit-overflow-scrolling: touch !important;
|
||||||
|
padding-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-area {
|
||||||
|
height: 45dvh !important;
|
||||||
|
max-height: 45dvh !important;
|
||||||
|
min-height: 180px !important;
|
||||||
|
width: 100% !important;
|
||||||
|
flex: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#configurator {
|
||||||
|
height: 100dvh !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-handle {
|
.mobile-handle {
|
||||||
@ -223,6 +258,108 @@ html {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Small phones */
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.glass-panel-responsive {
|
||||||
|
height: 58dvh !important;
|
||||||
|
max-height: 58dvh !important;
|
||||||
|
border-radius: 0.75rem 0.75rem 0 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-area {
|
||||||
|
height: 42dvh !important;
|
||||||
|
max-height: 42dvh !important;
|
||||||
|
min-height: 160px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glass-panel-responsive header {
|
||||||
|
padding: 0.75rem 1rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glass-panel-responsive > div[role="region"] {
|
||||||
|
padding: 1rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Very small phones (iPhone SE, etc.) */
|
||||||
|
@media (max-width: 375px) {
|
||||||
|
.glass-panel-responsive {
|
||||||
|
height: 60dvh !important;
|
||||||
|
max-height: 60dvh !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-area {
|
||||||
|
height: 40dvh !important;
|
||||||
|
max-height: 40dvh !important;
|
||||||
|
min-height: 140px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Landscape mobile */
|
||||||
|
@media (max-height: 500px) and (orientation: landscape) {
|
||||||
|
.layout-container {
|
||||||
|
flex-direction: row !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glass-panel-responsive {
|
||||||
|
order: unset !important;
|
||||||
|
position: relative !important;
|
||||||
|
width: 320px !important;
|
||||||
|
min-width: 320px !important;
|
||||||
|
height: 100% !important;
|
||||||
|
max-height: 100% !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-top: none !important;
|
||||||
|
border-left: 1px solid var(--color-border) !important;
|
||||||
|
overflow-y: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-area {
|
||||||
|
height: 100% !important;
|
||||||
|
max-height: 100% !important;
|
||||||
|
width: auto !important;
|
||||||
|
flex: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-handle {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.mobile-handle {
|
.mobile-handle {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Hide expand button on desktop */
|
||||||
|
.panel-expand-btn {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show expand button only on mobile */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.panel-expand-btn {
|
||||||
|
display: flex !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expanded (fullscreen) panel state – position handled by React inline styles */
|
||||||
|
.layout-expanded .canvas-area {
|
||||||
|
height: 0 !important;
|
||||||
|
max-height: 0 !important;
|
||||||
|
min-height: 0 !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.glass-panel-responsive.panel-expanded {
|
||||||
|
height: 100dvh !important;
|
||||||
|
max-height: 100dvh !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 375px) {
|
||||||
|
.glass-panel-responsive.panel-expanded {
|
||||||
|
height: 100dvh !important;
|
||||||
|
max-height: 100dvh !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import { useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useUrlSync } from '@/hooks/useUrlSync';
|
import { useUrlSync } from '@/hooks/useUrlSync';
|
||||||
import { RobotCanvas } from '@/components/RobotCanvas';
|
import { RobotCanvas } from '@/components/RobotCanvas';
|
||||||
@ -10,6 +11,7 @@ import { CheckoutOverlay } from '@/components/CheckoutOverlay';
|
|||||||
export function ConfiguratorSection() {
|
export function ConfiguratorSection() {
|
||||||
const { isHydrated } = useUrlSync();
|
const { isHydrated } = useUrlSync();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const [panelExpanded, setPanelExpanded] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
@ -23,7 +25,7 @@ export function ConfiguratorSection() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="layout-container"
|
className={`layout-container${panelExpanded ? ' layout-expanded' : ''}`}
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
@ -32,9 +34,8 @@ export function ConfiguratorSection() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<aside
|
<aside
|
||||||
className="glass-panel-responsive"
|
className={`glass-panel-responsive${panelExpanded ? ' panel-expanded' : ''}`}
|
||||||
style={{
|
style={{
|
||||||
order: -1,
|
|
||||||
width: '420px',
|
width: '420px',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
background: 'rgba(255, 255, 255, 0.9)',
|
background: 'rgba(255, 255, 255, 0.9)',
|
||||||
@ -45,28 +46,39 @@ export function ConfiguratorSection() {
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
overflow: 'hidden',
|
overflowX: 'hidden',
|
||||||
|
overflowY: 'auto',
|
||||||
}}
|
}}
|
||||||
role="complementary"
|
role="complementary"
|
||||||
aria-label={t('panel.title')}
|
aria-label={t('panel.title')}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="mobile-handle"
|
className="mobile-handle"
|
||||||
|
onClick={() => setPanelExpanded((v) => !v)}
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
aria-label={panelExpanded ? 'Collapse panel' : 'Expand panel'}
|
||||||
|
onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setPanelExpanded((v) => !v); } }}
|
||||||
style={{
|
style={{
|
||||||
padding: '0.75rem',
|
padding: '0.75rem',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
position: 'relative',
|
||||||
|
cursor: 'pointer',
|
||||||
|
userSelect: 'none',
|
||||||
}}
|
}}
|
||||||
aria-hidden="true"
|
|
||||||
>
|
>
|
||||||
|
{/* Drag indicator – tap to expand/collapse */}
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
width: '40px',
|
width: '40px',
|
||||||
height: '4px',
|
height: '4px',
|
||||||
backgroundColor: '#e2e8f0',
|
backgroundColor: '#e2e8f0',
|
||||||
borderRadius: '2px',
|
borderRadius: '2px',
|
||||||
|
transition: 'width 0.2s, background-color 0.2s',
|
||||||
}}
|
}}
|
||||||
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -94,7 +106,7 @@ export function ConfiguratorSection() {
|
|||||||
style={{
|
style={{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
padding: '1.5rem',
|
padding: '1.5rem',
|
||||||
overflowY: 'auto',
|
overflowY: 'visible',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
}}
|
}}
|
||||||
@ -106,6 +118,7 @@ export function ConfiguratorSection() {
|
|||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<main
|
<main
|
||||||
|
className="canvas-area"
|
||||||
style={{
|
style={{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user