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