/* =============================================================
   design-system.css — ฐานกลางของทั้งเว็บ
   =============================================================

   ไฟล์นี้ทำ 3 อย่าง:

   1. ประกาศ "ค่ามาตรฐาน" (token) ของสี ระยะ มุมโค้ง เงา จังหวะ
      โดยค่าทุกตัว = ค่าที่เว็บใช้อยู่จริงอยู่แล้ว ไม่ได้เปลี่ยนหน้าตาอะไร
      มีไว้ให้โค้ดที่เขียนต่อจากนี้เลิกเดาเลขเอง

   2. วางพื้นฐาน accessibility ที่ทั้งเว็บขาด — โดยเฉพาะขอบโฟกัส

   3. component ที่ใช้ซ้ำทั้งเว็บ — เขียนครั้งเดียวที่นี่ ไม่ต้องไปก๊อป
      ลง <style> ของแต่ละหน้าอีก (ดูส่วนท้ายไฟล์)

   กติกาการใช้:
   - หน้าใหม่/โค้ดที่แก้ ให้ใช้ var(--ds-*) แทนการพิมพ์เลขหรือสีดิบ
   - ห้ามประกาศ :root ทับในหน้าใดหน้าหนึ่ง (ทำให้ธีมแตกเป็นเกาะ)
   - ไฟล์นี้ต้องโหลด "หลัง" stylesheet หลัก เพราะชั้น accessibility
     ต้องชนะกฎ outline:none ที่กระจายอยู่ 38 จุดทั่วเว็บ

   ที่มาของค่า: นับจากโค้ดจริงทั้งเว็บ (styles.css, style-dashboard.css
   และ <style> ในทุกหน้า) แล้วเลือกค่าที่ใช้บ่อยที่สุดเป็นมาตรฐาน
   ============================================================= */


/* -------------------------------------------------------------
   1. สี — zinc scale ที่ทั้ง frontend และ backend ใช้ตรงกันอยู่แล้ว
   ------------------------------------------------------------- */

:root {
    /* โทนกลาง (ใช้ 340+ ครั้งทั้งเว็บ) */
    --ds-zinc-50: #fafafa;
    --ds-zinc-100: #f4f4f5;
    --ds-zinc-200: #e4e4e7;
    --ds-zinc-400: #a1a1aa;
    --ds-zinc-500: #71717a;
    --ds-zinc-800: #27272a;
    --ds-zinc-900: #18181b;
    --ds-zinc-950: #09090b;

    --ds-white: #ffffff;
    --ds-black: #000000;

    /* สีสื่อความหมาย — ค่าเดียวกับที่ style-dashboard.css ใช้อยู่
       (--ds-info เพิ่มทีหลัง ใช้ค่าเดียวกับสีฟ้าที่ toast.info และสถานะ
       "กำลังดำเนินการ" ของหน้าออเดอร์ใช้อยู่แล้ว) */
    --ds-success: #22c55e;
    --ds-success-subtle: rgba(34, 197, 94, .1);
    --ds-warning: #f59e0b;
    --ds-warning-subtle: rgba(245, 158, 11, .1);
    --ds-danger: #ef4444;
    --ds-danger-subtle: rgba(239, 68, 68, .1);
    --ds-info: #3b82f6;
    --ds-info-subtle: rgba(59, 130, 246, .1);

    /* สีตัวหนังสือเวลาวางบนพื้น -subtle

       ห้ามเอาสีฐานข้างบนมาใช้เป็นสีตัวหนังสือตรงๆ — บนธีมสว่างมันอ่านไม่ออก
       วัดค่า contrast จริงบนพื้น subtle/ขาว ได้ success 2.09 · warning 1.99 ·
       danger 3.30 · info 3.28 ซึ่งต่ำกว่าเกณฑ์ WCAG AA (4.5) ทุกตัว
       ชุดข้างล่างนี้วัดได้ 4.61 ถึง 8.98 ผ่านทั้งสองธีม

       ค่าธีมมืดตรงกับที่ products.php ใช้อยู่แล้ว (#4ade80) ไม่ได้คิดใหม่ */
    --ds-success-text: #4ade80;
    --ds-warning-text: #fbbf24;
    --ds-danger-text: #f87171;
    --ds-info-text: #60a5fa;

    /* badge โทนกลาง — ต้องเป็น token ไม่ใช่เขียนสีลงในกฎ [data-theme] ตรงๆ
       เพราะ [data-theme="light"] .ds-badge มี specificity สูงกว่า .ds-badge-success
       ถ้าใส่สีตรงนั้น variant ทุกตัวจะกลายเป็นสีเทาหมดในธีมสว่าง (เคยพลาดมาแล้ว) */
    --ds-badge-fg: var(--ds-zinc-400);
    --ds-badge-bg: var(--ds-tint-weak);
    --ds-badge-border: var(--ds-zinc-800);

    /* โครงหลอกตอนโหลด (skeleton) — sheen ต้อง "สว่างกว่า" base เสมอ
       ธีมมืดเลยเป็นขาวจางๆ ทับ ส่วนธีมสว่างเป็นขาวทึบทับเทาอ่อน */
    --ds-skeleton-base: var(--ds-zinc-800);
    --ds-skeleton-sheen: var(--ds-tint);

    /* ชั้นทับซ้อน (overlay/glass) ที่ใช้ซ้ำบ่อย */
    --ds-overlay-weak: rgba(0, 0, 0, .05);
    --ds-overlay: rgba(0, 0, 0, .1);
    --ds-overlay-strong: rgba(0, 0, 0, .5);
    --ds-tint-weak: rgba(255, 255, 255, .05);
    --ds-tint: rgba(255, 255, 255, .1);
    --ds-tint-strong: rgba(255, 255, 255, .2);


    /* ---------------------------------------------------------
       2. มุมโค้ง — เดิมมี 12 ค่ากระจัดกระจาย รวมเหลือ 6 ขั้น
          (ค่าที่เลือก = ค่าที่ถูกใช้จริงมากที่สุดในแต่ละขนาด)
       --------------------------------------------------------- */
    --ds-radius-xs: 4px;
    /* 37 ครั้ง — badge เล็ก, tag */
    --ds-radius-sm: 6px;
    /* 46 ครั้ง — ปุ่มเล็ก, chip */
    --ds-radius-md: 8px;
    /* 158 ครั้ง — ค่ามาตรฐานของ input/ปุ่ม */
    --ds-radius-lg: 12px;
    /* 108 ครั้ง — การ์ด, modal */
    --ds-radius-xl: 16px;
    /* 19 ครั้ง — การ์ดใหญ่ */
    --ds-radius-pill: 9999px;
    /* เดิมเขียน 3 แบบ: 9999px / 999px / 99px */


    /* ---------------------------------------------------------
       3. ระยะห่าง — ฐาน 4px
       --------------------------------------------------------- */
    --ds-space-1: 4px;
    --ds-space-2: 8px;
    --ds-space-3: 12px;
    --ds-space-4: 16px;
    --ds-space-5: 20px;
    --ds-space-6: 24px;
    --ds-space-8: 32px;
    --ds-space-10: 40px;
    --ds-space-12: 48px;


    /* ---------------------------------------------------------
       4. เงา
       --------------------------------------------------------- */
    --ds-shadow-sm: 0 1px 2px rgba(0, 0, 0, .06);
    --ds-shadow-md: 0 4px 10px -4px rgba(0, 0, 0, .22);
    --ds-shadow-lg: 0 12px 28px -8px rgba(0, 0, 0, .38), 0 4px 10px -4px rgba(0, 0, 0, .22);
    --ds-shadow-xl: 0 24px 48px -12px rgba(0, 0, 0, .45);


    /* ---------------------------------------------------------
       5. จังหวะการเคลื่อนไหว
       --------------------------------------------------------- */
    --ds-duration-fast: .14s;
    --ds-duration: .2s;
    --ds-duration-slow: .32s;
    --ds-ease: cubic-bezier(.4, 0, .2, 1);


    /* ---------------------------------------------------------
       6. ลำดับชั้น z-index — เดิมมีเลขสุ่มตั้งแต่ 1 ถึง 99999
          ทำให้ modal โผล่ใต้ dropdown เป็นบางที
       --------------------------------------------------------- */
    --ds-z-base: 1;
    --ds-z-dropdown: 60;
    --ds-z-sticky: 100;
    --ds-z-modal: 200;
    --ds-z-toast: 300;


    /* ---------------------------------------------------------
       7. ขอบโฟกัส
       --------------------------------------------------------- */
    --ds-focus-ring: var(--ds-zinc-50);
    /* ธีมมืดเป็นค่าตั้งต้นของเว็บนี้ */
    --ds-focus-width: 2px;

    /* ระยะห่างระหว่างขอบโฟกัสกับตัว element
       1px พอให้เห็นว่าเป็นคนละเส้นกับขอบของ element โดยไม่บวมออกมามาก
       (เดิม 2px + เส้นหนา 2px = กินพื้นที่รอบละ 4px ซึ่งดูเทอะทะบนช่องกรอกเล็กๆ) */
    --ds-focus-offset: 1px;
}


/* ธีมสว่าง — ขอบโฟกัสต้องกลับเป็นสีเข้มถึงจะมองเห็น
   (frontend ใส่ data-theme ไว้ทั้ง html และ body, backend ใส่ที่ html) */
[data-theme="light"] {
    --ds-focus-ring: var(--ds-zinc-900);

    /* สีเดียวกันบนพื้นสว่างจะจ้าจนอ่านไม่ออก ต้องเข้มลงมา (ดูตัวเลข contrast ข้างบน)

       วัดบน "พื้นการ์ด" #fafafa ไม่ใช่ขาวล้วน เพราะ badge ส่วนใหญ่อยู่ในการ์ด/ตาราง
       ซึ่งเป็นกรณีที่แย่กว่า — success/warning ขั้น -700 วัดได้ 4.43 / 4.47
       ตกเกณฑ์หวุดหวิด เลยลงมาอีกขั้นเป็น -800 (6.29 / 6.31) */
    --ds-success-text: #166534;
    --ds-warning-text: #92400e;
    --ds-danger-text: #b91c1c;
    --ds-info-text: #1d4ed8;

    /* zinc-500 บนพื้น zinc-100 วัดได้ 4.40 ต่ำกว่าเกณฑ์ AA (4.5) นิดเดียวแต่ก็คือไม่ผ่าน
       ตัวหนังสือ badge เล็กแค่ .75em เลยต้องเข้มลงมาอีกขั้นเป็น zinc-600 → 7.03 */
    --ds-badge-fg: #52525b;
    --ds-badge-bg: var(--ds-zinc-100);
    --ds-badge-border: var(--ds-zinc-200);

    --ds-skeleton-base: var(--ds-zinc-100);
    --ds-skeleton-sheen: var(--ds-white);
}


/* =============================================================
   ชั้น ACCESSIBILITY

   ส่วนนี้คือส่วนเดียวในไฟล์ที่ "เปลี่ยนสิ่งที่เห็น" และตั้งใจให้เปลี่ยน
   ============================================================= */


/* -------------------------------------------------------------
   ขอบโฟกัสสำหรับคนใช้คีย์บอร์ด

   ทั้งเว็บมี outline:none อยู่ 38 จุด แต่ใส่ :focus-visible กลับมาแค่ 7
   ที่เหลือคือกดปุ่ม Tab แล้วไม่รู้เลยว่าตอนนี้อยู่ตรงไหน — คนที่ใช้เมาส์
   ไม่ไม่ได้รับผลอะไร แต่คนที่ใช้คีย์บอร์ดหรือ screen reader ใช้งานไม่ได้จริง

   ทำไมต้อง !important:
   หน้า backend ทั้ง 31 หน้ามี <style> ฝังอยู่ในตัวหน้า ซึ่งโหลดทีหลัง
   ไฟล์นี้เสมอ ไม่ว่าจะวาง <link> ไว้ตรงไหนก็ตาม กฎ outline:none ในนั้น
   จะชนะทุกครั้งถ้าไม่ใช้ !important
   ใช้เฉพาะ outline อย่างเดียว ไม่แตะ property อื่น จึงไม่กระทบ layout

   :focus-visible เบราว์เซอร์จะยิงให้เฉพาะตอนใช้คีย์บอร์ด กดเมาส์ไม่ขึ้น
   หน้าตาตอนใช้งานปกติจึงเหมือนเดิมทุกประการ
   ------------------------------------------------------------- */

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible,
[role="button"]:focus-visible,
[role="tab"]:focus-visible,
[role="option"]:focus-visible,
[contenteditable="true"]:focus-visible {
    outline: var(--ds-focus-width) solid var(--ds-focus-ring) !important;
    outline-offset: var(--ds-focus-offset) !important;
}
/* หมายเหตุ: ไม่ต้องตั้ง border-radius ตรงนี้ — เบราว์เซอร์สมัยใหม่วาด outline
   ตามความโค้งของ element ให้เองอยู่แล้ว ถ้าเผลอใส่ border-radius: inherit
   ปุ่มเหลี่ยมที่อยู่ในการ์ดโค้งจะกลายเป็นโค้งตอนโฟกัส = หน้าตาเปลี่ยน */

/* ช่องกรอกข้อความ — ให้ขอบโฟกัสแนบไปกับกรอบช่องเลย ไม่ต้องเว้นระยะ
   เพราะสองเหตุผล:

   1. ช่องกรอกมีกรอบของตัวเองอยู่แล้ว ขอบโฟกัสที่ลอยห่างออกมาจึงอ่านเป็น
      "กล่องซ้อนกล่อง" แทนที่จะเป็นช่องที่ถูกไฮไลต์

   2. :focus-visible ทำงานกับช่องกรอกตอน "คลิกเมาส์" ด้วย ไม่ใช่เฉพาะคีย์บอร์ด
      (สเปกกำหนดไว้ เพราะช่องพวกนี้รับคีย์บอร์ดต่อทันที) วงนี้จึงเด้งบ่อยมาก
      ต้องเรียบร้อยกว่าวงของปุ่มที่นานๆ โผล่ที

   ส่วนปุ่ม/ลิงก์ยังเว้นระยะตามเดิม เพราะวงที่แนบติดปุ่มทึบจะกลืนไปกับตัวปุ่ม */
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[contenteditable="true"]:focus-visible {
    outline-offset: 0 !important;
}

/* องค์ประกอบที่ชนขอบ container จนขอบโฟกัสโดนตัด ให้วาดเข้าข้างในแทน */
.ds-focus-inset:focus-visible {
    outline-offset: calc(var(--ds-focus-offset) * -1) !important;
}


/* -------------------------------------------------------------
   เคารพการตั้งค่า "ลดการเคลื่อนไหว" ของระบบ

   style-dashboard.css ไม่มีส่วนนี้เลย (styles.css มีแค่จุดเดียว)
   คนที่มีอาการเวียนหัวจากภาพเคลื่อนไหว (vestibular disorder) ตั้งค่านี้
   ไว้ที่ OS แล้วคาดหวังว่าเว็บจะหยุดขยับให้
   ------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}


/* -------------------------------------------------------------
   ข้อความสำหรับ screen reader อย่างเดียว

   ใช้กับปุ่มที่มีแต่ไอคอน เมื่อไม่อยากใส่ aria-label
   เช่น <button><i data-lucide="trash"></i><span class="ds-sr-only">ลบ</span></button>
   ------------------------------------------------------------- */

.ds-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ซ่อนตามปกติ แต่โผล่มาเมื่อโฟกัสถึง — ใช้กับลิงก์ "ข้ามไปเนื้อหา" */
.ds-sr-only-focusable:not(:focus):not(:focus-within) {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}


/* -------------------------------------------------------------
   พื้นที่กดขั้นต่ำบนมือถือ

   WCAG 2.2 กำหนด 24x24px เป็นอย่างน้อย (แนะนำ 44px)
   ใส่คลาสนี้กับปุ่มไอคอนเล็กๆ ที่กดพลาดบ่อยบนมือถือได้
   ขยายด้วย ::after จึงไม่ดันเลย์เอาต์รอบข้าง
   ------------------------------------------------------------- */

.ds-tap-target {
    position: relative;
}

.ds-tap-target::after {
    content: "";
    position: absolute;
    inset: 50% auto auto 50%;
    width: max(100%, 44px);
    height: max(100%, 44px);
    transform: translate(-50%, -50%);
}


/* =============================================================
   ชั้น COMPONENT

   component ที่ใช้ซ้ำหลายหน้า เขียนไว้ที่เดียว
   ทุกค่าที่ใช้ต้องมาจาก --ds-* ตามกติกาข้อ 1
   ============================================================= */


/* -------------------------------------------------------------
   .ds-kbd — ป้ายปุ่มคีย์บอร์ด

   ใช้บอกผู้ใช้ว่ากดปุ่มไหนได้ เช่นป้าย "Ctrl K" ในช่องค้นหา
   หรือในตารางรวมปุ่มลัด

   <kbd class="ds-kbd">Esc</kbd>

   ปุ่มหลายตัวที่กดพร้อมกัน ครอบด้วย .ds-kbd-group
   <span class="ds-kbd-group"><kbd class="ds-kbd">Ctrl</kbd><kbd class="ds-kbd">K</kbd></span>

   ขนาดอิงจาก em ไม่ใช่ px — วางในข้อความขนาดไหนก็ย่อขยายตามเอง
   จึงไม่ต้องมี .ds-kbd-sm / -lg แยก
   ------------------------------------------------------------- */

.ds-kbd {
    display: inline-flex;
    align-items: center;
    justify-content: center;

    /* min-width ทำให้ปุ่มตัวอักษรเดียว ("K") ไม่ผอมกว่าปุ่มหลายตัว ("Ctrl")
       จนดูเป็นคนละชุดกัน */
    min-width: 1.7em;
    height: 1.7em;
    padding: 0 .45em;

    font-family: inherit;
    /* ไม่ใช้ monospace — ทั้งเว็บใช้ Kanit ป้ายที่เป็นฟอนต์อื่นจะดูหลุด */
    font-size: .75em;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;

    color: var(--ds-zinc-400);
    background: var(--ds-tint-weak);
    border: 1px solid var(--ds-zinc-800);
    border-radius: var(--ds-radius-xs);

    /* เส้นเข้มบางๆ ที่ขอบล่าง ทำให้ดูเป็นปุ่มนูนโดยไม่ต้องใส่เงาจริง
       (เงาจริงจะไปชนกับพื้นหลัง glass ของ navbar) */
    box-shadow: inset 0 -1px 0 var(--ds-overlay);

    /* ป้ายนี้เป็นข้อมูล ไม่ใช่ข้อความให้ลาก */
    user-select: none;
}

[data-theme="light"] .ds-kbd {
    color: var(--ds-zinc-500);
    background: var(--ds-zinc-100);
    border-color: var(--ds-zinc-200);
    box-shadow: inset 0 -1px 0 var(--ds-overlay-weak);
}

.ds-kbd-group {
    display: inline-flex;
    align-items: center;
    gap: .25em;
}

/* -------------------------------------------------------------
   .ds-badge — ป้ายสถานะ

   <span class="ds-badge ds-badge-success">พร้อมส่ง</span>
   <span class="ds-badge ds-badge-danger"><i class="ri-close-line" aria-hidden="true"></i> ยกเลิก</span>
   <span class="ds-badge">ร่าง</span>   <- ไม่ใส่ variant = โทนกลาง

   ขนาดอิง em เหมือน .ds-kbd วางในตารางหรือในหัวข้อก็ย่อขยายตามเอง

   ทั้งเว็บมี .status-badge / .badge เขียนซ้ำอยู่ราว 15 หน้า หน้าตาใกล้กันมาก
   (pill + พื้นจางสีสถานะ + ตัวหนังสือสีเดียวกัน) ตัวนี้คือรูปแบบนั้นที่เขียนไว้
   ที่เดียว ใช้ token ล้วน — ของเดิมยังอยู่ ไม่ได้ไปแตะ ให้ทยอยย้ายตอนแก้แต่ละหน้า
   ------------------------------------------------------------- */

.ds-badge {
    display: inline-flex;
    align-items: center;
    gap: .4em;

    padding: .25em .7em;
    border-radius: var(--ds-radius-pill);

    font-family: inherit;
    font-size: .75em;
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;

    /* โทนกลางเป็นค่าตั้งต้น ใส่ variant ทับเมื่อมีความหมายสถานะจริงๆ
       ป้ายที่ระบายสีทุกอันเท่ากับไม่ได้เน้นอะไรเลย

       ค่าสีมาจาก token ที่สลับตามธีมเอง ห้ามเขียนกฎ [data-theme="light"] .ds-badge
       มาทับตรงนี้ — มันชนะ .ds-badge-success ที่ specificity ต่ำกว่า */
    color: var(--ds-badge-fg);
    background: var(--ds-badge-bg);
    border: 1px solid var(--ds-badge-border);
}

/* variant ใช้ -text ไม่ใช่สีฐาน เพราะสีฐานบนพื้น subtle อ่านไม่ออกบนธีมสว่าง
   ส่วนเส้นขอบใช้สีฐานที่ 30% ตามที่ทั้งเว็บทำอยู่แล้ว */
.ds-badge-success {
    color: var(--ds-success-text);
    background: var(--ds-success-subtle);
    border-color: rgba(34, 197, 94, .3);
}

.ds-badge-warning {
    color: var(--ds-warning-text);
    background: var(--ds-warning-subtle);
    border-color: rgba(245, 158, 11, .3);
}

.ds-badge-danger {
    color: var(--ds-danger-text);
    background: var(--ds-danger-subtle);
    border-color: rgba(239, 68, 68, .3);
}

.ds-badge-info {
    color: var(--ds-info-text);
    background: var(--ds-info-subtle);
    border-color: rgba(59, 130, 246, .3);
}

/* ไอคอนในป้ายห้ามถูกบีบตอนป้ายไปอยู่ในช่องตารางแคบๆ
   (ครอบทั้ง <i> ของ Remix Icon และ <svg> ที่ lucide แปลงมาให้) */
.ds-badge > i,
.ds-badge > svg {
    flex-shrink: 0;
}

/* จุดกลมนำหน้าข้อความ สำหรับสถานะที่ต้องกวาดตาหาเร็วๆ ในตารางยาวๆ
   <span class="ds-badge ds-badge-success ds-badge-dot">ออนไลน์</span>
   ใช้ ::before จึงไม่ต้องเพิ่ม element และสีตามข้อความเองด้วย currentColor */
.ds-badge-dot::before {
    content: "";
    width: .5em;
    height: .5em;
    border-radius: var(--ds-radius-pill);
    background: currentColor;
    flex-shrink: 0;
}


/* -------------------------------------------------------------
   .ds-skeleton — โครงหลอกตอนโหลด

   ดีกว่าคำว่า "กำลังโหลด…" ตรงที่บอกล่วงหน้าว่ากำลังจะมีอะไรโผล่มา
   ตรงไหนบ้าง หน้าเลยไม่กระตุกตอนข้อมูลมาถึง

   <span class="ds-skeleton"></span>
   <span class="ds-skeleton ds-skeleton-title"></span>
   <span class="ds-skeleton ds-skeleton-circle"></span>
   <div class="ds-skeleton ds-skeleton-card"></div>

   ปรับขนาดผ่านตัวแปร ไม่ต้องเขียน CSS ใหม่:
   <span class="ds-skeleton" style="--ds-skeleton-w: 40%"></span>

   ที่มา: ยกมาจาก .pm-skel ใน _paymatch_section.php ซึ่งใช้งานจริงอยู่แล้ว
   เปลี่ยนแค่ให้ใช้ token แทนตัวแปรเฉพาะหน้าหลังบ้าน
   ------------------------------------------------------------- */

.ds-skeleton {
    display: block;
    width: var(--ds-skeleton-w, 100%);
    height: var(--ds-skeleton-h, 12px);
    border-radius: var(--ds-radius-sm);

    /* แยกเป็น 2 ชั้น (สีพื้น + แถบไล่สี) แทนที่จะไล่สี 3 จุดในชั้นเดียว
       จะได้เปลี่ยนสีพื้นตามธีมโดยไม่ต้องเขียน gradient ใหม่ทั้งเส้น */
    background-color: var(--ds-skeleton-base);
    background-image: linear-gradient(90deg,
            transparent 25%,
            var(--ds-skeleton-sheen) 37%,
            transparent 63%);
    background-size: 400% 100%;
    background-repeat: no-repeat;

    animation: ds-skeleton-sweep 1.4s var(--ds-ease) infinite;

    /* เป็นภาพหลอก ไม่มีข้อความให้ลาก และไม่ควรกดโดน */
    user-select: none;
    pointer-events: none;
}

/* ชั้น accessibility ท้ายไฟล์หยุด animation ให้เองเมื่อผู้ใช้ตั้ง
   prefers-reduced-motion จึงไม่ต้องเขียนซ้ำตรงนี้ — เหลือเป็นบล็อกนิ่งๆ ซึ่งยังสื่อความหมายครบ */

@keyframes ds-skeleton-sweep {
    from {
        background-position: 100% 50%;
    }

    to {
        background-position: 0 50%;
    }
}

/* บรรทัดข้อความ — สูงเท่าบรรทัดจริงของข้อความที่จะมาแทน */
.ds-skeleton-text {
    --ds-skeleton-h: 1em;
    border-radius: var(--ds-radius-xs);
}

.ds-skeleton-title {
    --ds-skeleton-h: 1.4em;
}

/* บรรทัดสุดท้ายของย่อหน้าจริงมักไม่เต็มบรรทัด ทำให้เหมือนของจริงขึ้น */
.ds-skeleton-text:last-child {
    --ds-skeleton-w: 65%;
}

/* รูปโปรไฟล์ / ไอคอนกลม — คุมขนาดตัวเดียวได้ทั้งกว้างและสูง */
.ds-skeleton-circle {
    --ds-skeleton-w: var(--ds-skeleton-size, 40px);
    --ds-skeleton-h: var(--ds-skeleton-size, 40px);
    border-radius: var(--ds-radius-pill);
    flex-shrink: 0;
}

/* การ์ดสินค้า / รูปแบนเนอร์ */
.ds-skeleton-card {
    --ds-skeleton-h: 160px;
    border-radius: var(--ds-radius-lg);
}


/* =============================================================
   ช่องกรอกตัวเลข — ซ่อนลูกศรขึ้น/ลง (spinner) ทั้งเว็บ
   =============================================================

   ลูกศรจิ๋วที่เบราว์เซอร์แถมมาให้ input[type=number] กดยากบนจอเล็ก
   กดพลาดแล้วค่าเปลี่ยนโดยไม่ตั้งใจ และหน้าตาไม่เข้ากับธีมมืดของเว็บ
   ทุกที่ที่ต้องการปุ่มเพิ่ม/ลด เว็บนี้ทำปุ่มของตัวเองอยู่แล้ว
   (เช่นตัวเลือกจำนวนในหน้าสินค้า)

   เดิมมี 6 หน้าที่เขียนกฎนี้ซ้ำใน <style> ของตัวเอง ส่วนหน้าอื่นตกหล่น
   ย้ายมาไว้ที่เดียวตรงนี้ให้ครอบคลุมทั้งหน้าบ้านและหลังบ้าน

   หมายเหตุ: ยังพิมพ์ตัวเลขและใช้ลูกศรขึ้น/ลงบนคีย์บอร์ดได้ตามปกติ
   ซ่อนแค่ปุ่มที่กดด้วยเมาส์เท่านั้น */

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    appearance: none;
    margin: 0;
}

input[type="number"] {
    -moz-appearance: textfield;  /* Firefox */
    appearance: textfield;       /* Chrome/Edge รุ่นใหม่ และมาตรฐาน */
}


/* =============================================================
   [hidden] ต้องซ่อนได้จริง
   =============================================================

   เบราว์เซอร์ซ่อน [hidden] ด้วยกฎ display:none ใน UA stylesheet
   ซึ่งแพ้ inline style เสมอ องค์ประกอบที่เขียน style="display: flex"
   ไว้ตรง ๆ จึงยังโผล่อยู่ทั้งที่ติด hidden แล้ว
   (เจอจริงกับแถบ "สินค้าหมดชั่วคราว" ในหน้าสินค้า)

   ประกาศทับให้ชนะ inline style เพื่อให้ el.hidden = true ใช้ได้เสมอ
   ไม่ต้องมานั่งจำว่าองค์ประกอบไหนเขียน display อะไรไว้ */

[hidden] {
    display: none !important;
}
