<div class="scene-frame">
<div class="scene">
<div class="holder">
<div class="candle">
<div class="candle-light"></div>
<div class="wax-top"></div>
<div class="wax-lip"><span class="lip-notch n1"></span><span class="lip-notch n2"></span><span class="lip-notch n3"></span></div>
<div class="wax-crater"></div>
<div class="wax-pool"></div>
<div class="drip"></div>
<div class="drip drip-left"></div>
<div class="frozen-drip fd1"></div>
<div class="frozen-drip fd2"></div>
<div class="frozen-drip fd3"></div>
<div class="wax-grain"></div>
<div class="wax-scuff s1"></div>
<div class="wax-scuff s2"></div>
<div class="wax-scuff s3"></div>
<div class="blinking-glow"></div>
<div class="flame-halo"></div>
<div class="thread"></div>
<div class="glow"></div>
<div class="flame"></div>
</div>
</div>
</div>
</div>
:root {
--bg: #15110f;
--wax-light: #e8604a;
--wax-mid: #9c1f1f;
--wax-dark: #470c0c;
--wax-deep: #220505;
--scene-w: 320;
--scene-h: 610;
--frame-w: min(320px, calc(100vw - 24px), calc((100dvh - 24px) * var(--scene-w) / var(--scene-h)));
--scene-scale: calc(var(--frame-w) / (var(--scene-w) * 1px));
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
width: 100%;
min-height: 100%;
}
body {
min-height: 100vh;
min-height: 100dvh;
overflow: hidden;
display: grid;
place-items: center;
padding: 12px;
color: #fff;
background:
radial-gradient(circle at 50% 35%, rgba(255, 134, 32, .11) 0 8%, rgba(255, 104, 22, .045) 18%, transparent 44%),
radial-gradient(circle at 50% 84%, rgba(0, 0, 0, .08), rgba(0, 0, 0, .52) 58%, rgba(0, 0, 0, .78) 100%),
var(--bg);
}
.scene-frame {
width: var(--frame-w);
aspect-ratio: var(--scene-w) / var(--scene-h);
display: grid;
place-items: center;
overflow: visible;
}
.scene {
position: relative;
width: calc(var(--scene-w) * 1px);
height: calc(var(--scene-h) * 1px);
display: flex;
align-items: flex-end;
justify-content: center;
isolation: isolate;
transform: scale(var(--scene-scale));
transform-origin: center center;
}
/* halo général projeté par la flamme */
.scene::before {
content: "";
position: absolute;
left: 50%;
top: 60px;
width: 260px;
height: 330px;
transform: translateX(-50%);
border-radius: 50%;
background: radial-gradient(ellipse at center,
rgba(255, 186, 74, .20) 0%,
rgba(255, 113, 21, .09) 32%,
rgba(255, 84, 8, .03) 52%,
transparent 74%);
filter: blur(16px);
pointer-events: none;
animation: roomGlow 2.8s ease-in-out infinite alternate;
}
.scene::after {
content: "";
position: absolute;
bottom: 5px;
left: 50%;
width: 205px;
height: 34px;
transform: translateX(-50%);
border-radius: 50%;
background: rgba(0, 0, 0, .58);
filter: blur(14px);
z-index: -2;
}
.holder {
position: relative;
width: 170px;
height: 470px;
}
.candle {
position: absolute;
left: 50%;
bottom: 0;
width: 170px;
height: 320px;
transform: translateX(-50%);
border-radius: 18px 21px 82px 88px / 26px 24px 42px 38px;
overflow: visible;
isolation: isolate;
background:
radial-gradient(74px 170px at 52% 10%, rgba(255, 190, 180, .16), transparent 52%),
radial-gradient(42px 180px at 30% 18%, rgba(255,255,255,.05), transparent 68%),
linear-gradient(90deg,
rgba(20, 2, 2, .62) 0%,
rgba(90, 10, 10, .88) 10%,
rgba(178, 26, 26, .98) 29%,
rgba(214, 45, 45, .97) 45%,
rgba(150, 20, 20, .98) 66%,
rgba(66, 10, 10, .98) 89%,
rgba(24, 3, 3, 1) 100%),
linear-gradient(180deg,
#c4342c 0%,
#9c1f1f 18%,
#6e1414 48%,
#470c0c 71%,
#220505 100%);
box-shadow:
inset 16px 0 24px rgba(255, 140, 130, .12),
inset -22px 0 32px rgba(0, 0, 0, .42),
inset 0 -45px 55px rgba(0, 0, 0, .34),
0 26px 44px rgba(0, 0, 0, .38);
z-index: 1;
}
/* translucidité orangée dans les premiers centimètres de cire */
.candle::before {
content: "";
position: absolute;
left: 50%;
top: -2px;
width: 140px;
height: 170px;
transform: translateX(-50%);
pointer-events: none;
z-index: 2;
opacity: .95;
background:
radial-gradient(ellipse at 50% 8%, rgba(255, 140, 110, .34) 0%, rgba(255, 90, 70, .24) 18%, rgba(255, 60, 50, .14) 34%, rgba(255, 50, 40, .06) 52%, transparent 74%),
radial-gradient(ellipse at 45% 18%, rgba(255, 200, 190, .08), transparent 54%);
filter: blur(8px);
mix-blend-mode: screen;
}
/* texture très discrète de la cire */
.candle::after {
content: "";
position: absolute;
inset: 10px 9px 8px;
border-radius: inherit;
opacity: .38;
pointer-events: none;
z-index: 3;
background:
radial-gradient(circle at 19% 17%, rgba(255,255,255,.12) 0 1px, transparent 1.5px),
radial-gradient(circle at 66% 13%, rgba(255,255,255,.08) 0 1px, transparent 1.5px),
radial-gradient(circle at 76% 44%, rgba(255,255,255,.055) 0 1px, transparent 1.5px),
radial-gradient(circle at 34% 62%, rgba(0,0,0,.18) 0 1px, transparent 1.8px),
radial-gradient(circle at 58% 79%, rgba(255,255,255,.055) 0 1px, transparent 1.5px),
linear-gradient(87deg, transparent 0 39%, rgba(255,255,255,.04) 42%, transparent 46%),
linear-gradient(94deg, transparent 0 68%, rgba(0,0,0,.11) 71%, transparent 75%);
background-size: 31px 37px, 43px 29px, 37px 41px, 29px 33px, 47px 35px, auto, auto;
mix-blend-mode: soft-light;
}
/* plateau supérieur + bord de cire irrégulier */
.wax-top {
position: absolute;
left: 50%;
top: -18px;
width: 170px;
height: 50px;
transform: translateX(-50%) rotate(-.25deg);
border-radius: 50%;
background:
radial-gradient(ellipse at 48% 44%, #f0705d 0 3%, #c92f2f 27%, #7a1414 61%, #430b0b 83%, #260505 100%);
box-shadow:
inset 0 7px 9px rgba(255, 150, 140, .28),
inset 0 -9px 13px rgba(60, 10, 10, .52),
0 3px 2px rgba(255, 110, 100, .16);
z-index: 6;
}
.wax-top::before {
content: "";
position: absolute;
inset: 4px 8px 5px;
border-radius: 50%;
background:
radial-gradient(ellipse at 49% 46%,
rgba(255, 140, 120, .65) 0 4%,
rgba(200, 40, 35, .84) 32%,
rgba(110, 20, 15, .86) 65%,
rgba(55, 10, 8, .95) 100%);
box-shadow:
inset 0 4px 5px rgba(255, 170, 160, .20),
inset 0 -4px 6px rgba(35, 5, 5, .60);
}
/* petites bosses du rebord : donnent un contour moins géométrique */
.wax-lip {
position: absolute;
left: 50%;
top: -15px;
width: 166px;
height: 47px;
transform: translateX(-50%);
border-radius: 49% 51% 46% 54% / 54% 50% 50% 46%;
border: 5px solid rgba(180, 30, 25, .92);
border-top-color: rgba(220, 70, 55, .94);
border-left-width: 6px;
border-right-width: 7px;
filter: drop-shadow(0 2px 1px rgba(55, 10, 8, .5));
z-index: 7;
}
.wax-lip::before,
.wax-lip::after {
content: "";
position: absolute;
border-radius: 50%;
background: #a02020;
box-shadow: inset 0 2px 2px rgba(255, 140, 120, .25);
}
.wax-lip::before {
width: 20px;
height: 10px;
left: 12px;
top: 1px;
transform: rotate(-7deg);
}
.wax-lip::after {
width: 16px;
height: 9px;
right: 17px;
top: -1px;
transform: rotate(8deg);
}
/* cratère creusé autour de la cire liquide */
.wax-crater {
position: absolute;
left: 50%;
top: -8px;
width: 128px;
height: 34px;
transform: translateX(-50%) rotate(-.35deg);
border-radius: 50%;
z-index: 8;
background:
radial-gradient(ellipse at 50% 48%, rgba(255, 170, 150, .10) 0 10%, rgba(120, 20, 18, .18) 30%, rgba(80, 14, 12, .52) 58%, rgba(30, 6, 5, .92) 100%);
box-shadow:
inset 0 7px 7px rgba(255, 150, 130, .08),
inset 0 -10px 10px rgba(18, 3, 3, .52);
}
/* cire liquide au centre */
.wax-pool {
position: absolute;
left: 50%;
top: -3px;
width: 112px;
height: 31px;
transform: translateX(-50%) rotate(-.6deg);
border-radius: 50%;
z-index: 9;
background:
radial-gradient(ellipse at 50% 30%, rgba(255, 220, 200, .88) 0 7%, rgba(255, 160, 140, .62) 17%, rgba(224, 60, 50, .84) 34%, rgba(150, 25, 20, .94) 64%, rgba(70, 12, 10, .98) 100%);
box-shadow:
inset 0 2px 2px rgba(255, 220, 210, .45),
inset 0 8px 10px rgba(255, 160, 140, .08),
inset 0 -7px 10px rgba(70, 12, 10, .50),
0 0 15px rgba(255, 60, 50, .12);
}
.wax-pool::before {
content: "";
position: absolute;
left: 22px;
top: 6px;
width: 46px;
height: 9px;
border-radius: 50%;
background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255, 220, 210, .72), rgba(255,255,255,.05));
filter: blur(.35px);
opacity: .85;
}
.wax-pool::after {
content: "";
position: absolute;
left: 50%;
top: 9px;
width: 60px;
height: 9px;
transform: translateX(-50%);
border-radius: 50%;
background: radial-gradient(ellipse at center, rgba(255, 210, 200, .42), rgba(255, 120, 100, .08) 63%, transparent 72%);
filter: blur(.3px);
}
/* une coulure discrète sur le côté */
.drip {
position: absolute;
right: 13px;
top: 19px;
width: 12px;
height: 67px;
border-radius: 7px 7px 10px 10px;
background: linear-gradient(90deg, rgba(85,15,12,.62), rgba(180,35,30,.80) 45%, rgba(82,14,12,.72));
box-shadow: inset 2px 0 3px rgba(255, 120, 100, .14), 2px 2px 5px rgba(0,0,0,.15);
opacity: .78;
z-index: 16;
}
.drip::after {
content: "";
position: absolute;
left: 1px;
bottom: -4px;
width: 10px;
height: 12px;
border-radius: 50%;
background: #601515;
}
/* petite irrégularité de corps sur l'autre côté */
.drip-left {
left: 16px;
right: auto;
top: 28px;
width: 8px;
height: 44px;
border-radius: 7px 7px 8px 8px;
background: linear-gradient(90deg, rgba(75,12,10,.40), rgba(190,45,38,.56) 45%, rgba(80,14,12,.52));
opacity: .36;
}
.drip-left::after {
width: 7px;
height: 8px;
left: 0;
bottom: -2px;
}
/* bord supérieur fondu : irrégularités plus organiques */
.wax-lip {
clip-path: polygon(
0% 47%, 4% 34%, 9% 30%, 13% 18%, 20% 23%, 25% 12%,
31% 19%, 36% 11%, 43% 18%, 49% 8%, 56% 16%, 63% 12%,
69% 20%, 76% 14%, 82% 24%, 88% 19%, 94% 31%, 100% 39%,
100% 100%, 0% 100%
);
}
.wax-lip .lip-notch {
position: absolute;
top: 0;
width: 15px;
height: 11px;
border-radius: 50%;
background: radial-gradient(circle at 50% 65%, rgba(75, 10, 10, .82) 0 38%, rgba(140, 25, 20, .45) 48%, transparent 70%);
filter: blur(.15px);
opacity: .82;
}
.wax-lip .lip-notch.n1 { left: 37px; transform: rotate(-8deg); }
.wax-lip .lip-notch.n2 { left: 77px; width: 12px; height: 9px; transform: rotate(6deg); opacity: .7; }
.wax-lip .lip-notch.n3 { right: 30px; width: 14px; height: 10px; transform: rotate(10deg); opacity: .74; }
/* coulures figées : épaisseurs et reliefs différents */
.frozen-drip {
position: absolute;
z-index: 15;
pointer-events: none;
background:
linear-gradient(90deg,
rgba(65, 12, 10, .55) 0%,
rgba(165, 32, 26, .86) 28%,
rgba(214, 55, 45, .78) 52%,
rgba(100, 18, 15, .76) 100%);
box-shadow:
inset 2px 0 2px rgba(255, 130, 110, .15),
inset -2px 0 3px rgba(45, 8, 7, .22),
1px 2px 3px rgba(0,0,0,.13);
}
.frozen-drip.fd1 {
left: 7px;
top: 23px;
width: 10px;
height: 58px;
border-radius: 8px 7px 10px 9px / 10px 9px 18px 17px;
opacity: .55;
}
.frozen-drip.fd2 {
left: 48px;
top: 25px;
width: 7px;
height: 33px;
border-radius: 7px 7px 8px 8px / 9px 9px 16px 15px;
opacity: .36;
}
.frozen-drip.fd3 {
right: 37px;
top: 26px;
width: 9px;
height: 46px;
border-radius: 8px 8px 10px 9px / 9px 9px 19px 18px;
opacity: .43;
}
.frozen-drip::after {
content: "";
position: absolute;
left: 50%;
bottom: -4px;
width: 82%;
height: 9px;
transform: translateX(-50%);
border-radius: 50%;
background: inherit;
}
/* micro-imperfections : pores, fines rayures, zones mates */
.wax-grain {
position: absolute;
inset: 8px 7px 10px;
z-index: 4;
pointer-events: none;
border-radius: inherit;
opacity: .27;
mix-blend-mode: soft-light;
background:
radial-gradient(circle at 17% 12%, rgba(255,255,255,.15) 0 .7px, transparent 1.1px),
radial-gradient(circle at 71% 16%, rgba(0,0,0,.18) 0 .8px, transparent 1.2px),
radial-gradient(circle at 42% 28%, rgba(255,255,255,.11) 0 .6px, transparent 1px),
radial-gradient(circle at 84% 41%, rgba(0,0,0,.17) 0 .7px, transparent 1.1px),
radial-gradient(circle at 25% 58%, rgba(255,255,255,.08) 0 .6px, transparent 1px),
radial-gradient(circle at 62% 69%, rgba(0,0,0,.14) 0 .8px, transparent 1.2px),
linear-gradient(88deg, transparent 0 24%, rgba(255,255,255,.035) 25%, transparent 27%),
linear-gradient(93deg, transparent 0 63%, rgba(0,0,0,.05) 64%, transparent 66%),
repeating-linear-gradient(94deg, transparent 0 13px, rgba(255,255,255,.014) 14px 15px, transparent 16px 29px);
background-size:
29px 31px, 37px 43px, 41px 35px, 33px 39px, 47px 29px, 31px 37px,
auto, auto, auto;
}
.wax-scuff {
position: absolute;
z-index: 5;
pointer-events: none;
border-radius: 999px;
filter: blur(.15px);
opacity: .28;
background: linear-gradient(90deg, transparent, rgba(255, 150, 130, .18), transparent);
}
.wax-scuff.s1 { left: 26px; top: 104px; width: 48px; height: 2px; transform: rotate(-7deg); }
.wax-scuff.s2 { right: 19px; top: 176px; width: 31px; height: 1.5px; transform: rotate(9deg); opacity: .2; }
.wax-scuff.s3 { left: 51px; top: 239px; width: 39px; height: 1.5px; transform: rotate(-3deg); opacity: .18; }
/* mèche */
.thread {
position: absolute;
width: 6px;
height: 36px;
top: -17px;
left: 50%;
z-index: 15;
border-radius: 40% 40% 0 0;
transform: translateX(-50%);
background: linear-gradient(#d6994a, #4b232c, #121212, black, #e8bb31 90%);
}
/* halo bleu de combustion */
.glow {
position: absolute;
width: 26px;
height: 60px;
border-radius: 50% 50% 35% 35%;
left: 50%;
top: -58px;
z-index: 16;
opacity: 0.7;
transform: translateX(-50%);
transform-origin: 50% 100%;
background: rgba(0, 133, 255, .7);
box-shadow:
0 -40px 30px 0 #dc8a0c,
0 40px 50px 0 #dc8a0c,
inset 3px 0 2px 0 rgba(0, 133, 255, .6),
inset -3px 0 2px 0 rgba(0, 133, 255, .6);
animation: moveFlame 6s linear infinite;
}
.glow::before {
content: "";
position: absolute;
left: 50%;
bottom: 0;
width: 70%;
height: 60%;
transform: translateX(-50%);
border-radius: 50%;
background: rgba(0, 0, 0, .35);
}
/* flicker rapide */
.blinking-glow {
position: absolute;
width: 100px;
height: 180px;
left: 50%;
top: -55%;
z-index: 7;
transform: translateX(-50%);
border-radius: 50%;
background: #ff6000;
filter: blur(60px);
animation: blinkIt .1s infinite;
}
@keyframes blinkIt {
50% {
opacity: .8;
}
}
/* halo proche de la flamme */
.flame-halo {
position: absolute;
left: 50%;
top: -147px;
width: 106px;
height: 162px;
transform: translateX(-50%);
border-radius: 50%;
z-index: 10;
background: radial-gradient(ellipse at center,
rgba(255, 210, 96, .22) 0%,
rgba(255, 122, 24, .15) 28%,
rgba(255, 82, 11, .08) 46%,
transparent 73%);
filter: blur(13px);
animation: haloPulse 1.7s ease-in-out infinite alternate;
}
.flame {
position: absolute;
width: 24px;
height: 120px;
left: 50%;
transform-origin: 50% 100%;
transform: translateX(-50%);
bottom: 100%;
border-radius: 50% 50% 20% 20%;
background: linear-gradient(white 80%, transparent);
z-index: 20;
animation: moveFlame 6s linear infinite, enlargeFlame 5s linear infinite;
}
.flame:before {
content: "";
position: absolute;
width: 100%;
height: 100%;
border-radius: 50% 50% 20% 20%;
box-shadow: 0 0 15px 0 rgba(247, 93, 0, .4), 0 -6px 4px 0 rgba(247, 128, 0, .7);
}
@keyframes moveFlame {
0%, 100% {
transform: translateX(-50%) rotate(-2deg);
}
50% {
transform: translateX(-50%) rotate(2deg);
}
}
@keyframes enlargeFlame {
0%, 100% {
height: 120px;
}
50% {
height: 140px;
}
}
/* lueur orange renvoyée sur le haut de la bougie */
.candle-light {
position: absolute;
left: 50%;
top: -21px;
width: 150px;
height: 88px;
transform: translateX(-50%);
border-radius: 50%;
z-index: 3;
background: radial-gradient(ellipse at 50% 30%, rgba(255, 181, 62, .26), rgba(255, 103, 18, .08) 52%, transparent 73%);
filter: blur(8px);
pointer-events: none;
animation: candleLight 1.8s ease-in-out infinite alternate;
}
@keyframes haloPulse {
from {
opacity: .72;
transform: translateX(-50%) scale(.94, .96);
}
to {
opacity: 1;
transform: translateX(-50%) scale(1.06, 1.04);
}
}
@keyframes roomGlow {
from {
opacity: .75;
transform: translateX(-50%) scale(.98);
}
to {
opacity: 1;
transform: translateX(-50%) scale(1.03);
}
}
@keyframes candleLight {
from { opacity: .70; }
to { opacity: 1; }
}
@media (max-width: 420px), (max-height: 720px) {
body {
padding: 8px;
}
}
@media (prefers-reduced-motion: reduce) {
.scene::before,
.flame,
.glow,
.blinking-glow,
.flame-halo,
.candle-light {
animation: none;
}
}