MikaFil commited on
Commit
9ebe235
·
verified ·
1 Parent(s): 13e3cdc

Update style/defaults/style.css

Browse files
Files changed (1) hide show
  1. style/defaults/style.css +349 -464
style/defaults/style.css CHANGED
@@ -1,468 +1,353 @@
1
- // interface.js
2
- // ==============================
3
-
4
- const currentScriptTag = document.currentScript;
5
-
6
- (function() {
7
- // 1. Locate the <script> and read data-config
8
- let scriptTag = currentScriptTag;
9
- if (!scriptTag) {
10
- const scripts = document.getElementsByTagName('script');
11
- for (let i = 0; i < scripts.length; i++) {
12
- if (scripts[i].src.includes('interface.js') && scripts[i].hasAttribute('data-config')) {
13
- scriptTag = scripts[i];
14
- break;
15
- }
16
- }
17
- if (!scriptTag && scripts.length > 0) {
18
- scriptTag = scripts[scripts.length - 1];
19
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
21
-
22
- const configUrl = scriptTag.getAttribute('data-config');
23
- let config = {};
24
- if (configUrl) {
25
- fetch(configUrl)
26
- .then(response => response.json())
27
- .then(cfg => {
28
- config = cfg;
29
- main();
30
- });
31
- } else {
32
- return;
33
  }
34
-
35
- // Inject CSS for pointer events and z-index insurance!
36
- function injectCompatCSS() {
37
- if (document.getElementById('ply-compat-css')) return;
38
- const style = document.createElement('style');
39
- style.id = 'ply-compat-css';
40
- style.textContent = `
41
- .ply-widget-container,
42
- .viewer-container,
43
- .ply-canvas,
44
- .tooltip-panel,
45
- .widget-button,
46
- .menu-content {
47
- pointer-events: auto !important;
48
- z-index: 9999 !important;
49
- }
50
- .tooltip-panel {
51
- max-width: 90vw !important;
52
- max-height: 80vh !important;
53
- overflow: auto !important;
54
- box-sizing: border-box !important;
55
- }
56
- .tooltip-content {
57
- position: relative;
58
- width: 100%;
59
- box-sizing: border-box;
60
- padding-top: 0;
61
- }
62
- .tooltip-close {
63
- position: absolute;
64
- top: 12px;
65
- right: 12px;
66
- width: 32px;
67
- height: 32px;
68
- border-radius: 8px;
69
- background: #F2F0EF;
70
- color: #545454;
71
- display: flex;
72
- align-items: center;
73
- justify-content: center;
74
- font-size: 18px;
75
- z-index: 10001;
76
- border: 1px solid #ccc;
77
- cursor: pointer;
78
- box-sizing: border-box;
79
- }
80
- .tooltip-panel img {
81
- max-width: 100%;
82
- height: auto;
83
- display: block;
84
- margin-top: 8px;
85
- border-radius: 6px;
86
- }
87
- @media (max-width: 600px) {
88
- .tooltip-panel {
89
- max-width: 96vw !important;
90
- max-height: 60vh !important;
91
- }
92
- .tooltip-close {
93
- top: 8px;
94
- right: 8px;
95
- width: 28px;
96
- height: 28px;
97
- font-size: 16px;
98
- }
99
- }
100
- `;
101
- document.head.appendChild(style);
102
  }
103
-
104
- function main() {
105
- injectCompatCSS();
106
-
107
- // 3. Generate a unique instanceId for this widget
108
- const instanceId = Math.random().toString(36).substr(2, 8);
109
-
110
- // 4. Compute the aspect ratio (padding-bottom %)
111
- let aspectPercent = "100%";
112
- if (config.aspect) {
113
- if (config.aspect.includes(":")) {
114
- const parts = config.aspect.split(":");
115
- const w = parseFloat(parts[0]);
116
- const h = parseFloat(parts[1]);
117
- if (!isNaN(w) && !isNaN(h) && w > 0) {
118
- aspectPercent = (h / w * 100) + "%";
119
- }
120
- } else {
121
- const aspectValue = parseFloat(config.aspect);
122
- if (!isNaN(aspectValue) && aspectValue > 0) {
123
- aspectPercent = (100 / aspectValue) + "%";
124
- }
125
- }
126
- } else {
127
- const parentContainer = scriptTag.parentNode;
128
- const containerWidth = parentContainer.offsetWidth;
129
- const containerHeight = parentContainer.offsetHeight;
130
- if (containerWidth > 0 && containerHeight > 0) {
131
- aspectPercent = (containerHeight / containerWidth * 100) + "%";
132
- }
133
- }
134
-
135
- // 5. Create the widget container
136
- const widgetContainer = document.createElement('div');
137
- widgetContainer.id = 'ply-widget-container-' + instanceId;
138
- widgetContainer.classList.add('ply-widget-container');
139
- widgetContainer.style.height = "0";
140
- widgetContainer.style.paddingBottom = aspectPercent;
141
- widgetContainer.setAttribute('data-original-aspect', aspectPercent);
142
-
143
- // Conditionally include the “tooltips-toggle button only if config.tooltips_url is defined
144
- const tooltipsButtonHTML = config.tooltips_url
145
- ? `<button id="tooltips-toggle-${instanceId}" class="widget-button tooltips-toggle">⦿</button>`
146
- : '';
147
-
148
- widgetContainer.innerHTML = `
149
- <div id="viewer-container-${instanceId}" class="viewer-container">
150
- <div id="progress-dialog-${instanceId}" class="progress-dialog">
151
- <progress id="progress-indicator-${instanceId}" max="100" value="0"></progress>
152
- </div>
153
- <button id="fullscreen-toggle-${instanceId}" class="widget-button fullscreen-toggle">⇱</button>
154
- <button id="help-toggle-${instanceId}" class="widget-button help-toggle">?</button>
155
- <button id="reset-camera-btn-${instanceId}" class="widget-button reset-camera-btn">
156
- <span class="reset-icon">⟲</span>
157
- </button>
158
- ${tooltipsButtonHTML}
159
- <div id="menu-content-${instanceId}" class="menu-content">
160
- <span id="help-close-${instanceId}" class="help-close">×</span>
161
- <div class="help-text"></div>
162
- </div>
163
- </div>
164
- <div id="tooltip-panel" class="tooltip-panel" style="display: none;">
165
- <div class="tooltip-content">
166
- <span id="tooltip-close" class="tooltip-close">×</span>
167
- <div id="tooltip-text" class="tooltip-text"></div>
168
- <img id="tooltip-image" class="tooltip-image" src="" alt="" style="display: none;" />
169
- </div>
170
- </div>
171
- `;
172
-
173
- scriptTag.parentNode.appendChild(widgetContainer);
174
-
175
- // 6. Grab references to new DOM elements
176
- const viewerContainerElem = document.getElementById('viewer-container-' + instanceId);
177
- const fullscreenToggle = document.getElementById('fullscreen-toggle-' + instanceId);
178
- const helpToggle = document.getElementById('help-toggle-' + instanceId);
179
- const helpCloseBtn = document.getElementById('help-close-' + instanceId);
180
- const resetCameraBtn = document.getElementById('reset-camera-btn-' + instanceId);
181
- const tooltipsToggleBtn = document.getElementById('tooltips-toggle-' + instanceId);
182
- const menuContent = document.getElementById('menu-content-' + instanceId);
183
- const helpTextDiv = menuContent.querySelector('.help-text');
184
- const tooltipPanel = document.getElementById('tooltip-panel');
185
- const tooltipTextDiv = document.getElementById('tooltip-text');
186
- const tooltipImage = document.getElementById('tooltip-image');
187
- const tooltipCloseBtn = document.getElementById('tooltip-close');
188
-
189
- const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
190
- const isMobile = isIOS || /Android/i.test(navigator.userAgent);
191
-
192
- const tooltipInstruction = config.tooltips_url
193
- ? '- Cliquez sur ⦿ pour afficher/masquer les tooltips.<br>'
194
- : '';
195
-
196
- if (isMobile) {
197
- helpTextDiv.innerHTML =
198
- '- Pour vous déplacer, glissez deux doigts sur l\'écran.<br>' +
199
- '- Pour orbiter, utilisez un doigt.<br>' +
200
- '- Pour zoomer, pincez avec deux doigts.<br>' +
201
- tooltipInstruction +
202
- '- ⟲ Réinitialise la caméra.<br>' +
203
- '- ⇱ Passe en plein écran.<br>';
204
- } else {
205
- helpTextDiv.innerHTML =
206
- '- orbitez avec le clic droit<br>' +
207
- '- zoomez avec la molette<br>' +
208
- '- déplacez vous avec le clic gauche<br>' +
209
- tooltipInstruction +
210
- '- ⟲ Réinitialise la caméra.<br>' +
211
- '- ⇱ Passe en plein écran.<br>';
212
- }
213
-
214
- menuContent.style.display = 'block';
215
- viewerContainerElem.style.display = 'block';
216
-
217
- let dragHide = null;
218
- let tooltipJustOpened = false;
219
-
220
- function hideTooltipPanel() {
221
- if (dragHide) {
222
- viewerContainerElem.removeEventListener('pointermove', dragHide);
223
- dragHide = null;
224
- }
225
- tooltipPanel.style.display = 'none';
226
- }
227
- function hideHelpPanel() {
228
- menuContent.style.display = 'none';
229
- }
230
-
231
- // 7. Dynamically load viewer.js
232
- let viewerModule;
233
- import('https://mikafil-viewer-gs.static.hf.space/viewer.js')
234
- .then(mod => {
235
- viewerModule = mod;
236
- return viewerModule.initializeViewer(config, instanceId);
237
- })
238
- .then(() => {
239
- const canvasId = 'canvas-' + instanceId;
240
- const canvasEl = document.getElementById(canvasId);
241
-
242
- // 8. Conditional display of tooltips-toggle button
243
- if (tooltipsToggleBtn) {
244
- if (!config.tooltips_url) {
245
- tooltipsToggleBtn.style.display = 'none';
246
- } else {
247
- fetch(config.tooltips_url)
248
- .then(resp => { if (!resp.ok) tooltipsToggleBtn.style.display = 'none'; })
249
- .catch(() => { tooltipsToggleBtn.style.display = 'none'; });
250
- }
251
- }
252
-
253
- // 9. Fullscreen / state-preservation logic
254
- let isFullscreen = false;
255
- let savedState = null;
256
-
257
- function saveCurrentState() {
258
- if (isFullscreen) return;
259
- const originalAspect = widgetContainer.getAttribute('data-original-aspect') || aspectPercent;
260
- savedState = {
261
- widget: {
262
- position: widgetContainer.style.position,
263
- top: widgetContainer.style.top,
264
- left: widgetContainer.style.left,
265
- width: widgetContainer.style.width,
266
- height: widgetContainer.style.height,
267
- maxWidth: widgetContainer.style.maxWidth,
268
- maxHeight:widgetContainer.style.maxHeight,
269
- paddingBottom: widgetContainer.style.paddingBottom || originalAspect,
270
- margin: widgetContainer.style.margin,
271
- },
272
- viewer: {
273
- borderRadius: viewerContainerElem.style.borderRadius,
274
- border: viewerContainerElem.style.border,
275
- }
276
- };
277
- }
278
-
279
- function restoreOriginalStyles() {
280
- if (!savedState) return;
281
- const aspectToUse = savedState.widget.paddingBottom;
282
- widgetContainer.style.position = savedState.widget.position || "";
283
- widgetContainer.style.top = savedState.widget.top || "";
284
- widgetContainer.style.left = savedState.widget.left || "";
285
- widgetContainer.style.width = "100%";
286
- widgetContainer.style.height = "0";
287
- widgetContainer.style.maxWidth = savedState.widget.maxWidth || "";
288
- widgetContainer.style.maxHeight = savedState.widget.maxHeight || "";
289
- widgetContainer.style.paddingBottom= aspectToUse;
290
- widgetContainer.style.margin = savedState.widget.margin || "";
291
- widgetContainer.classList.remove('fake-fullscreen');
292
-
293
- viewerContainerElem.style.position = "absolute";
294
- viewerContainerElem.style.top = "0";
295
- viewerContainerElem.style.left = "0";
296
- viewerContainerElem.style.right = "0";
297
- viewerContainerElem.style.bottom = "0";
298
- viewerContainerElem.style.width = "100%";
299
- viewerContainerElem.style.height = "100%";
300
- viewerContainerElem.style.borderRadius = savedState.viewer.borderRadius || "";
301
- viewerContainerElem.style.border = savedState.viewer.border || "";
302
-
303
- if (viewerModule.app) {
304
- viewerModule.app.resizeCanvas(
305
- viewerContainerElem.clientWidth,
306
- viewerContainerElem.clientHeight
307
- );
308
- }
309
- if (fullscreenToggle) fullscreenToggle.textContent = '⇱';
310
-
311
- savedState = null;
312
- }
313
-
314
- function applyFullscreenStyles() {
315
- widgetContainer.style.position = 'fixed';
316
- widgetContainer.style.top = '0';
317
- widgetContainer.style.left = '0';
318
- widgetContainer.style.width = '100vw';
319
- widgetContainer.style.height = '100vh';
320
- widgetContainer.style.maxWidth = '100vw';
321
- widgetContainer.style.maxHeight = '100vh';
322
- widgetContainer.style.paddingBottom = '0';
323
- widgetContainer.style.margin = '0';
324
- widgetContainer.style.border = 'none';
325
- widgetContainer.style.borderRadius = '0';
326
-
327
- viewerContainerElem.style.width = '100%';
328
- viewerContainerElem.style.height = '100%';
329
- viewerContainerElem.style.borderRadius= '0';
330
- viewerContainerElem.style.border = 'none';
331
-
332
- if (viewerModule.app) {
333
- viewerModule.app.resizeCanvas(window.innerWidth, window.innerHeight);
334
- }
335
-
336
- if (fullscreenToggle) fullscreenToggle.textContent = '⇲';
337
- isFullscreen = true;
338
- }
339
-
340
- function enterFullscreen() {
341
- if (!savedState) saveCurrentState();
342
- if (isIOS) {
343
- applyFullscreenStyles();
344
- widgetContainer.classList.add('fake-fullscreen');
345
- } else if (widgetContainer.requestFullscreen) {
346
- widgetContainer.requestFullscreen()
347
- .then(applyFullscreenStyles)
348
- .catch(() => {
349
- applyFullscreenStyles();
350
- widgetContainer.classList.add('fake-fullscreen');
351
- });
352
- } else {
353
- applyFullscreenStyles();
354
- widgetContainer.classList.add('fake-fullscreen');
355
- }
356
- }
357
-
358
- function exitFullscreen() {
359
- if (document.fullscreenElement === widgetContainer && document.exitFullscreen) {
360
- document.exitFullscreen().catch(() => {});
361
- }
362
- widgetContainer.classList.remove('fake-fullscreen');
363
- restoreOriginalStyles();
364
- isFullscreen = false;
365
- if (fullscreenToggle) fullscreenToggle.textContent = '⇱';
366
- }
367
-
368
- fullscreenToggle.addEventListener('click', () => {
369
- hideTooltipPanel();
370
- isFullscreen ? exitFullscreen() : enterFullscreen();
371
- });
372
-
373
- document.addEventListener('fullscreenchange', () => {
374
- if (!document.fullscreenElement && isFullscreen) {
375
- isFullscreen = false;
376
- restoreOriginalStyles();
377
- if (fullscreenToggle) fullscreenToggle.textContent = '⇱';
378
- } else if (document.fullscreenElement === widgetContainer) {
379
- if (fullscreenToggle) fullscreenToggle.textContent = '⇲';
380
- }
381
- });
382
-
383
- helpToggle.addEventListener('click', (e) => {
384
- hideTooltipPanel();
385
- e.stopPropagation();
386
- menuContent.style.display = menuContent.style.display === 'block' ? 'none' : 'block';
387
- });
388
- helpCloseBtn.addEventListener('click', hideHelpPanel);
389
-
390
- resetCameraBtn.addEventListener('click', () => {
391
- hideTooltipPanel();
392
- if (viewerModule.resetViewerCamera) {
393
- viewerModule.resetViewerCamera();
394
- }
395
- });
396
-
397
- if (tooltipsToggleBtn) {
398
- let tooltipsVisible = !!config.showTooltipsDefault;
399
- tooltipsToggleBtn.style.opacity = tooltipsVisible ? '1' : '0.5';
400
- tooltipsToggleBtn.addEventListener('click', () => {
401
- hideTooltipPanel();
402
- tooltipsVisible = !tooltipsVisible;
403
- tooltipsToggleBtn.style.opacity = tooltipsVisible ? '1' : '0.5';
404
- document.dispatchEvent(new CustomEvent('toggle-tooltips', { detail: { visible: tooltipsVisible } }));
405
- });
406
- }
407
-
408
- tooltipCloseBtn.addEventListener('click', hideTooltipPanel);
409
-
410
- // TOOLTIP POPUP + RELIABILITY TWEAK: add 0.1s delay before dragHide is active
411
- document.addEventListener('tooltip-selected', (evt) => {
412
- const { title, description, imgUrl } = evt.detail;
413
- tooltipTextDiv.innerHTML = `<strong>${title}</strong><br>${description}`;
414
- if (imgUrl) {
415
- tooltipImage.src = imgUrl;
416
- tooltipImage.style.display = 'block';
417
- } else {
418
- tooltipImage.style.display = 'none';
419
- }
420
- tooltipPanel.style.display = 'flex';
421
-
422
- // Focus for accessibility (mobile esp.)
423
- tooltipCloseBtn.focus();
424
-
425
- tooltipJustOpened = true;
426
- if (dragHide) {
427
- viewerContainerElem.removeEventListener('pointermove', dragHide);
428
- dragHide = null;
429
- }
430
- setTimeout(() => {
431
- tooltipJustOpened = false;
432
- }, 120);
433
-
434
- dragHide = (e) => {
435
- if (tooltipJustOpened) return; // Don't close immediately after open
436
- if ((e.pointerType === 'mouse' && e.buttons !== 0) || e.pointerType === 'touch') {
437
- hideTooltipPanel();
438
- }
439
- };
440
- viewerContainerElem.addEventListener('pointermove', dragHide);
441
- });
442
-
443
- if (canvasEl) {
444
- canvasEl.addEventListener('wheel', hideTooltipPanel, { passive: true });
445
- }
446
- document.addEventListener('keydown', (e) => {
447
- if ((e.key === 'Escape' || e.key === 'Esc') && isFullscreen) exitFullscreen();
448
- });
449
- window.addEventListener('resize', () => {
450
- if (viewerModule.app) {
451
- if (isFullscreen) {
452
- viewerModule.app.resizeCanvas(window.innerWidth, window.innerHeight);
453
- } else {
454
- viewerModule.app.resizeCanvas(
455
- viewerContainerElem.clientWidth,
456
- viewerContainerElem.clientHeight
457
- );
458
- }
459
- }
460
- });
461
-
462
- setTimeout(() => {
463
- saveCurrentState();
464
- document.dispatchEvent(new CustomEvent('toggle-tooltips', { detail: { visible: !!config.showTooltipsDefault } }));
465
- }, 200);
466
- });
467
  }
468
- })();
 
1
+ /* viewer.css */
2
+
3
+ /* Widget container styling */
4
+ .ply-widget-container {
5
+ position: relative;
6
+ width: 100%;
7
+ height: 0;
8
+ background-color: white;
9
+ transition: all 0.3s ease;
10
+ box-sizing: border-box;
11
+ overflow: hidden;
12
+ }
13
+ .ply-widget-container.fake-fullscreen {
14
+ position: fixed !important;
15
+ top: 0 !important;
16
+ left: 0 !important;
17
+ width: 100vw !important;
18
+ height: 100vh !important;
19
+ padding-bottom: 0 !important;
20
+ z-index: 9999 !important;
21
+ background-color: black;
22
+ border-radius: 0 !important;
23
+ margin: 0 !important;
24
+ max-width: 100vw !important;
25
+ max-height: 100vh !important;
26
+ box-sizing: border-box;
27
+ overflow: hidden;
28
+ }
29
+ .ply-widget-container:fullscreen,
30
+ .ply-widget-container:-webkit-full-screen,
31
+ .ply-widget-container:-moz-full-screen,
32
+ .ply-widget-container:-ms-fullscreen {
33
+ width: 100vw !important;
34
+ height: 100vh !important;
35
+ padding-bottom: 0 !important;
36
+ border-radius: 0 !important;
37
+ background-color: black;
38
+ }
39
+ .viewer-container {
40
+ display: none;
41
+ position: absolute;
42
+ top: 0; left: 0; right: 0; bottom: 0;
43
+ width: 100%; height: 100%;
44
+ background: black;
45
+ border: 1px solid #474558;
46
+ border-radius: 10px;
47
+ overflow: hidden;
48
+ box-sizing: border-box;
49
+ transition: all 0.3s ease;
50
+ min-height: 100%;
51
+ object-fit: contain;
52
+ }
53
+ .fake-fullscreen .viewer-container,
54
+ :fullscreen .viewer-container,
55
+ :-webkit-full-screen .viewer-container,
56
+ :-moz-full-screen .viewer-container,
57
+ :-ms-fullscreen .viewer-container {
58
+ border-radius: 0;
59
+ border: none;
60
+ width: 100%;
61
+ height: 100%;
62
+ }
63
+ .ply-canvas {
64
+ width: 100%;
65
+ height: 100%;
66
+ display: block;
67
+ background-color: transparent;
68
+ z-index: 1;
69
+ position: absolute;
70
+ top: 0; left: 0; right: 0; bottom: 0;
71
+ }
72
+ .fake-fullscreen .ply-canvas,
73
+ :fullscreen .ply-canvas,
74
+ :-webkit-full-screen .ply-canvas,
75
+ :-moz-full-screen .ply-canvas,
76
+ :-ms-fullscreen .ply-canvas {
77
+ width: 100vw;
78
+ height: 100vh;
79
+ }
80
+ .progress-dialog {
81
+ position: absolute;
82
+ top: 50%; left: 50%;
83
+ transform: translate(-50%, -50%);
84
+ border: none;
85
+ background: rgba(0,0,0,0.7);
86
+ padding: 20px;
87
+ border-radius: 5px;
88
+ z-index: 1000;
89
+ display: none;
90
+ color: white;
91
+ }
92
+ progress {
93
+ width: 250px;
94
+ height: 15px;
95
+ appearance: none;
96
+ border: none;
97
+ border-radius: 10px;
98
+ overflow: hidden;
99
+ }
100
+ progress::-webkit-progress-bar {
101
+ background-color: #333;
102
+ border-radius: 10px;
103
+ }
104
+ progress::-webkit-progress-value {
105
+ background-color: #4682B4;
106
+ border-radius: 10px;
107
+ }
108
+ progress::-moz-progress-bar {
109
+ background-color: #4682B4;
110
+ border-radius: 10px;
111
+ }
112
+ /* Menu (instructions) content styling */
113
+ .menu-content {
114
+ display: none;
115
+ position: absolute;
116
+ top: 50%; left: 50%;
117
+ transform: translate(-50%, -50%);
118
+ background: rgba(242,240,239,0.9);
119
+ color: #545454;
120
+ border: 1px solid #ddd;
121
+ border-radius: 10px;
122
+ padding: 18px 24px;
123
+ font-size: 15px;
124
+ line-height: 1.4;
125
+ box-shadow: none;
126
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
127
+ z-index: 1010;
128
+ }
129
+ .help-close {
130
+ position: absolute;
131
+ top: 8px;
132
+ right: 8px;
133
+ background-color: #B0B0B0;
134
+ color: #333;
135
+ border: none;
136
+ border-radius: 4px;
137
+ width: 24px;
138
+ height: 24px;
139
+ line-height: 24px;
140
+ text-align: center;
141
+ cursor: pointer;
142
+ font-size: 16px;
143
+ display: flex;
144
+ align-items: center;
145
+ justify-content: center;
146
+ padding: 0;
147
+ }
148
+ .widget-button {
149
+ position: absolute;
150
+ width: 32px;
151
+ height: 32px;
152
+ background-color: #F2F0EF;
153
+ border: 1px solid #ccc;
154
+ border-radius: 8px;
155
+ cursor: pointer;
156
+ font-size: 16px;
157
+ color: #545454;
158
+ display: flex !important;
159
+ align-items: center;
160
+ justify-content: center;
161
+ transition: background-color 0.2s ease;
162
+ z-index: 1000;
163
+ opacity: 1 !important;
164
+ visibility: visible !important;
165
+ margin-right: 8px;
166
+ }
167
+ .widget-button:hover { background-color: rgba(242,240,239,0.7); }
168
+ .fullscreen-toggle { top: 12px; right: 12px; }
169
+ .help-toggle { top: 12px; right: 52px; font-size: 18px; }
170
+ .reset-camera-btn { top: 12px; right: 92px; font-size: 18px; line-height: normal; padding: 0; }
171
+ .tooltips-toggle { top: 12px; right: 132px; font-size: 18px; }
172
+ .fake-fullscreen .widget-button,
173
+ :fullscreen .widget-button,
174
+ :-webkit-full-screen .widget-button,
175
+ :-moz-full-screen .widget-button,
176
+ :-ms-fullscreen .widget-button { z-index: 10000; }
177
+
178
+ /* --------- TOOLTIP PANEL ----------- */
179
+ /* ...rest of your CSS remains unchanged... */
180
+
181
+ /* --------- TOOLTIP PANEL ----------- */
182
+ .tooltip-panel {
183
+ position: absolute;
184
+ top: 50%;
185
+ right: 5%;
186
+ transform: translate(0, -50%);
187
+ background: rgba(242,240,239,0.97);
188
+ color: #545454;
189
+ border: 1px solid #ddd;
190
+ border-radius: 6px;
191
+ padding: 20px 20px 16px 16px; /* Extra top/right for button */
192
+ max-width: 340px;
193
+ width: 92vw;
194
+ min-width: 180px;
195
+ min-height: 60px;
196
+ max-height: 90vh;
197
+ z-index: 20000;
198
+ display: none;
199
+ flex-direction: column;
200
+ align-items: flex-start;
201
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
202
+ overflow: auto;
203
+ box-sizing: border-box;
204
+ position: absolute;
205
+ }
206
+
207
+ /* Ensure content does not go under close button */
208
+ .tooltip-content {
209
+ width: 100%;
210
+ min-width: 160px;
211
+ max-width: 100%;
212
+ box-sizing: border-box;
213
+ display: flex;
214
+ flex-direction: column;
215
+ align-items: flex-start;
216
+ overflow: hidden;
217
+ margin-top: 0;
218
+ }
219
+
220
+ /* CLOSE BUTTON AS SQUARE WITH ROUNDED CORNERS */
221
+ .tooltip-close {
222
+ position: absolute;
223
+ top: 12px;
224
+ right: 12px;
225
+ width: 32px;
226
+ height: 32px;
227
+ background: #F2F0EF;
228
+ color: #333;
229
+ border: 1px solid #ccc;
230
+ border-radius: 8px;
231
+ font-size: 17px;
232
+ font-weight: bold;
233
+ display: flex;
234
+ align-items: center;
235
+ justify-content: center;
236
+ line-height: 1;
237
+ cursor: pointer;
238
+ z-index: 2;
239
+ transition: background 0.18s;
240
+ box-sizing: border-box;
241
+ padding: 0;
242
+ }
243
+ .tooltip-close:hover,
244
+ .tooltip-close:focus {
245
+ background: #e0e0e0;
246
+ outline: none;
247
+ }
248
+
249
+ /* Tooltip text and image */
250
+ .tooltip-text {
251
+ margin-bottom: 10px;
252
+ font-size: 14px;
253
+ line-height: 1.4;
254
+ overflow-wrap: break-word;
255
+ word-break: break-word;
256
+ max-width: 100%;
257
+ }
258
+ .tooltip-image {
259
+ max-width: 100%;
260
+ max-height: 35vh;
261
+ border-radius: 4px;
262
+ margin-top: 5px;
263
+ display: block;
264
+ object-fit: contain;
265
+ box-sizing: border-box;
266
+ }
267
+
268
+ /* --- MOBILE adjustments --- */
269
+ @media (max-width: 600px) {
270
+ .tooltip-panel {
271
+ top: auto;
272
+ bottom: 8px;
273
+ right: 3vw;
274
+ left: 3vw;
275
+ transform: none;
276
+ width: auto;
277
+ max-width: 94vw;
278
+ min-width: 0;
279
+ max-height: 55vh;
280
+ padding: 16px 10px 12px 10px;
281
+ font-size: 13.5px;
282
  }
283
+ .tooltip-close {
284
+ top: 8px;
285
+ right: 8px;
286
+ width: 26px;
287
+ height: 26px;
288
+ font-size: 15px;
 
 
 
 
 
 
289
  }
290
+ .tooltip-image {
291
+ max-height: 22vh;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
  }
293
+ }
294
+
295
+
296
+ /* --- Mobile adjustments --- */
297
+ @media (max-width: 600px) {
298
+ .tooltip-panel {
299
+ top: auto;
300
+ bottom: 8px;
301
+ right: 3vw;
302
+ left: 3vw;
303
+ transform: none;
304
+ width: auto;
305
+ max-width: 94vw;
306
+ min-width: 0;
307
+ max-height: 55vh;
308
+ padding: 28px 14px 12px 12px; /* extra for top, right */
309
+ font-size: 13.5px;
310
+ }
311
+ .tooltip-content {
312
+ min-width: 0;
313
+ }
314
+ .tooltip-close {
315
+ top: 6px;
316
+ right: 6px;
317
+ width: 26px;
318
+ height: 26px;
319
+ font-size: 15px;
320
+ }
321
+ .tooltip-image {
322
+ max-height: 22vh;
323
+ }
324
+ }
325
+
326
+ .ply-widget-container.mobile .widget-button {
327
+ width: 24px;
328
+ height: 24px;
329
+ font-size: 12px;
330
+ }
331
+ .ply-widget-container.mobile .help-toggle { font-size: 14px; }
332
+ .ply-widget-container.mobile .fullscreen-toggle { top: 8px; right: 8px; }
333
+ .ply-widget-container.mobile .help-toggle { top: 8px; right: 40px; }
334
+ .ply-widget-container.mobile .reset-camera-btn { top: 8px; right: 72px; }
335
+ .ply-widget-container.mobile .tooltips-toggle { top: 8px; right: 104px; }
336
+
337
+ #application-canvas { width: 100%; height: 100%; display: block; }
338
+ html, body { margin: 0; padding: 0; height: 100%; }
339
+ .progress-dialog p { margin: 0; padding: 5px; }
340
+
341
+ @media (max-width: 600px) {
342
+ .menu-content {
343
+ width: 85vw;
344
+ max-height: 55vh;
345
+ overflow-y: auto;
346
+ padding: 40px 18px 14px;
347
+ font-size: 14px;
348
+ }
349
+ .menu-content .help-close {
350
+ top: 6px;
351
+ right: 6px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
  }
353
+ }