/* ═══════════════════════════════════════════════════════════════════════════
   leh_layers.css — บันไดชั้นการซ้อนทับของทั้งระบบ (SSOT ของโทเคน --leh-z-*)

   🔴 ไฟล์นี้เป็น "ที่เดียว" ที่ได้รับอนุญาตให้นิยามโทเคน --leh-z-*
      ตรึงด้วย tests/Smoke/LayerLadderContractTest.php

   โหลดโดย: system/importCss.php · portal/_head.php
            · system/customerPortal/public/_layout.php · system/fieldApp/views/*
      (แบบเดียวกับ leh_copy.css ซึ่งแยกไฟล์ด้วยเหตุผลเดียวกันเป๊ะ — พื้นผิวอื่น
       โหลด styleNew.css ทั้งก้อนไม่ได้ เพราะจะทับธีมของตัวเอง)

   ─── หลักการจัดลำดับ (ตัวตัดสินเวลาสงสัยว่าของใหม่ควรอยู่ชั้นไหน) ───────────
   ยิ่ง "ชั่วคราว" และยิ่ง "ต้องการคำตอบจากผู้ใช้" ยิ่งอยู่หน้า
   ยิ่ง "อยู่ถาวร" และเป็นบริบท ยิ่งอยู่หลัง

   กฎที่ตามมา 3 ข้อ:
     1. อะไรที่ถูกย้ายไปเกาะ <body> (portal) ต้องอยู่ **เหนือชั้นโมดัล**
        เพราะมันเกิดจากในโมดัลได้ และเมื่อหลุดจาก stacking context ของโมดัลแล้ว
        ไม่มีอะไรพามันขึ้นมาอีก
     2. ของที่ยังเป็น "ลูก" ของ overlay ไม่ต้องมีชั้นระดับระบบ — ใช้เลขเล็ก
        ในบ้านตัวเอง (ค่า <= 100 ไม่อยู่ในบังคับของ ratchet)
     3. โทเคนไม่ได้ลบความจำเป็นของการ portal — `.wrapper-content.animated`
        ทิ้ง transform ค้างไว้เป็น containing block ของ position:fixed ทุกตัว
        (บทเรียนที่ทำให้ .leh-bulkbar เคยไปอยู่นอกจอ) ⇒ ตัวที่ portal อยู่แล้ว
        ห้ามถอดออกเพราะ "มีโทเคนแล้ว"

   ─── 🔴 หมุดที่ห้ามขยับ ────────────────────────────────────────────────────
   --leh-z-modal-bd / --leh-z-modal ต้องคงค่า 2040 / 2050
   เพราะ system/js/leh_notify.js (lehHasBlockingOverlay) ใช้เกณฑ์ "z >= 1040"
   เป็นนิยามของ "นี่คือโมดัล" ที่ใช้สั่งล็อกการเลื่อนหน้า และ
   MobileNavDrawerContractTest บังคับว่า backdrop ของ drawer ต้องผ่านเกณฑ์นั้น
   ⇒ ทุกชั้นตั้งแต่ย่าน B ขึ้นไปต้องไม่ต่ำกว่าเกณฑ์นั้น

   ─── ทำไมย่าน D เริ่มที่ 3000 ไม่ใช่ 2100 ──────────────────────────────────
   ระหว่างย้ายทีละกลุ่ม จะมีช่วงที่โทเคนใหม่กับตัวเลขเก่าอยู่หน้าเดียวกัน
   ย่าน 2100-2600 **มีของอยู่แล้ว** (tour · เมนูข้อความในห้องแชท · liveOps)
   ⇒ จะเกิดค่าเท่ากันเป๊ะที่ตัดสินด้วยลำดับ DOM = บั๊กที่ทำซ้ำยากที่สุด
   ย่าน 3000-3600 วัดแล้วว่างสนิท ไม่มีตัวเลขไหนในระบบใช้อยู่เลย
   ═══════════════════════════════════════════════════════════════════════════ */

:root {

    /* ── ย่าน A · ในหน้า ─────────────────────────────────────────────────── */
    --leh-z-behind:          -1;   /* พื้นหลังตกแต่งหลังเนื้อหา */
    --leh-z-base:             1;   /* ชั้นในการ์ด */
    --leh-z-raised:          10;   /* ของที่ยกทับพี่น้องในกล่องเดียวกัน */
    --leh-z-sticky:         100;   /* หัวตารางที่ตรึงไว้ · แถวการ์ด KPI */
    --leh-z-sticky-lead:    110;   /* เซลล์มุมของตารางที่ตรึงสองแกน */
    --leh-z-veil:           120;   /* ผ้าคลุมระดับ "กล่อง" (ตัวหมุนตอนโหลดที่ปูเต็มการ์ด/ตาราง)
                                      🔴 ต้องสูงกว่าหัวตารางที่ตรึงไว้ ไม่งั้นหัวตารางทะลุผ้าคลุม
                                      (เจอจริงตอนจัดบันได : ย้ายไปชั้น raised แล้วหัวตาราง sticky
                                       ซึ่งอยู่ชั้น sticky ลอยขึ้นมาทับตัวหมุน)
                                      ⚠️ คนละตัวกับ --leh-z-modal-veil ซึ่งคลุม "ทั้งหน้า" */
    --leh-z-chrome:        1000;   /* ท้ายหน้าแบบตรึง · แถบข้างขวา */

    /* ── ย่าน B · เปลือกระบบ + ของลอยที่เปิดค้างคู่กับหน้า ─────────────────
       🔴 ทุกค่าในย่านนี้ต้องไม่ต่ำกว่าเกณฑ์ "นี่คือโมดัล" ของ leh_notify.js */
    /* แถบเลือกหลายรายการ — ถูกย้ายไปท้าย <body> จึงต้องกดตัวเองให้ต่ำด้วยตัวเลข
       🔴 ต้องอยู่ **ใต้** แถบบน · มุมมองเต็มจอ · และแผงข้าง (ค่าเดิม 1030 ต่ำกว่าทั้งสาม)
          วัดเทียบย้อนหลังแล้วพบว่ารอบแรกผมตั้งไว้ 1310 ซึ่ง **สูงกว่าแผงเมล**
          ⇒ แถบจะไปทับแผงเมลที่มุมล่างขวา ทั้งที่เจตนาที่บันทึกไว้คือให้จมใต้แผง */
    --leh-z-bulkbar:       1050;
    --leh-z-nav:           1100;   /* แถบบน + แถบข้าง */
    --leh-z-nav-menu:      1110;   /* เมนูที่ห้อยจากแถบบน · ป้ายชื่อเมนูตอนย่อ */
    --leh-z-workspace:     1200;   /* มุมมองเต็มจอที่ "แทนหน้า" */
    --leh-z-side-panel:    1300;   /* แผงข้างที่เปิดค้าง (แผงเมล · สมุดโน้ต) */
    --leh-z-fab:           1320;   /* คอลัมน์ปุ่มลอย */
    --leh-z-panel:         1330;   /* แผงของปุ่มลอย — เหนือแผงข้างเสมอ */

    /* 🔴 เมนูมือถือต้องอยู่ **เหนือแผงลอยทุกตัว** — วางไว้ท้ายย่าน B
       เหตุผล : มันคือพื้นผิวชั่วคราวที่ "บล็อกงาน" (มีฉากมืดของตัวเอง + ล็อกการเลื่อนหน้า)
       ตามหลักการของบันไดนี้ ของที่บล็อกงานต้องอยู่หน้าของที่เปิดค้าง
       ⚠️ รอบแรกวางไว้ใต้แถบบน (ตามค่าเดิม 2000/2001 < 2030) แล้ววัดเทียบย้อนหลังพบว่า
          เมื่อรวมกับมติ "แผงลอยอยู่เหนือมุมมองเต็มจอ" มันไล่ให้แผงเมล (1300) สูงกว่า
          เมนูมือถือไปด้วย ⇒ บนมือถือ เปิดแผงเมลค้างไว้แล้วกดแฮมเบอร์เกอร์
          **เมนูจะเปิดอยู่หลังแผงจนมองไม่เห็น** (แผงเมลกว้าง 92-100vw บนจอเล็ก)
       ⚠️ ผลข้างเคียงที่ยอมรับ : แถบบนถูกฉากมืดคลุมด้วย — ปุ่มแฮมเบอร์เกอร์จะหรี่ลง
          แต่ยังกดปิดได้ เพราะแตะตรงนั้นคือแตะฉากมืด ซึ่งเป็นทางปิดอยู่แล้ว */
    --leh-z-drawer-bd:     1400;   /* ฉากมืดของเมนูมือถือ */
    --leh-z-drawer:        1410;   /* เมนูมือถือ */

    /* ── ย่าน C · โมดัล (สิ่งที่บล็อกงานผู้ใช้) ──────────────────────────── */
    --leh-z-modal-bd:      2040;   /* 🔴 หมุด */
    --leh-z-modal:         2050;   /* 🔴 หมุด */
    --leh-z-modal-nested-bd: 2060; /* โมดัลที่เปิดซ้อนบนโมดัล */
    --leh-z-modal-nested:  2070;
    --leh-z-modal-veil:    2080;   /* ฉากคลุมเต็มจอตอนล็อกหน้า — ต้องคลุมโมดัลด้วย */

    /* ── ย่าน D · เหนือโมดัล (ของที่ถูกย้ายไปเกาะ body) ──────────────────── */
    --leh-z-menu:          3000;   /* เมนู · ตัวเลือก · เติมคำอัตโนมัติ · เมนูดาวน์โหลด */
    --leh-z-tooltip:       3010;
    --leh-z-hovercard:     3020;   /* การ์ดพรีวิวตอนชี้ค้าง · ปุ่มคัดลอกลอย */
    --leh-z-viewer:        3100;   /* ตัวดูไฟล์เต็มจอ */
    --leh-z-viewer-over:   3110;   /* แผงที่เปิดจาก "ในตัว" ตัวดูไฟล์ */
    --leh-z-alert:         3200;   /* กล่องยืนยัน — ต้องเหนือทุกอย่างที่มันถาม */
    --leh-z-progress:      3300;   /* แถบความคืบหน้าบนสุด (ไม่รับคลิก) */
    --leh-z-toast:         3400;   /* แจ้งผล — ต้องอ่านได้เสมอ */
    --leh-z-command:       3500;   /* แถบคำสั่งลัด */
    --leh-z-critical:      3600;   /* หมดเวลาใช้งาน · หลุดการเชื่อมต่อ */

    /* ═══════════════════════════════════════════════════════════════════════
       ความลึกที่ "มองเห็นได้" — ฉากมืด + เงา
       ═══════════════════════════════════════════════════════════════════════
       บันไดข้างบนตอบว่า **ใครอยู่หน้าใคร** · ส่วนนี้ตอบว่า **ผู้ใช้รู้ได้อย่างไร**
       ทั้งสองเรื่องเป็นระบบเดียวกัน จึงอยู่ไฟล์เดียวกัน

       🔴 ทำไมต้องมี (วัดจริง 2026-08-31) : ฉากมืดของ overlay เต็มจอมี **17 แบบใน 46 จุด**
          ความทึบกระจาย .38 ถึง .85 · สีฐานต่างกัน 7 ชุด (15,23,42 · 30,41,59 · 20,28,46
          · 20,30,50 · 52,71,103 · 26,39,64 · 0,0,0)
       🔴 ตัวที่กระทบกว้างที่สุดคือ **ฉากมืดของโมดัลมาตรฐาน ซึ่ง Bootstrap ตั้งเป็น `#000`
          แล้วเปิดที่ opacity .5** ⇒ หน้าที่ใช้โมดัลปกติ (หลายร้อยหน้า) ดำสนิท
          ขณะที่โมดัลที่หน้าเขียนเองเป็น navy-slate ⇒ **สองภาษาบนจอเดียวกัน**
          และดำสนิทอ่านว่า "หนัก" กว่าที่ควร ซึ่งคือข้อที่ผู้ใช้บอกว่าไม่สบายตา

       เกณฑ์เลือกชั้น — ถามว่า "ชั้นล่างยังต้องอ่านได้ไหม"
         sheet  ยังต้องเห็นบริบท (แผ่นเลื่อน · แผงเลือก · ป๊อปอัปรูปในแชท)
         modal  ชั้นล่างหยุดทำงาน ต้องรู้ทันทีว่าแตะไม่ได้
         media  ภาพต้องเด่นที่สุด พื้นหลังห้ามแย่งสายตา (ตัวดูรูป)

       ⚠️ **ไม่ใส่ `backdrop-filter` เป็นค่าเริ่มต้น** — วัดแล้ว 35 จาก 46 จุดไม่มีเบลอ
          และการเบลอเต็มจอมีราคาแพงบนเครื่องที่แรงน้อย ⇒ ให้เป็นทางเลือกรายพื้นผิว
          ไม่ใช่กฎกลาง (ความสม่ำเสมอของ "สีและความทึบ" คือกำไรก้อนใหญ่)

       ⚠️ ทุกค่าใช้ฐาน 15,23,42 ซึ่งเป็นเฉดที่ระบบใช้อยู่แล้ว ⇒ ไม่เพิ่มจำนวนเฉด
          (ratchet `scan_color_tokens` นับ "จำนวนเฉดที่ไม่ซ้ำกัน") */
    --leh-scrim-sheet:  rgba(15, 23, 42, .45);
    --leh-scrim-modal:  rgba(15, 23, 42, .58);
    --leh-scrim-media:  rgba(15, 23, 42, .88);

    /* เงาของพื้นผิวที่ "ลอยอยู่จริง" — ยกจากค่าที่ระบบใช้อยู่แล้ว ไม่ได้คิดใหม่
       (ศูนย์รวมแชทเคยเป็น .28 · ผู้ช่วย AI เป็น .25 ⇒ ต่างกัน .03 = ตั้งใจให้เหมือนกันอยู่แล้ว)
       ⚠️ แผงที่เลื่อนออกจากขอบขวา (แผงเมล · สมุดโน้ต) ใช้เงา **มีทิศทาง** ของตัวเอง
          `-16px 0 50px` ซึ่งถูกต้องตามการเคลื่อนที่ของมัน — ห้ามยุบมารวมกับสองตัวนี้ */
    --leh-elev-menu:  0 12px 32px -8px rgba(15, 23, 42, .22), 0 0 0 1px rgba(15, 23, 42, .05);
    --leh-elev-panel: 0 24px 64px -16px rgba(15, 23, 42, .26), 0 8px 24px -8px rgba(15, 23, 42, .12), 0 0 0 1px rgba(15, 23, 42, .05);
}

/* ═══════════════════════════════════════════════════════════════════════════
   ส่วนที่เจ็ดของระบบเดียวกัน — จังหวะการเคลื่อนไหวของชั้นลอย  (2026-08-31)
   ───────────────────────────────────────────────────────────────────────────
   บันไดตอบว่าใครอยู่หน้าใคร · ฉากมืดตอบว่าผู้ใช้รู้ได้อย่างไร
   · ข้อนี้ตอบว่า **คนที่ขอให้ลดการเคลื่อนไหว ได้สิ่งที่ขอไหม**

   วัดจริงก่อนแก้ : ไฟล์ที่ทำแอนิเมชันให้ชั้นลอย **68 ไฟล์ · มีทางออก 13 · ไม่มี 55**
   · จังหวะ transition ของชั้นลอยมี **28 ค่าไม่ซ้ำ** (.01s ถึง 1.15s)
   ⇒ แก้ 55 ไฟล์คือ sweep ข้ามไฟล์โดยไม่มี coverage ⇒ ทำเป็น **กฎกลางที่เดียว**
     ไฟล์นี้ถูกโหลดบนทุกพื้นผิว (ระบบหลัก · พอร์ทัล · พอร์ทัลลูกค้า · แอปช่าง · หน้าเข้าระบบ)

   🔴 **ทำไมไม่ใช้กฎมาตรฐานที่แพร่หลาย** (`*{animation-iteration-count:1!important}`)
      — วัดแล้วระบบนี้มีแอนิเมชัน `infinite` **142 จุดใน 53 ไฟล์** ซึ่งเกือบทั้งหมด
        คือ **ตัวหมุนรอโหลด** ⇒ กฎนั้นจะ **แช่แข็งตัวหมุนทั้งระบบ** แล้วผู้ใช้อ่านว่า "ค้าง"
        ซึ่งแย่กว่าการเคลื่อนไหวที่เขาอยากเลี่ยง
      ⇒ ที่นี่แตะ **transition อย่างเดียว** (จังหวะตอบสนองการกด/เปิด-ปิด)
        ส่วน `animation` ปล่อยไว้ ยกเว้น `.animated` ของ animate.css ซึ่งเป็น
        **แอนิเมชันเข้าหน้า** ที่เลื่อนเนื้อหาทั้งหน้าจากขอบขวา — ตรงกับสิ่งที่ผู้ใช้กลุ่มนี้
        ขอให้เลิกพอดี และไม่มีตัวหมุนตัวไหนใช้คลาสนี้

   🔴 **ห้ามใส่ `transform: none !important`** — รีโปเคยเจอมาแล้วว่ากฎแบบนั้น
      กินเอฟเฟกต์ hover ของปุ่ม (`.login-line-btn`) เพราะ `!important` ชนะ specificity
      ⇒ ที่นี่ตั้งแต่ **ระยะเวลา** เท่านั้น เอฟเฟกต์ยังอยู่ครบ แค่เกิดทันที

   ⚠️ ข้อจำกัดที่รู้ตัว : `transition … !important` ที่คอมโพเนนต์ตั้งเอง **28 จุด / 12 ไฟล์**
      ยังชนะกฎนี้ (คลาสชนะ `*` เมื่อ !important เท่ากัน) — เป็นจุดที่ยอมรับไว้
      ไม่ใช่รูที่มองไม่เห็น
   ⚠️ โค้ดที่รอ `transitionend` ยังทำงาน (event ยังยิง แค่เร็วมาก)
      · โค้ดที่ใช้ `setTimeout` ให้ตรงกับ transition ก็ยังถูก (แค่รอหลังของขยับเสร็จแล้ว)
   ═══════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        transition-duration: .01ms !important;
        transition-delay: 0s !important;
        scroll-behavior: auto !important;
    }
    /* animate.css — แอนิเมชันเข้าหน้าเท่านั้น ไม่ใช่ตัวหมุน */
    .animated {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
    }
}
