.slfx{ position:absolute; inset:0; overflow:hidden; pointer-events:none; z-index:2; }
.slfx-p{ position:absolute; inset-inline-start:var(--x); top:var(--y); width:var(--s); height:var(--s);
    animation-duration:var(--d,8s); animation-delay:var(--dl,0s); animation-iteration-count:infinite; animation-timing-function:ease-in-out; }

/* ── embers — BBQ / fire: glowing sparks rising with flicker ── */
.slfx-embers .slfx-p{ border-radius:50%; background:var(--c,#ffb347);
    box-shadow:0 0 6px 2px color-mix(in srgb, var(--c,#ff8c42) 80%, transparent), 0 0 16px 4px color-mix(in srgb, var(--c,#ff8c42) 35%, transparent);
    opacity:0; animation-name:slfxEmber; animation-timing-function:cubic-bezier(.3,.6,.5,1); }
@keyframes slfxEmber{
    0%{ transform:translate(0,0) scale(1); opacity:0 }
    8%{ opacity:1 }
    45%{ transform:translate(calc(var(--sw,24px) * .5), -46%) scale(.9); opacity:.95 }
    72%{ transform:translate(calc(var(--sw,24px) * -.3), -78%) scale(.6); opacity:.6 }
    100%{ transform:translate(calc(var(--sw,24px) * .2), -110%) scale(.25); opacity:0 } }
.slfx-embers .slfx-p:nth-child(3n){ animation-timing-function:cubic-bezier(.5,.2,.6,1); }

/* ── ramadan — crescent at the top-left, hanging lanterns, gold stars ──
   • Container-level ::before: one elegant large crescent pinned to the
     TOP-LEFT corner (physical left in both directions), breathing softly
     with a warm glow.
   • Even pieces: CSS-drawn fanous lanterns HANGING from the top edge on
     thin strings, swinging gently around their hang point (alternate
     ease-in-out pendulum). Body, string and bottom finial are pure CSS.
   • Odd pieces: four-point gold stars twinkling across the slide.
   Everything is local CSS on system rendering — zero external assets. */
.slfx-ramadan::before{ content:""; position:absolute; top:16px; left:20px; z-index:1;
    width:clamp(46px,7vw,84px); aspect-ratio:1; border-radius:50%;
    background:radial-gradient(circle at 68% 32%, transparent 55%, #ffd166 56%);
    filter:drop-shadow(0 0 10px rgba(255,209,102,.65)) drop-shadow(0 0 26px rgba(255,209,102,.28));
    rotate:-24deg; animation:slfxHilal 9s ease-in-out infinite; }
.slfx-ramadan::after{ content:""; position:absolute; top:-6px; left:-10px;
    width:clamp(80px,12vw,140px); aspect-ratio:1; border-radius:50%; pointer-events:none;
    background:radial-gradient(circle, rgba(255,214,120,.35) 0%, rgba(255,214,120,.12) 45%, transparent 72%);
    animation:slfxHilalHalo 9s ease-in-out infinite; }
@keyframes slfxHilal{ 0%,100%{ transform:translateY(0) scale(1); rotate:-24deg } 50%{ transform:translateY(-8px) scale(1.05); rotate:-19deg } }
@keyframes slfxHilalHalo{ 0%,100%{ transform:scale(.92); opacity:.55 } 50%{ transform:scale(1.12); opacity:.9 } }

.slfx-ramadan .slfx-p{ opacity:0; }

/* lanterns — richly drawn fanous hanging from the top edge.
   Silky motion: the pendulum starts MID-swing (negative, per-piece
   animation-delay) so nothing ever jumps into position; the period is
   long and eased both ways, and a second, independent animation pulses
   the inner light. Body = base gold gradient + vertical glass slats +
   a breathing inner glow; metal crown via border-top; the string pseudo
   carries a centered luminous thread ending in a hanging ring. */
.slfx-ramadan .slfx-p:nth-child(even){
    top:30px !important; height:calc(var(--s) * 1.5); opacity:.97;
    background:
        repeating-linear-gradient(90deg, rgba(120,70,10,.28) 0 1.5px, transparent 1.5px 22%),
        radial-gradient(ellipse at 50% 42%, rgba(255,246,214,.55) 0%, transparent 62%),
        linear-gradient(180deg, #f8dc8a 0%, var(--c,#ffd166) 45%, #c8871f 100%);
    border-radius:34% 34% 46% 46% / 14% 14% 52% 52%;
    border-top:4px solid #b97b16;
    box-shadow:inset 0 2px 5px rgba(255,255,255,.5),
               inset 0 -6px 10px rgba(120,70,10,.4),
               0 0 18px color-mix(in srgb, var(--c,#ffd166) 50%, transparent);
    transform-origin:50% -34px;
    animation:
        slfxLantern calc(var(--d,3s) + 1.6s) ease-in-out calc(var(--dl,0s) * -1) infinite alternate,
        slfxLanternGlow 3.6s ease-in-out calc(var(--dl,0s) * -1.3) infinite alternate; }
.slfx-ramadan .slfx-p:nth-child(even)::before{ content:""; position:absolute;
    top:-34px; left:50%; translate:-50% 0; width:11px; height:34px;
    background:
        radial-gradient(circle 3.2px at 50% calc(100% - 3.5px), transparent 1.6px, #e9b64a 1.8px 3px, transparent 3.3px),
        linear-gradient(180deg, rgba(255,233,168,.1), rgba(255,233,168,.85)) 50% 0 / 1.5px calc(100% - 7px) no-repeat; }
.slfx-ramadan .slfx-p:nth-child(even)::after{ content:""; position:absolute;
    bottom:-8px; left:50%; translate:-50% 0; width:24%; aspect-ratio:1;
    rotate:45deg; background:linear-gradient(135deg, #e9b64a, #b97b16); border-radius:2px;
    box-shadow:0 0 9px color-mix(in srgb, var(--c,#ffd166) 60%, transparent); }
@keyframes slfxLantern{ from{ rotate:-5.5deg } to{ rotate:5.5deg } }
@keyframes slfxLanternGlow{
    from{ filter:drop-shadow(0 0 4px rgba(255,214,102,.35)) brightness(.97) }
    to{   filter:drop-shadow(0 0 13px rgba(255,224,130,.75)) brightness(1.06) } }

/* stars — soft gold twinkle across the slide */
.slfx-ramadan .slfx-p:nth-child(odd){
    background:var(--c,#ffe9a8); width:calc(var(--s) * .5); height:calc(var(--s) * .5);
    clip-path:polygon(50% 0%, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0% 50%, 38% 38%);
    filter:drop-shadow(0 0 5px color-mix(in srgb, var(--c,#ffe9a8) 80%, transparent));
    animation-name:slfxRamadanStar; }
@keyframes slfxRamadanStar{
    0%,100%{ transform:scale(.2) rotate(var(--rot,0deg)); opacity:0 }
    35%{ opacity:1 }
    50%{ transform:scale(1) rotate(calc(var(--rot,0deg) + 45deg)); opacity:1 }
    70%{ opacity:.6 } }

/* ── ripples — rolling sea waves, summer & sea ──
   Two solid wave-crest bands (drawn as filled SVG, not stroked rings) hug
   the bottom edge and scroll horizontally at different speeds/opacities
   for parallax depth — this is what actually reads as "the sea" instead
   of the old expanding-circle rings. A soft sun-glint layer of small
   twinkling dots sits over the water surface for sparkle. */
.slfx-ripples::before, .slfx-ripples::after{ content:""; position:absolute; inset-inline:-10%; bottom:-4%; height:34%;
    background-repeat:repeat-x; background-position-y:bottom; background-size:200px 100%;
    background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='100' viewBox='0 0 200 100'%3E%3Cpath d='M0 50 Q25 34 50 50 T100 50 T150 50 T200 50 L200 100 L0 100 Z' fill='rgba(255,255,255,0.16)'/%3E%3C/svg%3E"),
        linear-gradient(180deg, rgba(255,255,255,.08), transparent 65%);
    animation:slfxSeaWave 9s linear infinite; }
.slfx-ripples::after{ height:46%; bottom:-9%; opacity:.7;
    background-size:200px 100%;
    background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='100' viewBox='0 0 200 100'%3E%3Cpath d='M0 52 Q25 72 50 52 T100 52 T150 52 T200 52 L200 100 L0 100 Z' fill='rgba(255,255,255,0.24)'/%3E%3C/svg%3E");
    animation-duration:13s; animation-direction:reverse; }
@keyframes slfxSeaWave{ from{ background-position-x:0 } to{ background-position-x:200px } }
.slfx-ripples .slfx-p{ border-radius:50%; opacity:0;
    background:radial-gradient(circle, #ffffff 0%, rgba(255,255,255,.4) 55%, transparent 75%);
    filter:blur(.3px); animation-name:slfxGlint; animation-timing-function:ease-in-out; }
@keyframes slfxGlint{ 0%,100%{ transform:scale(.4); opacity:0 } 45%{ transform:scale(1); opacity:.9 } 70%{ opacity:.3 } }

/* ── rays — sweeping sun shafts (container-level layer) ── */
.slfx-rays::before, .slfx-rays::after{ content:""; position:absolute; inset:-30%;
    background:repeating-linear-gradient(115deg,
        transparent 0 90px, rgba(255,255,255,.07) 90px 130px,
        transparent 130px 260px, rgba(255,255,255,.11) 260px 310px);
    animation:slfxRays 9s linear infinite; }
.slfx-rays::after{ animation-duration:14s; animation-direction:reverse; opacity:.6;
    background:repeating-linear-gradient(115deg, transparent 0 180px, rgba(255,255,240,.08) 180px 240px, transparent 240px 460px); }
@keyframes slfxRays{ from{ transform:translateX(-6%) } to{ transform:translateX(6%) } }

/* ── snow — winter drift: crisp ice-crystal glyphs (near flakes) mixed
   with soft blurred dots (far flakes) for real depth, both drifting,
   spinning and swaying like real snowfall. ── */
.slfx-snow .slfx-p{ opacity:0; animation-name:slfxSnow; animation-timing-function:linear; }
.slfx-snow .slfx-p:nth-child(3n){ /* far flake — soft blurred dot */
    width:var(--s); height:var(--s); border-radius:50%; font-size:0;
    background:radial-gradient(circle at 40% 35%, #fff 0%, rgba(255,255,255,.85) 45%, rgba(255,255,255,.25) 78%, transparent 100%);
    filter:blur(.5px) drop-shadow(0 0 2px rgba(255,255,255,.6)); }
.slfx-snow .slfx-p:not(:nth-child(3n)){ /* near flake — crisp ice-crystal glyph */
    width:auto; height:auto; font-size:var(--s); line-height:1; color:#fff;
    filter:drop-shadow(0 0 4px rgba(210,235,255,.75)); }
@keyframes slfxSnow{
    0%{ transform:translate(0,0) rotate(var(--rot,0deg)); opacity:0 }
    6%{ opacity:.95 }
    50%{ transform:translate(var(--sw,26px), 55vh) rotate(calc(var(--rot,0deg) + 180deg)); opacity:.9 }
    96%{ opacity:.7 }
    100%{ transform:translate(calc(var(--sw,26px) * -.4), 110vh) rotate(calc(var(--rot,0deg) + 360deg)); opacity:0 } }

/* ── speed — sport motion streaks dashing across ── */
.slfx-speed .slfx-p{ height:max(2px, var(--s2,3px)); border-radius:99px; opacity:0;
    background:linear-gradient(90deg, transparent, rgba(255,255,255,.85) 45%, rgba(255,255,255,.25) 80%, transparent);
    animation-name:slfxSpeed; animation-timing-function:cubic-bezier(.55,0,.3,1); }
[dir="rtl"] .slfx-speed .slfx-p{ transform:scaleX(-1); }
@keyframes slfxSpeed{
    0%{ translate:-140% 0; opacity:0 }
    12%{ opacity:.95 }
    70%{ opacity:.85 }
    100%{ translate:calc(100vw) 0; opacity:0 } }

/* ── leaves — herbal tumble, pharmacy & nature ── */
.slfx-leaves .slfx-p{ background:var(--c,#7dc98f); opacity:0;
    border-radius:0 62% 0 62%; box-shadow:inset -2px -2px 5px rgba(0,0,0,.14);
    animation-name:slfxLeaf; animation-timing-function:ease-in-out; }
@keyframes slfxLeaf{
    0%{ transform:translate(0,0) rotate(var(--rot,0deg)); opacity:0 }
    8%{ opacity:.9 }
    35%{ transform:translate(var(--sw,34px), 34vh) rotate(calc(var(--rot,0deg) + 150deg)) }
    65%{ transform:translate(calc(var(--sw,34px) * -.6), 70vh) rotate(calc(var(--rot,0deg) + 260deg)); opacity:.85 }
    100%{ transform:translate(calc(var(--sw,34px) * .3), 112vh) rotate(calc(var(--rot,0deg) + 420deg)); opacity:0 } }

/* ── sparkle — jewelry glints with cross-flare ── */
.slfx-sparkle .slfx-p{ background:var(--c,#fff); opacity:0;
    clip-path:polygon(50% 0%, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0% 50%, 38% 38%);
    filter:drop-shadow(0 0 5px color-mix(in srgb, var(--c,#fff) 90%, transparent))
           drop-shadow(0 0 14px color-mix(in srgb, var(--c,#ffe9a8) 45%, transparent));
    animation-name:slfxSparkle; }
@keyframes slfxSparkle{
    0%,100%{ transform:scale(.15) rotate(var(--rot,0deg)); opacity:0 }
    40%{ opacity:1 }
    50%{ transform:scale(1) rotate(calc(var(--rot,0deg) + 45deg)); opacity:1 }
    60%{ opacity:.85 } }

/* ── confettirain — dense celebration scraps raining down with light sway ── */
.slfx-confettirain .slfx-p{ height:var(--s2,4px); background:var(--c,#ff5d73); opacity:0;
    border-radius:1.5px; animation-name:slfxConfettiRain; animation-timing-function:linear; }
@keyframes slfxConfettiRain{
    0%{ transform:translate(0,-10%) rotate(var(--rot,0deg)); opacity:0 }
    8%{ opacity:1 }
    50%{ transform:translate(calc(var(--sw,14px) * .6), 55vh) rotate(calc(var(--rot,0deg) + 180deg)); opacity:1 }
    90%{ opacity:.9 }
    100%{ transform:translate(calc(var(--sw,14px) * -.4), 116vh) rotate(calc(var(--rot,0deg) + 360deg)); opacity:0 } }

/* ── bubbles — soap foam rising with wobble + highlight ── */
.slfx-bubbles .slfx-p{ border-radius:50%; opacity:0;
    border:1.5px solid rgba(255,255,255,.65);
    background:radial-gradient(circle at 68% 72%, rgba(255,255,255,.16) 0%, transparent 55%);
    box-shadow:inset 2px 2px 4px rgba(255,255,255,.35);
    animation-name:slfxBubble; animation-timing-function:ease-in; }
.slfx-bubbles .slfx-p::after{ content:""; position:absolute; top:16%; inset-inline-start:20%;
    width:26%; height:18%; border-radius:50%; background:rgba(255,255,255,.85); filter:blur(.5px); }
@keyframes slfxBubble{
    0%{ transform:translate(0,0) scale(.7); opacity:0 }
    10%{ opacity:.95 }
    45%{ transform:translate(var(--sw,26px), -48%) scale(.95) }
    78%{ transform:translate(calc(var(--sw,26px) * -.5), -86%) scale(1.05); opacity:.85 }
    97%{ transform:translate(calc(var(--sw,26px) * .2), -112%) scale(1.18); opacity:.5 }
    100%{ transform:translate(calc(var(--sw,26px) * .2), -114%) scale(1.35); opacity:0 } }

/* ══════════════════════════════════════════════════════════════
   petals — cosmetics & care: real rose petals on the wind
   ──────────────────────────────────────────────────────────────
   A petal is a translucent, curved, uneven thing that catches light
   on one face and loses it on the other. The previous rule drew a
   flat pink lozenge — one radius, one solid fill, one flat spin —
   which is why it read as confetti wearing a pastel colour.

   Four ideas, each costing one declaration or one keyframe:

   1. SILHOUETTE.  --pv (0/1/2, cycled per piece in core/sliders.php)
      selects one of three cuts: a broad fan, a narrow teardrop, and
      an asymmetric curl. Neighbours never match, so the eye stops
      reading a repeated stamp.

   2. TRANSLUCENCY.  The fill is a two-stop gradient from a lit rim
      to a saturated cup, with an inset shadow along the base — a
      petal is thin, so light passes through the edge and pools where
      it folds. ::before adds the specular sheen, ::after the midrib.

   3. FLUTTER.  The travel keyframe carries rotateY, so each petal
      genuinely turns through its own plane and passes edge-on twice
      per fall. A second, independently-timed brightness cycle runs
      against it: the face brightens as it turns into the light and
      dims as it turns away. That interference is what makes the
      motion look observed rather than looped.

   4. DEPTH.  --dp (0 far → 1 near) buys blur, scale and opacity from
      one number, so the layer occupies space instead of sitting on
      a single plane. Far petals are small, soft and pale; near ones
      are crisp and full.

   Cost is unchanged: still one absolutely-positioned element per
   petal, still GPU-only properties (transform / opacity / filter),
   still no JavaScript, no images, no external assets.
   ══════════════════════════════════════════════════════════════ */
.slfx-petals .slfx-p{
    opacity:0;
    /* Depth: near petals render at full size, far ones shrink toward
       70%. The origin sits below centre, where a petal's mass is, so
       the flutter pivots about the cup rather than the tip. */
    width:calc(var(--s) * (0.7 + 0.3 * var(--dp, 1)));
    height:calc(var(--s) * (0.7 + 0.3 * var(--dp, 1)));
    background:
        radial-gradient(ellipse 120% 85% at 50% 100%,
            color-mix(in srgb, var(--c,#ffc2d1) 88%, #b04a72) 0%,
            var(--c,#ffc2d1) 42%,
            color-mix(in srgb, var(--c,#ffc2d1) 55%, #ffffff) 100%);
    box-shadow:
        inset 0 -3px 7px color-mix(in srgb, #a33b63 26%, transparent),
        inset 0 2px 4px rgba(255,255,255,.42);
    /* Far petals lose their edge to the air between them. */
    filter:blur(calc((1 - var(--dp, 1)) * 0.9px));
    transform-origin:50% 65%;
    animation-name:slfxPetal, slfxPetalLight;
    animation-timing-function:ease-in-out, ease-in-out;
    /* The light cycle is deliberately NOT the fall duration: two
       coprime-ish periods never re-sync, so no petal ever repeats the
       same shape/light pairing within a visit. */
    animation-duration:var(--d,9s), calc(var(--d,9s) * 0.37);
    animation-delay:var(--dl,0s), var(--dl,0s);
    animation-iteration-count:infinite, infinite;
}

/* ── the three silhouettes ── */
/* 0 — broad fan: wide crown, pinched base. The everyday rose petal. */
.slfx-petals .slfx-p{ border-radius:74% 74% 46% 46% / 88% 88% 26% 26%; }
/* 1 — narrow teardrop: taller than wide, tipped to one side. */
.slfx-petals .slfx-p[style*="--pv:1"]{
    border-radius:82% 62% 52% 40% / 78% 84% 32% 24%;
    width:calc(var(--s) * (0.7 + 0.3 * var(--dp, 1)) * .78);
}
/* 2 — asymmetric curl: one shoulder rolled, as a petal does when it
       dries. Also the only variant that reads clearly edge-on. */
.slfx-petals .slfx-p[style*="--pv:2"]{
    border-radius:58% 92% 38% 62% / 72% 76% 30% 34%;
    height:calc(var(--s) * (0.7 + 0.3 * var(--dp, 1)) * .86);
}

/* Specular sheen — the highlight sliding on the cup of the petal. */
.slfx-petals .slfx-p::before{
    content:""; position:absolute; inset:8% 20% 42% 16%;
    border-radius:inherit;
    background:linear-gradient(150deg, rgba(255,255,255,.68) 0%, rgba(255,255,255,.16) 45%, transparent 72%);
    pointer-events:none;
}
/* Midrib — the single vein running from base to tip. Hairline, low
   contrast: at these sizes anything stronger reads as a crack. */
.slfx-petals .slfx-p::after{
    content:""; position:absolute; left:50%; top:18%; bottom:6%;
    width:1px; translate:-50% 0; border-radius:1px;
    background:linear-gradient(180deg, transparent, color-mix(in srgb, #9c3a5e 30%, transparent) 55%, transparent);
    opacity:calc(.35 + .35 * var(--dp, 1));
    pointer-events:none;
}

/* Travel: a drifting, turning descent. The horizontal component
   reverses twice — a petal caught by the wind does not fall on a
   line — and rotateY carries it edge-on at 34% and again at 78%. */
@keyframes slfxPetal{
    0%{   transform:translate(0,0) rotate(var(--rot,0deg)) rotateY(0deg);
          opacity:0 }
    7%{   opacity:calc(.55 + .4 * var(--dp, 1)) }
    26%{  transform:translate(var(--sw,44px), 26vh)
                    rotate(calc(var(--rot,0deg) + 96deg)) rotateY(62deg) }
    34%{  transform:translate(calc(var(--sw,44px) * .82), 34vh)
                    rotate(calc(var(--rot,0deg) + 128deg)) rotateY(88deg) }
    52%{  transform:translate(calc(var(--sw,44px) * -.72), 54vh)
                    rotate(calc(var(--rot,0deg) + 206deg)) rotateY(184deg) }
    78%{  transform:translate(calc(var(--sw,44px) * -.28), 82vh)
                    rotate(calc(var(--rot,0deg) + 302deg)) rotateY(272deg);
          opacity:calc(.5 + .35 * var(--dp, 1)) }
    100%{ transform:translate(calc(var(--sw,44px) * .46), 114vh)
                    rotate(calc(var(--rot,0deg) + 392deg)) rotateY(360deg);
          opacity:0 }
}
/* The light cycle. Runs on its own clock (see animation-duration
   above) so the face catches and loses the sun out of step with the
   turn — which is exactly what stops the loop from being legible. */
@keyframes slfxPetalLight{
    0%,100%{ filter:blur(calc((1 - var(--dp, 1)) * 0.9px)) brightness(.92) saturate(1.04) }
    50%{     filter:blur(calc((1 - var(--dp, 1)) * 0.9px)) brightness(1.14) saturate(.94) }
}

/* Motion sensitivity: the petals stay, scattered and lit, but stop
   travelling. Removing the layer entirely would strip the slide of a
   composition the merchant deliberately chose. */
@media (prefers-reduced-motion: reduce){
    .slfx-petals .slfx-p{
        animation:none;
        opacity:calc(.4 + .3 * var(--dp, 1));
        transform:rotate(var(--rot,0deg));
    }
}

/* ── confetti — celebration tumble ── */
.slfx-confetti .slfx-p{ height:var(--s2,6px); background:var(--c,#ff5d73); opacity:0;
    border-radius:2px; animation-name:slfxConfetti; animation-timing-function:linear; }
@keyframes slfxConfetti{
    0%{ transform:translate(0,0) rotate(var(--rot,0deg)) skewX(0); opacity:0 }
    6%{ opacity:1 }
    30%{ transform:translate(var(--sw,30px), 30vh) rotate(calc(var(--rot,0deg) + 240deg)) skewX(18deg) }
    60%{ transform:translate(calc(var(--sw,30px) * -.7), 64vh) rotate(calc(var(--rot,0deg) + 480deg)) skewX(-14deg); opacity:.95 }
    100%{ transform:translate(calc(var(--sw,30px) * .35), 112vh) rotate(calc(var(--rot,0deg) + 760deg)) skewX(8deg); opacity:0 } }

/* ── balloons — drifting up on a string ── */
.slfx-balloons .slfx-p{ height:var(--s2,calc(var(--s) * 1.2)); opacity:0;
    background:radial-gradient(circle at 34% 28%, color-mix(in srgb, var(--c,#ff5d73) 55%, #fff) 0%, var(--c,#ff5d73) 55%, color-mix(in srgb, var(--c,#ff5d73) 78%, #000) 100%);
    border-radius:50% 50% 50% 50% / 44% 44% 56% 56%;
    animation-name:slfxBalloon; animation-timing-function:ease-in-out; }
.slfx-balloons .slfx-p::before{ content:""; position:absolute; bottom:-6%; left:50%; translate:-50% 0;
    border-style:solid; border-width:0 5px 7px 5px; border-color:transparent transparent color-mix(in srgb, var(--c,#ff5d73) 82%, #000) transparent; }
.slfx-balloons .slfx-p::after{ content:""; position:absolute; top:100%; left:50%;
    width:1.5px; height:85%; background:rgba(255,255,255,.55); transform-origin:top; animation:slfxString 3s ease-in-out infinite alternate; }
@keyframes slfxBalloon{
    0%{ transform:translate(0,0) rotate(-3deg); opacity:0 }
    8%{ opacity:.95 }
    50%{ transform:translate(var(--sw,24px), -58%) rotate(4deg) }
    92%{ opacity:.85 }
    100%{ transform:translate(calc(var(--sw,24px) * -.4), -118%) rotate(-3deg); opacity:0 } }
@keyframes slfxString{ from{ transform:rotate(-7deg) } to{ transform:rotate(7deg) } }

/* ── waves — tech signal lines flowing across + glowing data pulses ── */
.slfx-waves::before, .slfx-waves::after{ content:""; position:absolute; inset-inline:-10%; height:120px;
    background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='120' viewBox='0 0 260 120'%3E%3Cpath d='M0 60 Q 32.5 20 65 60 T 130 60 T 195 60 T 260 60' fill='none' stroke='rgba(255,255,255,0.22)' stroke-width='2'/%3E%3Cpath d='M0 78 Q 32.5 44 65 78 T 130 78 T 195 78 T 260 78' fill='none' stroke='rgba(255,255,255,0.10)' stroke-width='2'/%3E%3C/svg%3E");
    background-repeat:repeat-x; background-size:260px 120px;
    top:22%; animation:slfxWave 7s linear infinite; }
.slfx-waves::after{ top:auto; bottom:14%; height:120px; opacity:.75;
    animation-duration:11s; animation-direction:reverse; transform:scaleY(-1); }
@keyframes slfxWave{ from{ background-position-x:0 } to{ background-position-x:260px } }
.slfx-waves .slfx-p{ border-radius:50%; background:var(--c,#7dd3fc); opacity:0;
    box-shadow:0 0 8px 2px color-mix(in srgb, var(--c,#7dd3fc) 75%, transparent),
               0 0 20px 6px color-mix(in srgb, var(--c,#7dd3fc) 25%, transparent);
    animation-name:slfxPulseDot; animation-timing-function:cubic-bezier(.4,0,.4,1); }
@keyframes slfxPulseDot{
    0%{ translate:-120% 0; opacity:0 }
    10%{ opacity:.95 }
    50%{ translate:40vw -10px; opacity:.9 }
    90%{ opacity:.75 }
    100%{ translate:100vw 0; opacity:0 } }

/* ── blackfriday — two simple horizontal tapes hugging top & bottom ──
   The strip (.slfx-bf) is full-width, edge-anchored and clips its own
   overflow; the inner span holds TWO identical text halves and scrolls
   by exactly -50% of its own width — a seamless infinite loop in any
   font. Top and bottom tapes run in opposite directions. Pure CSS +
   system fonts — zero external assets. */
.slfx-bf{ position:absolute; inset-inline:0; overflow:hidden; direction:ltr;
    font-family:Arial, "Segoe UI", sans-serif; font-weight:900; line-height:1.65;
    font-size:clamp(10px,1.3vw,14px); letter-spacing:2px;
    border-block:4px solid transparent; box-shadow:0 4px 18px rgba(0,0,0,.35); }
.slfx-bf-top{ top:0;    background:#ffd60a; color:#0b0b0d;
    border-image:repeating-linear-gradient(45deg,#0b0b0d 0 12px,#ffd60a 12px 24px) 5; }
.slfx-bf-bot{ bottom:0; background:#0b0b0d; color:#ffd60a;
    border-image:repeating-linear-gradient(-45deg,#ffd60a 0 12px,#0b0b0d 12px 24px) 5; }
.slfx-bf > span{ display:inline-block; white-space:nowrap; will-change:transform; }
.slfx-bf-top > span{ animation:slfxBfA 30s linear infinite; }
.slfx-bf-bot > span{ animation:slfxBfB 40s linear infinite; }
@keyframes slfxBfA{ from{ transform:translateX(0) }     to{ transform:translateX(-50%) } }
@keyframes slfxBfB{ from{ transform:translateX(-50%) }  to{ transform:translateX(0) } }

/* ── hearts — soft rising pulse for occasions ── */
.slfx-hearts .slfx-p{ width:auto; height:auto; font-size:var(--s); line-height:1;
    color:var(--c,#ffb3c6); opacity:0;
    filter:drop-shadow(0 0 6px color-mix(in srgb, var(--c,#ff8fab) 55%, transparent));
    animation-name:slfxHeart; animation-timing-function:ease-in-out; }
@keyframes slfxHeart{
    0%{ transform:translate(0,0) scale(.6); opacity:0 }
    12%{ opacity:.9 }
    40%{ transform:translate(var(--sw,20px), -40%) scale(1.05) }
    55%{ transform:translate(var(--sw,20px), -52%) scale(.92) }
    70%{ transform:translate(calc(var(--sw,20px) * -.4), -74%) scale(1.02); opacity:.75 }
    100%{ transform:translate(calc(var(--sw,20px) * .2), -112%) scale(.8); opacity:0 } }

/* ── aurora — premium moving sheen (container-level layer) ── */
.slfx-aurora::before, .slfx-aurora::after{ content:""; position:absolute; inset:-40%; border-radius:40%;
    background:conic-gradient(from 0deg,
        rgba(255,255,255,0) 0deg, rgba(160,210,255,.14) 70deg, rgba(255,255,255,0) 140deg,
        rgba(255,190,235,.12) 210deg, rgba(255,255,255,0) 280deg, rgba(190,255,225,.12) 330deg, rgba(255,255,255,0) 360deg);
    filter:blur(28px); animation:slfxAurora 16s linear infinite; }
.slfx-aurora::after{ animation-duration:24s; animation-direction:reverse; opacity:.7; }
@keyframes slfxAurora{ from{ transform:rotate(0deg) } to{ transform:rotate(360deg) } }

/* ── fireworks — Eid / national day / grand-opening bursts ──
   Each shell rises on a thin rocket trail, then a ring of sparks (each
   with its own server-computed --tx/--ty radial endpoint, see
   slider_fx_pieces_html()) bursts outward and falls with a touch of
   gravity as it fades — a real radiating explosion instead of a static
   box-shadow dot cluster. A soft container-level flash still punctuates
   the show every few seconds. */
.slfx-fireworks::before{ content:""; position:absolute; inset:0; pointer-events:none;
    background:radial-gradient(circle at 50% 38%, rgba(255,255,255,.28), transparent 60%);
    opacity:0; animation:slfxFwFlash 6s ease-in-out infinite; }
@keyframes slfxFwFlash{ 0%,86%{ opacity:0 } 88%{ opacity:1 } 92%{ opacity:0 } 100%{ opacity:0 } }
.slfx-fireworks .slfx-p{ position:absolute; }
.slfx-fireworks .slfx-p::before{ content:""; position:absolute; inset-inline-start:calc(50% - 1px); bottom:0;
    width:2px; height:0; border-radius:2px; background:linear-gradient(180deg, var(--c,#ffd166), transparent);
    animation-name:slfxFwLaunch; animation-timing-function:cubic-bezier(.3,.7,.4,1);
    animation-iteration-count:infinite; animation-duration:var(--d,4s); animation-delay:var(--dl,0s); }
.slfx-fireworks .slfx-p b{ position:absolute; inset:0; margin:auto; width:var(--s); height:var(--s); border-radius:50%;
    background:var(--sc,var(--c,#ffd166)); opacity:0;
    box-shadow:0 0 4px 1px color-mix(in srgb, var(--sc,var(--c,#ffd166)) 70%, transparent);
    animation-name:slfxFwSpark; animation-timing-function:cubic-bezier(.15,.7,.3,1);
    animation-iteration-count:infinite; animation-duration:var(--d,4s);
    animation-delay:calc(var(--dl,0s) + var(--sdl,0s)); }
@keyframes slfxFwLaunch{
    0%{ height:0; opacity:0 } 28%{ opacity:.9 } 38%{ height:34vh; opacity:0 } 100%{ height:0; opacity:0 } }
@keyframes slfxFwSpark{
    0%, 36%{ transform:translate(0,0) scale(.3); opacity:0 }
    44%{ transform:translate(calc(var(--tx,20px) * .3), calc(var(--ty,20px) * .3 - 4px)) scale(1); opacity:1 }
    70%{ transform:translate(var(--tx,20px), calc(var(--ty,20px) + 14px)) scale(.85); opacity:.8 }
    100%{ transform:translate(calc(var(--tx,20px) * 1.15), calc(var(--ty,20px) + 46px)) scale(.4); opacity:0 } }

/* ── gifts — holiday & birthday campaigns: ribboned boxes drifting up ── */
.slfx-gifts .slfx-p{ opacity:0; border-radius:5px;
    background:
        linear-gradient(90deg, transparent 40%, #ffd166 40% 60%, transparent 60%),
        linear-gradient(180deg, transparent 42%, #ffd166 42% 58%, transparent 58%),
        linear-gradient(180deg, color-mix(in srgb, var(--c,#ff5d73) 82%, #fff) 0%, var(--c,#ff5d73) 100%);
    box-shadow:inset 0 0 0 1px rgba(255,255,255,.22), 0 4px 10px rgba(0,0,0,.14);
    animation-name:slfxGift; animation-timing-function:ease-in-out; }
.slfx-gifts .slfx-p::before{ content:""; position:absolute; top:-22%; left:50%; translate:-50% 0;
    width:46%; aspect-ratio:2/1; border-radius:50% 50% 0 0/100% 100% 0 0;
    background:#ffd166; box-shadow:inset 0 -2px 3px rgba(180,120,10,.3); }
@keyframes slfxGift{
    0%{ transform:translate(0,0) rotate(-4deg) scale(.85); opacity:0 }
    10%{ opacity:.95 }
    50%{ transform:translate(var(--sw,20px), -55%) rotate(4deg) scale(1) }
    100%{ transform:translate(calc(var(--sw,20px) * -.3), -118%) rotate(-3deg) scale(.9); opacity:0 } }

/* ── discount — flash sale / clearance: expanding water-ripple rings,
   as if a deal just "dropped" into the banner. A soft filled core flash
   plus two staggered expanding ring outlines, fading as they grow —
   replaces the old tumbling percentage-tag look. ── */
.slfx-discount .slfx-p{ opacity:0; border-radius:50%; background:transparent;
    border:2px solid var(--c,#fff);
    animation-name:slfxRipple; animation-timing-function:cubic-bezier(.15,.7,.3,1); }
.slfx-discount .slfx-p::before{ content:""; position:absolute; inset:28%; border-radius:50%;
    background:radial-gradient(circle, color-mix(in srgb, var(--c,#fff) 85%, transparent) 0%, transparent 75%);
    animation-name:slfxRippleCore; animation-timing-function:ease-out;
    animation-iteration-count:infinite; animation-duration:var(--d,3s); animation-delay:var(--dl,0s); }
.slfx-discount .slfx-p::after{ content:""; position:absolute; inset:0; border-radius:50%;
    border:2px solid var(--c,#fff); opacity:0;
    animation-name:slfxRipple; animation-timing-function:cubic-bezier(.15,.7,.3,1);
    animation-iteration-count:infinite; animation-duration:var(--d,3s);
    animation-delay:calc(var(--dl,0s) + var(--d,3s) * .3); }
@keyframes slfxRipple{
    0%{ transform:scale(.1); opacity:.9; border-width:3px }
    70%{ opacity:.3 }
    100%{ transform:scale(2.2); opacity:0; border-width:.5px } }
@keyframes slfxRippleCore{
    0%{ transform:scale(0); opacity:.9 } 25%{ transform:scale(1); opacity:.7 } 55%{ transform:scale(1.3); opacity:0 } 100%{ opacity:0 } }

/* ── coins — cashback / mega-sale: real 3D-spinning gold coins.
   The outer piece only carries the falling path (position + opacity);
   an inner disc spins continuously in true 3D with two backface-hidden
   faces, so the coin genuinely shows its front, its edge and its back
   as it tumbles — instead of a flat "$" glyph getting squished. ── */
.slfx-coins .slfx-p{ opacity:0; perspective:240px;
    animation-name:slfxCoinFall; animation-timing-function:ease-in; }
.slfx-coins .slfx-p .slfx-coin-disc{ position:absolute; inset:0; border-radius:50%;
    transform-style:preserve-3d; animation-name:slfxCoinSpin; animation-timing-function:linear;
    animation-iteration-count:infinite; animation-duration:calc(var(--d,5s) * .22); }
.slfx-coins .slfx-p .slfx-coin-disc::before, .slfx-coins .slfx-p .slfx-coin-disc::after{
    content:"$"; position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
    border-radius:50%; backface-visibility:hidden;
    font:800 calc(var(--s) * .5) Arial, sans-serif; color:#a9740f;
    background:radial-gradient(circle at 35% 30%, #fff6d8 0%, #ffd166 35%, #d69a1f 75%, #a9740f 100%);
    box-shadow:inset 0 0 0 2px rgba(255,255,255,.35), 0 0 8px rgba(255,209,102,.5); }
.slfx-coins .slfx-p .slfx-coin-disc::after{ content:"¢"; transform:rotateY(180deg);
    background:radial-gradient(circle at 65% 70%, #fff6d8 0%, #f4d488 35%, #c98a19 75%, #96690c 100%); }
@keyframes slfxCoinSpin{ from{ transform:rotateY(0deg) } to{ transform:rotateY(360deg) } }
@keyframes slfxCoinFall{
    0%{ transform:translate(0,0); opacity:0 }
    6%{ opacity:.95 }
    50%{ transform:translate(var(--sw,20px), 50vh) }
    92%{ opacity:.85 }
    100%{ transform:translate(calc(var(--sw,20px) * .3), 112vh); opacity:0 } }

/* ── shopping — new arrivals / general promo: drifting shopping bags ── */
.slfx-shopping .slfx-p{ width:auto; height:auto; font-size:var(--s); line-height:1; opacity:0;
    color:var(--c,#ffffff); filter:drop-shadow(0 2px 5px rgba(0,0,0,.22));
    animation-name:slfxShopping; animation-timing-function:ease-in-out; }
@keyframes slfxShopping{
    0%{ transform:translate(0,0) rotate(-6deg) scale(.7); opacity:0 }
    10%{ opacity:.95 }
    50%{ transform:translate(var(--sw,18px), -55%) rotate(6deg) scale(1.05) }
    100%{ transform:translate(calc(var(--sw,18px) * -.4), -118%) rotate(-4deg) scale(.85); opacity:0 } }

/* ── rain — rainy-season refresh & clearance drive: diagonal streaks + distant lightning ── */
.slfx-rain::before{ content:""; position:absolute; inset:0; pointer-events:none; background:rgba(255,255,255,.5);
    opacity:0; animation:slfxLightning 8s ease-in-out infinite; }
@keyframes slfxLightning{ 0%,92%{ opacity:0 } 93%{ opacity:.55 } 94%{ opacity:0 } 96%{ opacity:.3 } 97%{ opacity:0 } 100%{ opacity:0 } }
.slfx-rain .slfx-p{ width:max(1.5px, var(--s2,2px)); height:var(--s); opacity:0; border-radius:2px; rotate:12deg;
    background:linear-gradient(180deg, transparent, rgba(255,255,255,.8) 45%, rgba(200,225,255,.6));
    animation-name:slfxRain; animation-timing-function:linear; }
@keyframes slfxRain{
    0%{ transform:translate(0,0) scaleY(.6); opacity:0 }
    6%{ opacity:.85 }
    92%{ opacity:.65 }
    100%{ transform:translate(var(--sw,40px), 112vh) scaleY(1); opacity:0 } }

@media (prefers-reduced-motion: reduce){
    .slfx .slfx-p, .slfx-rays::before, .slfx-rays::after,
    .slfx-waves::before, .slfx-waves::after,
    .slfx-ripples::before, .slfx-ripples::after,
    .slfx-ramadan::before, .slfx-ramadan::after,
    .slfx-fireworks::before, .slfx-fireworks .slfx-p::before, .slfx-fireworks .slfx-p b,
    .slfx-coins .slfx-p .slfx-coin-disc,
    .slfx-discount .slfx-p::before, .slfx-discount .slfx-p::after,
    .slfx-rain::before,
    .slfx-bf > span,
    .slfx-aurora::before, .slfx-aurora::after{ animation:none!important; } }
