feat(gioser/web): fix mobile swipe, taskbar agnóstica, trazos zodiacales
1/* === Tokens === */
2:root {
3 --bg: #06050d;
4 --fg: #e8eaf5;
5 --gold: #d8a85d;
6 --gold-deep: #b77e34;
7 --aire: #d0dbff;
8 --agua: #6cd0f3;
9 --fuego: #f59056;
10 --tierra: #d49873;
11
12 --ease-emerge: cubic-bezier(0.22, 0.61, 0.20, 1);
13 --ease-magma: cubic-bezier(0.32, 0, 0.05, 1);
14 --ease-page: cubic-bezier(0.22, 0.61, 0.36, 1);
15
16 --taskbar-height: 52px;
17}
18
19* { box-sizing: border-box; }
20
21html, body {
22 margin: 0;
23 padding: 0;
24 width: 100%;
25 height: 100%;
26 background: var(--bg);
27 color: var(--fg);
28 font-family: 'Inter', system-ui, -apple-system, sans-serif;
29 font-weight: 300;
30 overflow: hidden;
31}
32
33/* === Canvas WebGL === */
34#gioser-canvas {
35 position: fixed;
36 inset: 0;
37 width: 100vw;
38 height: 100vh;
39 display: block;
40 z-index: 0;
41 transition: opacity 600ms var(--ease-emerge), filter 600ms var(--ease-emerge);
42}
43body.deck-visible #gioser-canvas {
44 opacity: 0.30;
45 filter: blur(4px) saturate(80%);
46}
47
48/* === Tips (botones cardinales sobre el aro) === */
49#tips {
50 position: fixed;
51 inset: 0;
52 pointer-events: none;
53 z-index: 5;
54 transition: opacity 250ms ease;
55}
56body.deck-visible #tips {
57 opacity: 0;
58 pointer-events: none;
59}
60
61.tip {
62 position: absolute;
63 top: 0; left: 0;
64 pointer-events: auto;
65 text-decoration: none;
66 color: var(--fg);
67 user-select: none;
68 cursor: pointer;
69
70 display: flex;
71 flex-direction: column;
72 align-items: center;
73 gap: 0.55rem;
74 padding: 1.1rem 1.6rem 0.95rem;
75 min-width: 168px;
76
77 background:
78 radial-gradient(ellipse at top, rgba(255, 255, 255, 0.04), transparent 65%),
79 rgba(8, 6, 22, 0.55);
80 backdrop-filter: blur(12px) saturate(140%);
81 -webkit-backdrop-filter: blur(12px) saturate(140%);
82 border-radius: 20px;
83 border: 1px solid rgba(216, 168, 93, 0.25);
84
85 box-shadow:
86 0 12px 36px rgba(0, 0, 0, 0.40),
87 inset 0 0 0 1px rgba(255, 255, 255, 0.04);
88
89 transition:
90 box-shadow 350ms var(--ease-emerge),
91 border-color 350ms var(--ease-emerge),
92 background 350ms var(--ease-emerge);
93}
94.tip::before {
95 content: "";
96 position: absolute;
97 inset: -10px;
98 border-radius: 26px;
99 border: 1px solid currentColor;
100 opacity: 0;
101 transition: opacity 400ms ease, inset 400ms var(--ease-emerge);
102 pointer-events: none;
103}
104.tip:hover {
105 border-color: currentColor;
106 background:
107 radial-gradient(ellipse at top, rgba(255, 255, 255, 0.07), transparent 65%),
108 rgba(20, 14, 40, 0.72);
109}
110.tip:hover::before {
111 opacity: 0.45;
112 inset: -16px;
113}
114.tip-glyph {
115 width: 54px;
116 height: 54px;
117 color: currentColor;
118 filter: drop-shadow(0 0 6px currentColor) drop-shadow(0 0 16px currentColor);
119 transition: filter 320ms ease, transform 350ms var(--ease-emerge);
120}
121.tip:hover .tip-glyph {
122 filter: drop-shadow(0 0 14px currentColor) drop-shadow(0 0 28px currentColor);
123 transform: translateY(-3px);
124}
125.tip-label {
126 font-family: 'Cinzel', serif;
127 font-size: 0.95rem;
128 letter-spacing: 0.42em;
129 font-weight: 600;
130 text-indent: 0.42em;
131 margin-top: 0.15rem;
132}
133.tip-sub {
134 font-family: 'Inter', sans-serif;
135 font-size: 0.7rem;
136 letter-spacing: 0.22em;
137 font-weight: 300;
138 color: rgba(232, 234, 245, 0.62);
139 text-transform: uppercase;
140 text-indent: 0.22em;
141}
142.tip-aire { color: var(--aire); }
143.tip-fuego { color: var(--fuego); }
144.tip-agua { color: var(--agua); }
145.tip-tierra { color: var(--tierra); }
146
147/* === DECK: contenedor único de páginas swipeable === */
148.deck {
149 position: fixed;
150 top: 0;
151 left: 0;
152 right: 0;
153 bottom: var(--taskbar-height);
154 z-index: 100;
155 pointer-events: none;
156 opacity: 0;
157 visibility: hidden;
158 transform-origin: var(--origin-x, 50%) var(--origin-y, 50%);
159 transform: scale(0.0);
160 overflow: hidden;
161 touch-action: pan-y;
162 background:
163 radial-gradient(ellipse at center, var(--deck-glow, rgba(216, 168, 93, 0.15)), transparent 65%),
164 rgba(6, 5, 13, 0.96);
165 backdrop-filter: blur(28px) saturate(140%);
166 -webkit-backdrop-filter: blur(28px) saturate(140%);
167 transition:
168 transform 600ms var(--ease-magma),
169 opacity 450ms ease,
170 visibility 0s 600ms;
171}
172.deck.open {
173 pointer-events: auto;
174 opacity: 1;
175 visibility: visible;
176 transform: scale(1);
177 transition:
178 transform 600ms var(--ease-magma),
179 opacity 450ms ease,
180 visibility 0s;
181}
182/* Acento del deck según elemento activo: glow radial del color. */
183body.deck-active-aire .deck { --deck-glow: rgba(208, 219, 255, 0.22); }
184body.deck-active-fuego .deck { --deck-glow: rgba(245, 144, 86, 0.28); }
185body.deck-active-agua .deck { --deck-glow: rgba(108, 208, 243, 0.22); }
186body.deck-active-tierra .deck { --deck-glow: rgba(212, 152, 115, 0.24); }
187
188/* Strip horizontal con páginas — vista-web traslada esto.
189 touch-action: pan-y declara al browser "yo manejo horizontal, el
190 vertical (scroll interno de cada página) lo dejas pasar". Sin esto
191 el navegador móvil se traga el gesto horizontal antes de que JS
192 pueda capturarlo. */
193.deck-strip {
194 display: flex;
195 flex-direction: row;
196 width: 100%;
197 height: 100%;
198 transform: translate3d(var(--vista-offset, 0px), 0, 0);
199 transition: transform 360ms var(--ease-page);
200 will-change: transform;
201 touch-action: pan-y;
202}
203/* Asegurar que TODOS los descendientes del strip hereden el contrato
204 touch-action — si el toque llega a un párrafo o <a>, el browser
205 chequea el touch-action del target, no del padre. */
206.deck-strip * {
207 touch-action: pan-y;
208}
209.deck-strip.vista-dragging,
210.deck-strip.vista-instant {
211 transition: none;
212}
213
214.deck-page {
215 flex: 0 0 100%;
216 width: 100%;
217 height: 100%;
218 position: relative;
219 overflow-y: auto;
220 overflow-x: hidden;
221 touch-action: pan-y;
222}
223.deck-page[data-element="aire"] { --page-accent: var(--aire); }
224.deck-page[data-element="fuego"] { --page-accent: var(--fuego); }
225.deck-page[data-element="agua"] { --page-accent: var(--agua); }
226.deck-page[data-element="tierra"] { --page-accent: var(--tierra); }
227
228/* Ambience por página */
229.page-ambience {
230 position: absolute;
231 inset: 0;
232 pointer-events: none;
233 z-index: 0;
234}
235.deck-page[data-element="aire"] .page-ambience {
236 background:
237 radial-gradient(circle at 18% 22%, rgba(208, 219, 255, 0.20), transparent 38%),
238 radial-gradient(circle at 78% 68%, rgba(208, 219, 255, 0.14), transparent 40%),
239 radial-gradient(circle at 45% 90%, rgba(180, 200, 255, 0.10), transparent 45%);
240 animation: aire-drift 28s ease-in-out infinite alternate;
241}
242.deck-page[data-element="fuego"] .page-ambience {
243 background:
244 radial-gradient(circle at 50% 100%, rgba(245, 144, 86, 0.35), transparent 55%),
245 radial-gradient(circle at 25% 80%, rgba(255, 90, 40, 0.18), transparent 35%),
246 radial-gradient(circle at 80% 85%, rgba(255, 140, 60, 0.18), transparent 35%);
247 animation: fuego-flicker 5s ease-in-out infinite;
248}
249.deck-page[data-element="agua"] .page-ambience {
250 background:
251 radial-gradient(ellipse at 50% 95%, rgba(60, 160, 230, 0.30), transparent 60%),
252 radial-gradient(ellipse at 20% 70%, rgba(108, 208, 243, 0.15), transparent 50%),
253 radial-gradient(ellipse at 80% 75%, rgba(108, 208, 243, 0.12), transparent 50%);
254 animation: agua-tide 14s ease-in-out infinite alternate;
255}
256.deck-page[data-element="tierra"] .page-ambience {
257 background:
258 radial-gradient(ellipse at 50% 100%, rgba(120, 80, 40, 0.40), transparent 60%),
259 radial-gradient(ellipse at 22% 88%, rgba(180, 130, 80, 0.20), transparent 45%),
260 radial-gradient(ellipse at 78% 88%, rgba(150, 100, 60, 0.22), transparent 45%);
261}
262@keyframes aire-drift {
263 from { transform: translate(-4%, -1%); }
264 to { transform: translate(4%, 2%); }
265}
266@keyframes fuego-flicker {
267 0%, 100% { opacity: 0.85; transform: scaleY(1.00); }
268 35% { opacity: 1.00; transform: scaleY(1.04); }
269 60% { opacity: 0.92; transform: scaleY(0.98); }
270}
271@keyframes agua-tide {
272 from { transform: translateY(0); }
273 to { transform: translateY(-3%); }
274}
275
276/* Head + controls */
277.page-controls {
278 position: absolute;
279 top: 1.8vh;
280 right: 1.8vw;
281 z-index: 5;
282 display: flex;
283 gap: 0.5rem;
284}
285.page-control-btn {
286 width: 40px;
287 height: 40px;
288 border-radius: 50%;
289 background: rgba(255, 255, 255, 0.04);
290 border: 1px solid rgba(255, 255, 255, 0.18);
291 color: var(--page-accent, var(--gold));
292 font-size: 1.2rem;
293 line-height: 1;
294 cursor: pointer;
295 display: inline-flex;
296 align-items: center;
297 justify-content: center;
298 padding: 0;
299 font-family: 'Inter', sans-serif;
300 transition:
301 background 200ms ease,
302 border-color 200ms ease,
303 transform 250ms var(--ease-emerge);
304}
305.page-control-btn:hover {
306 background: rgba(255, 255, 255, 0.10);
307 border-color: currentColor;
308}
309.page-minimize svg {
310 width: 18px;
311 height: 18px;
312}
313.page-close {
314 font-size: 1.6rem;
315}
316.page-close:hover { transform: rotate(90deg); }
317
318.page-head {
319 position: relative;
320 z-index: 2;
321 text-align: center;
322 padding: 7vh 8vw 2vh;
323 color: var(--page-accent, var(--gold));
324}
325.page-mark {
326 display: inline-block;
327 font-family: 'Inter', sans-serif;
328 font-size: 0.7rem;
329 letter-spacing: 0.55em;
330 text-transform: uppercase;
331 color: rgba(232, 234, 245, 0.6);
332 margin-bottom: 0.4rem;
333 text-indent: 0.55em;
334}
335.page-title {
336 font-family: 'Cinzel', serif;
337 font-weight: 700;
338 font-size: clamp(2.4rem, 6vw, 4.6rem);
339 margin: 0;
340 letter-spacing: 0.08em;
341 color: var(--page-accent, var(--gold));
342 text-shadow: 0 0 28px currentColor, 0 0 56px rgba(255, 255, 255, 0.10);
343}
344.page-tag {
345 display: block;
346 font-family: 'Inter', sans-serif;
347 font-size: 0.78rem;
348 letter-spacing: 0.32em;
349 text-transform: uppercase;
350 color: rgba(232, 234, 245, 0.55);
351 margin-top: 0.7rem;
352 text-indent: 0.32em;
353}
354.page-content {
355 position: relative;
356 z-index: 2;
357 padding: 1vh 10vw 8vh;
358 opacity: 0;
359 transition: opacity 400ms ease 250ms;
360}
361.deck.open .deck-page .page-content {
362 opacity: 1;
363}
364
365/* === pluma-doc dentro de la página === */
366.pluma-doc {
367 max-width: 760px;
368 margin: 0 auto;
369 font-family: 'Inter', sans-serif;
370 font-weight: 300;
371 font-size: 1.05rem;
372 line-height: 1.78;
373 color: rgba(232, 234, 245, 0.92);
374}
375.pluma-doc > * + * { margin-top: 1.0em; }
376.pluma-doc h1 {
377 font-family: 'Cinzel', serif;
378 font-weight: 700;
379 font-size: clamp(1.7rem, 3vw, 2.4rem);
380 color: var(--page-accent);
381 text-shadow: 0 0 18px currentColor;
382 letter-spacing: 0.04em;
383 margin-top: 1.4em;
384}
385.pluma-doc h2 {
386 font-family: 'Cinzel', serif;
387 font-weight: 500;
388 font-size: 1.5rem;
389 color: var(--page-accent);
390 letter-spacing: 0.04em;
391 margin-top: 1.6em;
392 padding-bottom: 0.3em;
393 border-bottom: 1px solid rgba(255, 255, 255, 0.10);
394}
395.pluma-doc h3 {
396 font-family: 'Inter', sans-serif;
397 font-weight: 600;
398 font-size: 1.18rem;
399 color: rgba(255, 255, 255, 0.92);
400 letter-spacing: 0.03em;
401 margin-top: 1.6em;
402}
403.pluma-doc p { margin: 0; }
404.pluma-doc a {
405 color: var(--page-accent);
406 text-decoration: none;
407 border-bottom: 1px solid currentColor;
408 transition: opacity 200ms ease;
409}
410.pluma-doc a:hover { opacity: 0.7; }
411.pluma-doc strong { color: rgba(255, 255, 255, 0.98); font-weight: 600; }
412.pluma-doc em { color: rgba(255, 255, 255, 0.92); }
413.pluma-doc code {
414 font-family: 'JetBrains Mono', ui-monospace, monospace;
415 background: rgba(255, 255, 255, 0.06);
416 padding: 0.12em 0.45em;
417 border-radius: 4px;
418 font-size: 0.92em;
419 color: var(--page-accent);
420}
421.pluma-doc pre {
422 background: rgba(0, 0, 0, 0.45);
423 border: 1px solid rgba(255, 255, 255, 0.08);
424 border-left: 3px solid var(--page-accent);
425 border-radius: 8px;
426 padding: 1rem 1.2rem;
427 overflow-x: auto;
428 font-size: 0.92rem;
429}
430.pluma-doc pre code {
431 background: transparent;
432 color: rgba(232, 234, 245, 0.92);
433 padding: 0;
434}
435.pluma-doc blockquote {
436 border-left: 3px solid var(--page-accent);
437 padding: 0.4em 1.2em;
438 color: rgba(232, 234, 245, 0.75);
439 font-style: italic;
440 background: rgba(255, 255, 255, 0.03);
441 border-radius: 0 6px 6px 0;
442}
443.pluma-doc ul, .pluma-doc ol { padding-left: 1.6em; }
444.pluma-doc li { margin: 0.4em 0; }
445.pluma-doc li::marker { color: var(--page-accent); }
446.pluma-doc hr {
447 border: none;
448 height: 1px;
449 background: linear-gradient(to right, transparent, var(--page-accent), transparent);
450 margin: 2em 0;
451}
452.pluma-doc table {
453 border-collapse: collapse;
454 width: 100%;
455 font-size: 0.95rem;
456}
457.pluma-doc th, .pluma-doc td {
458 padding: 0.55em 0.9em;
459 border-bottom: 1px solid rgba(255, 255, 255, 0.08);
460 text-align: left;
461}
462.pluma-doc th {
463 color: var(--page-accent);
464 font-weight: 600;
465 letter-spacing: 0.04em;
466}
467.pluma-loading, .pluma-error {
468 display: flex;
469 align-items: center;
470 justify-content: center;
471 min-height: 30vh;
472 color: rgba(232, 234, 245, 0.55);
473 font-family: 'Cinzel', serif;
474 letter-spacing: 0.4em;
475 font-size: 0.9rem;
476}
477.pluma-loading::before {
478 content: "";
479 width: 28px;
480 height: 28px;
481 margin-right: 1rem;
482 border: 1px solid var(--page-accent);
483 border-top-color: transparent;
484 border-radius: 50%;
485 animation: pluma-spin 1s linear infinite;
486}
487.pluma-error { color: var(--fuego); font-style: italic; }
488@keyframes pluma-spin { to { transform: rotate(360deg); } }
489
490/* === Taskbar estilo Windows === */
491.taskbar {
492 position: fixed;
493 left: 0;
494 right: 0;
495 bottom: 0;
496 height: var(--taskbar-height);
497 z-index: 200;
498 display: flex;
499 align-items: center;
500 gap: 0.5rem;
501 padding: 0 0.8rem;
502 background: linear-gradient(to top, rgba(6, 5, 13, 0.94), rgba(8, 6, 22, 0.80));
503 backdrop-filter: blur(24px) saturate(140%);
504 -webkit-backdrop-filter: blur(24px) saturate(140%);
505 border-top: 1px solid rgba(216, 168, 93, 0.22);
506 box-shadow: 0 -10px 36px rgba(0, 0, 0, 0.45);
507}
508
509.taskbar-home {
510 width: 40px;
511 height: 40px;
512 display: inline-flex;
513 align-items: center;
514 justify-content: center;
515 background: transparent;
516 border: 1px solid rgba(216, 168, 93, 0.32);
517 color: var(--gold);
518 border-radius: 9px;
519 cursor: pointer;
520 padding: 0;
521 transition: all 220ms var(--ease-emerge);
522}
523.taskbar-home:hover {
524 border-color: var(--gold);
525 background: rgba(216, 168, 93, 0.12);
526 box-shadow: 0 0 16px rgba(216, 168, 93, 0.35);
527 transform: translateY(-1px);
528}
529.taskbar-home-glyph {
530 width: 22px;
531 height: 22px;
532 filter: drop-shadow(0 0 6px currentColor);
533}
534
535.taskbar-brand {
536 font-family: 'Cinzel', serif;
537 font-weight: 700;
538 font-size: 1.30rem;
539 letter-spacing: 0.07em;
540 color: #f4eedf;
541 text-decoration: none;
542 text-shadow: 0 0 14px rgba(216, 168, 93, 0.45);
543 padding: 0 0.55rem;
544 user-select: none;
545 transition: text-shadow 220ms ease, color 220ms ease;
546 white-space: nowrap;
547}
548.taskbar-brand:hover {
549 color: #ffffff;
550 text-shadow: 0 0 20px rgba(216, 168, 93, 0.7), 0 0 36px rgba(245, 144, 86, 0.30);
551}
552.taskbar-brand .brand-dot {
553 color: var(--gold);
554 margin: 0 0.05em;
555}
556
557.taskbar-divider {
558 display: inline-block;
559 width: 1px;
560 height: 26px;
561 background: rgba(255, 255, 255, 0.12);
562 margin: 0 0.25rem;
563}
564
565.taskbar-list {
566 list-style: none;
567 margin: 0;
568 padding: 0;
569 display: flex;
570 gap: 0.4rem;
571 overflow-x: auto;
572 scrollbar-width: none;
573 -ms-overflow-style: none;
574}
575.taskbar-list::-webkit-scrollbar { display: none; }
576
577.taskbar-item {
578 height: 38px;
579 padding: 0 1.0rem;
580 display: inline-flex;
581 align-items: center;
582 gap: 0.55rem;
583 background: rgba(255, 255, 255, 0.04);
584 border: 1px solid rgba(255, 255, 255, 0.10);
585 border-radius: 9px;
586 color: var(--task-color, var(--fg));
587 font-family: 'Cinzel', serif;
588 font-size: 0.72rem;
589 letter-spacing: 0.36em;
590 text-indent: 0.36em;
591 font-weight: 600;
592 cursor: pointer;
593 transition: all 260ms var(--ease-emerge);
594 white-space: nowrap;
595}
596.taskbar-item:hover {
597 background: rgba(255, 255, 255, 0.09);
598 border-color: var(--task-color, currentColor);
599 transform: translateY(-1px);
600}
601.taskbar-item.active {
602 background: rgba(255, 255, 255, 0.11);
603 border-color: var(--task-color);
604 box-shadow:
605 0 0 18px var(--task-color),
606 inset 0 -2px 0 0 var(--task-color);
607}
608.taskbar-item-dot {
609 width: 8px;
610 height: 8px;
611 border-radius: 50%;
612 background: var(--task-color, var(--gold));
613 box-shadow: 0 0 8px currentColor;
614}
615.taskbar-item[data-task="aire"] { --task-color: var(--aire); }
616.taskbar-item[data-task="fuego"] { --task-color: var(--fuego); }
617.taskbar-item[data-task="tierra"] { --task-color: var(--tierra); }
618.taskbar-item[data-task="agua"] { --task-color: var(--agua); }
619
620.taskbar-spacer {
621 flex: 1;
622 min-width: 0.6rem;
623}
624
625.taskbar-credit {
626 display: inline-flex;
627 align-items: center;
628 gap: 0.4rem;
629 font-family: 'Inter', sans-serif;
630 font-size: 0.78rem;
631 letter-spacing: 0.04em;
632 color: rgba(216, 168, 93, 0.75);
633 text-decoration: none;
634 padding: 0.35rem 0.7rem;
635 border-radius: 8px;
636 border: 1px solid transparent;
637 transition: all 220ms var(--ease-emerge);
638 white-space: nowrap;
639}
640.taskbar-credit:hover {
641 color: var(--gold);
642 border-color: rgba(216, 168, 93, 0.25);
643 background: rgba(216, 168, 93, 0.06);
644}
645.copyleft-mark {
646 display: inline-block;
647 font-size: 1rem;
648 /* © con escala horizontal -1 = copyleft visual. */
649 transform: scaleX(-1);
650 color: currentColor;
651}
652
653@media (max-width: 720px) {
654 .tip { min-width: 110px; padding: 0.7rem 0.9rem; }
655 .tip-glyph { width: 36px; height: 36px; }
656 .tip-label { font-size: 0.72rem; }
657 .tip-sub { display: none; }
658 .page-head { padding: 5vh 5vw 1vh; }
659 .page-content { padding: 0 5vw 5vh; }
660 .taskbar { height: 46px; padding: 0 0.4rem; gap: 0.3rem; }
661 .taskbar-home { width: 36px; height: 36px; }
662 .taskbar-item { height: 34px; padding: 0 0.7rem; font-size: 0.65rem; }
663 .taskbar-brand { font-size: 1.05rem; padding: 0 0.3rem; }
664 .taskbar-credit-text { display: none; }
665 .deck { bottom: 46px; }
666 :root { --taskbar-height: 46px; }
667}