/* ตัวโหลดในปุ่มกลาง (2026-10-21 · มติเจ้าของ: "ปุ่มทุกปุ่มตอนโหลดเป็นแบบนี้" ยกเว้นปุ่มเพิ่มลงตะกร้าที่มีอนิเมชันของตัวเอง)
   จุด 3 จุดกระโดดเป็นคลื่น (ตามไฟล์ LOADING.svg ของเจ้าของ: รอบ 0.533 วินาที · จุดซ้ายนำหน้าจุดขวา ~83ms)
   ใช้ผ่าน public/js/btn-loading.js (PrintpaoBtn.start/stop · ฟอร์ม/ปุ่ม Livewire ทำให้อัตโนมัติ)
   ★ ขนาดปุ่มไม่เปลี่ยน: ซ่อนเนื้อหาด้วย color/visibility (ยังกินที่) แล้ววางจุดทับตรงกลาง
   ★ ขนาดจุดเป็น em ตามตัวอักษรของปุ่ม · สีจุด = สีตัวหนังสือเดิมของปุ่ม (JS ใส่ --pp-dot) → ขาวบนปุ่มชมพู เข้มบนปุ่มขาว */
.is-btn-loading { position: relative; color: transparent !important; pointer-events: none; cursor: progress; }
.is-btn-loading > *:not(.pp-dots) { visibility: hidden; }
.is-btn-loading:disabled { opacity: 1; }   /* ปุ่มที่ถูก disabled ตอนโหลด (เช่นปุ่มฟอร์ม auth) ไม่ต้องจางซ้ำ */

.pp-dots { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: .34em; pointer-events: none; }
.pp-dots i {
  display: block; width: .52em; height: .52em; border-radius: 50%; background: var(--pp-dot, currentColor);
  animation: pp-dot-bounce .533s infinite;
}
.pp-dots i:nth-child(1) { animation-delay: -.166s; }
.pp-dots i:nth-child(2) { animation-delay: -.083s; }

@keyframes pp-dot-bounce {
  0%        { transform: translateY(-.2em); animation-timing-function: cubic-bezier(.514, 0, .424, 1); }
  47%       { transform: translateY(.2em);  animation-timing-function: cubic-bezier(.054, 0, .465, 1); }
  94%, 100% { transform: translateY(-.2em); }
}

/* ผู้ใช้ตั้ง "ลดการเคลื่อนไหว" = จุดไม่กระโดด กะพริบเบาๆ แทน */
@media (prefers-reduced-motion: reduce) {
  .pp-dots i { animation: pp-dot-fade 1s ease-in-out infinite; }
  .pp-dots i:nth-child(2) { animation-delay: .15s; }
  .pp-dots i:nth-child(3) { animation-delay: .3s; }
  @keyframes pp-dot-fade { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
}
