diff --git a/CLAUDE.md b/CLAUDE.md index 1ce4a3f..e73a9a8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -59,7 +59,7 @@ Pure HTML/CSS/JS, no external dependencies. All visuals are self-contained: | Milky Way | Per-pixel sampling of `milkyway.jpg` (Gaia photo, full res): `buildMwGrid` caches viewport unit vectors + extinction/glare, `renderMilkyWay` applies only the sidereal rotation (camera azimuth folded into the equatorial→galactic matrix) and stylized "development" (deep blacks, saturation, cool shadows). Decoded texture stays resident (~75 MB) | | Moon & planets | Astronomy Engine topocentric ephemerides: Moon with real phase texture + bright-limb angle, 7 planets with magnitude-scaled dots (labels only in constellation mode) | | Zodiac constellations | Stellarium Modern lines (traces only, no artwork); toggled via `/tmp` file or `C` key | -| Day mode | Real sun altitude (Astronomy Engine, follows the timelapse clock) drives `--sun-bottom` (horizon → ~78% at culmination) and a `dia` body class: light blue/pink `#daySky`, bright sun disc, golden horizon, stars/nebulae fade out, dancer replaced by a CSS coffin. Balada/chuva override day visuals via `:not()` selectors | +| Day mode | Real sun altitude (Astronomy Engine, follows the timelapse clock) drives `--sun-bottom` (horizon → ~78% at culmination) and a `dia` body class: pink vaporwave `#daySky` with green grass below the horizon, drifting CSS clouds, bright sun disc, golden horizon, stars dimmed to ghosts (0.12), dancer replaced by a grounded gravestone (flattened-ellipse mound/shadow for perspective, no religious symbols). Balada/chuva override day visuals via `:not()` selectors | | Nebula blobs, grid floor, horizon | CSS animations | | DANCEBOT-9000 robot | Pure CSS (divs + `@keyframes`) | | Chest EQ bars & VU meter | JS-driven `requestAnimationFrame` | diff --git a/plugin/contents/ui/dancer.html b/plugin/contents/ui/dancer.html index c557bdd..d9a232e 100644 --- a/plugin/contents/ui/dancer.html +++ b/plugin/contents/ui/dancer.html @@ -1132,7 +1132,8 @@ body.chuva #sunChuvaFace { opacity: 1; transition: opacity 5s ease; } Balada e chuva têm prioridade sobre o visual diurno. ============================================================ */ -/* Céu diurno: azul lá em cima, rosa no horizonte, lilás sob a grade */ +/* Céu diurno vaporwave: rosa orquídea -> pêssego no horizonte, + e o chão vira gramado verde sob a grade neon */ #daySky { position: absolute; inset: 0; @@ -1140,20 +1141,54 @@ body.chuva #sunChuvaFace { opacity: 1; transition: opacity 5s ease; } opacity: 0; transition: opacity 12s ease; background: linear-gradient(to bottom, - #5fb2ef 0%, - #8fd0f7 32%, - #cfeaff 50%, - #ffd9ec 58.5%, - #f2e2ff 58.6%, - #d9c8f0 100%); + #c86fe0 0%, + #f18ade 26%, + #ffaede 44%, + #ffcfe0 54%, + #ffe4c9 58.5%, + #86e29e 58.6%, + #4fbb6b 78%, + #2e9550 100%); } body.dia:not(.balada):not(.chuva) #daySky { opacity: 1; } -/* Estrelas, nebulosas e meteoros ofuscados pela luz do dia */ -body.dia:not(.balada):not(.chuva) #starfield { opacity: 0; transition: opacity 12s ease; } +/* Estrelas viram fantasmas de dia; nebulosas e meteoros somem */ +body.dia:not(.balada):not(.chuva) #starfield { opacity: 0.12; transition: opacity 12s ease; } body.dia:not(.balada):not(.chuva) .nebula { opacity: 0; } body.dia:not(.balada):not(.chuva) #meteorLayer { opacity: 0; } +/* Nuvens diurnas: chapadas embaixo, fofas em cima, rosadas por baixo */ +.day-cloud { + position: absolute; + border-radius: 10vh; + pointer-events: none; + opacity: 0; + transition: opacity 12s ease; + background: linear-gradient(to bottom, #fffdfe 0%, #ffe4f2 62%, #ffc7e6 100%); + box-shadow: 0 1.6vh 3.2vh rgba(255,110,200,0.20); + animation: cloudDrift ease-in-out infinite alternate; +} +.day-cloud::before, .day-cloud::after { + content: ''; + position: absolute; + border-radius: 50%; + background: inherit; +} +.cloud-a { width: 30vh; height: 7.5vh; top: 9%; left: 10%; animation-duration: 110s; } +.cloud-a::before { width: 11vh; height: 11vh; top: -5.2vh; left: 5vh; } +.cloud-a::after { width: 14vh; height: 14vh; top: -6.4vh; right: 6vh; } +.cloud-b { width: 22vh; height: 5.5vh; top: 20%; right: 12%; animation-duration: 140s; animation-delay: -40s; } +.cloud-b::before { width: 8vh; height: 8vh; top: -3.8vh; left: 3.6vh; } +.cloud-b::after { width: 10vh; height: 10vh; top: -4.6vh; right: 4.4vh; } +.cloud-c { width: 16vh; height: 4.2vh; top: 33%; left: 30%; animation-duration: 90s; animation-delay: -70s; } +.cloud-c::before { width: 6vh; height: 6vh; top: -2.8vh; left: 2.6vh; } +.cloud-c::after { width: 7.5vh; height: 7.5vh; top: -3.4vh; right: 3.2vh; } +@keyframes cloudDrift { + from { transform: translateX(-3vw); } + to { transform: translateX(3vw); } +} +body.dia:not(.balada):not(.chuva) .day-cloud { opacity: 0.92; } + /* O sol vira sol de verdade: disco quente, sem listras retrô */ #sunDiaBg { position: absolute; @@ -1196,55 +1231,96 @@ body.dia:not(.balada):not(.chuva) .horizon { box-shadow: 0 0 25px rgba(255,210,130,0.7), 0 0 80px rgba(255,190,110,0.25); } -/* De dia o esqueleto dorme: some o dançarino, aparece o caixão */ +/* De dia o esqueleto dorme: some o dançarino, fica a lápide no gramado. + Perspectiva: monte e sombra são elipses bem achatadas no plano do chão, + e a pedra fica plantada entre o horizonte (41.5%) e a borda inferior. */ body.dia:not(.balada):not(.chuva) .robot-wrap { opacity: 0 !important; } -.coffin-wrap { +.grave-wrap { position: absolute; left: 50%; - bottom: 28%; + bottom: 22%; transform: translateX(-50%); opacity: 0; transition: opacity 4s ease; pointer-events: none; } -body.dia:not(.balada):not(.chuva) .coffin-wrap { opacity: 1; } -.coffin-shade { +body.dia:not(.balada):not(.chuva) .grave-wrap { opacity: 1; } + +/* sombra projetada no gramado (elipse rasa = objeto apoiado no plano) */ +.grave-shade { position: absolute; - bottom: -1.6vh; + bottom: -2.6vh; left: 50%; transform: translateX(-50%); - width: 22vh; - height: 3.2vh; + width: 30vh; + height: 4.6vh; border-radius: 50%; - background: radial-gradient(ellipse, rgba(40,20,40,0.38), transparent 70%); + background: radial-gradient(ellipse, rgba(25,60,35,0.42), transparent 68%); } -.coffin { + +/* montinho de terra gramado aos pés da pedra */ +.grave-mound { + position: absolute; + bottom: -1.8vh; + left: 50%; + transform: translateX(-50%); + width: 26vh; + height: 5vh; + border-radius: 50%; + background: linear-gradient(to bottom, #6fd486 0%, #43a75f 60%, #2e8348 100%); + box-shadow: inset 0 0.7vh 1.2vh rgba(255,255,210,0.30); +} + +/* pedra: topo arredondado, granito lilás com luz rosa do céu */ +.gravestone { position: relative; width: 15vh; - height: 34vh; - clip-path: polygon(32% 0%, 68% 0%, 100% 26%, 73% 100%, 27% 100%, 0% 26%); + height: 19vh; + border-radius: 7.5vh 7.5vh 0.8vh 0.8vh; background: - linear-gradient(105deg, rgba(255,255,255,0.10), rgba(0,0,0,0.24) 62%), - linear-gradient(to bottom, #7a4a28 0%, #5c3620 46%, #452716 100%); - filter: drop-shadow(0 6px 18px rgba(60,30,20,0.45)); + linear-gradient(115deg, + rgba(255,170,225,0.38) 0%, rgba(255,255,255,0.10) 34%, + rgba(30,18,55,0.28) 100%), + linear-gradient(to bottom, #bfaed4 0%, #9789b4 55%, #6f6494 100%); + box-shadow: + inset 0 -1.4vh 2.2vh rgba(28,16,52,0.38), + 0 0 26px rgba(255,120,200,0.30); } -.coffin::before { /* costura da tampa */ - content: ''; +/* inscrição gravada (rebaixo: sombra clara embaixo, escura em cima) */ +.grave-text { position: absolute; - left: 6%; right: 6%; - top: 26%; - height: 3px; - background: rgba(0,0,0,0.45); - border-radius: 2px; + top: 23%; + width: 100%; + text-align: center; + font-family: 'Courier New', monospace; + font-weight: bold; + font-size: 3vh; + letter-spacing: 0.3vh; + color: #4c4170; + text-shadow: 0 1px 0 rgba(255,255,255,0.38), 0 -1px 1px rgba(18,10,40,0.65); } -.coffin-cross-v, .coffin-cross-h { +.grave-line { position: absolute; - background: linear-gradient(to bottom, #e8c87e, #c9a250); - border-radius: 2px; - box-shadow: 0 0 10px rgba(255,225,150,0.55); + top: 48%; + left: 22%; right: 22%; + height: 0.55vh; + border-radius: 0.3vh; + background: rgba(64,54,96,0.55); + box-shadow: 0 1px 0 rgba(255,255,255,0.30); } -.coffin-cross-v { left: 50%; top: 36%; width: 0.9vh; height: 24%; transform: translateX(-50%); } -.coffin-cross-h { left: 50%; top: 42%; width: 34%; height: 0.9vh; transform: translateX(-50%); } +.grave-line.short { top: 56%; left: 30%; right: 30%; } + +/* tufos de grama para amarrar a base na cena */ +.grass-tuft { + position: absolute; + bottom: -0.6vh; + width: 3vh; + height: 3.6vh; + clip-path: polygon(8% 100%, 22% 22%, 36% 100%, 50% 0%, 64% 100%, 80% 30%, 94% 100%); + background: linear-gradient(to top, #2e8a48, #74dd8d); +} +.tuft-l { left: -8vh; } +.tuft-r { right: -7vh; transform: scaleX(-1); } @@ -1254,6 +1330,9 @@ body.dia:not(.balada):not(.chuva) .coffin-wrap { opacity: 1; }
+
+
+
@@ -1295,13 +1374,17 @@ body.dia:not(.balada):not(.chuva) .coffin-wrap { opacity: 1; } - -
-
-
-
-
+ +
+
+
+
+
R.I.P.
+
+
+
+