/** * Spaxel Dashboard - Expert Mode Styles * * Expert mode 3D scene layout with responsive canvas sizing. * Handles iOS Safari visual viewport quirks and bottom navigation spacing. */ /* ===== Scene Container (3D Canvas) ===== */ #scene-container { position: fixed; top: 0; left: 0; width: 100%; /* Full viewport height by default */ height: 100vh; /* Fallback for browsers that don't support viewport units */ height: 100%; z-index: 1; } /* Canvas height adjustment when simple mode navigation is visible */ body.simple-mode #scene-container { /* Simple mode has 56px bottom nav, subtract from viewport height */ height: calc(100vh - 56px); } /* iOS Safari-specific handling for visual viewport */ @supports (-webkit-touch-callout: none) { /* iOS Safari with visual viewport API */ #scene-container { /* Use dynamic viewport height on iOS (handles address bar) */ height: 100dvh; } body.simple-mode #scene-container { /* Subtract bottom navigation bar height */ height: calc(100dvh - 56px); } } /* iOS Safari orientation change handling */ /* Prevent iOS Safari from scaling content on orientation change */ @supports (-webkit-touch-callout: none) { body { /* Prevent automatic text size adjustment on orientation change */ -webkit-text-size-adjust: 100%; } } /* Ensure canvas doesn't overflow during transitions */ #scene-container canvas { display: block; max-width: 100%; max-height: 100%; } /* Handle visual viewport resize events (iOS Safari keyboard, address bar) */ .visual-viewport-resizing #scene-container { /* Prevent layout shift during visual viewport changes */ pointer-events: none; } /* ===== Status Bar ===== */ #status-bar { position: fixed; top: 0; left: 0; right: 0; height: 40px; background: rgba(0, 0, 0, 0.9); z-index: 100; display: flex; align-items: center; padding: 0 16px; border-bottom: 1px solid rgba(255, 255, 255, 0.1); } /* Adjust scene container when status bar is visible */ #status-bar ~ #scene-container { top: 40px; height: calc(100vh - 40px); } /* Simple mode navigation bar adjustment */ body.simple-mode .simple-quick-actions { position: fixed; bottom: 0; left: 0; right: 0; height: 56px; z-index: 100; } /* ===== Mode Toggle Bar ===== */ .mode-toggle-bar { position: fixed; top: 40px; left: 0; right: 0; height: 44px; z-index: 90; } /* Adjust scene container when mode toggle bar is visible */ .mode-toggle-bar ~ #scene-container, body:not(.simple-mode) .mode-toggle-bar ~ #scene-container { top: 84px; /* 40px status bar + 44px mode toggle bar */ height: calc(100vh - 84px); } /* Both status bar and mode toggle bar present */ #status-bar .mode-toggle-bar ~ #scene-container { top: 84px; height: calc(100vh - 84px); } /* ===== Alert Banner ===== */ #alert-banner { position: fixed; top: 0; left: 0; right: 0; z-index: 5000; } /* Adjust scene container when alert banner is visible */ #alert-banner.visible ~ #scene-container { top: 60px; /* Approximate alert banner height */ height: calc(100vh - 60px); } /* ===== Orientation-specific adjustments ===== */ /* Landscape orientation */ @media screen and (orientation: landscape) { #scene-container { /* In landscape, ensure full height is used */ height: 100vh; height: 100dvh; } body.simple-mode #scene-container { height: calc(100vh - 56px); height: calc(100dvh - 56px); } /* Adjust for landscape status bar */ #status-bar ~ #scene-container { height: calc(100vh - 40px); height: calc(100dvh - 40px); } /* Adjust for landscape mode toggle bar */ .mode-toggle-bar ~ #scene-container { height: calc(100vh - 44px); height: calc(100dvh - 44px); } } /* Portrait orientation */ @media screen and (orientation: portrait) { #scene-container { height: 100vh; height: 100dvh; } body.simple-mode #scene-container { height: calc(100vh - 56px); height: calc(100dvh - 56px); } } /* ===== Responsive breakpoints ===== */ /* Small mobile devices */ @media screen and (max-width: 600px) { #scene-container { height: 100vh; height: 100dvh; } body.simple-mode #scene-container { height: calc(100vh - 56px); height: calc(100dvh - 56px); } /* On small mobile, status bar and mode toggle may stack */ #status-bar ~ .mode-toggle-bar ~ #scene-container { top: 84px; height: calc(100vh - 84px); height: calc(100dvh - 84px); } } /* Tablets and larger */ @media screen and (min-width: 601px) { #scene-container { height: 100vh; height: 100dvh; } } /* ===== Safe area insets for notched devices ===== */ @supports (padding: max(0px)) { #scene-container { /* Use safe-area-inset for devices with notches (iPhone X+) */ padding-top: env(safe-area-inset-top); padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); padding-bottom: env(safe-area-inset-bottom); } /* Adjust height calculation to account for safe areas */ #scene-container { height: calc(100vh - env(safe-area-inset-top) - env(safe-area-inset-bottom)); height: calc(100dvh - env(safe-area-inset-top) - env(safe-area-inset-bottom)); } body.simple-mode #scene-container { /* Simple mode: also subtract bottom nav height */ height: calc(100vh - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 56px); height: calc(100dvh - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 56px); } } /* ===== Prevent overscroll/bounce on iOS ===== */ @supports (-webkit-touch-callout: none) { #scene-container { /* Prevent rubber-band scrolling effect */ -webkit-overflow-scrolling: touch; overscroll-behavior: none; } } /* ===== Loading state ===== */ #scene-container.loading { opacity: 0.5; pointer-events: none; transition: opacity 0.3s ease; } /* ===== Hide scene container in simple mode ===== */ body.simple-mode #scene-container { display: none; } /* ===== Expert mode specific styles ===== */ body:not(.simple-mode) #scene-container { display: block; }