233 lines
5.8 KiB
CSS
233 lines
5.8 KiB
CSS
/* Bolo de aniversário do tema sazonal Aniversário (56 anos da De Paula
|
|
Contadores, só 15/10) — canto inferior-direito da tela Principal, com
|
|
velinhas que o usuário apaga clicando. Escondido por padrão (`hidden` no
|
|
HTML) e só exibido via `pidApplyAniversarioCake()` (seasonal-theme.js)
|
|
quando `pidIsAniversarioActive()` — ver
|
|
`docs/temas-sazonais/temas-sazonais.md`. */
|
|
|
|
.pid-aniv-cake {
|
|
position: fixed;
|
|
right: 20px;
|
|
bottom: 16px;
|
|
width: clamp(90px, 9vw, 130px);
|
|
z-index: 5;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.pid-aniv-cake__btn {
|
|
all: unset;
|
|
display: block;
|
|
width: 100%;
|
|
cursor: pointer;
|
|
pointer-events: auto;
|
|
}
|
|
|
|
.pid-aniv-cake__btn svg {
|
|
display: block;
|
|
width: 100%;
|
|
height: auto;
|
|
overflow: visible;
|
|
filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.4));
|
|
}
|
|
|
|
.pid-cake-shadow {
|
|
fill: rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
/* Cada gotejamento é da cor da camada DE CIMA (escorre sobre a de baixo) —
|
|
pintá-lo da mesma cor da própria camada o tornaria invisível. */
|
|
.pid-cake-tier2 {
|
|
fill: #7b5ba8;
|
|
}
|
|
|
|
.pid-cake-drip2 {
|
|
fill: #c6a24a;
|
|
}
|
|
|
|
.pid-cake-tier1 {
|
|
fill: #c6a24a;
|
|
}
|
|
|
|
.pid-cake-drip1 {
|
|
fill: #f2ede3;
|
|
}
|
|
|
|
.pid-cake-dot--blue {
|
|
fill: #2e86de;
|
|
}
|
|
|
|
.pid-cake-dot--pink {
|
|
fill: #e8446e;
|
|
}
|
|
|
|
.pid-cake-dot--amber {
|
|
fill: #f2a93b;
|
|
}
|
|
|
|
/* A luz das velas é feita em duas camadas: o `drop-shadow` aqui é o brilho
|
|
colado na própria chama (o "núcleo"), e `.pid-cake-halo` abaixo é o halo
|
|
largo de luz no ar em volta das velas. Os dois pulsam, mas em ciclos de
|
|
durações diferentes (1,4s e 2,6s) pra não parecerem sincronizados —
|
|
fogo real não pisca no compasso. O `filter` fica também na regra base (não
|
|
só nos keyframes) pra o brilho continuar existindo enquanto a chama se
|
|
apaga, quando `pidCakeFlameOut` assume o lugar do tremular. */
|
|
.pid-cake-flame {
|
|
fill: #f2a93b;
|
|
transform-box: fill-box;
|
|
transform-origin: center bottom;
|
|
filter: drop-shadow(0 0 2px rgba(242, 169, 59, 0.95)) drop-shadow(0 0 7px rgba(242, 169, 59, 0.5));
|
|
animation: pidCakeFlicker 1.4s ease-in-out infinite;
|
|
}
|
|
|
|
.pid-cake-halo {
|
|
/* Pico da intensidade — o tema claro abaixa (um brilho quente sobre fundo
|
|
claro vira névoa suja em vez de luz). */
|
|
--halo-max: 1;
|
|
transform-box: fill-box;
|
|
transform-origin: center;
|
|
animation: pidCakeHalo 2.6s ease-in-out infinite;
|
|
}
|
|
|
|
:root[data-theme="light"] .pid-cake-halo {
|
|
--halo-max: 0.5;
|
|
}
|
|
|
|
/* `nth-of-type` (não `nth-child`): as 3 velas são os 3 únicos `<g>` do SVG,
|
|
mas estão cercadas de `<path>`/`<circle>` do bolo, então a contagem por
|
|
posição absoluta não acertaria nenhuma delas. */
|
|
.pid-cake-candle:nth-of-type(2) .pid-cake-flame {
|
|
animation-delay: -0.5s;
|
|
}
|
|
|
|
.pid-cake-candle:nth-of-type(3) .pid-cake-flame {
|
|
animation-delay: -0.9s;
|
|
}
|
|
|
|
.pid-cake-smoke {
|
|
stroke: #b9aecb;
|
|
stroke-width: 1.1;
|
|
fill: none;
|
|
stroke-linecap: round;
|
|
opacity: 0;
|
|
/* Sem `fill-box`, o `scale` da fumaça subindo cresceria a partir da origem
|
|
do viewBox e jogaria o traço pra longe do pavio. */
|
|
transform-box: fill-box;
|
|
transform-origin: center bottom;
|
|
}
|
|
|
|
/* Clicar apaga as velinhas — toca uma vez (`pidApplyAniversarioCake()`,
|
|
seasonal-theme.js, adiciona `.is-blowing` no clique e troca pra `.is-blown`
|
|
`PID_CAKE_BLOW_MS` depois). `.is-blown` é o estado final em repouso (sem
|
|
`animation`), e dura só até o próximo carregamento da página: as velinhas
|
|
reacendem sozinhas, o estado apagado não é persistido de propósito (ver
|
|
`docs/temas-sazonais/temas-sazonais.md`). */
|
|
.pid-aniv-cake.is-blowing .pid-cake-flame {
|
|
animation: pidCakeFlameOut 500ms ease-out forwards;
|
|
}
|
|
|
|
.pid-aniv-cake.is-blowing .pid-cake-smoke {
|
|
animation: pidCakeSmokeRise 1400ms ease-out forwards;
|
|
}
|
|
|
|
.pid-aniv-cake.is-blowing .pid-cake-halo {
|
|
animation: pidCakeHaloOut 600ms ease-out forwards;
|
|
}
|
|
|
|
.pid-aniv-cake.is-blown .pid-cake-flame {
|
|
animation: none;
|
|
opacity: 0;
|
|
}
|
|
|
|
.pid-aniv-cake.is-blown .pid-cake-smoke {
|
|
animation: none;
|
|
opacity: 0;
|
|
}
|
|
|
|
.pid-aniv-cake.is-blown .pid-cake-halo {
|
|
animation: none;
|
|
opacity: 0;
|
|
}
|
|
|
|
.pid-aniv-cake.is-blowing .pid-aniv-cake__btn,
|
|
.pid-aniv-cake.is-blown .pid-aniv-cake__btn {
|
|
cursor: default;
|
|
pointer-events: none;
|
|
}
|
|
|
|
@keyframes pidCakeFlicker {
|
|
0%, 100% {
|
|
transform: scale(1) rotate(0deg);
|
|
opacity: 1;
|
|
filter: drop-shadow(0 0 2px rgba(242, 169, 59, 0.95)) drop-shadow(0 0 7px rgba(242, 169, 59, 0.5));
|
|
}
|
|
50% {
|
|
transform: scale(1.08) rotate(-3deg);
|
|
opacity: 0.9;
|
|
filter: drop-shadow(0 0 3px rgba(242, 169, 59, 1)) drop-shadow(0 0 11px rgba(242, 169, 59, 0.7));
|
|
}
|
|
}
|
|
|
|
@keyframes pidCakeHalo {
|
|
0%, 100% {
|
|
opacity: calc(var(--halo-max) * 0.72);
|
|
transform: scale(1);
|
|
}
|
|
50% {
|
|
opacity: var(--halo-max);
|
|
transform: scale(1.06);
|
|
}
|
|
}
|
|
|
|
@keyframes pidCakeFlameOut {
|
|
0% {
|
|
opacity: 1;
|
|
transform: scale(1) skewX(0deg);
|
|
filter: drop-shadow(0 0 3px rgba(242, 169, 59, 1)) drop-shadow(0 0 11px rgba(242, 169, 59, 0.7));
|
|
}
|
|
40% {
|
|
opacity: 0.6;
|
|
transform: scale(1.3) skewX(14deg);
|
|
filter: drop-shadow(0 0 2px rgba(242, 169, 59, 0.6)) drop-shadow(0 0 6px rgba(242, 169, 59, 0.3));
|
|
}
|
|
100% {
|
|
opacity: 0;
|
|
transform: scale(0.2) skewX(0deg);
|
|
filter: drop-shadow(0 0 0 rgba(242, 169, 59, 0));
|
|
}
|
|
}
|
|
|
|
/* A luz morre junto com a chama — um halo sobrevivendo às velas apagadas
|
|
deixaria uma mancha quente boiando no canto da tela. */
|
|
@keyframes pidCakeHaloOut {
|
|
0% {
|
|
opacity: calc(var(--halo-max) * 0.85);
|
|
transform: scale(1);
|
|
}
|
|
100% {
|
|
opacity: 0;
|
|
transform: scale(0.82);
|
|
}
|
|
}
|
|
|
|
@keyframes pidCakeSmokeRise {
|
|
0% {
|
|
opacity: 0;
|
|
transform: translateY(0) scale(1);
|
|
}
|
|
15% {
|
|
opacity: 0.65;
|
|
}
|
|
100% {
|
|
opacity: 0;
|
|
transform: translateY(-14px) scale(1.7);
|
|
}
|
|
}
|
|
|
|
@media (max-width: 600px) {
|
|
.pid-aniv-cake {
|
|
width: clamp(72px, 20vw, 96px);
|
|
right: 12px;
|
|
bottom: 12px;
|
|
}
|
|
}
|