/* ==========================================================================
   Diwali seasonal theme - authored layer.

   Scoped entirely under body.theme-diwali and only loaded when
   active_theme=diwali, so the default site is untouched.

   Load order matters: diwali-palette.css (generated colour sweep) comes
   first, this file second, so anything authored here wins on conflict.

   Colours all resolve from the CSS variables set inline in
   layouts/app.blade.php from admin settings, including the derived
   --diwali-primary-700/-900/-tint/-gold-soft ramp - so an admin colour
   change restyles everything without touching this file.

   Motion policy: only opacity/transform/filter are animated (compositor
   properties). Nothing here animates layout. All decor is pointer-events:
   none and aria-hidden, and the whole motion layer is disabled under
   prefers-reduced-motion.
   ========================================================================== */

/* -------------------------------------------------------------------------
   1. Palette - highest-visibility surfaces.
   ------------------------------------------------------------------------- */

body.theme-diwali .navbar {
    background: linear-gradient(in oklab 180deg, var(--diwali-primary) 0%, var(--diwali-primary-700) 100%) !important;
    border-bottom: 1px solid color-mix(in oklab, var(--diwali-gold) 45%, transparent) !important;
}

body.theme-diwali .announcement-marquee-wrapper {
    background: linear-gradient(in oklab 135deg, var(--diwali-dark) 0%, var(--diwali-primary-900) 55%, var(--diwali-primary) 100%) !important;
    border-bottom-color: var(--diwali-gold) !important;
}

body.theme-diwali .announcement-marquee-content .marquee-separator {
    color: var(--diwali-gold) !important;
}

body.theme-diwali .text-brand {
    color: var(--diwali-gold) !important;
}

body.theme-diwali .btn-brand {
    background: linear-gradient(in oklab 135deg, var(--diwali-gold) 0%, var(--diwali-gold-deep) 100%) !important;
    color: var(--diwali-dark) !important;
    border-color: var(--diwali-gold) !important;
}

body.theme-diwali .btn-brand:hover {
    background: var(--diwali-dark) !important;
    color: var(--diwali-gold) !important;
}

body.theme-diwali .btn-outline-brand {
    border-color: var(--diwali-gold) !important;
    color: var(--diwali-gold) !important;
}

body.theme-diwali .btn-outline-brand:hover,
body.theme-diwali .btn-outline-brand.active {
    background-color: var(--diwali-gold) !important;
    color: var(--diwali-dark) !important;
}

body.theme-diwali .cart-badge {
    background-color: var(--diwali-gold) !important;
    color: var(--diwali-dark) !important;
    border-color: var(--diwali-primary) !important;
}

body.theme-diwali .category-section-wrapper {
    background: linear-gradient(in oklab 160deg, var(--diwali-primary) 0%, var(--diwali-primary-900) 100%) !important;
}

body.theme-diwali .footer-section {
    background: linear-gradient(in oklab 180deg, var(--diwali-primary-900) 0%, var(--diwali-dark) 100%) !important;
}

/* -------------------------------------------------------------------------
   1b. Inline-style hooks.

   A handful of brand colours are written as inline style="" attributes in
   Blade, which no external stylesheet rule can reach by selector. Those
   attributes were changed to `var(--brand-x, #originalhex)` - the fallback
   keeps the default theme pixel-identical, and defining the variable here
   is what recolours them under Diwali.
   ------------------------------------------------------------------------- */

body.theme-diwali {
    --brand-green: var(--diwali-primary);
    --brand-gold: var(--diwali-gold);
}

/* -------------------------------------------------------------------------
   1c. Bootstrap's own default-blue components.

   These never appear in style.css at all - they're Bootstrap's built-in
   `--bs-primary` (#0d6efd) applied straight from the framework, on markup
   like `btn btn-primary`, `text-primary`, or Laravel's stock paginator view
   (`$products->links('pagination::bootstrap-5')`). The generated sweep in
   diwali-palette.css only ever reads style.css, so it can't see these - a
   grep across every Blade view for text-primary/btn-primary/bg-primary/
   border-primary/pagination turned up the actual usages below. Same
   base+hover+active !important discipline as the rest of this file, so no
   state can win over another by accident.
   ------------------------------------------------------------------------- */

body.theme-diwali .pagination .page-link {
    color: var(--diwali-primary) !important;
}

body.theme-diwali .pagination .page-link:hover,
body.theme-diwali .pagination .page-link:focus {
    color: #ffffff !important;
    background-color: var(--diwali-primary) !important;
    border-color: var(--diwali-primary) !important;
}

body.theme-diwali .pagination .page-item.active .page-link {
    background-color: var(--diwali-primary) !important;
    border-color: var(--diwali-primary) !important;
    color: #ffffff !important;
}

body.theme-diwali .pagination .page-item.disabled .page-link {
    color: #9ca3af !important; /* left neutral on purpose - disabled isn't a brand state */
}

body.theme-diwali .btn-primary,
body.theme-diwali .bg-primary {
    background-color: var(--diwali-primary) !important;
    border-color: var(--diwali-primary) !important;
    color: #ffffff !important;
}

body.theme-diwali .btn-primary:hover,
body.theme-diwali .btn-primary:focus {
    background-color: var(--diwali-primary-900) !important;
    border-color: var(--diwali-primary-900) !important;
    color: #ffffff !important;
}

body.theme-diwali .text-primary {
    color: var(--diwali-primary) !important;
}

body.theme-diwali .border-primary {
    border-color: var(--diwali-primary) !important;
}

/* -------------------------------------------------------------------------
   2. Corner ribbon.
   ------------------------------------------------------------------------- */

body.theme-diwali .diwali-ribbon {
    position: fixed;
    top: 20px;
    right: -58px;
    width: 220px;
    rotate: 45deg;
    /* Decor z-indices all live in a low band (30-65), deliberately BELOW
       Bootstrap's own reserved stacking scale (dropdown-menu starts at 1000,
       then sticky/fixed/offcanvas/modal/popover/tooltip climb from there).
       An earlier version used 1030-1045, which sat INSIDE that reserved
       range and let the fairy-light garland render on top of the Categories
       dropdown (and would have done the same to any modal/offcanvas/tooltip
       site-wide) - decor must never be able to cover interactive UI. */
    z-index: 40;
    pointer-events: none;
    background: linear-gradient(in oklab 135deg, var(--diwali-primary) 0%, var(--diwali-primary-900) 100%);
    color: var(--diwali-gold);
    text-align: center;
    padding: 7px 0;
    font-weight: 700;
    font-size: 13px;
    letter-spacing: 1.5px;
    border-block: 1px solid color-mix(in oklab, var(--diwali-gold) 70%, transparent);
    box-shadow: 0 3px 14px rgba(0, 0, 0, .4);
    text-shadow: 0 0 10px color-mix(in oklab, var(--diwali-gold) 60%, transparent);
}

/* A slow sheen travelling across the ribbon, so it reads as foil rather than
   flat print. Uses background-position on a masked pseudo-element rather than
   on the ribbon itself, keeping the animation off the paint-heavy parent. */
body.theme-diwali .diwali-ribbon::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(100deg,
        transparent 35%,
        color-mix(in oklab, var(--diwali-gold) 35%, transparent) 50%,
        transparent 65%);
    background-size: 300% 100%;
    animation: diwali-sheen 5s ease-in-out infinite;
}

@keyframes diwali-sheen {
    0%, 65% { background-position: 130% 0; }
    100%    { background-position: -30% 0; }
}

@media (max-width: 768px) {
    body.theme-diwali .diwali-ribbon { display: none; }
}

/* -------------------------------------------------------------------------
   3. Hanging garland (toran).

   Replaces the previous flat row of dots. Real festival string lights hang
   on a slack wire, so the bulbs sit on a quadratic curve (y = 6 + 136t(1-t),
   computed per bulb in the Blade partial to match the SVG wire exactly) and
   each bulb glows on its own duration/delay. Even spacing on a straight line
   is what made the old version read as printed clipart.
   ------------------------------------------------------------------------- */

body.theme-diwali .diwali-garland {
    position: fixed;
    top: 140px; /* marquee bar (40px) + navbar min-height (100px) */
    left: 0;
    right: 0;
    height: 92px;
    z-index: 35; /* below Bootstrap's dropdown floor (1000) - see the ribbon rule above */
    pointer-events: none;
    overflow: hidden;
}

body.theme-diwali .diwali-garland-wire {
    display: block;
    width: 100%;
    height: 92px;
}

body.theme-diwali .diwali-garland-wire path {
    fill: none;
    stroke: color-mix(in oklab, var(--diwali-gold) 55%, transparent);
    stroke-width: 1.5;
}

body.theme-diwali .dg-bulb {
    position: absolute;
    left: var(--gb-x);
    top: var(--gb-y);
    width: var(--gb-size, 11px);
    height: calc(var(--gb-size, 11px) * 1.45);
    translate: -50% 0;
    border-radius: 50% 50% 55% 55% / 42% 42% 58% 58%;
    background:
        radial-gradient(ellipse 60% 45% at 50% 32%,
            color-mix(in oklab, var(--gb-color) 25%, #fff) 0%,
            var(--gb-color) 55%,
            color-mix(in oklab, var(--gb-color) 70%, #000) 100%);
    box-shadow:
        0 0 6px  var(--gb-color),
        0 0 16px color-mix(in oklab, var(--gb-color) 55%, transparent),
        0 0 34px color-mix(in oklab, var(--gb-color) 28%, transparent);
    animation: diwali-bulb var(--gb-duration, 3.4s) ease-in-out infinite;
    animation-delay: var(--gb-delay, 0s);
    will-change: opacity, filter;
}

/* Bulb cap - the little dark fitting where the bulb meets the wire. */
body.theme-diwali .dg-bulb::before {
    content: "";
    position: absolute;
    top: -4px;
    left: 50%;
    translate: -50% 0;
    width: 44%;
    height: 5px;
    border-radius: 2px 2px 0 0;
    background: var(--diwali-primary-900);
    box-shadow: none;
}

@keyframes diwali-bulb {
    0%, 100% { opacity: .45; filter: brightness(.75); }
    45%      { opacity: 1;   filter: brightness(1.35); }
    62%      { opacity: .8;  filter: brightness(1.05); }
}

@media (max-width: 768px) {
    body.theme-diwali .diwali-garland { top: 138px; height: 60px; }
    body.theme-diwali .diwali-garland-wire { height: 60px; }
    body.theme-diwali .dg-bulb:nth-child(even) { display: none; }
}

/* -------------------------------------------------------------------------
   4. Diya lamps.

   Built as layered SVG rather than a single silhouette: clay bowl with its
   own gradient and rim, an oil pool, a wick, and a four-layer flame (blue
   base -> orange body -> gold mid -> white core) sitting inside a soft halo.
   The layering is what makes it read as a lit lamp instead of a flame icon.

   Each flame layer flickers on a DIFFERENT duration (2.9s / 1.7s / 1.13s)
   so the layers drift out of phase and the motion never visibly loops - a
   single shared duration is what makes CSS flames look mechanical.
   ------------------------------------------------------------------------- */

body.theme-diwali .diwali-diya {
    position: fixed;
    bottom: 0;
    z-index: 30; /* below Bootstrap's dropdown floor (1000) - see the ribbon rule above */
    pointer-events: none;
    width: var(--dy-size, 104px);
    height: var(--dy-size, 104px);
    animation: diya-bob calc(var(--dy-speed, 1.7s) * 3.7) ease-in-out infinite;
    animation-delay: var(--dy-delay, 0s);
}

body.theme-diwali .diwali-diya svg {
    width: 100%;
    height: 100%;
    overflow: visible;
}

body.theme-diwali .diwali-diya-left  { left: 12px; }
body.theme-diwali .diwali-diya-right { right: 12px; }

/* The evenly spaced row across the bottom edge - desktop only, since on
   narrow screens it would sit on top of sticky add-to-cart bars. */
body.theme-diwali .diwali-diya-row { left: var(--dy-x); }

@media (max-width: 991px) {
    body.theme-diwali .diwali-diya-row { display: none; }
}

@keyframes diya-bob {
    0%, 100% { translate: 0 0; }
    50%      { translate: 0 -3px; }
}

/* SVG transforms need fill-box, otherwise transform-origin resolves against
   the whole viewBox and the flame pivots from the wrong point. */
body.theme-diwali .dy-flame > * {
    transform-box: fill-box;
    transform-origin: bottom center;
}

body.theme-diwali .dy-f-outer {
    animation: diya-flicker-a calc(var(--dy-speed, 1.7s) * 1.7) ease-in-out infinite;
    animation-delay: var(--dy-delay, 0s);
}

body.theme-diwali .dy-f-mid {
    animation: diya-flicker-b var(--dy-speed, 1.7s) ease-in-out infinite;
    animation-delay: calc(var(--dy-delay, 0s) * -1.3);
}

body.theme-diwali .dy-f-core {
    animation: diya-flicker-c calc(var(--dy-speed, 1.7s) * .66) ease-in-out infinite;
    animation-delay: calc(var(--dy-delay, 0s) * -0.7);
}

body.theme-diwali .dy-halo {
    transform-box: fill-box;
    transform-origin: center;
    animation: diya-halo calc(var(--dy-speed, 1.7s) * 1.35) ease-in-out infinite;
    animation-delay: var(--dy-delay, 0s);
}

/* Irregular step positions (not 0/50/100) are what break the "breathing"
   look and read as a real flame reacting to air. */
/* `skew` has no independent-property form (only translate/rotate/scale do),
   so the lean uses the transform shorthand. That is safe here because these
   keyframes are the only thing transforming this element, and the shorthand
   composes after translate/rotate/scale rather than fighting them. */
@keyframes diya-flicker-a {
    0%   { scale: 1 1;      transform: skewX(0deg);    opacity: .92; }
    18%  { scale: .95 1.06; transform: skewX(-2deg);   opacity: 1; }
    37%  { scale: 1.04 .94; transform: skewX(1.5deg);  opacity: .86; }
    58%  { scale: .97 1.03; transform: skewX(-1deg);   opacity: .97; }
    79%  { scale: 1.02 .97; transform: skewX(2deg);    opacity: .9; }
    100% { scale: 1 1;      transform: skewX(0deg);    opacity: .92; }
}

@keyframes diya-flicker-b {
    0%   { scale: 1 1;      translate: 0 0;      opacity: .95; }
    23%  { scale: .92 1.09; translate: .6px 0;   opacity: 1; }
    46%  { scale: 1.06 .92; translate: -.5px 0;  opacity: .82; }
    71%  { scale: .96 1.04; translate: .3px 0;   opacity: .98; }
    100% { scale: 1 1;      translate: 0 0;      opacity: .95; }
}

@keyframes diya-flicker-c {
    0%   { scale: 1 1;      opacity: .85; }
    31%  { scale: .88 1.12; opacity: 1; }
    64%  { scale: 1.08 .9;  opacity: .7; }
    100% { scale: 1 1;      opacity: .85; }
}

@keyframes diya-halo {
    0%, 100% { scale: 1;    opacity: .5; }
    43%      { scale: 1.14; opacity: .82; }
    68%      { scale: .96;  opacity: .58; }
}

@media (max-width: 480px) {
    body.theme-diwali .diwali-diya {
        width: 58px;
        height: 58px;
    }
}

/* -------------------------------------------------------------------------
   5. Rangoli corner ornaments.
   Low-opacity gold mandala arcs anchored in the page corners - static, cheap,
   and they frame the page the way festival storefront art does.
   ------------------------------------------------------------------------- */

body.theme-diwali .diwali-rangoli {
    position: fixed;
    width: 190px;
    height: 190px;
    z-index: 1;
    pointer-events: none;
    opacity: .16;
    color: var(--diwali-gold);
}

body.theme-diwali .diwali-rangoli-tl { top: 148px; left: -46px; rotate: 0deg; }
body.theme-diwali .diwali-rangoli-br { bottom: -46px; right: -46px; rotate: 180deg; }

@media (max-width: 991px) {
    body.theme-diwali .diwali-rangoli { display: none; }
}

/* -------------------------------------------------------------------------
   6. Product-card festive badge.
   One rule against the shared .prod-visual-box class covers every product
   card site-wide. Sits at z-index 4 - below .prod-quick-action (15) and the
   .prod-label / .prod-wish-trigger widgets (20) so it never covers a control.
   ------------------------------------------------------------------------- */

body.theme-diwali .prod-visual-box::after {
    content: "\2726 Diwali Special \2726";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 4;
    background: linear-gradient(in oklab 90deg, var(--diwali-primary-900), var(--diwali-primary), var(--diwali-primary-900));
    color: var(--diwali-gold);
    border-top: 1px solid color-mix(in oklab, var(--diwali-gold) 55%, transparent);
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .5px;
    text-align: center;
    padding: 4px 0;
    pointer-events: none;
}

/* -------------------------------------------------------------------------
   7. Interactive feedback.

   Press state is CSS (instant, works with keyboard activation and with JS
   off); the gold spark burst on click is drawn by diwali-theme.js into the
   shared particle canvas. The .diwali-ripple node below is created by that
   script and animated with the Web Animations API.
   ------------------------------------------------------------------------- */

body.theme-diwali button,
body.theme-diwali .btn,
body.theme-diwali [role="button"],
body.theme-diwali input[type="submit"] {
    transition: scale .12s cubic-bezier(.34, 1.56, .64, 1), filter .18s ease;
}

body.theme-diwali button:active,
body.theme-diwali .btn:active,
body.theme-diwali [role="button"]:active,
body.theme-diwali input[type="submit"]:active {
    scale: .96;
    filter: brightness(1.12);
}

body.theme-diwali .diwali-ripple {
    position: fixed;
    z-index: 65; /* below Bootstrap's dropdown floor (1000) - see the ribbon rule above */
    pointer-events: none;
    border-radius: 50%;
    border: 2px solid var(--diwali-gold);
    box-shadow:
        0 0 12px color-mix(in oklab, var(--diwali-gold) 70%, transparent),
        inset 0 0 12px color-mix(in oklab, var(--diwali-gold) 40%, transparent);
    will-change: transform, opacity;
}

/* -------------------------------------------------------------------------
   8. Particle canvas - ambient embers, sparkler cursor trail, click bursts.

   All three effects share one <canvas> and one requestAnimationFrame loop.
   Canvas rather than DOM nodes because the sparkler alone runs a few hundred
   short-lived particles, and because additive blending ('lighter') is what
   makes overlapping sparks read as light instead of stacked dots - which is
   not reproducible with DOM elements.
   ------------------------------------------------------------------------- */

body.theme-diwali #diwali-canvas {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 60; /* above page chrome, below the ripple, below Bootstrap's dropdown floor (1000) */
    pointer-events: none;
}

/* -------------------------------------------------------------------------
   9. Reduced motion.
   Everything decorative still renders, it just stops moving. The canvas is
   never even created by the script under this preference (see bail()).
   ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    body.theme-diwali *,
    body.theme-diwali *::before,
    body.theme-diwali *::after {
        animation: none !important;
        transition: none !important;
    }

    body.theme-diwali .dg-bulb { opacity: .9; }
}
