/* =====================================================================
   แอนิเมชันหน้าร้าน (เลือกระดับได้ที่หลังบ้าน > ปรับแต่งหน้าตาร้าน > สไตล์รวม > แอนิเมชัน)
   - ทุกกฎทำงานเฉพาะเมื่อ assets/js/motion.js ใส่ class "mx-on" ที่ <html> (ไม่ใส่เมื่อเลือก "ปิดทั้งหมด")
   - html.mx-reduced = เครื่องตั้งค่าลดการเคลื่อนไหว: เหลือแค่จางเข้า ไม่มีเลื่อน/ซูม/ลอย/แสงวิ่ง
   - body.ls-motion-subtle = นุ่มนวล / body.ls-motion-rich = จัดเต็ม (เพิ่มแสงตามเมาส์ ปุ่มวิบวับ พื้นหลังเรืองแสง)
   - ใช้แค่ opacity / translate / scale (ไม่แตะ transform ของการ์ดที่ใช้กับ hover เดิม และลื่นบนมือถือ)
   ===================================================================== */

/* ---------- เข้าหน้า ---------- */
/* ไม่ใช้ fill-mode: เล่นจบแล้วต้องไม่เหลือ stacking context ไม่งั้น modal ในหน้าจะโดน backdrop ของ Bootstrap ทับ */
html.mx-on #appContentArea { animation: mxPageIn 0.45s ease-out; }
@keyframes mxPageIn { from { opacity: 0; } to { opacity: 1; } }

/* ---------- เลื่อนแล้วค่อย ๆ โผล่ (motion.js ใส่ .mx-reveal / .mx-in แล้วลบออกเมื่อเล่นจบ) ---------- */
html.mx-on .mx-reveal { opacity: 0; }
html.mx-on .mx-reveal.mx-in {
    animation: mxRise 0.7s cubic-bezier(0.22, 0.68, 0, 1) both;
    animation-delay: calc(var(--mx-i, 0) * 70ms);
}
@keyframes mxRise {
    from { opacity: 0; translate: 0 22px; }
    to { opacity: 1; translate: 0 0; }
}
html.mx-on .mx-reveal.mx-pop.mx-in { animation-name: mxPop; }
@keyframes mxPop {
    from { opacity: 0; scale: 0.94; }
    to { opacity: 1; scale: 1; }
}
/* เลื่อนขึ้น: การ์ดที่เข้ามาจากด้านบนจอ ให้ลงมาจากบน */
html.mx-on .mx-reveal.mx-from-top.mx-in { animation-name: mxDrop; }
@keyframes mxDrop {
    from { opacity: 0; translate: 0 -22px; }
    to { opacity: 1; translate: 0 0; }
}

/* ---------- แบนเนอร์สไลด์: ซูมช้า ๆ + ข้อความเลื่อนขึ้นทุกครั้งที่เปลี่ยนสไลด์ ---------- */
html.mx-on .hero-carousel-item.active .hero-bg-media { animation: mxKenBurns 14s ease-out both; }
@keyframes mxKenBurns { from { scale: 1.12; } to { scale: 1; } }
html.mx-on .hero-carousel-item.active .hero-content-anchor { animation: mxCaption 0.8s 0.15s cubic-bezier(0.22, 0.68, 0, 1) both; }
@keyframes mxCaption { from { opacity: 0; translate: 0 16px; } to { opacity: 1; translate: 0 0; } }

/* ---------- การ์ดสินค้า: แสงวิ่งผ่านรูปตอนชี้ (เอฟเฟกต์ "แสงกระจกวิ่ง" ls-hover-shine แบบอื่นดู hover-effects.css) ---------- */
html.mx-on body.ls-hover-shine .gaming-img-wrapper::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, 0.26) 48%, rgba(255, 255, 255, 0.08) 56%, transparent 70%);
    translate: -130% 0;
}
html.mx-on body.ls-hover-shine .gaming-product-card:is(:hover, .hfx-run) .gaming-img-wrapper::after {
    animation: mxCardShine 0.75s cubic-bezier(.2, .6, .3, 1) 1;
}
@keyframes mxCardShine { from { translate: -110% 0; } to { translate: 130% 0; } }

/* ---------- แบนเนอร์ข้าง: เลื่อนเข้าจากขอบจอ ลอยขึ้นลงช้า ๆ และแสงวิ่งผ่านเป็นระยะ ---------- */
/* ใช้ translate (ไม่ใช่ transform) เพราะกล่องแบนเนอร์ใช้ transform จัดกึ่งกลางจอ และการ์ดใช้ transform ตอนชี้ */
html.mx-on .side-sticky-banner .side-banner-card {
    position: relative;
    animation: mxSideIn 0.8s cubic-bezier(0.22, 0.68, 0, 1) 0.3s both, mxSideFloat 4.5s ease-in-out 1.1s infinite;
}
html.mx-on .side-banner-left .side-banner-card { --mx-side-from: -40px; }
html.mx-on .side-banner-right .side-banner-card { --mx-side-from: 40px; animation-delay: 0.45s, 1.25s; }
@keyframes mxSideIn { from { opacity: 0; translate: var(--mx-side-from, 0) 0; } to { opacity: 1; translate: 0 0; } }
@keyframes mxSideFloat { 0%, 100% { translate: 0 0; } 50% { translate: 0 -8px; } }
html.mx-on .side-banner-card::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, 0.3) 48%, rgba(255, 255, 255, 0.08) 56%, transparent 70%);
    translate: -130% 0;
    animation: mxSideShine 5.5s ease-in-out 1.5s infinite;
}
html.mx-on .side-banner-right .side-banner-card::after { animation-delay: 4.2s; }
@keyframes mxSideShine { 0%, 70% { translate: -130% 0; } 100% { translate: 130% 0; } }

/* ---------- การ์ดหมวดหมู่: แสงวิ่งผ่านตอนชี้ ---------- */
html.mx-on body.ls-hover-shine .wide-category-card::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    border-radius: inherit;
    background: linear-gradient(115deg, transparent 32%, rgba(255, 255, 255, 0.2) 50%, transparent 68%);
    translate: -130% 0;
}
html.mx-on body.ls-hover-shine .wide-category-card:is(:hover, .hfx-run)::after {
    animation: mxCardShine 0.8s cubic-bezier(.2, .6, .3, 1) 1;
}

/* ---------- ปุ่มซื้อ: แสงวิ่งตอนชี้ + กดแล้วยุบนิดหนึ่ง ---------- */
html.mx-on .btn-gaming-buy { position: relative; overflow: hidden; isolation: isolate; }
html.mx-on .btn-gaming-buy::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: linear-gradient(110deg, transparent 25%, rgba(255, 255, 255, 0.35) 50%, transparent 75%);
    translate: -120% 0;
}
html.mx-on .btn-gaming-buy:hover::after { translate: 120% 0; transition: translate 0.7s ease; }
html.mx-on :is(.btn-gaming-buy, .btn-buy-action, .btn-auth-submit, .home-shortcut-card):active { scale: 0.97; }

/* ---------- จุดสต็อก: กะพริบเบา ๆ ---------- */
html.mx-on .stock-indicator-dot.dot-in-stock { animation: mxPulseDot 2.2s ease-in-out infinite; }
@keyframes mxPulseDot {
    0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.55); }
    60% { box-shadow: 0 0 0 6px rgba(16, 185, 129, 0); }
}

/* =====================================================================
   จัดเต็ม (rich)
   ===================================================================== */

/* แสงตามเมาส์บนการ์ด (motion.js ใส่ --mx-x / --mx-y) */
html.mx-on body.ls-motion-rich :is(.gaming-product-card, .clean-stat-card) { position: relative; }
html.mx-on body.ls-motion-rich :is(.gaming-product-card, .clean-stat-card) > .mx-spot {
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.3s ease;
    background: radial-gradient(240px circle at var(--mx-x, 50%) var(--mx-y, 50%), color-mix(in srgb, var(--app-primary, #38bdf8) 20%, transparent), transparent 70%);
}
html.mx-on body.ls-motion-rich :is(.gaming-product-card, .clean-stat-card):hover > .mx-spot { opacity: 1; }

/* ปุ่มซื้อมีแสงวิ่งเองเป็นระยะ */
html.mx-on body.ls-motion-rich .btn-gaming-buy::after { animation: mxSweep 4.5s ease-in-out infinite; }
html.mx-on body.ls-motion-rich .btn-gaming-buy:hover::after { animation: none; }
@keyframes mxSweep {
    0%, 62% { translate: -120% 0; }
    85%, 100% { translate: 120% 0; }
}

/* ไอคอนสถิติลอยขึ้นลง */
html.mx-on body.ls-motion-rich .clean-stat-icon-outline i { display: inline-block; animation: mxFloat 3.6s ease-in-out infinite; }
html.mx-on body.ls-motion-rich .clean-stat-card:nth-child(2n) .clean-stat-icon-outline i { animation-delay: -1.8s; }
@keyframes mxFloat {
    0%, 100% { translate: 0 0; }
    50% { translate: 0 -5px; }
}

/* ป้ายลอยบนการ์ด (แนะนำ / ขายดี) เด้งเบา ๆ */
html.mx-on body.ls-motion-rich .gaming-badge-floating { animation: mxBadge 2.8s ease-in-out infinite; }
@keyframes mxBadge {
    0%, 100% { scale: 1; }
    50% { scale: 1.07; }
}

/* พื้นหลังแสงเรืองสีธีมลอยช้า ๆ (อยู่ใต้เนื้อหา เหนือรูปพื้นหลัง) */
.mx-ambient { display: none; }
html.mx-on body.ls-motion-rich .mx-ambient {
    display: block;
    position: fixed;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    pointer-events: none;
}
html.mx-on body.ls-motion-rich .mx-ambient span {
    position: absolute;
    width: 46vmax;
    height: 46vmax;
    border-radius: 50%;
    opacity: 0.42;
    background: radial-gradient(circle, color-mix(in srgb, var(--app-primary, #38bdf8) 55%, transparent) 0%, transparent 65%);
    animation: mxDrift 26s ease-in-out infinite alternate;
}
html.mx-on body.ls-motion-rich .mx-ambient span:nth-child(1) { top: -18vmax; left: -14vmax; }
html.mx-on body.ls-motion-rich .mx-ambient span:nth-child(2) {
    bottom: -20vmax; right: -16vmax;
    background: radial-gradient(circle, color-mix(in srgb, var(--app-secondary, #2563eb) 55%, transparent) 0%, transparent 65%);
    animation-duration: 32s;
    animation-delay: -10s;
}
html.mx-on body.ls-motion-rich .mx-ambient span:nth-child(3) {
    top: 35%; left: 45%;
    width: 30vmax; height: 30vmax;
    opacity: 0.25;
    animation-duration: 38s;
    animation-delay: -20s;
}
html.mx-on body.ls-motion-rich.theme-light .mx-ambient span { opacity: 0.22; }
@keyframes mxDrift {
    0% { translate: 0 0; scale: 1; }
    50% { translate: 8vmax 6vmax; scale: 1.15; }
    100% { translate: -6vmax 10vmax; scale: 0.95; }
}

/* =====================================================================
   เครื่องที่ตั้งค่าลดการเคลื่อนไหว: เหลือแค่จางเข้า (หน้าเว็บ + การ์ด) ไม่มีการเคลื่อนที่
   ===================================================================== */
html.mx-on.mx-reduced .mx-reveal.mx-in,
html.mx-on.mx-reduced .mx-reveal.mx-pop.mx-in,
html.mx-on.mx-reduced .mx-reveal.mx-from-top.mx-in { animation-name: mxFade; animation-duration: 0.6s; }
@keyframes mxFade { from { opacity: 0; } to { opacity: 1; } }
html.mx-on.mx-reduced .hero-carousel-item.active .hero-bg-media,
html.mx-on.mx-reduced .hero-carousel-item.active .hero-content-anchor,
html.mx-on.mx-reduced .stock-indicator-dot.dot-in-stock { animation: none; }
html.mx-on.mx-reduced .btn-gaming-buy::after { display: none; }
html.mx-on.mx-reduced .side-sticky-banner .side-banner-card { animation: mxFade 0.6s ease-out 0.3s both; }
html.mx-on.mx-reduced .side-banner-card::after { display: none; }
html.mx-on.mx-reduced :is(.btn-gaming-buy, .btn-buy-action, .btn-auth-submit, .home-shortcut-card):active { scale: none; }
