Rewild Your Web
web browser dweb
at main 311 lines 6.4 kB view raw
1/* SPDX-License-Identifier: AGPL-3.0-or-later */ 2 3/* Hide desktop-only elements */ 4body.mobile-mode #sidebar { 5 display: none; 6} 7 8body.mobile-mode #header { 9 display: none; 10} 11 12/* Root becomes full-screen container for carousel */ 13body.mobile-mode #root { 14 flex: 1; 15 display: block; 16 overflow: hidden; 17 position: relative; 18} 19 20/* Each webview container is full-screen, stacked */ 21body.mobile-mode .mobile-webview-container { 22 position: absolute; 23 top: 0; 24 left: 0; 25 right: 0; 26 bottom: var(--keyboard-offset); 27 opacity: 0; 28 visibility: hidden; 29 transition: 30 opacity 0.3s ease, 31 visibility 0.3s ease, 32 bottom 0.3s ease; 33 z-index: var(--z-base); 34} 35 36body.mobile-mode .mobile-webview-container.active { 37 opacity: 1; 38 visibility: visible; 39 z-index: var(--z-base-active); 40} 41 42/* WebView fills container completely */ 43body.mobile-mode .mobile-webview-container web-view { 44 width: 100%; 45 height: 100%; 46} 47 48/* Override WebView to hide title bar on mobile */ 49body.mobile-mode web-view::part(bar) { 50 display: none; 51} 52 53/* Footer (keyboard) adjustments for mobile */ 54body.mobile-mode #footer { 55 position: fixed; 56 bottom: 0; 57 left: 0; 58 right: 0; 59 z-index: var(--z-chrome); 60} 61 62/* Mobile action bar adjustments when keyboard is open */ 63body.mobile-mode mobile-action-bar { 64 transition: bottom var(--transition-fast) ease; 65} 66 67body.mobile-mode.keyboard-open mobile-action-bar { 68 bottom: var(--keyboard-height); 69} 70 71/* ============================================================================ 72 Peek Preview Styles 73 ============================================================================ */ 74 75.mobile-peek-preview { 76 position: fixed; 77 top: 0; 78 width: 100%; 79 height: 100%; 80 background: var(--bg-menu); 81 z-index: var(--z-gesture); 82 display: flex; 83 flex-direction: column; 84 box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); 85 opacity: 0; 86 visibility: hidden; 87} 88 89.mobile-peek-preview.visible { 90 opacity: 1; 91 visibility: visible; 92} 93 94/* Animate transform on release (commit or cancel) */ 95.mobile-peek-preview.animating { 96 transition: transform var(--transition-fast); 97} 98 99.mobile-peek-preview.from-left { 100 left: 0; 101 transform: translateX(-100%); 102} 103 104.mobile-peek-preview.from-right { 105 right: 0; 106 left: auto; 107 transform: translateX(100%); 108} 109 110.peek-header { 111 display: flex; 112 align-items: center; 113 gap: var(--spacing-sm); 114 padding: var(--spacing-md); 115 background: var(--bg-header); 116} 117 118.peek-favicon { 119 width: 20px; 120 height: 20px; 121 object-fit: contain; 122 border-radius: 4px; 123} 124 125.peek-favicon[src=""] { 126 display: none; 127} 128 129.peek-title { 130 flex: 1; 131 font-size: 14px; 132 font-weight: 600; 133 color: var(--color-text-menu); 134 white-space: nowrap; 135 overflow: hidden; 136 text-overflow: ellipsis; 137} 138 139.peek-screenshot { 140 flex: 1; 141 width: 100%; 142 object-fit: cover; 143 object-position: top; 144} 145 146/* ============================================================================ 147 Tab Count Indicator (shown during edge swipe) 148 ============================================================================ */ 149 150.mobile-tab-indicator { 151 position: fixed; 152 bottom: 60px; 153 left: 50%; 154 transform: translateX(-50%); 155 display: flex; 156 gap: 6px; 157 padding: 8px 12px; 158 background: rgba(0, 0, 0, 0.6); 159 border-radius: 16px; 160 z-index: var(--z-gesture); 161 opacity: 0; 162 visibility: hidden; 163 transition: 164 opacity 0.2s ease, 165 visibility 0.2s ease; 166} 167 168.mobile-tab-indicator.visible { 169 opacity: 1; 170 visibility: visible; 171} 172 173.tab-dot { 174 width: 8px; 175 height: 8px; 176 border-radius: 50%; 177 background: rgba(255, 255, 255, 0.3); 178 transition: 179 background 0.2s ease, 180 transform 0.2s ease; 181} 182 183.tab-dot.active { 184 background: var(--color-focus-ring); 185 transform: scale(1.2); 186} 187 188/* ============================================================================ 189 Transition Animations 190 ============================================================================ */ 191 192/* Slide transition between webviews */ 193@keyframes slideInFromLeft { 194 from { 195 transform: translateX(-100%); 196 } 197 to { 198 transform: translateX(0); 199 } 200} 201 202@keyframes slideInFromRight { 203 from { 204 transform: translateX(100%); 205 } 206 to { 207 transform: translateX(0); 208 } 209} 210 211@keyframes slideOutToLeft { 212 from { 213 transform: translateX(0); 214 } 215 to { 216 transform: translateX(-100%); 217 } 218} 219 220@keyframes slideOutToRight { 221 from { 222 transform: translateX(0); 223 } 224 to { 225 transform: translateX(100%); 226 } 227} 228 229body.mobile-mode .mobile-webview-container.slide-in-left { 230 animation: slideInFromLeft 0.3s ease forwards; 231} 232 233body.mobile-mode .mobile-webview-container.slide-in-right { 234 animation: slideInFromRight 0.3s ease forwards; 235} 236 237body.mobile-mode .mobile-webview-container.slide-out-left { 238 animation: slideOutToLeft 0.3s ease forwards; 239} 240 241body.mobile-mode .mobile-webview-container.slide-out-right { 242 animation: slideOutToRight 0.3s ease forwards; 243} 244 245/* ============================================================================ 246 Edge Zone Visual Feedback (subtle) 247 ============================================================================ */ 248 249.edge-feedback { 250 position: fixed; 251 z-index: var(--z-gesture); 252 pointer-events: none; 253 opacity: 0; 254 transition: opacity 0.15s ease; 255} 256 257.edge-feedback.active { 258 opacity: 1; 259} 260 261.edge-feedback.left { 262 left: 0; 263 top: 0; 264 width: 4px; 265 height: 100%; 266 background: linear-gradient(to right, var(--color-focus-ring), transparent); 267} 268 269.edge-feedback.right { 270 right: 0; 271 top: 0; 272 width: 4px; 273 height: 100%; 274 background: linear-gradient(to left, var(--color-focus-ring), transparent); 275} 276 277.edge-feedback.bottom { 278 bottom: 0; 279 left: 0; 280 width: 100%; 281 height: 4px; 282 background: linear-gradient(to top, var(--color-focus-ring), transparent); 283} 284 285.edge-feedback.top { 286 top: 0; 287 left: 0; 288 width: 100%; 289 height: 4px; 290 background: linear-gradient(to bottom, var(--color-focus-ring), transparent); 291} 292 293.gesture-edge-overlay { 294 position: fixed; 295 z-index: calc(var(--z-gesture) + 1); 296 touch-action: none; 297 pointer-events: auto; 298 background: transparent; 299 /* rgba(77, 215, 220, 0.49); */ 300} 301 302/* Expand edge overlay to full screen during active gesture, 303 above the peek preview so we keep receiving touch events */ 304.gesture-edge-overlay.fullscreen-overlay { 305 left: 0 !important; 306 top: 0 !important; 307 right: auto !important; 308 bottom: auto !important; 309 width: 100% !important; 310 height: 100% !important; 311}