/* ============================================================
   X10 Chat — ชั้นมือถือ (iOS / Android)
   ซีด "มือถือ iOS และ Android" 2026-08-22
   ------------------------------------------------------------
   ⚠️ กฎเหล็ก: ทุก selector ในไฟล์นี้ต้องขึ้นต้นด้วย body.x10m
   เดสก์ท็อปต้องไม่ได้รับผลกระทบแม้แต่กฎเดียว
   ⚠️ ไฟล์นี้โหลดหลัง x10-ui.css เพื่อชนะ .x10v3 (บทเรียน safe-area 2026-08-21)
   ============================================================ */

body.x10m {
  /* พื้นที่ปลอดภัย: iOS 26px ตามซีด / Android gesture nav 20px */
  --x10m-safe-b: max(env(safe-area-inset-bottom), 26px);
  --x10m-tabbar-h: 56px;
  --x10m-hit: 44px;              /* พื้นที่แตะขั้นต่ำตามซีดหน้า 03 */

  /* ════════════════════════════════════════════════════════════
     ปรับขนาดตามรุ่นเครื่องอัตโนมัติ (Boss สั่ง 2026-09-06)
     "แต่ละรุ่นขนาดไม่เท่ากัน" — จริง แต่ **ไม่ hardcode ทีละรุ่น**
     เพราะจะพังทันทีที่ Apple ออกรุ่นใหม่ ใช้ 2 กลไกที่ระบบบอกมาเอง:
       1) env(safe-area-inset-*) = iOS บอกความสูงรอยบาก/เกาะ ตามรุ่นจริง
          (SE≈20px · 14≈47px · Pro Max≈59px · Dynamic Island ต่างอีก)
       2) ความสูงจอ (dvh) = จอเตี้ยบีบเอง จอใหญ่โปร่งเอง ไล่ต่อเนื่อง
          ไม่ใช่กระโดดเป็นขั้นแบบ breakpoint
     ⚠️ ใช้ dvh ไม่ใช่ vh — คีย์บอร์ด/แถบ Safari ขึ้นลง vh ไม่อัปเดตตาม
     ════════════════════════════════════════════════════════════ */
  /* หัวห้อง: จอเตี้ย (SE 667) ได้ ~50px · จอใหญ่ (932) ได้ ~58px */
  --x10m-head-h: clamp(48px, 7.2dvh, 60px);
  --x10m-head-fs: clamp(14px, 1.9dvh, 16px);      /* ชื่อห้อง */
  --x10m-head-sub: clamp(10.5px, 1.45dvh, 12.5px);/* บรรทัดรอง (สมาชิก/หัวข้อ) */

  /* ---- ทั้งแอปปรับตามรุ่น (Boss สั่ง 2026-09-06 รอบ 2: "ทั้งแอพเลย") ----
     แอปมี design token อยู่แล้ว (--fs-* / --s* ที่ style.css:1011)
     และถูกเรียกใช้ 199 จุดทั่วแอป → **ทับที่นี่จุดเดียว มีผลทั้งแอปทันที**
     ไม่ต้องไล่แก้ 448 จุด และเดสก์ท็อปไม่กระทบ (อยู่ใน body.x10m ล้วน)

     ⚠️ ฐานคิดจาก Android เป็นหลัก (Boss: "ส่วนใหญ่ในบริษัทใช้แอนดรอย")
        จอ Android ที่ใช้จริง 360-412px → ตั้งให้ค่ากลางตรงกับของเดิมเป๊ะ
        จอ 360px = ได้ค่าเท่าเดิมทุกตัว (คนส่วนใหญ่จึงไม่รู้สึกว่าอะไรเปลี่ยน)
        เล็กกว่านั้น (320px) ค่อยหดลง · ใหญ่กว่า (430px+) ค่อยขยาย

     ⚠️ ใช้ vw (ความกว้าง) ไม่ใช่ dvh สำหรับตัวอักษร/ระยะ — ความกว้างคือ
        ตัวกำหนดว่าข้อความจะตัดบรรทัดไหม ส่วน dvh ใช้เฉพาะของที่กินความสูง
     ⚠️ ทุกตัวมี clamp คุมบน-ล่าง ไม่ให้จอเล็กเละหรือจอใหญ่บวม */
  /* ตัวอักษร: พื้นล่างยกให้ใกล้ของเดิม — จอ 320px ก็ยังต้องอ่านออก
     (รอบแรกตั้ง 13px ที่ fs-md แล้ววัดได้ว่าเล็กเกินไปสำหรับใช้งานจริง) */
  --fs-xs:   clamp(10.5px, 2.9vw, 12px);
  --fs-sm:   clamp(12px,   3.4vw, 13.5px);
  --fs-md:   clamp(13.5px, 3.9vw, 15px);
  --fs-base: clamp(14.5px, 4.2vw, 16px);
  --fs-lg:   clamp(16.5px, 4.7vw, 18.5px);
  --fs-xl:   clamp(19px,   5.6vw, 22px);
  /* ระยะห่าง: เพดานเตี้ยกว่าตัวอักษร — จอใหญ่ควรได้ "เห็นเนื้อหาเพิ่ม"
     ไม่ใช่ได้ช่องว่างเพิ่ม (รอบแรก s6 บวมไป +4.8px = เปลืองจอเปล่า) */
  --s1: clamp(3.5px, 1.1vw, 4.5px);
  --s2: clamp(7px,   2.2vw, 9px);
  --s3: clamp(10.5px, 3.3vw, 13px);
  --s4: clamp(14px,  4.4vw, 17.5px);
  --s5: clamp(17.5px, 5.6vw, 21.5px);
  --s6: clamp(21px,  6.7vw, 26px);

  /* ⚠️ บั๊กเดิมของแอป: --card/--bg/--text/--border ถูกประกาศ **เฉพาะใน
     html[data-theme="dark"]** เท่านั้น → ธีมสว่างไม่มีค่าเหล่านี้เลย
     ของเดิมไม่พังเพราะแต่ละ element ใส่สีตัวเองไว้ แต่ชั้นมือถือใช้ token พวกนี้
     ถ้าไม่กันไว้ แผ่นเมนู/แถบล่างจะ "โปร่งใส" ในธีมสว่าง (เจอจริงจากภาพทดสอบ)
     → ตั้งค่าสำรองเฉพาะชั้นมือถือ ไม่แตะ token ส่วนกลาง (เดสก์ท็อปไม่กระทบ) */
  --x10m-surface: var(--card, #FFFFFF);
  --x10m-ground: var(--bg, #F4F6F9);
  --x10m-line: var(--border, #E6EBF1);
  --x10m-ink: var(--text, #1E293B);
  --x10m-dim: var(--muted, #64748B);
}
html[data-theme="dark"] body.x10m {
  --x10m-surface: var(--card, #172231);
  --x10m-ground: var(--bg, #0E1621);
  --x10m-line: var(--border, #2A3849);
  --x10m-ink: var(--text, #E5EAF0);
  --x10m-dim: var(--muted, #94A3B8);
}
body.x10m.plat-android { --x10m-safe-b: max(env(safe-area-inset-bottom), 20px); }

/* ---- ซ่อนแถบล่างเดิม (8 ปุ่มเรียงแบน) แทนด้วยโครง 3 แท็บ + เมนู ---- */
body.x10m .bottom-nav { display: none !important; }

/* เว้นที่ให้แถบล่างใหม่ ไม่ให้ทับเนื้อหา */
body.x10m .app { padding-bottom: calc(var(--x10m-tabbar-h) + var(--x10m-safe-b)); }
body.x10m.in-room .app { padding-bottom: 0; }   /* อยู่ในห้องแชท: ซ่อนแถบ ให้ที่กับกล่องพิมพ์ */

/* ============================================================
   แถบแท็บล่าง (ซีดหน้า 02)
   ============================================================ */
body.x10m .x10m-tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  display: flex; align-items: stretch;
  height: calc(var(--x10m-tabbar-h) + var(--x10m-safe-b));
  padding-bottom: var(--x10m-safe-b);
  background: var(--x10m-surface);
  border-top: 1px solid var(--x10m-line);
  /* เบลอพื้นหลังแบบ iOS — Android ไม่ทุกเครื่องรองรับ แต่ fallback เป็นสีทึบอยู่แล้ว */
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
}
body.x10m.in-room .x10m-tabbar { display: none; }   /* ในห้องแชท = เต็มจอ */

body.x10m .x10m-tab {
  flex: 1 1 0; min-width: 0;
  min-height: var(--x10m-hit);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; position: relative;
  background: none; border: 0; padding: 4px 2px;
  color: var(--x10m-dim); font: inherit; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
body.x10m .x10m-tab-ic { font-size: 21px; line-height: 1; }
body.x10m .x10m-tab-tx {
  font-size: 10.5px; font-weight: 500; letter-spacing: -.01em;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body.x10m .x10m-tab.active { color: var(--blue); }
body.x10m .x10m-tab.active .x10m-tab-tx { font-weight: 700; }
body.x10m .x10m-tab:active { background: var(--side-hover); }

/* ป้ายแจ้งเตือน */
body.x10m .x10m-tab-badge {
  position: absolute; top: 2px; left: 50%; margin-left: 6px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 999px; background: var(--red); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 17px; text-align: center;
}
body.x10m .x10m-tab-badge.dot-only {
  min-width: 8px; width: 8px; height: 8px; padding: 0; margin-left: 10px;
}
body.x10m .x10m-tab-badge.hidden { display: none; }

/* ============================================================
   หัวข้อ: iOS กลาง / Android ชิดซ้าย (ซีดหน้า 03)
   ============================================================ */
body.x10m .page-head { min-height: var(--x10m-hit); align-items: center; }
body.x10m.plat-ios .page-head h2 {
  flex: 1; text-align: center;
  font-size: 17px; font-weight: 600;
  /* ปุ่ม ☰ ซ้ายกว้าง ~40px — เผื่อขวาเท่ากันไม่ให้หัวข้อเยื้อง */
  padding-right: 40px;
}
body.x10m.plat-android .page-head h2 {
  flex: 1; text-align: left;
  font-size: 20px; font-weight: 600; letter-spacing: -.01em;
}

/* พื้นที่แตะทุกปุ่มไม่น้อยกว่า 44px (ซีดหน้า 03) */
body.x10m .icon-btn,
body.x10m .nav-btn,
body.x10m .btn {
  min-height: var(--x10m-hit);
  min-width: var(--x10m-hit);
}
/* ⚠️ ยกเว้นปุ่มบนหัวห้อง (กระดิ่ง/⋯/☰) — x10-ui.css ตั้งใจย่อเป็น 32px บนจอแคบ
   แต่ min-*:44px ข้างบนทับ ทำให้กลายเป็นกล่องใหญ่คร่อมหัวห้อง
   (Boss 2026-08-28: "ในมือถือการแจ้งเตือนมันใหญ่ไป")
   → คืนขนาดกล่องเป็น 34px แล้วขยายพื้นที่แตะด้วย ::after แทน นิ้วยังกดติดเท่าเดิม */
body.x10m .chat-head .icon-btn,
body.x10m .chat-actions .icon-btn {
  min-width: 34px; min-height: 34px;
  width: 34px; height: 34px;
  position: relative;
}
body.x10m .chat-head .icon-btn::after,
body.x10m .chat-actions .icon-btn::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: var(--x10m-hit); height: var(--x10m-hit);
  transform: translate(-50%, -50%);
}
/* ปุ่มในแถวแน่น ๆ (chip/ตัวกรอง) ไม่ต้องสูง 44 แต่ต้องแตะติด → ขยายด้วย pseudo */
body.x10m .chip, body.x10m .tab-btn { position: relative; }
body.x10m .chip::after, body.x10m .tab-btn::after {
  content: ''; position: absolute; inset: 50% 0 auto 0;
  height: var(--x10m-hit); transform: translateY(-50%);
}

/* ============================================================
   แผ่นเลื่อนขึ้น "เมนูรวม" (ซีดหน้า 04)
   ============================================================ */
body.x10m .x10m-sheet-bd {
  position: fixed; inset: 0; z-index: 70;
  background: rgba(8, 12, 18, .45);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
body.x10m .x10m-sheet-bd.hidden { display: none; }

body.x10m .x10m-sheet {
  position: fixed; left: 0; right: 0;
  /* วางเหนือแถบแท็บ ไม่ทับ (แถบยังกดได้ตอนแผ่นเปิด) */
  bottom: calc(var(--x10m-tabbar-h) + var(--x10m-safe-b)); z-index: 71;
  background: var(--x10m-surface);
  border-top: 1px solid var(--x10m-line);
  border-radius: 18px 18px 0 0;
  box-shadow: var(--shadow-modal);
  padding-bottom: 8px;
  /* ซ่อนลงใต้จอ: ต้องเลื่อนเลยความสูงแถบแท็บด้วย ไม่งั้นขอบแผ่นโผล่ค้าง */
  transform: translateY(calc(100% + var(--x10m-tabbar-h) + var(--x10m-safe-b)));
  transition: transform 220ms cubic-bezier(.32, .72, 0, 1);
  /* ต้องไม่สูงจนทับแถบแท็บล่าง (เจอจริงในภาพทดสอบ Android/สว่าง)
     เผื่อความสูงแถบ + safe area + ระยะหายใจ 12px */
  max-height: calc(100vh - var(--x10m-tabbar-h) - var(--x10m-safe-b) - 12px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
body.x10m .x10m-sheet.up { transform: translateY(0); }
body.x10m .x10m-sheet.hidden { display: none; }

body.x10m .x10m-sheet-grip { padding: 8px 0 2px; display: flex; justify-content: center; touch-action: none; }
body.x10m .x10m-sheet-grip span {
  width: 38px; height: 4px; border-radius: 999px; background: var(--x10m-line);
}
body.x10m .x10m-sheet-head { padding: 4px 20px 10px; touch-action: none; }
body.x10m .x10m-sheet-head h3 {
  margin: 0; font-size: 17px; font-weight: 700; color: var(--x10m-ink);
}
body.x10m.plat-ios .x10m-sheet-head h3 { text-align: center; }

/* ตาราง 3 คอลัมน์ — 9 ฟังก์ชันพอดี 3 แถว */
body.x10m .x10m-sheet-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 6px; padding: 4px 12px 12px;
}
body.x10m .x10m-mtile {
  position: relative;
  min-height: 84px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
  background: none; border: 1px solid transparent; border-radius: var(--radius);
  color: var(--x10m-ink); font: inherit; cursor: pointer; padding: 10px 4px;
  -webkit-tap-highlight-color: transparent;
}
body.x10m .x10m-mtile:active { background: var(--side-hover); }
body.x10m .x10m-mtile.active { border-color: var(--blue); color: var(--blue); background: var(--side-hover); }
body.x10m .x10m-mtile-ic { font-size: 23px; line-height: 1; }
body.x10m .x10m-mtile-tx {
  font-size: 11.5px; font-weight: 500; text-align: center; line-height: 1.25;
  max-width: 100%; overflow: hidden; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
body.x10m .x10m-mtile-badge {
  position: absolute; top: 8px; right: 12px;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 999px; background: var(--red); color: #fff;
  font-size: 10.5px; font-weight: 700; line-height: 18px; text-align: center;
}

/* ท้ายแผ่น: สวิตช์ธีม */
body.x10m .x10m-sheet-foot {
  border-top: 1px solid var(--x10m-line); padding: 8px 12px;
}
body.x10m .x10m-foot-btn {
  width: 100%; min-height: var(--x10m-hit);
  display: flex; align-items: center; gap: 10px;
  background: none; border: 0; border-radius: var(--radius);
  color: var(--x10m-ink); font: inherit; font-size: 14px; padding: 10px 12px;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
body.x10m .x10m-foot-btn:active { background: var(--side-hover); }

@media (prefers-reduced-motion: reduce) {
  body.x10m .x10m-sheet { transition: none; }
}

/* ============================================================
   ปัดซ้ายที่รายการแชท (ซีดหน้า 06)
   ============================================================ */
body.x10m .x10m-swrap { position: relative; overflow: hidden; }
body.x10m .x10m-swrap > .chan-item {
  position: relative; z-index: 1;
  /* ทึบแสงจริง ไม่งั้นจะเห็นปุ่มด้านล่างทะลุขึ้นมาตอนเลื่อน
     ⚠️ ต้องใช้ --v3-side (สีที่ .x10v3 .sidebar ทาจริง) ไม่ใช่ --side-bg
        ไม่งั้นเลือกชุดสีแล้วแถวนี้สีไม่ตรงกับแถบข้างที่มันอยู่ */
  background: var(--v3-side, var(--side-bg));
  transition: transform 180ms cubic-bezier(.32, .72, 0, 1);
  will-change: transform;
}
/* ตอนลาก JS ตั้ง transform ตรง ๆ — ปิด transition ไม่ให้หนืดตามนิ้ว */
body.x10m .x10m-swrap > .chan-item.sw-drag { transition: none; }

body.x10m .x10m-sacts {
  position: absolute; inset: 0 0 0 auto; z-index: 0;
  display: flex; align-items: stretch;
}
body.x10m .x10m-sact {
  width: 76px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  border: 0; color: #fff; font: inherit; font-size: 10.5px; font-weight: 600;
  line-height: 1.15; padding: 2px 4px; text-align: center;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  /* แถวห้องเตี้ยกว่า 44px ได้ → ห้ามใส่ min-height ที่ปุ่ม ไม่งั้นตัวหนังสือถูกตัด
     พื้นที่แตะยังผ่านเกณฑ์เพราะปุ่มสูงเท่าแถว + กว้าง 76px */
  min-width: 44px;
  overflow: hidden;
}
body.x10m .x10m-sact span:first-child { font-size: 15px; line-height: 1; }
body.x10m .x10m-sact span:last-child {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* แถวในรายการห้องบนมือถือต้องสูงพอให้ทั้งแตะติดและวางปุ่มได้ */
body.x10m .x10m-swrap > .chan-item { min-height: var(--x10m-hit); align-items: center; }
body.x10m .sact-read { background: var(--blue); }
body.x10m .sact-mute { background: #6B7280; }
body.x10m .x10m-sact:active { filter: brightness(.9); }

/* ห้องที่ปิดเสียงอยู่ — ให้เห็นสถานะในรายการ */
body.x10m .chan-item.chan-muted { opacity: .62; }
body.x10m .chan-item.chan-muted .grow::after {
  content: ' 🔇'; font-size: 11px; opacity: .8;
}

/* ============================================================
   ลากลงรีเฟรช
   ============================================================ */
body.x10m .x10m-ptr {
  height: 0; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  transition: height 160ms ease;
  color: var(--x10m-dim);
}
body.x10m .x10m-ptr-ic { font-size: 18px; display: block; }
body.x10m .x10m-ptr.ready .x10m-ptr-ic { color: var(--blue); }
body.x10m .x10m-ptr.spin .x10m-ptr-ic { animation: x10m-spin 800ms linear infinite; }
@keyframes x10m-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  body.x10m .x10m-ptr { transition: none; }
  body.x10m .x10m-ptr.spin .x10m-ptr-ic { animation: none; }
}

/* ============================================================
   กล้อง / สแกนสลิป (ซีดหน้า 05-06)
   ============================================================ */
/* ⚠️⚠️ ห้ามใช้ display:none กับ input ถ่ายรูป — Android Chrome ไม่ให้เกียรติ capture="environment"
   กับ element ที่ display:none แล้วถอยไปเปิด "อัลบั้มรูป" แทนกล้อง
   (Boss แจ้ง 2026-09-12 "กดถ่ายรูป แต่มันเข้ามาเลือกในอัลบัม")
   ต้องซ่อนแบบ "ยังอยู่ในผัง" — กินพื้นที่ 1px มุมจอ แตะไม่โดน มองไม่เห็น */
body.x10m .x10m-hidden-file {
  position: fixed; left: 0; bottom: 0;
  width: 1px; height: 1px;
  opacity: 0; pointer-events: none; z-index: -1;
  border: 0; padding: 0; margin: 0;
}

body.x10m .x10m-camrow {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
  margin: 0 0 10px;
}
body.x10m .x10m-cambtn {
  min-height: 56px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  background: var(--side-hover); border: 1px solid var(--x10m-line);
  border-radius: var(--radius); color: var(--x10m-ink);
  font: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
body.x10m .x10m-cambtn span:first-child { font-size: 20px; line-height: 1; }
body.x10m .x10m-cambtn:active { background: var(--blue-light); border-color: var(--blue); }

/* ============================================================
   แถบสถานะออฟไลน์ / ข้อความค้างส่ง (ซีดหน้า 06)
   ============================================================ */
body.x10m .x10m-offbar {
  position: fixed; left: 0; right: 0;
  bottom: calc(var(--x10m-tabbar-h) + var(--x10m-safe-b));
  z-index: 59;
  padding: 7px 14px;
  font-size: 12px; font-weight: 600; text-align: center;
  color: #fff; background: var(--blue);
}
body.x10m .x10m-offbar.is-off { background: #B45309; }
/* (2026-09-23) มีข้อความค้าง = แถบกดได้ + ปุ่ม ✕ ขวาสุด → เปิดรายการ ส่งใหม่/ไม่ส่ง */
body.x10m .x10m-offbar.has-items { cursor: pointer; padding-right: 48px; }
body.x10m .x10m-offbar-x {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 34px; height: 30px; border: 0; border-radius: 8px;
  background: rgba(0,0,0,.22); color: #fff; font-size: 15px; font-weight: 700;
}
.x10m-obsheet { position: fixed; inset: 0; z-index: 210; display: flex; align-items: flex-end; justify-content: center; }
.x10m-obsheet-bd { position: absolute; inset: 0; background: rgba(0,0,0,.45); }
.x10m-obsheet-card {
  position: relative; width: 100%; max-width: 560px; max-height: 75vh; display: flex; flex-direction: column;
  background: var(--x10m-surface, #fff); color: var(--x10m-ink, #111); border-radius: 16px 16px 0 0;
  padding: 12px 14px calc(12px + env(safe-area-inset-bottom, 0px));
}
.x10m-obsheet-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.x10m-obsheet-head h3 { margin: 0; font-size: 16px; }
.x10m-obsheet-close { width: 36px; height: 36px; border: 0; border-radius: 10px; background: rgba(127,127,127,.15); color: inherit; font-size: 16px; }
.x10m-obsheet-list { overflow-y: auto; flex: 1 1 auto; min-height: 0; }
.x10m-ob-row { padding: 10px; border: 1px solid rgba(127,127,127,.25); border-radius: 12px; margin-bottom: 8px; }
.x10m-ob-meta { font-size: 12px; opacity: .7; margin-bottom: 4px; }
.x10m-ob-txt { font-size: 14px; white-space: pre-wrap; word-break: break-word; max-height: 7.5em; overflow: auto; }
.x10m-ob-acts { display: flex; gap: 8px; justify-content: flex-end; margin-top: 8px; }
.x10m-ob-acts button, .x10m-obsheet-foot button {
  min-height: 38px; padding: 0 14px; border-radius: 10px; border: 1px solid rgba(127,127,127,.35);
  background: transparent; color: inherit; font-size: 14px; font-weight: 600;
}
.x10m-ob-acts button.danger, .x10m-ob-delall { color: #DC2626 !important; border-color: rgba(220,38,38,.45) !important; }
.x10m-obsheet-foot { display: flex; gap: 8px; margin-top: 8px; }
.x10m-obsheet-foot button { flex: 1; }
/* ในห้องแชทไม่มีแถบล่าง → แถบนี้ต้องลงไปติดขอบจอ */
body.x10m.in-room .x10m-offbar { bottom: var(--x10m-safe-b); }
/* ⚠️ แก้ 2026-09-05 (เฟส 1): ในห้องแชท "ขอบจอ" คือที่ของกล่องพิมพ์
   เดิมแถบออฟไลน์ทับแถวปุ่ม ＋@😀🎤 เต็มๆ ตอนเน็ตหลุด — กดส่งไม่ได้
   ยกขึ้นเหนือกล่องพิมพ์ โดยวัดความสูงจริงจาก --x10m-composer-h
   (ห้ามเดาเป็นตัวเลขตายตัว กล่องพิมพ์ยืดตามบรรทัดที่พิมพ์: วัดได้ 108-132px) */
body.x10m.in-room .x10m-offbar {
  bottom: calc(var(--x10m-composer-h, 108px) + var(--x10m-safe-b));
}

/* ============================================================
   หน้าจอล็อกแอป (PIN / Face ID) — ซีดหน้า 06
   ============================================================ */
body.x10m .x10m-lock {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: var(--x10m-ground);
}
body.x10m .x10m-lock.hidden { display: none; }
body.x10m .x10m-lock-card {
  width: 100%; max-width: 320px; text-align: center;
}
body.x10m .x10m-lock-ic { font-size: 44px; margin-bottom: 10px; }
body.x10m .x10m-lock-card h3 {
  margin: 0 0 6px; font-size: 19px; font-weight: 700; color: var(--x10m-ink);
}
body.x10m .x10m-lock-sub {
  margin: 0 0 20px; font-size: 13px; color: var(--x10m-dim);
}
body.x10m #x10m-lock-pin {
  width: 100%; min-height: var(--x10m-hit);
  padding: 12px 14px; margin-bottom: 10px;
  font-size: 20px; text-align: center; letter-spacing: .3em;
  background: var(--x10m-surface); color: var(--x10m-ink);
  border: 1px solid var(--x10m-line); border-radius: var(--radius);
}
body.x10m #x10m-lock-pin.hidden { display: none; }
body.x10m .x10m-lock-err {
  min-height: 18px; margin-bottom: 8px;
  font-size: 12.5px; font-weight: 600; color: var(--red);
}
body.x10m .x10m-lock-btn, body.x10m .x10m-lock-bio {
  width: 100%; min-height: var(--x10m-hit);
  border-radius: var(--radius); border: 1px solid var(--x10m-line);
  font: inherit; font-size: 15px; font-weight: 600; cursor: pointer;
  margin-bottom: 8px;
}
body.x10m .x10m-lock-btn { background: var(--blue); color: #fff; border-color: var(--blue); }
body.x10m .x10m-lock-btn.hidden, body.x10m .x10m-lock-bio.hidden { display: none; }
body.x10m .x10m-lock-bio { background: transparent; color: var(--x10m-ink); }

/* ============================================================
   แถวตั้งค่าในแผ่นเมนูรวม (แจ้งเตือน / ล็อกแอป)
   ============================================================ */
body.x10m .x10m-setrow {
  display: flex; align-items: center; gap: 10px;
  width: 100%; min-height: var(--x10m-hit);
  padding: 10px 12px;
  background: none; border: 0; border-radius: var(--radius);
  color: var(--x10m-ink); font: inherit; font-size: 14px;
  text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
body.x10m .x10m-setrow:active { background: var(--side-hover); }
/* แถวเดียวกันนี้ใช้กับ <a> ด้วย (ลิงก์ติดตั้งแอป) — ตัดเส้นใต้และคุมกล่องให้เท่าปุ่ม */
body.x10m a.x10m-setrow { text-decoration: none; box-sizing: border-box; }
body.x10m .x10m-setrow .grow { flex: 1; min-width: 0; }
body.x10m .x10m-setrow .x10m-setstate {
  font-size: 12px; font-weight: 600; color: var(--x10m-dim);
}
body.x10m .x10m-setrow .x10m-setstate.on { color: var(--green); }

/* ============================================================
   ปัดขวาจากขอบซ้ายเปิดรายการห้อง (Boss สั่ง 2026-08-22)
   ============================================================ */
/* ตอนลากด้วยนิ้ว: ต้องเห็นฉากมืดค่อย ๆ เข้ม และต้องไม่มี transition มาหนืด
   (.show ของเดิมมี transition + pointer-events ซึ่งจะกินทัชระหว่างลาก) */
body.x10m .side-backdrop.x10m-dragging {
  transition: none;
  pointer-events: none;
}

/* ============================================================
   ล็อกหน้าไม่ให้ขยับตามนิ้ว (Boss แจ้ง 2026-08-22)
   ------------------------------------------------------------
   อาการ: ปัดซ้าย/ขวาแล้ว "หน้ามันไปตามนิ้ว" — เพราะเดิม html/body
   ไม่มี overscroll-behavior/touch-action เลย เบราว์เซอร์จึงใช้ค่าปกติ:
     · ยางยืดแนวนอน (overscroll) ของทั้งหน้า
     · iOS ปัดขอบจอ = ย้อนกลับหน้าเว็บ (swipe back navigation)
   ต้องการ: หน้านิ่ง ให้ขยับแค่แผงเมนู/แถวห้องที่เราคุมเอง
   ============================================================ */
/* html ต้องคุมด้วย :has() (html ไม่ใช่ลูกของ body จะเขียน body.x10m html ไม่ได้)
   :has() รองรับใน Safari 15.4+ / Chrome 105+ = ครอบมือถือที่ใช้งานจริงทั้งหมด
   ถ้าเบราว์เซอร์เก่าไม่รู้จัก ก็แค่ไม่ได้ผลตรงนี้ ตัว body ยังกันให้อยู่ */
html:has(body.x10m) {
  overscroll-behavior: none;
  overflow-x: hidden;
}

body.x10m {
  /* หน้าหลักต้องไม่มีสกรอลล์แนวนอนเด็ดขาด */
  overflow-x: hidden;
  /* ไม่ให้ลากจนทั้งหน้าเลื่อนไปมา (ยางยืดแนวนอน) */
  overscroll-behavior-x: none;

  /* ⚠️⚠️ ห้ามใส่ `touch-action: pan-y` ที่ body เด็ดขาด!
     touch-action **ไม่ inherit แต่ ancestor จำกัดลูกได้** — ถ้า body ตัด pan-x ทิ้ง
     ลูกจะ **ขอคืนไม่ได้เลย** (คำนวณออกมาเป็น `manipulation`)
     ผลคือตารางกว้าง / TaskFlow / โค้ดบล็อก **เลื่อนแนวนอนไม่ได้ทั้งแอป**
     (เจอจริงจาก test-hscroll.js: ทุกกล่องกลายเป็น manipulation)
     → กันหน้าขยับด้วย JS `preventDefault()` ตอนล็อกทิศเป็นแนวนอนแทน
       (ดู swipeMove / edgeMove ใน mobile.js ที่ใช้ passive:false) */
}
body.x10m .app { overflow-x: hidden; }

/* ยางยืดแนวนอนของกล่องที่เลื่อนได้ ไม่ให้ทะลุไปขยับหน้าแม่ */
body.x10m .tbl-wrap,
body.x10m .paste-queue,
body.x10m pre,
body.x10m .msg-table-wrap,
body.x10m #tf-body {
  overscroll-behavior-x: contain;
}

/* ============================================================
   แก้จากการตรวจ FLOW ทุกหน้า 2026-08-22
   ============================================================ */
/* หน้าเลขา: ปุ่ม "ล้างประวัติ" ล้นทะลุกรอบหน้าไปทับแถบแท็บล่าง
   วัดได้: หน้าจบที่ 582 แต่ .sec-chat-tools ยาวถึง 619 = เนื้อหาล้นตัวครอบ
   → ใส่ padding ในตัวมันแก้ไม่ได้ ต้อง "กัน" ที่ระดับหน้าแทน
   ⚠️ อีก session กำลังแก้โครง #sec-main / .sec-chat อยู่ (bak-secmainfix 11:43)
      จึง **ไม่แตะ #sec-main / .sec-chat** ที่นี่ เพื่อไม่ให้ทับ flex layout ของเขา */
/* หน้าเลขาบนมือถือ — ⚠️ ยังมีปัญหาค้าง (ไม่แก้ที่นี่ โดยเจตนา)
   อาการ: ปุ่ม "🗑 ล้างประวัติ" ถูกตัดหายใต้จอบน iPhone (แตะไม่ได้)
          และกล่องแชท .sec-chat ยุบเหลือ ~12px
   ต้นเหตุอยู่ที่โครง flex ของ .sec-wrap / #sec-main / .sec-sect ใน style.css
   ซึ่ง **อีก session กำลังแก้อยู่** (style.css.bak-secmainfix-20260822-114339
   คอมเมนต์เขาเขียนไว้ตรงกัน: "ถ้า #sec-main ไม่ส่งความสูงต่อ กล่องแชทจะยุบ")
   → ลองแก้จากชั้นมือถือแล้ว 3 วิธี (overflow:hidden / บีบ padding / flex)
     ทุกวิธีไม่หาย เพราะต้นเหตุอยู่เหนือขึ้นไปในสายที่เขาถืออยู่
   → **ปล่อยให้แก้ที่ต้นเหตุ** ดีกว่าใส่กฎทับแล้วชนกันภายหลัง (แจ้ง Boss แล้ว)
   Android ไม่มีปัญหานี้ (จอสูงกว่า ปุ่มอยู่ในจอพอดี) */

/* .btn-mini เดิมสูงแค่ ~25px — แตะยากบนมือถือ (เกณฑ์ซีด 44px)
   ขยายพื้นที่แตะด้วย pseudo แทนการดันขนาดปุ่ม เพื่อไม่ให้เลย์เอาต์เพี้ยน */
body.x10m .btn-mini {
  position: relative;
  padding: 6px 10px;
  font-size: 12.5px;
}
body.x10m .btn-mini::after {
  content: ''; position: absolute; left: 0; right: 0;
  top: 50%; height: var(--x10m-hit); transform: translateY(-50%);
}

/* ============================================================
   แบนเนอร์ชวนเปิดแจ้งเตือน (2026-08-28)
   ลอยเหนือแถบแท็บล่าง — ไม่ทับปุ่ม ไม่ทับ safe-area ของ iPhone
   ============================================================ */
body.x10m .x10m-pushnag {
  position: fixed;
  left: 10px; right: 10px;
  bottom: calc(var(--x10m-tabbar-h) + var(--x10m-safe-b) + 10px);
  z-index: 900;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  background: var(--x10m-surface);
  border: 1px solid var(--x10m-line);
  border-radius: 14px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
  animation: x10m-pushnag-in .22s ease-out;
}
@keyframes x10m-pushnag-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
body.x10m .x10m-pushnag-ic { font-size: 22px; line-height: 1; flex: 0 0 auto; }
body.x10m .x10m-pushnag-tx { flex: 1 1 auto; min-width: 0; }
body.x10m .x10m-pushnag-tx b {
  display: block; font-size: 14px; line-height: 1.3;
  color: var(--x10m-ink);
}
body.x10m .x10m-pushnag-tx span {
  display: block; font-size: 12px; line-height: 1.35; margin-top: 2px;
  color: var(--muted);
}
body.x10m .x10m-pushnag button {
  flex: 0 0 auto;
  min-height: 34px; padding: 0 12px;
  border-radius: 9px; font-size: 13px; font-weight: 600;
  border: 1px solid var(--x10m-line);
  background: transparent; color: var(--muted);
  cursor: pointer;
}
body.x10m .x10m-pushnag-go {
  border-color: transparent !important;
  background: var(--blue) !important;
  color: #fff !important;
}
/* จอแคบ 360px: ข้อความยาวไม่ดันปุ่มตกขอบ */
@media (max-width: 380px) {
  body.x10m .x10m-pushnag { gap: 8px; padding: 9px 10px; }
  body.x10m .x10m-pushnag-ic { font-size: 19px; }
  body.x10m .x10m-pushnag button { padding: 0 9px; font-size: 12px; }
}

/* ============================================================
   แถบพิมพ์แบบ Slack (Boss 2026-08-28) — ประหยัดพื้นที่บนมือถือ
   ------------------------------------------------------------
   Slack มีแค่ ＋ / ช่องพิมพ์ / ไมค์ — ปุ่มส่งโผล่ตอนพิมพ์เท่านั้น
   ของเรามี 4-5 ปุ่มเบียดจนช่องพิมพ์เหลือนิดเดียว
   → ยังไม่พิมพ์: โชว์ไมค์ (อัดเสียง) ซ่อนปุ่มส่ง
     พิมพ์แล้ว/มีไฟล์แนบ: โชว์ปุ่มส่ง ซ่อนไมค์
   สลับด้วยคลาส .has-text ที่ JS ใส่ให้ (composerToggleSend)
   ============================================================ */
body.x10m .composer .icon-btn.send { display: none; }
body.x10m .composer.has-text .icon-btn.send { display: flex; }
/* ไมค์ต้องอยู่ตลอด แม้มีข้อความ/ไฟล์ค้าง (พี่ปองแจ้ง 1ต.ค.: ส่งรูป+พิมพ์แล้วอัดเสียงไม่ได้) */
/* ช่องพิมพ์ได้พื้นที่คืนเต็มที่ เหลือปุ่มข้างละ 1 */
body.x10m .composer #msg-input { min-width: 0; flex: 1; }

/* ---- แผ่นแนบไฟล์แบบ Slack (แถบรูปแนวนอน + เมนูรายการ) ---- */
body.x10m .atsheet-bd { position: fixed; inset: 0; z-index: 80; background: rgba(8,12,18,.45); }
body.x10m .atsheet-bd.hidden { display: none; }
body.x10m .atsheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 81;
  background: var(--x10m-surface, var(--card));
  border-radius: 18px 18px 0 0; box-shadow: var(--shadow-modal);
  padding: 0 0 calc(8px + var(--x10m-safe-b, 0px));
  max-height: 82vh; overflow-y: auto;
  transform: translateY(100%); transition: transform 220ms cubic-bezier(.32,.72,0,1);
}
body.x10m .atsheet.open { transform: translateY(0); }
body.x10m .atsheet.hidden { display: none; }
body.x10m .atsheet-grip { display: flex; justify-content: center; padding: 8px 0 4px; }
body.x10m .atsheet-grip span { width: 40px; height: 4px; border-radius: 2px; background: var(--x10m-line, var(--border)); }
body.x10m .atsheet-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 16px 10px; font-weight: 700; font-size: 15px;
}
body.x10m .atsheet-head .atsheet-x {
  background: none; border: 0; font-size: 20px; line-height: 1;
  color: var(--muted); padding: 4px 6px; cursor: pointer;
}
/* แถบรูปแนวนอน: การ์ดกล้อง + รูปที่เลือกไว้ (เลื่อนซ้ายขวา) */
body.x10m .atsheet-strip {
  display: flex; gap: 8px; overflow-x: auto; padding: 0 16px 12px;
  -webkit-overflow-scrolling: touch;
}
body.x10m .atsheet-tile {
  flex: 0 0 auto; width: 104px; height: 104px; border-radius: 12px;
  border: 1px solid var(--x10m-line, var(--border)); background: var(--sunken, var(--bg));
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; cursor: pointer; padding: 0; color: var(--muted); font-size: 12px;
}
body.x10m .atsheet-tile .atsheet-tile-ic { font-size: 26px; line-height: 1; }
body.x10m .atsheet-thumb {
  position: relative; flex: 0 0 auto; width: 104px; height: 104px;
  border-radius: 12px; overflow: hidden; border: 1px solid var(--x10m-line, var(--border));
}
body.x10m .atsheet-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
body.x10m .atsheet-thumb .atsheet-thx {
  position: absolute; top: 4px; right: 4px; width: 22px; height: 22px;
  border-radius: 50%; border: 0; background: rgba(0,0,0,.55); color: #fff;
  font-size: 12px; line-height: 1; cursor: pointer;
}
/* เมนูรายการแบบ Slack */
body.x10m .atsheet-row {
  display: flex; align-items: center; gap: 14px; width: 100%;
  padding: 14px 18px; background: none; border: 0; cursor: pointer;
  font-size: 15px; color: var(--text); text-align: left;
}
body.x10m .atsheet-row:active { background: var(--side-hover, rgba(127,127,127,.12)); }
body.x10m .atsheet-row .atsheet-row-ic { font-size: 19px; width: 24px; text-align: center; flex-shrink: 0; }
body.x10m .atsheet-sep { height: 1px; background: var(--x10m-line, var(--border)); margin: 6px 16px; }

/* ---- แถบแท็บใต้หัวห้อง — โหมดมือถือ (Boss 2026-08-29) ----
   ห้ามให้กฎ min-height 44px ของ mobile.css ไปทำแถบแท็บบวม
   (บทเรียนเดิม: ปุ่มกระดิ่ง/⋯ หัวห้องเคยบวมเพราะกฎนี้ทับ) */
body.x10m .room-tabs .rt-tab { min-height: 0; min-width: 0; padding: 8px 9px; }
body.x10m .room-tabs .rt-add { min-height: 0; min-width: 0; padding: 6px 9px; }

/* ============================================================
   แถบแท็บใต้หัวห้อง — เลื่อนข้างยาก (Boss แจ้ง 2026-09-02)
   ------------------------------------------------------------
   อาการ: บนมือถือ ปัดแถบแท็บซ้าย/ขวาแล้วไม่ค่อยติด ต้องปัดตรงมาก
   สาเหตุ: .room-tabs เป็น overflow-x:auto แต่ **ไม่ได้ประกาศ touch-action**
     → เบราว์เซอร์ใช้ค่า auto = ลังเลระหว่าง pan-x ของแท็บ กับ pan-y
       ของกล่องข้อความที่อยู่ใต้ลงไป ต้องปัดแนวนอนชัดมากถึงจะล็อกทิศให้
     ซ้ำร้าย ไม่มี overscroll-behavior-x → เลื่อนสุดแล้วแรงทะลุไปหน้าแม่
   แก้: ประกาศ pan-x ตรงๆ ที่ตัวแถบ (ไม่ใช่ที่ body — ancestor ตัด pan-x
        แล้วลูกขอคืนไม่ได้ ดูคำเตือน body.x10m ด้านบน)
   ⚠️ ต้องใส่ที่ตัวลูก (.rt-tab/.rt-add) ด้วย เพราะ touch-action ไม่ inherit
      นิ้วที่แตะโดนปุ่มพอดี (ซึ่งเป็นกรณีปกติ เพราะปุ่มเต็มความสูงแถบ)
      จะอ่านค่าจากปุ่ม ไม่ใช่จากแถบ
   ============================================================ */
body.x10m .room-tabs {
  touch-action: pan-x;
  overscroll-behavior-x: contain;
  scroll-behavior: smooth;
}
body.x10m .room-tabs .rt-tab,
body.x10m .room-tabs .rt-ic,
body.x10m .room-tabs .rt-add {
  touch-action: pan-x;
}

/* ============================================================
   เมนูแชทมือถือ — เลื่อนลงล่างสุดแล้วติดขัด (Boss แจ้ง 2026-09-02)
   ------------------------------------------------------------
   แก้หลักอยู่ที่ mobile.js (attachPulls ผูกผิดตัว + เช็ค scrollTop ทุกครั้ง)
   ตรงนี้กัน 2 อย่างที่เหลือ:
   1. overscroll-behavior-y: contain — เลื่อนถึงสุดแล้วแรงต้องไม่ทะลุไปหน้าแม่
      (หน้าแม่มี edgeMove/swipeMove ดักด้วย passive:false อยู่ = สะดุด)
   2. .x10m-ptr เป็นลูกของ .side-scroll ที่เป็น flex column → flex-shrink
      ค่าปกติ 1 จะบีบตัวหมุนตอนกาง ทำให้ท่าลากลงกระตุก
      (บทเรียนเดียวกับ .kpi-card ที่โดนบีบจนข้อความโดนตัด)
   ============================================================ */
body.x10m .side-scroll {
  overscroll-behavior-y: contain;
  -webkit-overflow-scrolling: touch;
}
body.x10m .side-scroll > .x10m-ptr { flex: 0 0 auto; }

/* ============================================================
   แถบแท็บล่างบังกล่องพิมพ์ (Boss แจ้ง 2026-09-02)
   ------------------------------------------------------------
   แก้ต้นเหตุแล้วที่ app.js (openChannel เรียก showPage ก่อนปลด hidden
   ทำให้ showPage ถอดคลาส `in-room` ทิ้ง แถบล่างเลยโผล่มาทับ)
   ตรงนี้เป็น "กันชั้นสอง" ที่ไม่พึ่ง JS เลย:
     ถ้า #chat-room ไม่ได้ hidden = อยู่ในห้องจริง → ซ่อนแถบ + คืนที่ให้กล่องพิมพ์
   ต่อให้เส้นทางไหนลืมใส่ `in-room` กล่องพิมพ์ก็จะไม่ถูกบังอีก
   ⚠️ ต้องอยู่ท้ายไฟล์ = ประกาศทีหลังกฎบรรทัด 40-41/57 ถึงจะทับได้
   (`:has()` ใช้แบบเดียวกับ html:has(body.x10m) ด้านบนแล้ว)
   ============================================================ */
body.x10m:has(#chat-room:not(.hidden)) .x10m-tabbar { display: none; }
body.x10m:has(#chat-room:not(.hidden)) .app { padding-bottom: 0; }


/* ปุ่ม DM ข้างช่องค้นหาในแถบข้าง (Boss สั่ง 2026-09-04 · ทำเพื่อมือถือโดยเฉพาะ)
   เป้าแตะ 44px ตามมาตรฐาน — 36px ของจอคอมเล็กไปสำหรับนิ้ว */
body.x10m .side-dm-btn { width: 44px; height: 44px; font-size: 18px; }
body.x10m .side-search-row { gap: 8px; }
/* ⚠️ ช่องค้นหาต้องสูงเท่าปุ่มด้วย (Boss แจ้ง 2026-09-04 "มันเบี้ยว")
   เดิมปุ่มถูกดันเป็น 44px (เป้าแตะ) แต่ช่องค้นหายังสูง 40px ตาม padding เดิม
   → ปุ่มโผล่เกินขอบบน-ล่างข้างละ 2px เห็นเป็นแถวไม่ตรงกัน
   บังคับความสูงให้เท่ากันทั้งคู่ แทนที่จะพึ่ง padding */
body.x10m .side-search-row .side-search { height: 44px; padding-block: 0; }


/* ══════════════════════════════════════════════════════════════════════
   [เฟส 1] UI มือถือ — ย้ายมาจาก demo-chat (2026-09-05)
   ที่มา: /opt/x10-chat-demo/public/mobile.css บรรทัด 653-1530 (หมวด 1-9)
   ──────────────────────────────────────────────────────────────────────
   สิ่งที่แก้ระหว่างย้าย (ห้ามย้ายดิบ ๆ):
   1) scope `body.x10m` เพิ่ม 15 กฎ (.pm-* .dmp-*) — prod ใช้คลาสพวกนี้
      ฝั่งคอมอยู่แล้วใน style.css:3904/3945 ถ้าไม่ scope จะทับสไตล์คอม
   2) ตัดกฎที่อ้าง element ซึ่ง prod ไม่มี (ยืนยันด้วย querySelectorAll บน
      DOM จริง ไม่ได้เดา) — รวมป้ายเดโม #demo-flag / .demo-ribbon
   3) เลิกจองที่ก้นจอ 17px ที่เผื่อไว้ให้ป้ายเดโม — prod ไม่มีป้ายนั้น
      ถ้าคงไว้จะเหลือช่องว่างเปล่า 17px เหนือกล่องพิมพ์
   ⚠️ ทั้งบล็อก scope ด้วย body.x10m — ฝั่งคอมต้องไม่ขยับแม้แต่พิกเซลเดียว
   ══════════════════════════════════════════════════════════════════════ */

/* ============================================================
   รอบ 2 — ปรับ UI มือถือทั้งแอป (ตัวจำลอง 2026-09-04)
   อ้างอิง: โครงแบบ Slack + ความแน่นแบบ Discord
   หลักการ: ไม่ลบฟีเจอร์ใดๆ แค่ "ซ่อนของที่ไม่ได้ใช้ตลอดเวลา" ให้เนื้อหาเด่นขึ้น
   ⚠️ ทุก selector ต้องขึ้นต้น body.x10m (กฎเหล็กของไฟล์นี้)
   ⚠️ รองรับทั้ง Android และ iOS — ไม่ใช้ :has() กับ property ที่ Safari เก่าไม่รู้จัก
   ============================================================ */

/* ---- 1) แถบเครื่องมือใต้ทุกข้อความ (😊 ↩ ⧉ 🔖 ⋯) ----
   เดิมโชว์ครบ 5 ปุ่มใต้ "ทุกข้อความ" ตลอดเวลา = จอเต็มไปด้วยปุ่ม เนื้อหาจม
   Slack/Discord บนมือถือ: กดค้างที่ข้อความถึงจะขึ้นเมนู
   → ซ่อนปุ่มรอง เหลือ ⋯ ปุ่มเดียว (กดแล้วได้ทุกคำสั่งเหมือนเดิม ไม่มีอะไรหาย) */
/* ⚠️ แก้ 2026-09-04: รอบแรกซ่อนหมดเหลือแต่ ⋯ แต่ "ตอบกลับ" หายไปด้วย
   ซึ่งเป็นปุ่มที่ใช้บ่อยที่สุดในการคุยงาน (Boss ทัก "ระบบตอบกลับไม่มีได้ไง")
   Slack/Discord ก็โชว์ปุ่มตอบกลับไว้ตลอด → เหลือ 2 ปุ่ม: ↩ ตอบกลับ + ⋯ ที่เหลือ */
body.x10m .msg-under .msg-tools .msg-tool { display: none; }
/* ⚠️⚠️ แก้ 2026-09-05 (Boss แจ้ง "มือถือกดสติกเกอร์ที่ข้อความเพื่อบอกสถานะโพสไม่ได้")
   กฎชุดนี้ยกมาจาก demo ซึ่งเหลือไว้แค่ ↩ ตอบกลับ + ⋯ เมนู
   แต่นั่นทำให้ปุ่ม 🙂 (openReactPick) **หายไปจากมือถือทั้งหมด**
   = กดสติกเกอร์/สีระบุงานใส่ข้อความไม่ได้เลย ซึ่งทีมใช้บอกสถานะงานทุกวัน
   → ต้องโชว์ปุ่มรีแอ็กด้วยเสมอ (เป็นปุ่มแรกในแถว วัดได้ 34x34 = แตะสบาย) */
body.x10m .msg-under .msg-tools .msg-tool[onclick*="openReactPick"],
body.x10m .msg-under .msg-tools .msg-tool[onclick*="commentInThread"],
body.x10m .msg-under .msg-tools .msg-tool[onclick*="dmSetReply"],
body.x10m .msg-under .msg-tools .msg-tool:last-child { display: inline-flex; }
/* ปุ่มตอบกลับเด่นขึ้นนิด ให้เห็นว่ากดได้ */
body.x10m .msg-under .msg-tools .msg-tool[onclick*="commentInThread"],
body.x10m .msg-under .msg-tools .msg-tool[onclick*="dmSetReply"] { opacity: .85; }
/* เวลายังอยู่ แต่จางลงให้เป็นข้อมูลรอง */
body.x10m .msg-under-time { opacity: .6; font-size: 11px; }
body.x10m .msg-under { gap: 6px; margin-top: 1px; }

/* ---- 2) ความแน่นแบบ Discord ----
   ลดช่องไฟระหว่างข้อความ ให้เห็นบทสนทนาต่อจอมากขึ้น */
body.x10m .msg { padding-top: 2px; padding-bottom: 2px; }
body.x10m .msg + .msg { margin-top: 0; }

/* ---- 3) หัวห้อง: ยุบให้เตี้ยแบบ Slack ----
   มือถือมีที่จำกัด หัวห้องไม่ควรกินเกิน 1 บรรทัด */
body.x10m .chat-head { padding-top: 8px; padding-bottom: 8px; }
body.x10m .chat-name { font-size: 15px; }
/* หัวข้อห้อง (topic) ยาวๆ ซ่อนบนมือถือ — กดชื่อห้องดูได้อยู่แล้ว */
body.x10m .chat-topic { display: none; }

/* ---- 4) กล่องพิมพ์: เหลือปุ่มที่ใช้บ่อยจริง ----
   เดิม 6 ปุ่ม (＋ 📎 @ 😀 🎤 ☰) เบียดกันบนจอ 360px
   Slack มือถือมีแค่ ＋ กับ 😀 · ที่เหลืออยู่ในเมนู ＋ (ยังกดได้ครบ ไม่ได้ลบ)
   → ซ่อน 📎 (ซ้ำกับ ＋) และ ☰ (แถบจัดข้อความ นานๆ ใช้ที) */
/* หมายเหตุย้าย: #btn-attach-quick มีเฉพาะใน demo — prod ไม่มี ตัดออกจากชุด */
body.x10m .cp-act-l .cp-fmt-tg,
body.x10m .cp-act-l .cp-fmt { display: none; }
body.x10m .cp-act { padding: 5px 8px 6px; }

/* ---- 5) หัวห้องบรรทัดเดียวแบบ Slack ----
   ชื่อห้อง + ป้ายล็อก + จำนวนคน อยู่บรรทัดเดียวกัน ไม่ตกบรรทัด
   ⚠️ ต้อง min-width:0 ทุกชั้น ไม่งั้นชื่อยาวดันชิปหลุดขอบ (Flexbox overflow) */
body.x10m .chat-name-row { flex-wrap: nowrap; min-width: 0; gap: 6px; }
body.x10m .chat-name { min-width: 0; }
body.x10m .chat-meta-btn { font-size: 10.5px; padding: 1px 6px; }
/* ปุ่มหัวห้องเล็กลงนิด คืนที่ให้ชื่อห้อง */
body.x10m .chat-actions .icon-btn { width: 34px; height: 34px; }

/* ---- 6) แท็บล่างใหม่: ไอคอน SVG แบบ Slack/Discord ----
   เดิมใช้อีโมจิ (# 💬 🔔 ☑) ซึ่ง Android กับ iOS วาดคนละแบบ ขนาดไม่เท่ากัน
   บางเครื่อง # กับ ☑ ขึ้นเป็นสี่เหลี่ยมว่าง · เปลี่ยนเป็น SVG คุมได้ทุกเครื่อง */
body.x10m .x10m-tab-ic { font-size: 0; line-height: 0; display: inline-flex; }
body.x10m .x10m-tab-ic .ic { width: 23px; height: 23px; }
/* แท็บที่เลือกอยู่: ไอคอนทึบ + สีเน้น + ขีดบอกตำแหน่งด้านบน (แบบ Slack) */
body.x10m .x10m-tab.active::before {
  content: ''; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 26px; height: 3px; border-radius: 0 0 3px 3px; background: var(--blue);
}
/* กดแล้วต้องรู้สึกว่ากดติด — ย่อเล็กน้อยแทนพื้นหลังเทาที่มองแทบไม่เห็นบนมือถือ */
body.x10m .x10m-tab { transition: transform .09s ease, color .12s ease; }
body.x10m .x10m-tab:active { background: none; transform: scale(.90); }

/* ---- 7) หน้า DM: แถวแน่นขึ้นแบบ Discord ----
   เดิมแถวสูง ~132px เห็นได้แค่ 5 คนต่อจอ ต้องเลื่อนนานกว่าจะเจอคนที่จะทัก
   ลดรูปโปรไฟล์ 48→40 + บีบช่องไฟ → เห็น ~8 คนต่อจอ หาคนเจอเร็วขึ้น */
body.x10m .dmp-av .avatar { width: 40px !important; height: 40px !important; font-size: 15px; }
body.x10m .dmp-row { padding: 6px 8px; gap: 10px; }
body.x10m .dmp-name { font-size: 14.5px; }
body.x10m .dmp-prev { font-size: 12.5px; }
body.x10m .dmp-on { width: 11px; height: 11px; border-width: 2px; }

/* ปุ่ม "# ไปช่องแชท" บนหัวหน้า DM — ซ้ำกับแท็บ "ช่อง" ที่อยู่ข้างล่างแล้ว
   ซ่อนบนมือถือ คืนที่ให้หัวข้อ (คอมยังมีเหมือนเดิม เพราะคอมไม่มีแท็บล่าง) */
body.x10m #page-dm .page-head .btn { display: none; }

/* ============================================================
   รอบ 4 — ยกเครื่องแท็บ "ช่อง" (ตัวจำลอง 2026-09-04)
   ปัญหาเดิม: กดแท็บ "ช่อง" ได้หน้าว่างเปล่า! เพราะรายชื่อห้องอยู่ใน
   drawer ที่ต้องกดแฮมเบอร์เกอร์เปิด = เมนูหลักของแอปถูกซ่อนไว้
   Slack/Discord มือถือ: รายชื่อห้องเป็น "หน้าเต็มจอ" กดแท็บแล้วเห็นเลย
   → ทำให้ sidebar กลายเป็นหน้าจริงเมื่ออยู่แท็บช่อง (ไม่ใช่ drawer ลอย)
   ⚠️ ไม่แตะ JS ของ drawer เดิม — ยังเปิดด้วยแฮมเบอร์เกอร์ตอนอยู่ในห้องได้เหมือนเดิม
   ============================================================ */
body.x10m.page-chat-list .sidebar {
  position: static !important;
  transform: none !important;
  inset: auto !important;
  max-width: none !important;
  width: 100% !important;
  box-shadow: none !important;
  display: flex !important;
  flex: 1 1 auto;
  min-height: 0;
}
body.x10m.page-chat-list .app { flex-direction: column; }
body.x10m.page-chat-list .main { display: none !important; }
body.x10m.page-chat-list #side-backdrop { display: none !important; }
/* ปุ่มแฮมเบอร์เกอร์ในแถบข้างไม่ต้องมีตอนเป็นหน้าเต็ม */

/* ---- รอบ 4b: ล้างของซ้ำ/ของไม่จำเป็นออกจากหน้ารายชื่อห้อง ----
   กว่าจะถึงห้องแรกต้องผ่าน 6 ชั้น: โลโก้ → โปรไฟล์ → เมนู → ค้นหา → สลับมุมมอง → หมวด
   Slack/Discord: เปิดมาเห็นห้องเลย ของอื่นอยู่ในโปรไฟล์/เมนู */
/* โลโก้ X10 Chat + ปุ่มดาวน์โหลด/ธีม — ซ้ำกับแท็บล่าง/เมนู ไม่ต้องกินที่บนสุด */
body.x10m.page-chat-list .sidebar-head { display: none; }
/* กล่อง "เมนู" ในแถบข้าง = ไทล์ชุดเดียวกับแท็บล่าง+แผ่นเมนู (ซ้ำ 3 ที่) */
body.x10m.page-chat-list #mn-bar,
body.x10m.page-chat-list #mn-panel { display: none; }
/* แถวสลับมุมมอง "แยกกลุ่ม/รวมทั้งหมด" — ของนานๆ ใช้ ย้ายความสำคัญลง */
body.x10m.page-chat-list .side-section-row { padding: 4px 12px; font-size: 11px; opacity: .7; }
/* ปุ่มจัดการหมวด (🔔 ➕ 🗑) โผล่เฉพาะตอนกดค้าง/แอดมินกดเข้าไปจัดการ
   โชว์ตลอดบนมือถือ = กดโดนโดยไม่ตั้งใจ + รกสายตา */
body.x10m.page-chat-list .chan-sec-bell,
body.x10m.page-chat-list .chan-sec-add,
body.x10m.page-chat-list .chan-sec-del { display: none !important; }
/* "+ สร้างห้องใน …" ใต้ทุกหมวด — ซ้ำกับปุ่ม + ที่หัวแอป และคนทั่วไปไม่ได้สร้างห้องบ่อย */
/* "+ สร้างห้องใน …" ใต้ทุกหมวด — ซ้ำกับปุ่ม + ที่หัวแอป และคนทั่วไปไม่ได้สร้างห้องบ่อย */
/* "ลากห้องมาวางตรงนี้" — ลากวางเป็นท่าของเมาส์ บนมือถือทำไม่ได้ กินที่ครึ่งจอเปล่าๆ */
body.x10m.page-chat-list .chan-add-row,
body.x10m.page-chat-list .chan-drop-hint { display: none; }

/* ============================================================
   รอบ 5 — หน้าที่ยังเป็นตารางเดสก์ท็อป (ตัวจำลอง 2026-09-04)
   ============================================================ */

/* ---- "แผนของเรา": ตาราง 30 คอลัมน์ยัดลงจอ 360px ----
   เดิม table-layout:fixed + width:100% = บีบ 30 วันให้พอดีจอ
   → ช่องกว้าง ~9px เลขวันที่อ่านไม่ออก แตะเลือกวันไม่โดน
   แก้: ปล่อยให้ตารางกว้างตามจริงแล้ว "เลื่อนแนวนอน" แทน (ชื่อคนตรึงซ้ายอยู่แล้ว) */
body.x10m table.op-grid { width: auto !important; min-width: max-content; }
body.x10m table.op-grid td, body.x10m table.op-grid th { min-width: 26px; }
body.x10m .op-dnum { font-size: 11px; }
body.x10m .op-grid-wrap {
  overflow: auto; max-height: none;
  -webkit-overflow-scrolling: touch;   /* iOS: เลื่อนลื่น ไม่งั้นสะดุด */
  overscroll-behavior-x: contain;      /* เลื่อนตารางแล้วไม่ลากทั้งหน้าไปด้วย */
}
/* ชิปคำอธิบายสี (หยุด/สลับ/EX/HBD...) 12 อัน กินครึ่งจอก่อนถึงตาราง
   ยุบเป็นแถวเลื่อนข้างแทนการตัดบรรทัด */
body.x10m .op-legend {
  display: flex; flex-wrap: nowrap; overflow-x: auto; gap: 6px;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
body.x10m .op-legend::-webkit-scrollbar { display: none; }
body.x10m .op-legend > * { flex: 0 0 auto; }

/* ---- ตารางทั่วไปในหน้าอื่น (ภาพรวม/รายงาน) ----
   ตารางกว้างเกินจอต้องเลื่อนในกล่องตัวเอง ไม่ใช่ดันทั้งหน้าให้เลื่อนข้าง
   (กฎมาตรฐาน: หน้าเว็บห้ามเลื่อนแนวนอน แต่ตารางเลื่อนได้) */
body.x10m .page-body table { max-width: none; }
body.x10m .card > table, body.x10m .tbl-wrap, body.x10m .table-wrap {
  display: block; overflow-x: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
/* ---- ปุ่มเล็กเกินไปในหน้าตั้งค่า/แอดมิน ----
   เป้าแตะต่ำกว่า 38px = นิ้วกดพลาด (มาตรฐาน iOS 44 / Android 48) */
body.x10m .page-body .btn.small,
body.x10m .page-body .sec-tab,
body.x10m .page-body .chip { min-height: 38px; padding-top: 7px; padding-bottom: 7px; }
/* แถบแท็บย่อยในหน้า (เช่น ผู้ใช้/ประเภท/ทีม) เลื่อนข้างได้แทนตกบรรทัด */
body.x10m .sec-tabs, body.x10m .tab-bar {
  display: flex; flex-wrap: nowrap; overflow-x: auto; overflow-y: visible;
  align-items: stretch; flex-shrink: 0;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
/* ปุ่มแท็บย่อยต้องสูงพอกด (≥38px) แม้อยู่นอก .page-body เช่น #op-tabs หน้าแผนของเรา
   เดิม #op-tabs อยู่นอก .page-body จึงไม่โดนกฎ min-height → ปุ่มสูงแค่ 20px
   + overflow-x:auto ทำ overflow-y เป็น auto ตามไปด้วย กล่องยุบเหลือ 1px (แค่เส้นล่าง)
   ปุ่ม "ตารางไลฟ์สด" ล้นออกนอกกล่อง กดไม่โดน (แตะไปโดน section แทน) */
body.x10m .sec-tabs .sec-tab, body.x10m .tab-bar .sec-tab {
  min-height: 38px; display: flex; align-items: center;
}
body.x10m .sec-tabs::-webkit-scrollbar, body.x10m .tab-bar::-webkit-scrollbar { display: none; }
body.x10m .sec-tabs > *, body.x10m .tab-bar > * { flex: 0 0 auto; }

/* ============================================================
   รอบ 6 — เมนู ⋯ หัวห้อง + โมดัลเด้งจากล่าง (ตัวจำลอง 2026-09-04)
   ============================================================ */
/* ---- หัวข้อกลุ่มในเมนู ---- */
body.x10m .pm-head {
  font-size: 11px; font-weight: 700; letter-spacing: .04em;
  color: var(--muted, #64748B); padding: 8px 14px 4px; text-transform: none;
}
body.x10m .pm-sep { height: 1px; background: var(--border, #E2E8F0); margin: 4px 0; }

/* ---- เมนู ⋯ บนมือถือ = แผ่นเด้งจากขอบล่าง (แบบ Slack/Discord) ----
   เดิมเป็นป๊อปอัพเล็กๆ ลอยใต้ปุ่มมุมขวาบน → นิ้วโป้งเอื้อมไม่ถึง ต้องขยับมือจับใหม่
   แผ่นล่าง = อยู่ในระยะนิ้วโป้ง + แตะง่ายกว่า + มีที่ให้ปุ่มใหญ่ขึ้น */
body.x10m .pop-menu.head-more:not(.hidden) {
  position: fixed !important;
  left: 0 !important; right: 0 !important;
  top: auto !important; bottom: 0 !important;
  width: auto !important; max-width: none !important;
  max-height: 72vh; overflow-y: auto;
  border-radius: 16px 16px 0 0;
  padding: 6px 0 calc(10px + env(safe-area-inset-bottom));
  box-shadow: 0 -10px 40px rgba(0,0,0,.28);
  animation: x10mSheetUp .2s cubic-bezier(.22,.61,.36,1);
  z-index: 500;
}
@keyframes x10mSheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
/* ขีดจับด้านบนแผ่น บอกว่านี่คือแผ่นเลื่อน */
body.x10m .pop-menu.head-more:not(.hidden)::before {
  content: ''; display: block; width: 38px; height: 4px; border-radius: 99px;
  background: var(--border, #CBD5E1); margin: 2px auto 8px;
}
/* ปุ่มในแผ่นต้องใหญ่พอให้นิ้วกด */
body.x10m .pop-menu.head-more button {
  min-height: 48px; font-size: 15px; padding-left: 16px; padding-right: 16px;
}
body.x10m .pop-menu.head-more .pm-icon { width: 22px; }

/* ---- โมดัลทั้ง 48 ตัว = แผ่นเด้งจากขอบล่าง (แบบ Slack/Discord/iOS) ----
   เดิมเป็นกล่องลอยกลางจอแบบเดสก์ท็อป: ปุ่มปิด/ปุ่มยืนยันอยู่กลางจอหรือบนสุด
   นิ้วโป้งเอื้อมไม่ถึง ต้องขยับมือจับใหม่ทุกครั้ง
   แผ่นล่าง = เนื้อหาเริ่มจากล่างขึ้นบน ปุ่มสำคัญอยู่ในระยะนิ้ว + ปัดลงปิดได้ (ท่ามาตรฐานมือถือ)
   ⚠️ ไม่แตะ JS ของโมดัลเลย — เปิด/ปิดยังเป็นกลไกเดิมทุกตัว */
body.x10m .modal-backdrop { align-items: flex-end; padding: 0; }
body.x10m .modal {
  max-width: none; width: 100%;
  border-radius: 18px 18px 0 0;
  max-height: 90vh;
  padding: 8px 16px calc(16px + env(safe-area-inset-bottom));
  animation: x10mSheetUp .22s cubic-bezier(.22,.61,.36,1);
  margin-top: 0 !important;
}
/* ขีดจับด้านบน — บอกว่าปัดลงปิดได้ */
body.x10m .modal::before {
  content: ''; display: block; width: 38px; height: 4px; border-radius: 99px;
  background: var(--border, #CBD5E1); margin: 4px auto 10px;
  position: sticky; top: 0;
}
body.x10m .modal h3 { font-size: 17px; margin-bottom: 10px; }
/* ปุ่มท้ายโมดัลเรียงเต็มความกว้าง กดง่ายกว่าปุ่มเล็กชิดขวา */
body.x10m .modal-actions {
  flex-direction: column-reverse; gap: 8px; margin-top: 14px;
  position: sticky; bottom: 0; background: var(--card);
  padding-top: 10px;
}
body.x10m .modal-actions .btn { width: 100%; min-height: 46px; }
/* ⚠️ ยกเว้นแถวที่มีข้อความ/ตัวนับปนอยู่ (เช่น "เลือกแล้ว n") ไม่ต้องยืดเต็ม */
body.x10m .modal-actions .grow { width: auto; text-align: center; }

/* ---- หน้าแจ้งเตือน: ยุบแถวควบคุมให้แน่นขึ้น ----
   เดิม แท็บสถานะ + ปุ่ม "ทุกชนิด/ตั้งค่า" กิน 2 แถวเต็มก่อนถึงรายการจริง */
body.x10m #page-threads .ntf-tab { padding: 8px 10px; font-size: 13px; }
body.x10m #page-threads .ntf-tools,

/* ---- แผ่นเมนูรวม: ต้องเหลือพื้นหลังให้แตะปิด ----
   เดิม max-height เกือบเต็มจอ พอไทล์เพิ่มเป็น 10 อัน แผ่นสูงจนเหลือขอบบนแค่ 17px
   → แตะพื้นหลังเพื่อปิดแทบไม่ได้ และมือถือไม่มีปุ่ม Escape = ปิดยาก
   จำกัดที่ 78vh เหลือพื้นหลังชัดเจนด้านบน + เพิ่มปุ่มปิดในหัวแผ่นเป็นทางที่สอง */
body.x10m .x10m-sheet { max-height: 78vh; }
body.x10m .x10m-sheet-head { position: relative; }
body.x10m .x10m-sheet-close {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px; border: 0; background: none; cursor: pointer;
  font-size: 20px; line-height: 1; color: var(--x10m-dim);
  display: flex; align-items: center; justify-content: center; border-radius: 50%;
}
body.x10m .x10m-sheet-close:active { background: var(--side-hover); }

/* ---- หน้าแจ้งเตือน: ยุบส่วนหัวให้เหลือที่ให้เนื้อหา ----
   เดิม หัวเพจ 75px + แท็บ 45px + แถวปุ่มกรอง 75px = 195px หายไปก่อนถึงรายการแรก
   (จอสูง 780 เหลือให้เนื้อหาไม่ถึงครึ่ง) */
body.x10m #page-threads .page-head { padding-top: 8px; padding-bottom: 8px; min-height: 0; }
body.x10m #page-threads .page-head h2 { font-size: 16px; }
/* ปุ่ม "ทุกชนิด/ตั้งค่า" ยุบเป็นชิปเล็กแถวเดียวกับแท็บ ไม่กินอีกแถว */
/* หัวข้อพับ "ข้อความยังไม่ได้อ่าน" ให้ดูเป็นปุ่มกดได้จริง ไม่ใช่ข้อความลอย */
body.x10m #page-threads .ntf-fold,
body.x10m #page-threads summary {
  min-height: 44px; display: flex; align-items: center; gap: 6px;
  padding: 0 12px; font-size: 14px; cursor: pointer;
}
/* ข้อความ "ยังไม่มีการแจ้งเตือน" ไม่ต้องกินที่เยอะ */
body.x10m #page-threads .empty-hint,
body.x10m #page-threads .muted { padding: 18px 12px; }

/* ---- หน้า DM: แถวชิปกรอง (ตัวจำลอง 2026-09-04) ---- */
body.x10m .dmp-filters { display: flex; gap: 8px; padding: 8px 12px 4px; flex-wrap: wrap; }
body.x10m .dmp-fchip {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--border, #E2E8F0); background: var(--card, #fff);
  color: var(--muted, #64748B); font-family: inherit; font-size: 12.5px;
  padding: 6px 12px; border-radius: 999px; cursor: pointer; min-height: 34px;
}
body.x10m .dmp-fchip.on { background: var(--blue, #0F4C81); border-color: var(--blue, #0F4C81); color: #fff; }
body.x10m .dmp-fdot { width: 8px; height: 8px; border-radius: 50%; background: var(--online, #2BAC76); flex: 0 0 auto; }
body.x10m .dmp-fchip.on .dmp-fdot { background: #fff; }
body.x10m .dmp-fchip { min-height: 38px; font-size: 13px; }

/* ---- แถบเตือน "เบราว์เซอร์ปิดสิทธิ์แจ้งเตือน" ----
   วางที่ bottom:12px = ทับแถบแท็บล่างพอดี กดแท็บไม่ได้เลย (เจอตอนเทส 2026-09-04)
   ยกขึ้นเหนือแถบแท็บ + เหนือแถบเดโม และไม่ให้กินคลิกนอกตัวปุ่มเอง */
body.x10m #ntf-perm-bar {
  bottom: calc(var(--x10m-tabbar-h) + var(--x10m-safe-b) + 26px);
  pointer-events: none;
}
body.x10m #ntf-perm-bar .npb-how,
body.x10m #ntf-perm-bar .npb-x { pointer-events: auto; }
/* ในห้องแชทไม่มีแถบแท็บ → ลดระยะลงมา ไม่ให้ลอยกลางจอ */
body.x10m.in-room #ntf-perm-bar { bottom: calc(env(safe-area-inset-bottom) + 78px); }

/* ---- ปุ่มปักหมุดในแถว DM ---- */
body.x10m .dmp-row { position: relative; }
body.x10m .dmp-pin {
  border: 0; background: none; cursor: pointer; font-size: 17px; line-height: 1;
  color: var(--border, #CBD5E1); padding: 6px; flex: 0 0 auto; align-self: center;
  transition: color .12s, transform .12s;
}
body.x10m .dmp-pin.on { color: #F0B429; }
body.x10m .dmp-pin:active { transform: scale(1.25); }
body.x10m .dmp-pin { min-width: 40px; min-height: 40px; display: flex; align-items: center; justify-content: center; }
/* หัวข้อกลุ่มตำแหน่ง */
body.x10m .dmp-sec-job { display: flex; align-items: baseline; gap: 8px; }
body.x10m .dmp-sec-n { font-size: 11px; font-weight: 400; color: var(--muted, #64748B); }
body.x10m .dmp-sec-n i { font-style: normal; color: var(--online, #2BAC76); }
/* แถวชิปกรองเลื่อนข้างได้ ไม่ตกบรรทัดตอนมี 3 อัน */
body.x10m .dmp-filters {
  flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
body.x10m .dmp-filters::-webkit-scrollbar { display: none; }
body.x10m .dmp-filters > * { flex: 0 0 auto; }

/* ---- ปุ่มที่เผยตอนปัดซ้ายแถว DM ---- */
body.x10m .dmp-list { overflow-x: hidden; }
/* ⚠️ แถวต้องมีพื้นทึบ + z-index สูงกว่าปุ่มที่ซ่อนอยู่หลัง
   ไม่งั้นตอนปัด ตัวหนังสือของแถวจะทะลุออกมาซ้อนกับปุ่ม (เจอตอนเทส 2026-09-04) */
body.x10m .dmp-row {
  transition: transform .18s cubic-bezier(.22,.61,.36,1);
  background: var(--card, #fff); position: relative; z-index: 1;
}
body.x10m .dmp-row.swiped { box-shadow: 2px 0 8px rgba(0,0,0,.10); }
body.x10m .dmp-sw {
  position: absolute; top: 0; bottom: 0; left: 100%;
  display: flex; align-items: stretch; width: 132px; z-index: 0;
}
body.x10m .dmp-sw-b {
  flex: 1 1 0; border: 0; cursor: pointer; font-size: 20px; color: #fff;
  display: flex; align-items: center; justify-content: center;
}
body.x10m .dmp-sw-b.pin { background: #F0B429; }
body.x10m .dmp-sw-b.mute { background: #64748B; }
/* ⚠️⚠️ 2026-09-06 Boss แจ้ง "ในคอม ใน dm ตรงรายชื่อมันมีดาวให้กดสองอัน"
   ต้นเหตุ: กฎซ่อนเดิมเขียนว่า `body.x10m .dmp-sw { display:none }` = **มีผลเฉพาะมือถือ**
   แต่ `.dmp-sw` ถูก render ทุกจอ → **คอมไม่มีกฎไหนซ่อนเลย** ปุ่ม ★ ของแถบปัด
   จึงลอยมาเรียงข้างปุ่ม ★ ตัวจริง = ดาว 2 อัน (วัด DOM จริงยืนยัน: คอมเห็น 2 · มือถือเห็น 1)

   ⚠️ ห้ามซ่อนด้วย `.dmp-sw { display:none }` เปล่า ๆ — **ปัดซ้ายบนมือถือจะพัง**
      บนมือถือแถบนี้ "ไม่ได้" ถูกซ่อน แต่ถูกจอดไว้นอกกรอบรายชื่อ
      (.dmp-row position:relative + .dmp-sw absolute left:100%) แล้วโดน
      `#dmp-list { overflow-x:hidden }` เฉือนทิ้ง · พอปัดแถวเลื่อน -132px จึงเผยออกมา
      วัดจริงที่ 360px: กรอบรายชื่อกว้างถึง x=352 · แถบปัดเริ่มที่ x=352 = พอดีนอกกรอบ
   → ซ่อนเฉพาะ "ตอนไม่ใช่โหมดมือถือ" เท่านั้น (คอมไม่มี position:relative ที่แถว
      แถบจึงหลุดมาเรียงในแถวกลายเป็นดาวใบที่ 2) */
body:not(.x10m) .dmp-sw { display: none; }

/* ---- ข้อความเด้ง (toast) บนมือถือ ----
   ปัญหาที่เจอจริง (Boss ส่งภาพ 2026-09-04):
   1) ลอยอยู่กลางจอทับรายการในแผ่นเมนู อ่านเมนูไม่ได้
   2) พื้นขาวตัวอักษรดำ ขณะที่ธีมมืด → ดูเหมือนป๊อปอัพหลุดธีม
   3) ข้อความยาวขึ้น 4 บรรทัด กินที่มาก
   → ย้ายไปเกาะขอบบน (พ้นแผ่นเมนูที่เลื่อนขึ้นจากล่าง) + ใช้สีตามธีม + คุมความกว้าง */
body.x10m .toast {
  bottom: auto;
  top: calc(env(safe-area-inset-top) + 10px);
  z-index: 600;                       /* เหนือแผ่นเมนู (71) และโมดัล (500) */
  max-width: min(92vw, 420px);
  padding: 11px 16px; border-radius: 14px;
  font-size: 13.5px; line-height: 1.45; text-align: left;
  background: var(--x10m-surface, #1E293B);
  color: var(--text, #E5EAF0);
  border: 1px solid var(--x10m-line, rgba(255,255,255,.12));
  box-shadow: 0 10px 30px rgba(0,0,0,.35);
}

/* ============================================================
   หน้า "งาน & Note" ปรับใหม่ (ตัวจำลอง 2026-09-04)
   ปัญหาเดิม: ชื่องานยาวดันการ์ดกว้าง 841px ในกรอบ 344px
   → ชื่องานโดนตัดหายครึ่ง · ปุ่ม "+ สร้างงาน" หลุดออกนอกจอ กดไม่ได้
   ต้นเหตุ: .list-row .grow เป็น nowrap + ตัวหนังสือข้างในไม่มีกฎตัดคำ
   ============================================================ */
/* ให้ชื่องานตัดขึ้นบรรทัดใหม่ได้ สูงสุด 2 บรรทัดแล้วค่อย ... */
body.x10m #page-work .list-row .grow { white-space: normal; }
body.x10m #page-work .list-row .grow > div:first-child {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; line-height: 1.35; word-break: break-word;
}
body.x10m #page-work .list-row .grow .small-text {
  /* ⚠️ ห้ามใช้ nowrap ตรงนี้ — ทำให้กล่องกว้างเกินจอกลับมาอีก (เทสจับได้ scrollers 0→4)
     ใช้ตัดที่ 1 บรรทัดด้วย line-clamp แทน ซึ่งไม่ดันความกว้าง */
  display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical;
  overflow: hidden; word-break: break-word; line-height: 1.3; margin-top: 2px;
}
/* หัวการ์ด: ชื่อหมวด + ปุ่มสร้าง ต้องอยู่ในจอ ไม่ล้น */
body.x10m #page-work .card-head { flex-wrap: wrap; gap: 8px; }
body.x10m #page-work .card-head h3 { flex: 1 1 auto; min-width: 0; font-size: 15px; }
body.x10m #page-work .card-head .btn { flex: 0 0 auto; min-height: 38px; }
/* แถวงานแตะง่ายขึ้น + ช่องติ๊กใหญ่พอสำหรับนิ้ว */
body.x10m #page-work .list-row { padding: 10px 2px; align-items: flex-start; gap: 12px; }
body.x10m #page-work .list-row input[type="checkbox"] {
  width: 22px; height: 22px; margin-top: 2px; flex: 0 0 auto;
}
/* ป้ายสถานะ (ค้าง/เลยกำหนด/เสร็จ) ไม่ให้ถูกบีบจนอ่านไม่ออก */
body.x10m #page-work .list-row .pill { flex: 0 0 auto; align-self: center; font-size: 11px; }
/* งานที่เสร็จแล้ว จางลง ไม่ต้องเด่นเท่างานค้าง */
body.x10m #page-work .list-row:has(input:checked) { opacity: .55; }
/* การ์ดชิดขอบมากขึ้น คืนที่ให้เนื้อหาบนจอแคบ */
body.x10m #page-work .page-body { padding: 8px; }
body.x10m #page-work .card { padding: 12px; }

/* ============================================================
   รอบ 7 — เก็บงานหน้าที่ยังล้นขอบ (ตัวจำลอง 2026-09-04)
   หลักการที่ Boss วางไว้: "ไม่ตัดข้อความทิ้ง แต่จัดหน้าให้พอดีจอ"
   ตาราง/ตารางเวลา = ยอมให้เลื่อนซ้ายขวาได้ · ที่เหลือต้องพอดีจอ
   ============================================================ */

/* ---- แผงตัวเลือกแบบติ๊ก (ตัวกรองในหน้าภาพรวม/รายงาน) ----
   min-width:200px + left:0 → บนจอ 360px แผงยื่นออกนอกขอบขวา 52px
   กดเลือกตัวท้ายๆ ไม่ได้เพราะอยู่นอกจอ */
body.x10m .f-drop .check-list {
  min-width: 0; width: max-content; max-width: calc(100vw - 32px);
  left: auto; right: 0;                 /* กางจากขวาเข้ามา ไม่ล้นขอบ */
}
body.x10m .check-list label { padding: 8px 6px; font-size: 14px; }  /* แตะง่ายขึ้น */

/* ---- แถบกราฟ "Top ห้อง / Top คน" ในหน้าภาพรวม ----
   แท่งกราฟกว้างตายตัว 110px + ชื่อห้องยาว (nowrap) → รวมแล้วเกินการ์ดบนจอแคบ
   ดันทั้งหน้าให้เลื่อนซ้ายขวา 36px
   แก้: ให้ชื่อกินที่ที่เหลือแล้วตัด ... ส่วนแท่งกราฟย่อลงตามจอ (ยังเทียบสัดส่วนกันได้) */
body.x10m #dash-channels .list-row,
body.x10m #dash-users .list-row { gap: 8px; }
/* ⚠️ แท่งกราฟตั้งความกว้างด้วย inline style (style="width:110px") ซึ่งชนะ CSS ปกติ
   ต้องใช้ !important ที่ max-width ถึงจะบีบได้จริง (เทสจับได้: 388→371 ยังไม่พอ) */
body.x10m #dash-channels .bar,
body.x10m #dash-users .bar { max-width: 56px !important; flex: 0 1 auto; min-width: 4px; }
body.x10m #dash-channels .grow,
body.x10m #dash-users .grow { min-width: 0; }

/* ---- กริด 2 คอลัมน์ (.two-col) บนมือถือ ----
   ถึงจะยุบเป็น 1 คอลัมน์แล้ว แต่ track ของ grid ยังกว้างตาม "เนื้อหาที่แคบสุด"
   ของการ์ดข้างใน → การ์ดยืด 355px ในกรอบ 344px ดันหน้าให้เลื่อนซ้ายขวา
   minmax(0,1fr) บังคับให้ track ยอมหดได้จริง (ค่า default คือ minmax(auto,1fr)) */
body.x10m .two-col { grid-template-columns: minmax(0, 1fr); }
body.x10m .two-col > * { min-width: 0; }

/* ════════════════════════════════════════════════════════════════
   X10 Chat — มือถือ รอบยกโครง UI ใหม่  (ตัวจำลอง 2026-09-05)
   ────────────────────────────────────────────────────────────────
   ⚠️ ชั้นนี้ "ต่อท้าย" ของเดิม ไม่ได้ลบของเก่าทิ้ง
      พฤติกรรมเดิมที่ทำไว้ดีแล้วอยู่ครบ (ปัดแถว/ดึงรีเฟรช/ออฟไลน์/safe-area)
      แก้เฉพาะ "การจัดวาง" ที่พังจริงบนจอ 360x780 ตามที่วัดมา

   ปัญหาที่วัดได้จริงก่อนแก้ (360x780 · ห้อง 50):
     1. ข้อความ 1 ใบสูง 5321px / 775px / 672px  ← สูงกว่าทั้งจอ
        เหตุ: .msg-image มี max-width แต่ max-height: none
              และข้อความยาวไม่มีตัวหนีบเลย
     2. หัวห้องยัด 6 ปุ่มในแถว 360px → ชื่อห้องโดนตัด
     3. ก้นจอซ้อน 3 ชั้น (แถบขออนุญาตแจ้งเตือน + กล่องพิมพ์ + ริบบิ้นเดโม)
     4. แต่ละข้อความมีแถวเครื่องมือ 3 แถว (ชิป/เวลา+↩+⋯/คำตอบ)
   ════════════════════════════════════════════════════════════════ */

/* ---- โทเคนของชั้นใหม่ ---- */
body.x10m {
  --x10m-r: 14px;            /* รัศมีมุมมาตรฐาน */
  --x10m-gap: 10px;
  /* เพดานความสูงรูป — ไม่ให้รูปเดียวกินทั้งจอ
     ⚠️ iOS: vh นับรวมแถบ URL ที่ยุบได้ ทำให้รูปล้นจอจริง → ใช้ dvh ถ้ามี */
  --x10m-media-max: 46vh;
}

/* ════════════════════════════════════════════════
   1) หนีบสื่อ — ต้นเหตุข้อความสูง 775px
   รูปแนวตั้งเดิม 271x595 → เหลือสูงสุด 46vh (~359px)
   object-fit: cover ให้เห็นส่วนบนของรูป (คนถ่ายมักวางประเด็นไว้บน)
   กดเปิดดูเต็มได้เหมือนเดิม (lightbox เดิมยังทำงาน)
   ════════════════════════════════════════════════ */
body.x10m .msg img.msg-image,
body.x10m .msg video.msg-video,
body.x10m .album-card img,
body.x10m .msg-table-wrap img {
  max-width: 100% !important;
  max-height: var(--x10m-media-max) !important;
  height: auto;
  width: auto;
  object-fit: cover;
  object-position: top center;
  border-radius: var(--x10m-r);
  background: var(--x10m-ground);
}

@supports (height: 100dvh) {
  body.x10m { --x10m-media-max: 46dvh; }
}

/* ป้าย "แตะดูเต็ม" ให้รู้ว่ารูปถูกย่อ ไม่ใช่รูปมันเป็นแบบนี้ */

/* ════════════════════════════════════════════════
   2) หนีบข้อความยาว — ต้นเหตุใบสูง 5321px
   ยาวเกิน ~12 บรรทัดให้ค่อยๆ จางแล้วมีปุ่ม "อ่านต่อ"
   (JS ใส่คลาส .x10m-clamped/.x10m-expanded ให้)
   ════════════════════════════════════════════════ */
body.x10m .msg-text.x10m-clamped {
  max-height: 15.5em;
  overflow: hidden;
  position: relative;
}
/* ⚠️ Android WebView เก่า / iOS < 15.4 ไม่รองรับ mask-image
   ถ้าใส่ตรงๆ แล้วเบราว์เซอร์ไม่รองรับ = ตัวอักษรท่อนล่างโดนตัดห้วนๆ ไม่มีสัญญาณว่ายังมีต่อ
   จึงใส่เงาจางไว้ใน @supports เท่านั้น · เครื่องที่ไม่รองรับยังเห็นปุ่ม "อ่านต่อ" ตามปกติ */
@supports ((-webkit-mask-image: linear-gradient(#000, transparent)) or (mask-image: linear-gradient(#000, transparent))) {
  body.x10m .msg-text.x10m-clamped {
    -webkit-mask-image: linear-gradient(180deg, #000 72%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 72%, transparent 100%);
  }
}
body.x10m .msg-text.x10m-expanded { max-height: none; -webkit-mask-image: none; mask-image: none; }
body.x10m .x10m-more {
  display: inline-flex; align-items: center; gap: 4px;
  margin-top: 2px; padding: 3px 10px;
  border: 0; border-radius: 999px;
  background: var(--x10m-ground); color: var(--blue);
  font: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
body.x10m .x10m-more:active { opacity: .6; }

/* ════════════════════════════════════════════════
   3) หัวห้อง — จาก 6 ปุ่มเบียดกัน เหลือ "ชื่อห้องได้ที่"
   เก็บ: ย้อนกลับ · ชื่อ+ชิป · กระดิ่ง · ⋯
   ซ่อน: 🌐 ซ้ำ (มีในเมนู ⋯ อยู่แล้ว) · ชิปสมาชิกย้ายไปบรรทัดชื่อแบบกดได้
   ════════════════════════════════════════════════ */
body.x10m .chat-head {
  gap: 2px;
  padding: 6px 6px 6px 2px;
  min-height: 52px;
  align-items: center;
  /* 🔴 Boss แจ้ง 2026-09-06 (ภาพ 1000007090): "กดเข้าช่องแล้วไม่เห็นชื่อห้อง
     โดนบังจากขอบบนไอโฟน" — ข้อความไถขึ้นไปอยู่ใต้นาฬิกา/แบต โดยไม่มีหัวห้องคั่น
     ต้นเหตุ 2 ชั้นซ้อนกัน:
      1) กฎนี้ (specificity body.x10m > @supports .chat-head) ทับ padding-top
         ที่ style.css:3043 ใส่ safe-area ไว้ → เหลือ 6px หัวห้องมุดใต้รอยบาก
      2) .chat-head เป็น position:static z-index:auto แต่ body::before (แถบทึบ
         คลุมรอยบาก) เป็น z-index:30 → แถบวาดทับหัวห้อง
     แก้: คืน safe-area + ยกขึ้นเหนือแถบทึบ
     ⚠️ ไม่ต้องใส่ position:sticky — .chat-head เป็นพี่น้องกับ .messages
        (.main เป็น flex column, .messages ต่างหากที่ overflow-y:auto)
        หัวห้องจึงค้างอยู่แล้วโดยธรรมชาติ sticky เป็นโค้ดตายเปล่า ๆ
     ⚠️ ต้องมี background ทึบ ไม่งั้นเนื้อหาที่เลื่อนผ่านเห็นทะลุหลังหัวห้อง */
  padding-top: max(6px, env(safe-area-inset-top));
  position: relative; z-index: 31;
  background: var(--v3-card, var(--card));
}
/* ขนาดหัวห้องยืดตามความสูงจอ — จอเตี้ยไม่โดนหัวห้องกินที่, จอใหญ่ไม่อึดอัด
   (ทับ min-height:52px ด้านบน จึงต้องอยู่หลัง) */
body.x10m .chat-head { min-height: var(--x10m-head-h); }

/* 🔴 Boss แจ้ง 2026-09-06 (ภาพ IMG_8613 หน้า "แผนของเรา"):
   "ในไอโฟนเข้าไปไม่เห็นหัวข้อ เหมือนหน้ามันเบียดกันเละ"
   ต้นเหตุ: กฎ safe-area ครอบแค่ `.page-head`/`.chat-head`/`.sidebar-head`/`.sec-head`
   แต่ #page-ourplan ใช้ `.op-head` (div ธรรมดา) จึงไม่เคยเว้นรอยบาก
   → หัวข้อทะลุขึ้นไปอยู่ใต้นาฬิกา/แบต โดนตัดครึ่งบรรทัด
   แก้ที่ **ตัว .page เอง** ครั้งเดียว ครอบทุกหน้ารวมหน้าที่จะสร้างในอนาคต
   ⚠️ ต้องยกเว้น #page-chat — หัวห้องจัดการ inset ของตัวเองแล้ว (ซ้อนสองชั้น = เว้นเบิ้ล)
   ⚠️ ใช้ padding ไม่ใช่ margin — .page เป็น flex column ที่มี min-height:0 */
@supports (-webkit-touch-callout: none) {
  body.x10m .page:not(#page-chat):not(#page-dm) {
    padding-top: env(safe-area-inset-top);
  }
  /* หน้าที่มีหัวของตัวเองอยู่แล้ว ถอน padding ซ้ำออก ไม่ให้เว้นสองชั้น */
  body.x10m .page:not(#page-chat):not(#page-dm) > .page-head,
  body.x10m .page:not(#page-chat):not(#page-dm) > .sec-head { padding-top: var(--s2); }
}
body.x10m .chat-head .chat-name { font-size: var(--x10m-head-fs); }
body.x10m .chat-head .chat-topic { font-size: var(--x10m-head-sub); }
/* ปุ่มหัวห้องขนาดเดียวกันหมด แตะได้ 40px แต่ไม่บวมจนดันชื่อห้อง */
body.x10m .chat-head .icon-btn,
body.x10m .chat-head .chat-meta-btn {
  width: 38px; min-width: 38px; height: 38px;
  padding: 0; flex: 0 0 auto;
}
/* ชื่อห้องได้พื้นที่ที่เหลือทั้งหมด และตัดด้วย ellipsis ไม่ใช่หายไปเฉยๆ */
body.x10m .chat-head .chat-title { flex: 1 1 auto; min-width: 0; overflow: hidden; }
body.x10m .chat-head .chat-name {
  font-size: 16px; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* ชิปเมตา (สมาชิก/ปักหมุด) เล็กลง ไม่แย่งที่ชื่อ */
body.x10m .chat-head .chat-meta { gap: 4px; }
body.x10m .chat-head .chat-meta-btn {
  width: auto; min-width: 0; height: 26px;
  padding: 0 8px; border-radius: 999px;
  font-size: 12px;
}
/* 🌐 ตัวที่ 2 ในหัวห้องซ้ำกับเมนู ⋯ — ซ่อนเฉพาะมือถือ (ยังอยู่ในเมนู) */
body.x10m .chat-head .chat-title .lock-badge:empty { display: none; }

/* ════════════════════════════════════════════════
   4) ก้นจอ — เดิมซ้อน 3 ชั้นจนกล่องพิมพ์เกือบหลุด
   ริบบิ้นเดโมทำให้บางเบา ไม่กินที่ถาวร
   แถบขออนุญาตแจ้งเตือนยุบเป็นแถบบางแตะได้
   ════════════════════════════════════════════════ */
/* ริบบิ้น "ตัวจำลอง" — ลอยบางๆ ไม่ดันเนื้อหา */
body.x10m .demo-ribbon,

/* แถบขออนุญาตแจ้งเตือน: บางลง อ่านออก ปิดง่าย */
body.x10m .ntf-perm,
body.x10m [class*="perm-bar"],

/* กล่องพิมพ์: แน่นขึ้น ปุ่มแตะได้ครบ ไม่ล้นขอบ */
body.x10m .composer {
  gap: 4px;
  padding: 6px 6px calc(6px + env(safe-area-inset-bottom));
}
body.x10m .composer .icon-btn {
  width: 40px; min-width: 40px; height: 40px; padding: 0;
}
body.x10m .composer textarea,
body.x10m .composer #msg-input {
  font-size: 16px;              /* กัน iOS zoom */
  border-radius: var(--x10m-r);
  padding: 9px 12px;
  max-height: 38vh;             /* พิมพ์ยาวแล้วไม่ดันจอจนไม่เห็นข้อความ */
}
@supports (height: 100dvh) {
  body.x10m .composer textarea,
  body.x10m .composer #msg-input { max-height: 38dvh; }
}

/* ════════════════════════════════════════════════
   5) แถวข้อความ — เดิมเครื่องมือกิน 3 แถวต่อ 1 ข้อความ
   ยุบเวลา/↩/⋯ ให้อยู่แถวเดียว โผล่ชัดตอนแตะ
   ════════════════════════════════════════════════ */
body.x10m .msg { padding: 3px 8px; }
body.x10m .msg-under {
  gap: 4px; margin-top: 2px;
  align-items: center; flex-wrap: nowrap;
}
body.x10m .msg-under-time { font-size: 11px; opacity: .55; }
/* ปุ่มเครื่องมือใต้ข้อความ: กลมเล็ก แตะได้ 34px */
body.x10m .msg-under .msg-tool {
  width: 34px; min-width: 34px; height: 34px;
  padding: 0; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
}
/* แถบ "n คำตอบ" — จากแถบเต็มความกว้าง เหลือชิปเล็กแตะได้ */
body.x10m .msg .thread-open,
body.x10m .msg [class*="thread-bar"],
body.x10m .msg [class*="reply-bar"] {
  font-size: 12.5px;
  padding: 4px 10px;
  border-radius: 999px;
  margin-top: 3px;
}
/* ชิปรีแอ็กเล็กลง ไม่สูงเท่าปุ่ม */
body.x10m .msg .react-chip,
body.x10m .msg [class*="react"] .chip {
  min-height: 26px; padding: 2px 8px; font-size: 12.5px;
}

/* ════════════════════════════════════════════════
   6) ฟองข้อความ — แยก "ของเรา/ของคนอื่น" ให้อ่านไว
   ════════════════════════════════════════════════ */
body.x10m .msg .msg-text {
  font-size: 15px; line-height: 1.45;
  overflow-wrap: anywhere; word-break: break-word;
}
/* โค้ด/ตารางกว้างเกินจอ ให้เลื่อนในกล่องตัวเอง ไม่ดันทั้งหน้าให้เลื่อนแนวนอน */
body.x10m .msg pre,
body.x10m .msg .msg-table-wrap,
body.x10m .msg table {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
body.x10m .msg pre { font-size: 12.5px; border-radius: 10px; }

/* กันทั้งหน้าเลื่อนแนวนอน (กฎ mobile-first) */
body.x10m, body.x10m .app, body.x10m .main, body.x10m .page { max-width: 100vw; overflow-x: hidden; }

/* ════════════════════════════════════════════════════════════════
   7) ข้อต่างเฉพาะแพลตฟอร์ม (Boss กำชับ 2026-09-05)
   ทดสอบ 2 ชุดจริง: Chromium(Android UA) + WebKit(iOS UA)
   ════════════════════════════════════════════════════════════════ */

/* ---------- iOS ---------- */
/* กันหน้า "เด้ง" (rubber-band) แล้วเห็นพื้นหลังขาวหลังแอป
   ⚠️ ห้ามใส่ overflow:hidden ที่ body บน iOS — กล่องพิมพ์จะเลื่อนตามคีย์บอร์ดไม่ได้ */
body.x10m.plat-ios { overscroll-behavior-y: none; }

/* โมเมนตัมสกรอลล์ (iOS เก่ายังต้องใช้ prefix นี้) */
body.x10m.plat-ios .chat-scroll,
body.x10m.plat-ios .side-scroll,
body.x10m.plat-ios .msg pre,
body.x10m.plat-ios .msg-table-wrap { -webkit-overflow-scrolling: touch; }

/* ⚠️ iOS ซูมเองถ้า font-size < 16px ตอนโฟกัส input — ล็อกทุกช่องกรอก
   (เดิมกันไว้แค่ textarea ของกล่องพิมพ์ ช่องค้นหา/โมดัลยังเด้งซูมอยู่) */
body.x10m.plat-ios input,
body.x10m.plat-ios select,
body.x10m.plat-ios textarea { font-size: 16px; }

/* iOS: ปุ่มกลมของ Safari จะมีเงา/มุมของตัวเอง ทับให้เรียบเหมือน Android
   🔴🔴 (2026-09-14) ของเดิมเหมารวม `input` **ทุกชนิด** ⇒ ช่องติ๊ก/ตัวเลือกวงกลม
        ถูกถอดหน้าตาเนทีฟไปด้วย = **กลายเป็นกล่องขาวเปล่า ๆ เหมือนกันหมด**
        "ติ๊กแล้ว" กับ "ยังไม่ติ๊ก" **หน้าตาเหมือนกันเป๊ะบน iPhone** มองไม่ออกว่าเลือกอะไรไว้
        (ยืนยันด้วยภาพ: Android ขึ้นเครื่องหมายถูกสีน้ำเงิน · iPhone ว่างเปล่าทั้ง 3 อัน)
        กระทบ checkbox/radio ทั้งแอป 58 จุด (เลือกห้องส่งต่อ · ตั้งค่า · ฟอร์มต่าง ๆ)
   ⚠️⚠️ ต้อง **ยกเว้น checkbox/radio** — ตัวอื่น (text/search/number) ยังต้องเรียบเหมือนเดิม
   ⚠️ ห้ามแก้เป็น `appearance:auto` ทับทีหลัง เพราะ Safari บางรุ่นไม่คืนหน้าตาให้
      ต้อง **ไม่ประกาศตั้งแต่แรก** ด้วย :not() */
body.x10m.plat-ios button,
body.x10m.plat-ios input:not([type="checkbox"]):not([type="radio"]) {
  -webkit-appearance: none; appearance: none;
}
/* เผื่อกฎอื่นในอนาคตมาถอดอีก — ย้ำให้ช่องติ๊กใช้หน้าตาเนทีฟเสมอ
   ⚠️ accent-color ทำให้สีติ๊กตรงกับธีมแอป (Safari 15.4+ รองรับ · เก่ากว่านั้นได้สีฟ้าระบบ) */
body.x10m.plat-ios input[type="checkbox"],
body.x10m.plat-ios input[type="radio"] {
  -webkit-appearance: auto; appearance: auto;
  accent-color: var(--blue, #2563EB);
  width: 20px; height: 20px; flex: 0 0 auto;
}

/* safe-area ล่างของ iPhone มีแถบ home indicator จริง (26px ตามซีด)
   ริบบิ้นเดโมต้องหลบ ไม่งั้นโดนแถบขีดขาวทับ */

/* ---------- Android ---------- */
/* Android WebView: tap highlight สีฟ้าเริ่มต้นดูเหมือนบัค — ปิดทั้งแอป */
body.x10m.plat-android * { -webkit-tap-highlight-color: transparent; }

/* ⚠️ Android แป้นพิมพ์ "ดัน" viewport (resize) ต่างจาก iOS ที่ "ทับ" (overlay)
   ตอนแป้นขึ้น vh จะหดลงทันที ถ้าเพดานรูปผูกกับ vh รูปจะกระตุกเล็กลง
   → ตรึงเพดานรูปเป็น px ระหว่างพิมพ์ */
body.x10m.plat-android.kb-open { --x10m-media-max: 240px; }

/* Android: backdrop-filter ไม่รองรับทุกเครื่อง — บังคับพื้นทึบไว้ก่อน
   (ถ้าไม่ทึบ แถบล่างจะโปร่งจนอ่านไอคอนไม่ออกบนพื้นหลังสว่าง) */
body.x10m.plat-android .x10m-tabbar { background: var(--x10m-surface); }
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  body.x10m.plat-android .x10m-tabbar {
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    backdrop-filter: saturate(180%) blur(14px);
  }
}

/* Android gesture nav 20px (ตั้งไว้แล้วด้านบน) — ย้ำให้ริบบิ้นเดโมหลบด้วย */

/* ════════════════════════════════════════════════════════════════
   8) แก้ตามชื่อคลาสจริงที่อ่านจาก DOM (2026-09-05 รอบ 2)
   ⚠️ รอบแรกผมเดาชื่อคลาส (.ntf-perm/.demo-ribbon) ซึ่ง "ไม่มีอยู่จริง"
      กฎพวกนั้นเลยไม่ทำงานเลย — รอบนี้ยืนยันชื่อจาก DOM จริงแล้ว:
        แถบแจ้งเตือน = #ntf-perm-bar (ต่อกับ body ไม่ใช่ใน .app)
        ป้ายเดโม     = #demo-flag
        เครื่องมือใบ = .react-row / .msg-under
   ════════════════════════════════════════════════════════════════ */

/* ---- 8.1 ป้ายเดโม: จอ 360 ข้อความตัดบรรทัด = สูง ~36px ไม่ใช่ 18px ----
   ของเดิมจองที่ไว้ 18px → แถบล่าง/กล่องพิมพ์โดนทับจริงบนมือถือ
   แก้: ย่อข้อความให้พอดี 1 บรรทัด + จองที่ตามจริง */
/* 🔴 (2026-09-14) iPhone "แถบล่างลอย" — Boss แจ้ง (16 Pro Max ลอยเยอะสุด)
   ของเดิมบรรทัดนี้ตั้ง `bottom: env(safe-area-inset-bottom)` ทับ `bottom:0` (บรรทัด 91)
   แต่แถบ**จองที่ให้ safe-area ไว้แล้ว 2 ชั้น**: height(:94) + padding-bottom(:95)
   ⇒ ยก bottom อีก = safe-area เข้า 3 ชั้น แถบลอยเหนือขอบจอ 34px มีช่องโล่งใต้แถบ
   (วัดจริง: bottom:0 → gapBelow 0px · bottom:34px → gapBelow 34px)
   ⚠️⚠️ Android env()=0 จึงไม่เคยเห็นอาการนี้ = "แอนดรอยได้ iPhone ไม่ได้"
   ⚠️⚠️ ห้ามใส่ bottom กลับมา — ถ้าแถบเตี้ยไป ให้แก้ที่ --x10m-safe-b ตัวเดียว
        (คุม height+padding พร้อมกัน ไม่ทำให้ลอย) */
body.x10m .x10m-tabbar { bottom: 0; }
body.x10m .app {
  padding-bottom: calc(var(--x10m-tabbar-h) + var(--x10m-safe-b));
}
/* ในห้องแชท: ไม่มีแถบแท็บ แต่ยังต้องหลบป้ายเดโม ไม่งั้นกล่องพิมพ์โดนทับ */
body.x10m.in-room .composer { padding-bottom: calc(6px + env(safe-area-inset-bottom)); }

/* ---- 8.2 แถบขอสิทธิ์แจ้งเตือน: ลอยทับ ไม่ดันกล่องพิมพ์ ----
   เดิมกินก้นจอเต็มๆ 2 บรรทัด บีบกล่องพิมพ์จนเกือบหลุด
   ทำเป็นแถบบางลอยเหนือกล่องพิมพ์ อ่านออก ปิดง่าย แตะได้ */
body.x10m #ntf-perm-bar {
  left: 8px; right: 8px;
  bottom: calc(var(--x10m-tabbar-h) + var(--x10m-safe-b) + 22px);
  width: auto; max-width: none;
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px;
  border-radius: var(--x10m-r);
  font-size: 12px; line-height: 1.35;
  box-shadow: 0 6px 20px rgba(0,0,0,.22);
}
/* ในห้องแชท: วางเหนือกล่องพิมพ์
   ⚠️ ลองมาแล้ว 2 แบบ ไม่เอา:
      (ก) ไว้ก้นจอแบบเดิม = ซ้อน 3 ชั้น กล่องพิมพ์เกือบหลุดจอ
      (ข) ลอยใต้หัวห้อง   = บังข้อความใหม่สุด ซึ่งคือสิ่งที่คนเปิดห้องมาอ่าน
   ⚠️ ใช้ position:sticky ไม่ได้ เพราะ ntfPermBanner() ต่อ element นี้กับ <body>
      (นอก #messages) — sticky ต้องอยู่ในกล่องที่เลื่อนถึงจะเกาะ
   → คงเป็นแถบลอย แต่ยกมาไว้ "เหนือกล่องพิมพ์" + บางแถวเดียว
     ตรงนั้นเป็นที่ว่างอยู่แล้ว ไม่ทับทั้งข้อความและปุ่มพิมพ์ */
body.x10m.in-room #ntf-perm-bar {
  top: auto;
  /* ⚠️ อย่าเดาความสูงกล่องพิมพ์เป็นตัวเลขตายตัว — มันยืดตามจำนวนบรรทัดที่พิมพ์
     และแถวปุ่ม (＋ @ 😀 🎤) ทำให้สูงจริง ~125px ไม่ใช่ 58px ที่เดาไว้
     → ให้ JS วัดของจริงแล้วส่งมาทาง --x10m-composer-h (มีค่าสำรองเผื่อ JS ไม่ทัน) */
  /* ⚠️ แก้ 2026-09-05: +6px ไม่พอ วัดจริงแล้วแถบยังกินเข้าไปในกล่องพิมพ์ 10px
     (แถบ 628-666 · กล่องพิมพ์เริ่ม 656) เพราะ --x10m-composer-h วัดเฉพาะกล่อง
     ไม่รวม margin/เงาที่ล้นออกมา → เผื่อเป็น 18px ให้เหลือช่องว่างจริง */
  bottom: calc(var(--x10m-composer-h, 132px) + env(safe-area-inset-bottom) + 18px);
  padding: 5px 8px; font-size: 11.5px;
  box-shadow: 0 2px 10px rgba(0,0,0,.18);
}
body.x10m.in-room #ntf-perm-bar .npb-tx { -webkit-line-clamp: 1; }
body.x10m.in-room #ntf-perm-bar .npb-how { padding: 3px 8px; font-size: 11.5px; }
body.x10m.in-room #ntf-perm-bar .npb-x { width: 26px; height: 26px; }
body.x10m #ntf-perm-bar .npb-tx {
  flex: 1 1 auto; min-width: 0;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
body.x10m #ntf-perm-bar .npb-ic { flex: 0 0 auto; font-size: 15px; }
body.x10m #ntf-perm-bar .npb-how {
  flex: 0 0 auto; padding: 4px 10px; border-radius: 999px; font-size: 12px; font-weight: 700;
}
body.x10m #ntf-perm-bar .npb-x {
  flex: 0 0 auto; width: 30px; height: 30px; padding: 0;
  display: flex; align-items: center; justify-content: center; border-radius: 999px;
}

/* ---- 8.3 หัวห้อง: 🌐 กับ 👥95 อยู่ "ใน .chat-title" ไม่ใช่ .chat-actions ----
   จอ 360: ชื่อห้องเหลือ 139px (โดนตัด) เพราะชิปแย่งที่
   แก้: ชิปเล็กลง + ชื่อห้องได้ที่ก่อน */
body.x10m .chat-head .chat-title { display: flex; align-items: center; gap: 4px; min-width: 0; }
body.x10m .chat-head .chat-name-row { min-width: 0; flex: 1 1 auto; display: flex; align-items: center; gap: 4px; }
body.x10m .chat-head .chat-actions { flex: 0 0 auto; gap: 0; }
/* ชิปสมาชิกในหัวห้อง: ตัวเลขอย่างเดียวพอ ไอคอนบอกความหมายแล้ว */
body.x10m .chat-head .chat-meta-btn { height: 28px; padding: 0 7px; font-size: 12px; gap: 3px; }

/* ---- 8.4 เครื่องมือใต้ข้อความ: .react-row + .msg-under ยุบให้เตี้ยลง ---- */
body.x10m .msg .react-row { gap: 4px; margin-top: 2px; min-height: 0; }
body.x10m .msg .react-chip { min-height: 26px; height: 26px; padding: 0 8px; font-size: 12.5px; }
body.x10m .msg .react-chip img.react-pluto { width: 16px; height: 16px; }

/* ---- 8.5 ตารางในข้อความกว้าง 557px บนจอ 360 = หน้าเลื่อนแนวนอน ----
   <tr> ไม่ได้อยู่ใน .msg-table-wrap เสมอ → หนีบที่ table ตรงๆ ด้วย */
body.x10m .msg table { display: block; max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
body.x10m .msg table td, body.x10m .msg table th { white-space: nowrap; font-size: 12.5px; }

/* ---- 8.6 แถบ "n คำตอบ" (.thr-bar) ----
   ชื่อคลาสจริงคือ .thr-bar (ไม่ใช่ .thread-open/.reply-bar ที่เดาไว้รอบแรก)
   เดิมสูง ~44px เต็มความกว้าง + รูปหน้าคน 28px = กินที่พอๆ กับ 1 ข้อความ
   ย่อรูปหน้าคนลง + ทำเป็นแถบเตี้ย แต่ยังแตะได้สบาย (36px) */
body.x10m .msg .thr-bar {
  min-height: 36px; gap: 5px; padding: 4px 8px;
  border-radius: 999px; font-size: 12.5px; margin-top: 3px;
}
body.x10m .msg .thr-bar img,
body.x10m .msg .thr-faces img { width: 20px !important; height: 20px !important; }
body.x10m .msg .thr-count { font-weight: 700; }
/* "ล่าสุด 13:27" เป็นข้อมูลรอง — จอแคบให้ตัดทิ้งก่อน ไม่ให้ดันแถวเป็น 2 บรรทัด */
@media (max-width: 380px) {
  body.x10m .msg .thr-bar .thr-last { display: none; }
}

/* ════════════════════════════════════════════════════════════════
   9) รายชื่อห้องบนมือถือ — ให้ "เห็นหมวด" ชัด (Boss สั่ง 2026-09-05)
   ────────────────────────────────────────────────────────────────
   ⚠️ ของเดิม "แยกหมวดอยู่แล้ว" แต่บนมือถือมองไม่ออกว่าแยก เพราะวัดได้ว่า:
      • หัวข้อหมวด 11.5px — **เล็กกว่า** ชื่อห้อง 13.5px (หมวดเลยจมลงไป)
      • สีหัวข้อ rgb(30,41,59) เกือบดำสนิทบนแถบข้างสีเข้ม = แทบมองไม่เห็น
      • 15 หมวด · รายการยาว 4,656px บนจอ 780px = ต้องเลื่อน 6 จอถึงจะเห็นครบ
   → หัวข้อต้องเด่นกว่าชื่อห้อง + ห้องเยื้องเข้าให้เห็นว่าเป็นลูก
   ════════════════════════════════════════════════════════════════ */

/* ---- หัวข้อหมวด ----
   ⚠️ ทำแบบแอปจริง (Boss ส่งภาพอ้างอิงมา 2026-09-05):
      แยกหมวดด้วย "เส้นคั่นบางๆ + ที่ว่าง" ไม่ใช่แถบสีทึบ
      ผมเคยทำเป็นแถบสีเข้มก่อนหน้านี้ — หนาและรกกว่าของจริง
      ของจริง: พื้นโปร่ง · ตัวอักษรเล็กสีจาง · เส้นคั่นด้านบน · เว้นบน-ล่างเยอะ */
body.x10m #channel-list .chan-sec {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .02em;
  /* ⚠️ ห้ามใช้ var(--side-text) — ธีมนี้ตั้งไว้ #1E293B (เกือบดำ)
     แต่พื้นแถบข้างจริงเป็นน้ำตาลเข้ม rgb(99,64,10) = ดำบนเข้ม อ่านไม่ออก */
  color: #E9EDF2;
  opacity: .92;
  min-height: var(--x10m-hit);          /* แตะพับ/กางได้เต็มแถว */
  /* เว้นบนเยอะ = ตัวคั่นหมวดที่แท้จริง (แบบภาพอ้างอิง) */
  padding: 18px 10px 8px 12px;
  align-items: center;
  background: none;                      /* โปร่ง ไม่ใช่แถบสี */
  border-top: 1px solid rgba(255,255,255,.09);
}
body.x10m #channel-list > .chan-sec:first-child {
  border-top: 0;
  padding-top: 8px;
}

/* ลูกศรพับ/กาง ให้ใหญ่พอมองเห็นและแตะโดน */
body.x10m #channel-list .chan-sec-car {
  font-size: 13px; opacity: .85;
  margin-left: 2px;
}
/* ตัวเลขจำนวนห้องในหมวด — บอกว่าข้างในมีกี่ห้องโดยไม่ต้องกาง */
body.x10m #channel-list .chan-sec-n {
  font-size: 11px; font-weight: 700;
  opacity: .75;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--side-hover, rgba(255,255,255,.08));
}

/* ---- ห้องในหมวด: เยื้องเข้า + จางกว่าหัวข้อ = เห็นว่าเป็นลูก ---- */
body.x10m #channel-list .chan-body {
  /* ⚠️ แอปจริงมีเส้นแนวตั้งจางมาก + เยื้องน้อย — ไม่ใช่เส้นหนา
     ที่ทำให้ "เห็นว่าแยกหมวด" คือเส้นคั่นแนวนอน + ที่ว่างข้างบน ไม่ใช่เส้นนี้ */
  border-left: 1px solid rgba(255,255,255,.07);
  margin-left: 18px;
  padding-bottom: 4px;
}
body.x10m #channel-list .chan-body .chan-item {
  font-size: 13.5px;
  font-weight: 500;
  padding-left: 10px;
  min-height: 40px;
}
/* ห้องที่ยังไม่อ่านต้องเด่นกว่าห้องอ่านแล้ว (เดิมน้ำหนักเท่ากันหมด) */
body.x10m #channel-list .chan-item.unread,
body.x10m #channel-list .chan-item.has-unread { font-weight: 700; }




/* ══════════════════════════════════════════════════════════════════════
   [เฟส 2] Chat Head ฟองลอยแบบ Messenger — ย้ายจาก demo-chat (2026-09-05)
   ที่มา: /opt/x10-chat-demo/public/mobile.css บรรทัด 1531-1831
   ──────────────────────────────────────────────────────────────────────
   ใช้กับ "DM บนมือถือ" เท่านั้น · ห้องปกติยังเด้งการ์ด #notif-wrap เหมือนเดิม
   สิ่งที่แก้ระหว่างย้าย:
   • scope `body.x10m` ครบทุกกฎ (ต้นฉบับไม่มีเลยสักกฎ)
     demo พึ่ง @media (min-width:861px) ซ่อนบนคอม ซึ่งผูกกับ "ความกว้างจอ" —
     ย่อหน้าต่างบนคอมให้แคบกว่า 861px แล้วฟองจะโผล่ทันทีทั้งที่ไม่ใช่มือถือ
     body.x10m ผูกกับ "เป็นมือถือจริง" (mobile.js ตรวจ UA+touch) → ใส่ทั้งสองชั้น
   ⚠️ .dmw-btn เป็นคลาสของเดิม (หน้าต่าง DM ลอยบนคอม) — กฎที่นี่มี
      .chead-sheet นำหน้าเสมอ จึงไม่ทับของเดิม
   ══════════════════════════════════════════════════════════════════════ */
/* ===== 📱 Chat Head — ฟองกลมแบบ Messenger (พี่ปอง 2026-09-05 · ตัวจำลอง) =====
   เฉพาะ DM บนมือถือ · ห้องปกติยังใช้การ์ด .notif-wrap เหมือนเดิม
   ⚠️ z-index ต้องสูงกว่าแถบล่าง/โมดัล แต่ต่ำกว่า lightbox ดูรูป */
body.x10m .chead-wrap {
  /* เรียงแนวนอนด้านบนแบบ Messenger (พี่ปอง 12:18) — เดิมเป็นแนวตั้งขอบขวา
     ลากย้ายได้อิสระ ตำแหน่งที่ผู้ใช้ลากถูกเขียนทับด้วย inline style */
  /* เรียงเป็นแถวแบบ Messenger จริง (วัดจากรูปพี่ปอง 14:11: ศูนย์กลางห่าง = ขนาดฟอง = ชิดกัน)
     แถวยาวเกินจอ = เลื่อนแนวนอนได้ ไม่ดันฟองหลุดขอบ */
  position: fixed; right: 10px; top: calc(env(safe-area-inset-top, 0px) + 52px); z-index: 646;
  display: none; flex-direction: row; align-items: center; gap: 2px;
  max-width: calc(100vw - 20px); overflow-x: auto; scrollbar-width: none;
}
body.x10m .chead-wrap.on { display: flex; }
/* กางแผ่นอยู่ = ฟอง "ยังโชว์" ด้านบนแบบในรูป Messenger (พี่ปอง 12:18)
   ดันไปกึ่งกลางแถวบน + ฟองที่กำลังเปิดอยู่เด่นกว่าเพื่อน */
body.x10m.chead-open .chead-wrap {
  /* กางแผ่นอยู่: ฟองนั่ง "คร่อมขอบบนของแผ่น" แบบ Messenger — ไม่ลอยแยกกลางที่ว่าง
     แผ่นเริ่มที่ 13dvh · ฟองสูง 52 → วางให้ก้นฟองต่ำกว่าขอบแผ่นเล็กน้อย = ดูเชื่อมกัน
     ⚠️ ต้องมี !important ทุกตัว เพราะ inline style จากการลากยังค้างอยู่ (ตั้งใจเก็บไว้) */
  left: auto !important; right: 14px !important; bottom: auto !important; transform: none;
  top: calc(13dvh - 34px) !important;
}
body.x10m.chead-open .chead { opacity: .55; }
body.x10m.chead-open .chead.act { opacity: 1; box-shadow: 0 3px 16px rgba(0, 0, 0, .5); }
body.x10m .chead {
  /* ขนาดเดิม 52px — พี่ปองสั่ง 12:27 "ไม่ต้องทำให้ใหญ่เท่าตามภาพ" */
  position: relative; width: 52px; height: 52px; padding: 0; border-radius: 50%;
  border: 2px solid var(--card, #fff); background: var(--card, #fff);
  box-shadow: 0 3px 14px rgba(0, 0, 0, .34); cursor: pointer;
  touch-action: none;                      /* ⚠️ ต้องมี ไม่งั้นลากแล้วหน้าจอเลื่อนตาม */
  display: flex; align-items: center; justify-content: center; overflow: visible;
}
body.x10m .chead img, body.x10m .chead .avatar { width: 46px; height: 46px; border-radius: 50%; }
body.x10m .chead.dragging { opacity: .82; transform: scale(1.06); }
/* เด้งเข้ามา "จากขอบขวา" (พี่ปองแจ้ง 15:03 — เดิมผุดขึ้นกลางที่ ดูเหมือนโผล่จากล่าง) */
body.x10m .chead.pulse { animation: cheadPop .34s cubic-bezier(.2, .9, .3, 1); }
@keyframes cheadPop {
  0%   { transform: translateX(64px); opacity: 0 }
  70%  { transform: translateX(-5px); opacity: 1 }
  100% { transform: translateX(0); opacity: 1 }
}
/* ป้ายนับ: วัดจากรูปพี่ปอง = ฟ้า rgb(12,121,226) อยู่ "มุมบนซ้าย" (ไม่ใช่แดงมุมขวา) */
body.x10m .chead-n {
  position: absolute; top: -2px; left: -2px; min-width: 22px; height: 22px; padding: 0 5px;
  border-radius: 11px; background: #0C79E2; color: #fff; font-size: 12px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid #000; box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
}
body.x10m .chead-dot {
  position: absolute; top: 0; left: 0; width: 14px; height: 14px; border-radius: 50%;
  background: #0C79E2; border: 2px solid #000;
}
/* เป้าปิด — โผล่ตอนลากเท่านั้น */
/* เป้าลบ — ต้องเห็นชัดว่า "ลากมาตรงนี้เพื่อลบ" (พี่ปองแจ้ง 15:20 ว่ามองไม่ออก)
   เดิมเป็นวงกลมดำจาง ๆ ไม่มีคำบอก · ตอนนี้มีวงกลม ✕ + ป้ายข้อความ + แสงนำสายตา */
body.x10m .chead-trash {
  /* ⚠️⚠️ z-index ต้องสูงกว่าแผ่นแชท (645) และฟอง (646)
     เดิม 641 = ตอนเปิดแชทอยู่ถังถูกแผ่นบังมิด ผู้ใช้ไม่รู้ว่าต้องลากไปไหน
     (พี่ปองแจ้ง 15:24 — ผมทดสอบแค่ตอนพับ เลยไม่เจอ) */
  position: fixed; left: 50%; bottom: 30px; transform: translateX(-50%); z-index: 649;
  width: 64px; height: 64px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(20, 20, 24, .82); color: #fff; font-size: 25px; line-height: 1;
  border: 2px dashed rgba(255, 255, 255, .55);
  box-shadow: 0 0 0 14px rgba(0, 0, 0, .14), 0 6px 24px rgba(0, 0, 0, .45);
  animation: chTrashIn .18s ease;
}
@keyframes chTrashIn {
  0%   { opacity: 0; transform: translateX(-50%) translateY(30px) scale(.6) }
  60%  { opacity: 1; transform: translateX(-50%) translateY(-4px) scale(1.06) }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1) }
}
/* เต้นเบา ๆ ตลอดเวลาที่ลากอยู่ = สะดุดตา รู้ว่าเป้านี้รออยู่ */
body.x10m .chead-trash { animation: chTrashIn .26s cubic-bezier(.2,.9,.3,1), chTrashBeat 1.5s ease-in-out .3s infinite; }
@keyframes chTrashBeat {
  0%, 100% { box-shadow: 0 0 0 14px rgba(0,0,0,.14), 0 6px 24px rgba(0,0,0,.45) }
  50%      { box-shadow: 0 0 0 20px rgba(0,0,0,.08), 0 6px 24px rgba(0,0,0,.45) }
}
/* ฟองที่กำลังลาก = เอียงนิดหน่อย ให้รู้ว่ากำลังถูกยกอยู่ */
body.x10m .chead.dragging { transform: scale(1.1) rotate(-4deg); transition: transform .12s ease; }
/* ป้ายบอกใต้เป้า */
body.x10m .chead-trash::after {
  content: attr(data-lb);
  position: absolute; bottom: -26px; left: 50%; transform: translateX(-50%);
  white-space: nowrap; font-size: 12px; font-weight: 600; color: #fff;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .9); font-family: inherit;
}
body.x10m .chead-trash.near {
  background: #EF4444; border-style: solid; border-color: #fff;
  animation: chTrashNear .3s ease forwards;
}
@keyframes chTrashNear {
  0%   { transform: translateX(-50%) scale(1) }
  55%  { transform: translateX(-50%) scale(1.34) }
  100% { transform: translateX(-50%) scale(1.25);
         box-shadow: 0 0 0 20px rgba(239,68,68,.24), 0 8px 32px rgba(239,68,68,.55) }
}
/* ฟองหดลงตอนจ่ออยู่เหนือเป้า = สื่อว่ากำลังจะถูกดูดเข้าไป */
body.x10m .chead-trash.near ~ * .chead.dragging,
body.x10m .chead.dragging.will-drop { transform: scale(.78) rotate(0deg); opacity: .8; }
/* แผ่นแชทเล็กที่กางจากฟอง */
/* ===== ป๊อปอัพแบบ Messenger จริง (พี่ปองส่งรูปมา 12:18) =====
   ต่างจากรอบก่อน: แผ่นชนขอบซ้าย-ขวา-ล่าง โค้งเฉพาะมุมบน · ด้านบนโล่งให้เห็นแถวฟอง
   ฟองเรียง "แนวนอน" ด้านบน ไม่ใช่แนวตั้งขอบขวา */
body.x10m .chead-back {
  position: fixed; inset: 0; z-index: 644; background: rgba(0, 0, 0, .55);
  opacity: 0; transition: opacity .18s ease;
}
body.x10m .chead-back.in { opacity: 1; }
body.x10m .chead-sheet {
  position: fixed; z-index: 645;
  left: 0; right: 0; bottom: 0;
  /* วัดจากรูปที่พี่ปองส่ง (591x1280): ขอบบนแผ่นอยู่ที่ y=165 = 12.9% ของจอ
     → ใช้ 13dvh เพื่อให้สัดส่วนตรงทุกขนาดจอ ไม่ใช่ px ตายตัว */
  top: 13dvh;
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--card, #fff); border: none;
  border-radius: 12px 12px 0 0; box-shadow: none;
  transform: translateY(26px); opacity: 0;
  transition: transform .22s cubic-bezier(.2, .9, .3, 1), opacity .18s ease;
}
body.x10m .chead-sheet.in { transform: none; opacity: 1; }
body.x10m .chead-sheet .chs-body { min-height: 0; }
/* หัวแบบในรูป: รูปโปรไฟล์ + ชื่อ + ⓘ — ไม่ใช่แถบสีน้ำเงิน */
/* หัวในรูป = พื้นเดียวกับเนื้อแชท ไม่มีแถบสีคั่น · รูปโปรไฟล์ + ชื่อตัวหนา + ⓘ ขวาสุด */
body.x10m .chead-sheet .chs-head {
  background: var(--card, #fff); color: var(--text, #0f172a);
  border-bottom: none; border-radius: 12px 12px 0 0; padding: 13px 14px; gap: 12px;
}
body.x10m .chead-sheet .chs-body { background: var(--card, #fff); padding-top: 2px; }
body.x10m .chs-av { flex: 0 0 auto; display: flex; }
body.x10m .chs-av img, body.x10m .chs-av .avatar { width: 34px; height: 34px; border-radius: 50%; }
body.x10m .chead-sheet .chs-nm { font-size: 15px; }
body.x10m .chead-sheet .dmw-btn { color: var(--blue, #0F4C81); font-size: 17px; opacity: .9; }
/* จอเตี้ย (คีย์บอร์ดเด้ง) — ดันแผ่นขึ้น ให้พื้นที่อ่านมากที่สุด */
@media (max-height: 620px) { .chead-sheet { top: calc(env(safe-area-inset-top, 0px) + 76px); } }
body.x10m .chs-head { display: flex; align-items: center; gap: 7px; padding: 9px 11px;
  background: var(--blue, #0F4C81); color: var(--on-brand, #fff); }
body.x10m .chs-nm { flex: 1; min-width: 0; font-weight: 700; font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.x10m .chs-body { flex: 1; min-height: 140px; overflow-y: auto; padding: 10px;
  display: flex; flex-direction: column; gap: 8px; background: var(--bg, #F4F6F9); }
body.x10m .chs-foot { display: flex; align-items: flex-end; gap: 7px; padding: 8px;
  border-top: 1px solid var(--border, #E2E8F0);
  padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)); }
/* คอมไม่ใช้ฟอง — ใช้หน้าต่าง DM ลอย + การ์ดแจ้งเตือนเดิม */
@media (min-width: 861px) {
  .chead-wrap, .chead-sheet, .chead-trash, .chead-back, .chead-tip { display: none !important; }
}

/* แผงเลือกแชท ✎ ในหัวป๊อปอัพ (พี่ปอง 12:27) — ดูแชทอื่น/แชทหาคนใหม่ ไม่ต้องออกจากป๊อปอัพ */
/* หน้ารายชื่อ — กินพื้นที่ทั้งแผ่นใต้หัว "แทนที่" เนื้อแชท (พี่ปองสั่ง 13:22)
   เดิมเป็นการ์ดลอยทับแชทที่คุยอยู่ = อ่านของเดิมไม่ได้ ดูสับสน */
body.x10m .chs-pick {
  position: absolute; top: 56px; left: 0; right: 0; bottom: 0; z-index: 3;
  background: var(--card, #fff); border: none; border-radius: 0; box-shadow: none;
  display: flex; flex-direction: column; overflow: hidden;
}
/* อยู่โหมดรายชื่อ = ซ่อนเนื้อแชท+ช่องพิมพ์ (ไม่ใช่ทับไว้เฉย ๆ) */
body.x10m.chs-picking .chead-sheet .chs-body,
body.x10m.chs-picking .chead-sheet .chs-foot { visibility: hidden; }
/* โหมดรายชื่อ: ปุ่มเปลี่ยนเป็นลูกศรกลับ (ชัดกว่าพลิกไอคอนเดิม) */
/* อยู่หน้ารายชื่อ: ปุ่ม ✕ (ตัวสุดท้ายในหัว) กลายเป็นลูกศรกลับไปแชท
   ⚠️ ปุ่ม ✎ ย้ายออกจากหัวไปอยู่ในแถวฟองแล้ว (16:26) จึงต้องมีทางกลับที่นี่ */
body.x10m.chs-picking .chs-head .dmw-btn:last-child { font-size: 0; }
body.x10m.chs-picking .chs-head .dmw-btn:last-child::after { content: '←'; font-size: 19px; }
body.x10m .chs-q {
  border: none; border-bottom: 1px solid var(--border, #E2E8F0); background: none;
  color: var(--text, #0f172a); padding: 11px 13px; font-size: 14px; font-family: inherit; outline: none;
}
body.x10m .chs-list { overflow-y: auto; padding: 5px; }
body.x10m .chs-row {
  display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px 9px;
  border: none; background: none; color: var(--text, #0f172a); cursor: pointer;
  border-radius: 9px; font-family: inherit; font-size: 13.5px; text-align: left;
}
body.x10m .chs-row:hover, body.x10m .chs-row:active { background: var(--bg, #F4F6F9); }
body.x10m .chs-row img, body.x10m .chs-row .avatar { width: 32px; height: 32px; border-radius: 50%; flex: 0 0 32px; }
body.x10m .chs-rnm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ⚠️ .chs-pick เป็น absolute — พ่อแม่ที่ต้อง relative คือ .chead-sheet เอง
   (แผงอยู่ "นอก" .chs-head ในโครง HTML จึงตั้ง relative ที่ head ไม่ได้ผล)
   .chead-sheet เป็น position:fixed อยู่แล้ว = ใช้เป็น anchor ได้ ไม่ต้องแก้อะไร */

/* ป้ายข้อความข้างฟอง แบบ Messenger (พี่ปองสั่ง 12:36 "ต้องแสดงข้อความที่พิมพ์มาด้วย")
   ยาวเกิน = ตัด ... (2 บรรทัด) · รูป/ไฟล์ = msgPreview คืน "📷 ส่งรูปมา" ให้แล้ว */
body.x10m .chead-tip {
  position: fixed; z-index: 647; max-width: 58vw;
  padding: 8px 12px; border-radius: 14px;
  background: var(--card, #fff); color: var(--text, #0f172a);
  border: 1px solid var(--border, #E2E8F0); box-shadow: 0 4px 18px rgba(0, 0, 0, .32);
  display: flex; flex-direction: column; gap: 1px; cursor: pointer;
  /* ⚠️ transform ถูก JS ตั้งเป็น translateY(-50%) เพื่อจัดกลางให้ตรงระนาบฟอง
     จึงห้ามใช้ transform ทำแอนิเมชันที่นี่ (จะทับกัน) — ใช้ opacity อย่างเดียว */
  opacity: 0; transition: opacity .18s ease;
}
body.x10m .chead-tip.in { opacity: 1; }
body.x10m .chtip-nm { font-size: 11.5px; font-weight: 700; opacity: .72; }
/* ชื่อห้องต่อท้ายชื่อคนแท็ก (เฉพาะฟองกลุ่ม) — จางลงอีกชั้นให้ชื่อคนเด่นกว่า */
body.x10m .chtip-rm { font-weight: 600; opacity: .8; }
body.x10m .chtip-tx {
  font-size: 13px; line-height: 1.32;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; word-break: break-word;
}
/* ฟองห้องอื่นที่ "ซ้อนอยู่ข้างหลัง" — เห็นแค่ขอบเหลื่อมออกมา แบบ Messenger
   (พี่ปอง 13:41 "ต้องขึ้นอันเดียว ต่อให้เปิดแชทหลายคน") */
body.x10m .chead-bg {
  position: absolute; top: 0; right: 0; width: 52px; height: 52px; border-radius: 50%;
  overflow: hidden; border: 2px solid var(--card, #fff); pointer-events: none;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .3);
}
body.x10m .chead-bg img, body.x10m .chead-bg .avatar { width: 100%; height: 100%; border-radius: 50%; }
body.x10m .chead-bg1 { transform: translate(-7px, 4px) scale(.9); z-index: 1; opacity: .9; }
body.x10m .chead-bg2 { transform: translate(-13px, 8px) scale(.82); z-index: 0; opacity: .75; }
body.x10m .chead { z-index: 2; flex: 0 0 auto; }
/* "ไม่พบชื่อนี้" ตอนค้นหาในแผงเลือกแชท */
body.x10m .chs-none { padding: 18px; text-align: center; color: var(--muted, #64748b); font-size: 13px; }

/* ปุ่ม "แชทคนอื่น" ติดมุมล่างซ้ายของฟอง (พี่ปอง 13:57 — ปุ่มเดิมหายตอนเปลี่ยนเป็นฟองอันเดียว)
   ⚠️ ต้องอยู่ในกรอบ .chead-wrap ขนาด 52x52 จึงวางเหลื่อมออกมาทางซ้ายล่าง */






/* ===== โหมดพับ: ยุบเหลือใบเดียวชิดขอบ เหลื่อมออกนอกจอครึ่งใบ =====
   วัดจากรูปพี่ปอง (591px กว้าง ฟองจบที่ x=588 = เลยขอบ) — Messenger ซ่อนตัวเองไม่ให้กินที่
   ⚠️ ใช้ max-width + overflow ไม่ใช่ display:none กับใบอื่น
      เพราะการลาก/คำนวณตำแหน่งป้ายวัดจากกรอบ wrap ถ้าขนาดกระโดดจะเพี้ยน */
/* พับ = เหลือฟองใบเดียว (ตัวแรกในแถว ซึ่ง JS สลับให้เป็น "คนล่าสุด" ตอนพับ)
   ⚠️ ใช้ .chead ~ .chead ไม่ใช่ :last-of-type — เคยพลาดตอนมีปุ่มปนอยู่ในแถว
      ทำให้ฟองทุกใบเข้าเงื่อนไขแล้วหายหมด (เหลือ 0 ใบ กว้าง 0px) */
body.x10m .chead-wrap.folded { overflow: visible; }
body.x10m .chead-wrap.folded .chead ~ .chead { display: none; }

body.x10m .chead-wrap.folded .chead { opacity: .95; }
/* เหลื่อมออกนอกขอบจอเล็กน้อยตอนพับ (เฉพาะเมื่อยังไม่ถูกลากไปที่อื่น) */
body.x10m .chead-wrap.folded:not([style*="left"]) { right: -12px; }

/* ═══ แอนิเมชัน Chat Head ครบชุด (พี่ปองสั่ง 15:50) ═══════════════════ */

/* 1) มีคนทักมา — ฟองสั่นเรียกความสนใจ (ต่อจากจังหวะเลื่อนเข้าจากขวา) */
body.x10m .chead.ring { animation: chRing .62s cubic-bezier(.36,.07,.19,.97) .3s 1; }
@keyframes chRing {
  0%,100% { transform: rotate(0) }
  15% { transform: rotate(-13deg) } 30% { transform: rotate(11deg) }
  45% { transform: rotate(-8deg) }  60% { transform: rotate(6deg) }
  75% { transform: rotate(-3deg) }
}
/* ป้ายนับเด้งตามตอนมีข้อความใหม่ */
body.x10m .chead-n { animation: chBadge .34s cubic-bezier(.2,.9,.3,1); }
@keyframes chBadge { 0% { transform: scale(0) } 65% { transform: scale(1.3) } 100% { transform: scale(1) } }

/* 2) เปิดแชท — ป๊อปอัพคลี่ขึ้นมา "จากฟอง" ไม่ใช่โผล่เฉย ๆ */
body.x10m .chead-sheet { transform-origin: top right; }
body.x10m .chead-sheet.in { animation: chSheetIn .3s cubic-bezier(.2,.9,.3,1); }
@keyframes chSheetIn {
  0%   { opacity: 0; transform: translateY(-14px) scale(.9) }
  60%  { opacity: 1; transform: translateY(3px) scale(1.01) }
  100% { opacity: 1; transform: translateY(0) scale(1) }
}
/* ฟองที่กำลังเปิดแชทอยู่ = มีวงแหวนรอบ บอกว่าคุยกับใครอยู่ */
body.x10m .chead.act { box-shadow: 0 0 0 3px var(--blue, #0F4C81), 0 3px 14px rgba(0,0,0,.4); }

/* 3) พับเก็บ — ยุบกลับเข้าหาฟอง */
body.x10m .chead-sheet.closing { animation: chSheetOut .2s ease forwards; }
@keyframes chSheetOut {
  0%   { opacity: 1; transform: translateY(0) scale(1) }
  100% { opacity: 0; transform: translateY(-10px) scale(.92) }
}
/* ฟองยุบเข้าหากันตอนพับแถว */
body.x10m .chead-wrap.folded .chead { animation: chFoldIn .26s cubic-bezier(.2,.9,.3,1); }
@keyframes chFoldIn { 0% { transform: translateX(22px) scale(.86) } 100% { transform: none } }

/* 4) แตะฟอง — ยุบรับสัมผัสทันที (รู้ว่ากดโดน) */
body.x10m .chead:active { transform: scale(.9); transition: transform .1s ease; }
/* 5) ป้ายข้อความเลื่อนเข้ามาพร้อมฟอง */
body.x10m .chead-tip.in { animation: chTipIn .26s cubic-bezier(.2,.9,.3,1); }
@keyframes chTipIn { 0% { opacity: 0; transform: translateY(-50%) translateX(16px) } 100% { opacity: 1 } }

/* ปุ่ม "แชทคนอื่น" ในแถวฟอง (พี่ปองสั่ง 16:26 — ย้ายจากหัวป๊อปอัพมาข้างฟอง แบบ Messenger) */
body.x10m .chead-plus {
  position: static; flex: 0 0 auto; margin-left: 4px;
  width: 44px; height: 44px; padding: 0; border-radius: 50%;
  background: var(--card, #fff); color: var(--blue, #0F4C81);
  border: 2px solid var(--border, #E2E8F0); cursor: pointer;
  font-family: inherit; font-size: 19px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 12px rgba(0, 0, 0, .3);
}
body.x10m .chead-plus:active { transform: scale(.88); }
/* มีจุดเล็ก + มุมขวาล่าง สื่อว่า "เพิ่มคนคุย" ไม่ใช่แค่ดูโปรไฟล์ */
body.x10m .chead-plus { position: relative; }
body.x10m .chead-plus::after {
  content: '+'; position: absolute; right: -1px; bottom: -1px;
  width: 17px; height: 17px; border-radius: 50%;
  background: var(--blue, #0F4C81); color: #fff;
  font-size: 12px; font-weight: 700; line-height: 15px; text-align: center;
  border: 2px solid var(--card, #fff);
}
/* พับอยู่ = ซ่อน (เห็นแค่ฟองใบเดียว ไม่ต้องมีปุ่มลอย) */
body.x10m .chead-wrap.folded .chead-plus { display: none; }


/* ══════════════════════════════════════════════════════════════════════
   ปุ่ม DM 💬 ข้างช่องค้นหา — ซ่อนเฉพาะมือถือ (2026-09-05)
   ──────────────────────────────────────────────────────────────────────
   Boss สั่งเพิ่มปุ่มนี้ 2026-09-04 ตอนที่มือถือยัง "ไม่มีแท็บ DM"
   ตอนนี้แท็บล่างมี DM เป็นแท็บที่ 2 แล้ว = ปุ่มนี้เป็นทางที่ 3 ไปที่เดียวกัน
   และมันย่อช่องค้นหาจาก 344px เหลือ 284px (วัดจริง) ซึ่ง demo แก้ไปแล้ว
   ⚠️ ซ่อนเท่านั้น ไม่ลบ element — ฝั่งคอมยังใช้เหมือนเดิม
      และ mobile.js:476 ยังอ้าง #side-dm-badge อยู่ (มี if (sb) กันไว้ แต่ไม่ต้องเสี่ยง)
   ⚠️ ป้ายเลข DM ที่ยังไม่อ่าน ไม่หายไปไหน — อยู่บนแท็บล่างผ่าน setBadge('dm') */
body.x10m .side-dm-btn { display: none; }
body.x10m .side-search-row { display: block; }
body.x10m .side-search-row .side-search { width: 100%; }


/* ══════════════════════════════════════════════════════════════════════
   ตอนเปิดแอป: กัน "แถบข้างเก่าเด้งซ้อนแล้วเลื่อนหาย" (Boss แจ้ง 2026-09-05)
   ──────────────────────────────────────────────────────────────────────
   อาการที่วัดได้ (จอ 360, มี x10chat_last_room ค้าง = ผู้ใช้จริง):
     213ms  body ยังไม่มีคลาส
     234ms  body = "x10m page-chat-list"  → sidebar เป็นหน้าเต็มจอ (transform:none)
     837ms  body = "x10m in-room"         → คลาสหลุด sidebar กลับเป็น drawer
     837→1384ms  sidebar ค่อย ๆ เลื่อนจาก left:0 → left:-310  ⬅ ครึ่งวินาทีที่เห็นซ้อน
   ต้นเหตุ: `.sidebar` มี `transition: transform .3s` (Boss สั่งไว้ 2026-09-03 ให้เห็น
   แอนิเมชันตอน "กดเปิดเอง") แต่ตอน **บูต** การเปลี่ยนจากหน้าเต็มจอ→drawer
   ไม่ใช่การกดของผู้ใช้ ไม่ควรมีแอนิเมชัน — มันเลยกลายเป็นแถบเก่าไถออกไปให้เห็น

   แก้: ระหว่างบูต (body.x10m-boot) ปิด transition ของ sidebar+backdrop
        mobile.js ถอดคลาสนี้ออกหลังแอปนิ่ง → กดเปิดเองยังมีแอนิเมชันเหมือนเดิม
   ⚠️ ห้ามแก้ที่ `.sidebar{transition}` ตรง ๆ — จะทำให้ท่ากดเปิดเองหมดแอนิเมชันไปด้วย
   ══════════════════════════════════════════════════════════════════════ */
body.x10m.x10m-boot .sidebar,
body.x10m.x10m-boot #side-backdrop {
  transition: none !important;
}
/* ⚠️ ช่วง ~200ms แรก body ยังไม่มีคลาส .x10m (mobile.js ยังไม่ทัน applyShellClasses)
   แต่ sidebar ถูกวาดไปแล้ว → ต้องมีตัวจับที่ <html> คู่กัน ไม่งั้นยังเห็นไถอยู่ดี
   จำกัดด้วย @media ให้กระทบเฉพาะจอมือถือ (คอมไม่มี transform อยู่แล้ว แต่กันไว้) */
@media (max-width: 860px) {
  html.x10m-boot-html .sidebar,
  html.x10m-boot-html #side-backdrop {
    transition: none !important;
  }
}


/* ══════════════════════════════════════════════════════════════════════
   ป้ายล็อก/เปิดห้อง — ขยายเป้าแตะเฉพาะตอน "กดได้จริง" (2026-09-05)
   ──────────────────────────────────────────────────────────────────────
   ป้ายนี้ปกติเป็นแค่สถานะ (cursor:default ไม่มี onclick) วัดได้ 24x14 ซึ่งเล็ก
   แต่ไม่เป็นปัญหาเพราะกดไม่ได้อยู่แล้ว
   ⚠️ กรณีเจ้าของห้อง public จะมีคลาส .can-toggle = กดสลับล็อกได้จริง
      บนมือถือ @media(max-width:560px) ซ่อนข้อความเหลือแต่ไอคอน padding 3px 6px
      → เป้าแตะเล็กกว่า 24x14 อีก พลาดง่าย
   ขยายเฉพาะตัวที่กดได้ ไม่แตะป้ายสถานะเฉย ๆ (จะได้ไม่ไปดันชื่อห้องโดยไม่จำเป็น) */
body.x10m .chat-head .lock-badge.can-toggle {
  min-height: 30px; min-width: 34px;
  padding: 4px 9px;
  display: inline-flex; align-items: center; justify-content: center;
}


/* ══════════════════════════════════════════════════════════════════════
   ปุ่มดาว ★ ปักหมุดห้อง — ขยายเป้าแตะบนมือถือ (2026-09-05)
   ──────────────────────────────────────────────────────────────────────
   วัดได้ 17x20px (style.css:3219 `padding: 0 2px`) แต่ `cursor:pointer` + มี onclick
   = กดได้จริง · มาตรฐานเป้าแตะควร >=32px · นิ้วโป้งพลาดง่ายมาก
   แถวห้องสูง 40px อยู่แล้ว → ขยายได้โดยไม่ดันความสูงแถว
   ⚠️ ใช้ padding แทน min-width เพื่อไม่ให้ดันชื่อห้องสั้นลง
   ⚠️ คอมไม่แตะ — มีเมาส์ชี้ได้แม่นกว่า และแถวคอมแคบกว่า */
body.x10m #channel-list .chan-fav {
  min-width: 34px; min-height: 34px;
  padding: 0 6px; margin: -7px 0;
  display: inline-flex; align-items: center; justify-content: center;
}

/* ── แถบเครื่องมือในแผ่น Chat Head (แนบรูป/สติกเกอร์/อีโมจิ/อัดเสียง) ────────────
   เดิมมีแค่ช่องพิมพ์+ปุ่มส่ง — พี่ปองแจ้ง 07/09 ว่า "มีแต่ส่งข้อความ"
   ปุ่มขนาด 34px = แตะติดนิ้วบนมือถือ (ต่ำกว่านี้พลาดบ่อย) */
body.x10m .chs-tools { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }
body.x10m .chs-tb {
  border: none; background: none; cursor: pointer; font-size: 17px; line-height: 1;
  width: 34px; height: 34px; border-radius: 8px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  opacity: .75; transition: opacity .15s, background .15s;
}
body.x10m .chs-tb:active { background: var(--hover, rgba(0,0,0,.06)); opacity: 1; }
/* กำลังอัดเสียง = ต้องเห็นชัดว่ายังอัดอยู่ (ปุ่มเดียวกับของช่องพิมพ์ห้อง ใช้คลาสเดิม) */
body.x10m .chs-tb.recording { opacity: 1; background: var(--danger, #E5484D); border-radius: 50%; }
/* ช่องพิมพ์ต้องหดได้ ไม่งั้นแถบปุ่มดันปุ่มส่งตกขอบจอ 360px */
body.x10m .chs-foot .dmw-in { flex: 1 1 auto; min-width: 0; }
/* คิวไฟล์ที่แนบรอส่ง — อยู่เหนือแถบพิมพ์ ใช้สไตล์ .dmw-queue/.dmq-* ร่วมกับ DM ลอย */
body.x10m .chead-sheet .dmw-queue { border-top: 1px solid var(--border, #E2E8F0); padding: 6px 8px; }
/* แผงอีโมจิของแผ่น — กางขึ้นเหนือแถบพิมพ์ ไม่ล้นออกนอกการ์ด */
body.x10m .chs-emoji-pop {
  position: absolute; left: 6px; right: 6px; bottom: calc(52px + env(safe-area-inset-bottom, 0px));
  z-index: 5; max-height: 46vh; overflow: hidden;
  display: flex; flex-direction: column;
  background: var(--card, #fff); border: 1px solid var(--border, #E2E8F0);
  border-radius: 12px; box-shadow: 0 8px 28px rgba(0,0,0,.18);
}
body.x10m .chs-emoji-pop.hidden { display: none; }
body.x10m .chs-emoji-pop .emoji-grid { overflow-y: auto; }
/* อยู่หน้ารายชื่อ = ซ่อนแผงอีโมจิ/คิวไฟล์ด้วย (เหมือน chs-body/chs-foot) */
body.x10m.chs-picking .chead-sheet .chs-emoji-pop,
body.x10m.chs-picking .chead-sheet .dmw-queue { visibility: hidden; }

/* ══════════════════════════════════════════════════════════════════════
   โหมด "แผ่นเดียว" — เปิดด้วย ?chead=<cid> จากฟองลอย native (นอกแอป)
   หน้าต่างลอยเล็ก ๆ ต้องเห็น "แผ่นแชท" เต็มกรอบ ไม่ใช่ทั้งแอปย่อ ๆ
   (Boss 2026-09-07: ในแอป/นอกแอปคนละตัว แต่ตอนแสดงต้องเหมือนกันทุกอย่าง)
   ⚠️ ต้อง !important ทับกฎ .chead-sheet เดิมที่ตรึง top/height ไว้
   ⚠️ ซ่อนตัวฟองเอง — ในหน้าต่างลอยมีฟอง native อยู่ข้างนอกแล้ว ไม่ต้องมีซ้อน
   ══════════════════════════════════════════════════════════════════════ */
body.chead-solo .app,
body.chead-solo .sidebar,
body.chead-solo #x10m-tabbar,
body.chead-solo .chead-wrap,
body.chead-solo .chead-back,
body.chead-solo #boot-splash { display: none !important; }
body.chead-solo { background: var(--card, #fff); }
/* ⚠️⚠️ กฎฐานของ .chead-sheet ทั้งหมด scope ด้วย `body.x10m` — ถ้าหน้าต่างลอย
   ไม่ได้คลาสนั้น แผ่นจะ "ไม่มี layout เลย" กลายเป็นแอปย่อ ๆ ยัดในกรอบ
   (Boss ส่งรูป 15:43: ในแผ่นมีรายชื่อห้อง CAMERA/FE/HR + แถบล่าง 5 ปุ่ม = ทั้งแอป)
   → ประกาศ layout ที่จำเป็นซ้ำที่นี่ "โดยไม่พึ่ง x10m" กันพลาดทุกกรณี */
body.chead-solo .chead-sheet {
  display: flex !important;
  flex-direction: column !important;
  z-index: 2147483000 !important;
  background: var(--card, #fff) !important;
  box-shadow: none !important;
}
body.chead-solo .chead-sheet.hidden { display: none !important; }


/* 🔴🔴 2026-09-08 Boss: "กดอิโมจิ ตอบกลับ หรือจุดสามจุด กดแล้วไม่มีอะไรขึ้น
   ในแชทเฮดนอกแอพ" — บั๊กที่ 2 (คนละตัวกับ findMsgAnywhere)
   แผ่นโหมด solo ถูกดันเป็น `z-index: 2147483000` (เกือบสูงสุด) แต่ป๊อปอัพ
   ทั้งหมดต่อไว้ที่ <body> ด้วย z-index ต่ำกว่ามาก:
        .msg-menu = 500 · .react-pick = 320 · .emoji-pop/.modal ก็ต่ำกว่า
   → เมนู/แผงเปิด "อยู่ใต้แผ่น" มองไม่เห็นและ **แตะไม่ได้เลย**
     (Playwright ฟ้องตรง ๆ ว่า .chs-body intercepts pointer events)
   ⚠️ ห้ามลด z-index ของแผ่นลง — แผ่นต้องทับทุกอย่างในหน้าต่างลอยของฟอง
      แก้ที่ตัวป๊อปอัพให้สูงกว่าแผ่นแทน (เฉพาะโหมด solo เท่านั้น
      ไม่ไปยุ่งกับลำดับชั้นในแอปปกติ) */
body.chead-solo .msg-menu,
body.chead-solo .react-pick,
body.chead-solo .emoji-pop,
body.chead-solo .modal-backdrop,
body.chead-solo .modal,
body.chead-solo .toast,
body.chead-solo .lightbox,
/* จอโทรต้องอยู่เหนือแผ่นด้วย — โหมด solo แผ่นไม่ถูกปิดตอนโทรแล้ว
   (ดู cheadCall) ถ้าไม่ยกขึ้น ปุ่มวางสายจะถูกแผ่นบัง "กดวางสายไม่ได้" */
body.chead-solo .call-screen,
/* 🔴🔴 2026-09-08 Boss: "การโทรในแชทแฮดยังบัค" — โทร **วิดีโอ** จากแผ่นนอกแอป
   ผู้โทรเห็นแต่แผ่นแชท ไม่เห็นจอวิดีโอ และ **ไม่มีปุ่มวางสายให้กดเลย** = จอค้าง
   ต้นเหตุ: สายวิดีโอไม่ได้ใช้ `.call-screen` แต่ไปใช้ `#meet-stage`
   ซึ่งอยู่ที่ `z-index: 900` (style.css) — ต่ำกว่าแผ่น solo (2147483000) มหาศาล
   → จอวิดีโอเปิดจริง (display:flex เต็มจอ) แต่ **อยู่ใต้แผ่นแชท**
   กฎเดิมยกให้เฉพาะ `.call-screen` (จอโทรเสียง) จึงตกสายวิดีโอไปทั้งเส้น
   ยืนยันด้วยเทสจริง 2 เครื่องโทรหากัน: ก่อนแก้ 4 ข้อไม่ผ่าน
     (กลางจอได้ `dmw-empty`/`chs-body` = แผ่นแชท · ปุ่มวางสาย `mb-leave`
      วัดได้ 62x79 แต่ `covered: chs-foot` = ช่องพิมพ์ทับ กดไม่โดน)
   ⚠️ ห้ามลด z-index ของแผ่นลงแก้ — แผ่นต้องทับทุกอย่างในหน้าต่างลอยของฟอง
   ⚠️ ลูกใน #meet-stage ไม่ต้องยกตาม (อยู่ใน stacking context ของแม่แล้ว — เทสยืนยัน) */
body.chead-solo .meet-stage,
body.chead-solo #meet-stage { z-index: 2147483600 !important; }
/* ⚠️ .call-screen.hidden ต้องชนะกฎ z-index ข้างบนเรื่องการซ่อน — display:none
   ประกาศไว้ที่ style.css แล้ว แต่ย้ำที่นี่กัน specificity ของ body.chead-solo */
body.chead-solo .call-screen.hidden { display: none !important; }
body.chead-solo .chs-body { flex: 1 !important; min-height: 0 !important; overflow-y: auto !important; }
body.chead-solo .chs-head { flex: 0 0 auto !important; }
body.chead-solo .chs-foot { flex: 0 0 auto !important; }
body.chead-solo .chead-sheet {
  position: fixed !important;
  inset: 0 !important;
  top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important;
  width: 100% !important; height: 100% !important; max-height: none !important;
  border-radius: 0 !important;
  transform: none !important; opacity: 1 !important;
}
/* ปุ่ม ⓘ (เปิดห้องเต็มจอ) ไม่มีความหมายในหน้าต่างลอย — ฝั่ง native มีปุ่ม ⤢ ให้แล้ว */
body.chead-solo .chs-head .dmw-btn[onclick^="cheadExpand"] { display: none; }

/* ═══════════════════════════════════════════════════════════════════
   🆕 2026-09-09 โหมด "การ์ดลอย" แบบ Messenger (?chead=<id>&card=1)
   Boss: "เอารูปแบบแอพย่อแบบ chathead"
   ฝั่ง Android วาดการ์ดมุมมนสูง 76% ของจอ + ฉากหลังหรี่ให้แล้ว
   ฝั่งนี้แค่ทำให้เนื้อในกลืนกับการ์ด: พื้นโปร่ง (ไม่งั้นทับมุมมน)
   + หัวแผ่นมีเส้นคั่นบาง ๆ ให้ดูเป็นหน้าต่างจริง
   ⚠️⚠️ ต้องอยู่ **ใต้** `body.chead-solo .chead-sheet` ที่บังคับ `border-radius:0
      !important` + inset:0 — specificity เท่ากัน ผู้มาทีหลังชนะ วางบนแล้วมุมไม่มน
      (เทสจับได้: radius=0px ทั้งที่ตั้ง 18px — อย่าวางที่อื่น)
   ⚠️ scope ด้วย body.chead-card เท่านั้น ห้ามกระทบโหมด solo เดิม
   ═══════════════════════════════════════════════════════════════════ */
body.chead-card { background: transparent !important; }
body.chead-card .chead-sheet {
  /* ฝั่ง Android วาด "หน้าต่างแอปย่อ" มุมมนทุกด้านให้แล้ว (สูง 88% เว้นขอบข้าง 4%)
     แผ่นเต็มกรอบหน้าต่างนั้น — มนทุกมุมให้ตรงกับกรอบ ไม่ใช่แค่มุมบน */
  border-radius: 18px !important;
  overflow: hidden !important;
}
/* ⚠️ ไม่ใส่ grabber — นั่นเป็นภาษาของ bottom sheet (ลากขึ้นลง)
   ตัวนี้เป็น "หน้าต่างแอปย่อ" ลอยกลางจอ ปิดด้วยปุ่ม ✕ / Back / แตะนอกหน้าต่าง */

/* ═══════════════════════════════════════════════════════════════════
   ดูรูปเต็มจอจากในแผ่น Chat Head (พี่ปองแจ้ง 2026-09-07:
     "ในแชทเฮดกดรูปที่ส่งมาแล้วดูรูปเต็มๆไม่ได้")
   ต้นเหตุ: dmMsgHTML() มี onclick="openImage(this)" อยู่แล้วและ "ทำงานปกติ"
     แต่ .lightbox อยู่ z-index:300 (style.css) ต่ำกว่าแผ่นแชท 645 / ฟอง 646 / ถัง 649
     → รูปเปิดจริงแต่ถูกแผ่นบังมิด ผู้ใช้เลยเห็นเป็น "กดแล้วไม่มีอะไรเกิด"
   หมายเหตุ: คอมเมนต์เดิมบรรทัด ~1649 เขียนว่า "ต่ำกว่า lightbox" ไว้ตั้งแต่แรก
     แต่ไม่เคยมีกฎยก lightbox ขึ้นจริง — เพิ่มตรงนี้ให้ตรงกับที่ตั้งใจไว้
   ⚠️ ต้องสูงกว่า 649 (ถังลบ) ไม่ใช่แค่ 646 · แถบเครื่องมือวาด/ซูมอยู่ในตัว
      .lightbox จึงลอยตามขึ้นมาเอง ไม่ต้องยกแยก
   ═══════════════════════════════════════════════════════════════════ */
body.x10m .lightbox { z-index: 1200; }
/* ฟอง/แผ่น/ถัง ต้องหลบตอนดูรูป — ยก z ทางเดียวไม่พอถ้าเบราว์เซอร์สร้าง
   stacking context ใหม่ (transform บนแผ่น) แผ่นจะยังคร่อมรูปได้ */
body.x10m.lb-on .chead-wrap,
body.x10m.lb-on .chead-sheet,
body.x10m.lb-on .chead-back,
body.x10m.lb-on .chead-trash { z-index: 1 !important; }

/* รูปเต็มจอ "ใหญ่ไป" (พี่ปองแจ้ง 2026-09-07: "เล็กลงหน่อย")
   เดิม 92vw × 88vh = เกือบชนขอบจอทุกด้าน ไม่มีที่หายใจ + ชนแถบเครื่องมือล่าง
   ลดเหลือ 82vw × 70vh — เห็นทั้งใบสบายตา มีขอบดำรอบรูปให้รู้ว่าอยู่ในโหมดดูรูป
   ⚠️ ห้ามแตะ .lb-canvas — มันอิง 100% ของ .lb-stage อยู่แล้ว ลายเส้นวาดทับจะย่อตามเอง
   ⚠️ ยังซูมด้วยจีบนิ้ว/ปุ่ม + ได้ตามปกติ (transform อยู่ที่ .lb-stage คนละชั้นกับ max-width) */
body.x10m .lightbox img { max-width: 82vw; max-height: 70vh; }

/* ═══════════════════════════════════════════════════════════════════════
   อยู่หน้า DM = ซ่อนแชทเฮดทั้งชุด (Boss 2026-09-08 17:26
   "เวลากลับไปหน้า dm แชทก็ต้องหายไปด้วย เพราะเรากลับไปหน้าของมันอ่ะ")

   เหตุผล: หน้า DM คือรายชื่อแชทเต็มจอของมันเอง ฟองลอยทับซ้อนบนหน้านั้น
   = ของซ้ำกันสองชุดบนจอเดียว · ออกจากหน้า DM แล้วฟองกลับมาเหมือนเดิม

   ⚠️ ซ่อนด้วย CSS ไม่ใช่ลบ CHEAD ทิ้ง — ฟองต้องกลับมาครบตอนออกจากหน้า DM
   ⚠️ ต้องคลุม .chead-sheet/.chead-back/.chead-tip/.chead-trash ด้วย
      ไม่งั้นเข้าหน้า DM ตอนแผ่นกางอยู่ = ฟองหายแต่แผ่นค้างเต็มจอ
   ⚠️ !important เพราะ .chead-wrap.on ตั้ง display:flex ไว้ (specificity เท่ากัน
      แต่กฎนี้อยู่ท้ายไฟล์ = ชนะ · เขียนใต้กฎฐานเสมอ ดู x10chat_bubble_avatar_calls)
   ══════════════════════════════════════════════════════════════════════ */
body.x10m.chead-hide-dm .chead-wrap,
body.x10m.chead-hide-dm .chead-sheet,
body.x10m.chead-hide-dm .chead-trash,
body.x10m.chead-hide-dm .chead-back,
body.x10m.chead-hide-dm .chead-tip { display: none !important; }

/* ============================================================
   โหมด `?panel=` — แผ่นที่ฟองนอกแอปกาง = ทั้งแอป (2026-09-09)
   Boss: "ดู dm เสร็จก็ดูอย่างอื่นต่อในแอพ เช่นดูช่องว่าสรุปซักผ้าเป็นไงบ้าง"

   ⚠️⚠️ ตรงข้ามกับ body.chead-solo ข้างบน (บรรทัด ~2065) ที่ซ่อนแอปทั้งตัว
      ที่นี่ **ไม่ซ่อนอะไรเลย** แค่ทำให้ layout พอกับกรอบแคบของหน้าต่างลอย
   ⚠️⚠️ ต้อง override `body.x10m.in-room .x10m-tabbar{display:none}` (บรรทัด 102) ด้วย
      ไม่งั้นเปิดแผ่นมาที่ห้องหนึ่งจะได้คลาส in-room แล้ว tabbar หายอยู่ดี
      = เดินไปห้องอื่นไม่ได้ ซึ่งคือบั๊กเดิมทั้งดุ้น
   ⚠️ กฎทุกข้อ scope ด้วย body.chead-panel — ห้ามใช้ @media เปล่า ๆ
      ไม่งั้นไปโดนเว็บบนมือถือที่ Boss สั่งให้คงเดิม
   ============================================================ */
body.chead-panel #boot-splash { display: none !important; }

/* หัวใจ: อยู่ในห้องก็ยังต้องเห็นแท็บล่าง เพื่อเดินไปหน้าอื่นได้
   🔴🔴 2026-09-10 Boss: "เข้าหน้าแจ้งเตือนมีปัญหา กด back หรืออะไรไม่ได้"
      ต้นเหตุ: กฎเดิมผูกกับ `.in-room` **อย่างเดียว** → พอกดแท็บออกจากห้อง
      (แจ้งเตือน/งาน/DM) คลาส in-room หลุด = ไม่มีกฎไหนโชว์แท็บล่างอีกเลย
      แถมยังโดน `body.x10m:has(#chat-room:not(.hidden)) .x10m-tabbar{display:none}`
      (บรรทัด ~697) ซ่อนซ้ำ เพราะ #chat-room ไม่ได้ถูกใส่ hidden ทุกครั้งที่เปลี่ยนหน้า
      วัดได้จริง: กดแท็บ "แจ้งเตือน" → เข้าหน้าได้ แต่ปุ่มทั้ง 5 กว้าง 0px กดไม่ได้เลย
      = **ตีบตัน ออกไปไหนไม่ได้** ตรงกับที่ Boss แจ้งเป๊ะ
   → แผ่นในโหมด panel = แอปทั้งตัว แท็บล่างจึงต้อง **อยู่ตลอดทุกหน้า**
   ⚠️ ต้องคุมทั้ง 2 กฎที่ซ่อน (in-room บรรทัด 102 · :has(#chat-room) บรรทัด 697)
      selector ต้องชนะทั้งคู่ — ใช้ body.chead-panel นำหน้า + !important
   🔴🔴 2026-09-18 ต้อง scope ด้วย `body.x10m` ทุกกฎ (Boss แจ้งพร้อมรูป: แถบขวาบนจอคอมล้นขอบ)
      ต้นเหตุ: กฎนี้เดิมไม่มี .x10m → บังคับ display:flex แม้ไม่ได้อยู่โหมดมือถือ
      แต่ position:fixed/bottom/ความสูง/สีพื้น อยู่ใต้ `body.x10m` หมด (บรรทัด 91)
      = โชว์แต่ไม่มี layout → ไอคอน+ป้ายเรียงติดเป็นบรรทัดเดียวมุมขวาบน badge 99+ ถูกตัด
      เข้าเงื่อนไขได้เพราะ cheadPanelOpen() (app.js:2412,2483) ใส่ x10m เองด้วยมือ
      แล้ว applyShellClasses() (mobile.js:90) toggle('x10m', MQ.matches) ถอดออกตอนจอกว้าง
      **แต่ chead-panel ยังค้าง** → เหลือ chead-panel เดี่ยว ๆ = ตรงกับกฎเดิมเป๊ะ
      วัดจริง headless 1280×579: ไม่มี x10m → position:static สูง 27px · มี x10m → fixed สูง 109px
      ปลอดภัย: chead-panel ถูก add คู่กับ x10m ทั้ง 2 จุดเสมอ แผ่นฟองจริงบนมือถือจึงยังเข้ากฎครบ */
body.x10m.chead-panel .x10m-tabbar,
body.x10m.chead-panel.in-room .x10m-tabbar,
body.x10m.chead-panel:has(#chat-room:not(.hidden)) .x10m-tabbar { display: flex !important; }

/* 🔴 2026-09-18 ตาข่ายกันแถบล่างค้างบนเดสก์ท็อป
   ทุกกฎของ .x10m-tabbar scope ด้วย body.x10m ทั้งหมด → พอ body ไม่มี x10m
   จะ "ไม่มีกฎไหนโชว์ และไม่มีกฎไหนซ่อน" = โผล่เป็น block เปล่า 27px มุมขวาบน
   nav ถูกสร้างใต้ MQ.matches แต่ไม่เคยถูกถอด (mobile.js:1973 เรียกแค่ closeSheet)
   ⇒ ย่อจอแคบแล้วขยายคืน / เปิด ?panel= บนจอกว้าง = แถบค้าง
   กฎนี้ปิดทุกเคสจบ: ไม่ได้อยู่โหมดมือถือ = ไม่มีแท็บล่าง */
body:not(.x10m) .x10m-tabbar { display: none !important; }

/* ฟองเว็บไม่ต้องมีในแผ่น — ฟองตัวจริงเป็น native อยู่ข้างนอกแล้ว
   (ถ้าโชว์จะกลายเป็นฟองซ้อนฟอง = บั๊ก "2 ตัว" ที่กำลังแก้อยู่) */
body.chead-panel .chead-wrap,
body.chead-panel .chead-back,
body.chead-panel .chead-trash { display: none !important; }

/* หน้าต่างลอยแคบ — กันแถบล่างทับข้อความบรรทัดสุดท้าย */
/* ⚠️⚠️ 2026-09-10 ต้องชนะ 2 กฎที่ตั้ง padding-bottom:0 ให้ .app
     · `body.x10m.in-room .app` (บรรทัด 86)
     · `body.x10m:has(#chat-room:not(.hidden)) .app` (บรรทัด 698) ← **:has() specificity สูง**
   กฎเดิมที่นี่แพ้ตัวที่ 2 → วัดได้ `.app` padding-bottom = 0px ทั้งที่เขียนไว้แล้ว
   = แถวสุดท้ายของลิสต์จมใต้แท็บล่าง (ปุ่ม ☆ ในหน้า DM กดไม่ได้)
   คู่แฝดกับกฎ tabbar ข้างบน — แก้ตัวเดียวไม่พอ ต้องคุมทั้งคู่เสมอ */
body.chead-panel .app,
body.chead-panel.in-room .app,
body.chead-panel:has(#chat-room:not(.hidden)) .app {
  padding-bottom: calc(var(--x10m-tabbar-h) + var(--x10m-safe-b)) !important;
}

/* 🔴 2026-09-10 ผลพ่วงจากการให้แท็บล่างอยู่ทุกหน้า:
   หน้าที่มี "ลิสต์เลื่อนเอง" (overflow-y:auto) ไม่ได้รับ padding ของ .app
   → รายการใบสุดท้ายจมใต้แท็บล่าง กดปุ่มบนแถวนั้นไม่ได้ (เทสจับได้: ปุ่ม ☆ ถูกทับ)
   ⚠️ ต้องเป็น padding ของตัวลิสต์เอง ไม่ใช่ margin ของหน้า — ไม่งั้นแถบเลื่อนสั้นลงแทน */
body.chead-panel .dmp-list,
body.chead-panel .ntf-list,
body.chead-panel #page-threads .thr-list,
body.chead-panel #page-work .work-list {
  padding-bottom: calc(var(--x10m-tabbar-h) + var(--x10m-safe-b) + 8px);
}

/* 🔴 2026-09-09 แก้บั๊กจากรูปที่ 3 ของ Boss: "เราเปิดตัว dm ผมต้องการแนบไฟล์
   ไม่มีเห็นปุ่มไง"  วัดได้จริง: แท็บล่างเริ่มที่ y=614 แต่ปุ่ม 📎 อยู่ 634-678
   = **แท็บล่างทับปุ่มทั้งแถว**

   ต้นเหตุ: ปกติ `body.x10m.in-room` ซ่อนแท็บล่าง (บรรทัด 102) แถบพิมพ์จึงได้ขอบล่างทั้งแถบ
   แต่กฎ chead-panel ข้างบนบังคับให้แท็บล่าง **โชว์** ตอน in-room (เพื่อให้เดินไปห้องอื่นได้)
   → แถบพิมพ์กับแท็บล่างจึงมาซ้อนที่เดียวกัน

   วิธีแก้: ในโหมด panel ตอนอยู่ในห้อง ให้แถบพิมพ์ "ยกขึ้น" เหนือแท็บล่าง
   ⚠️ ใช้ margin-bottom ไม่ใช่ bottom — .composer เป็น flex item ในสายหน้า ไม่ได้ fixed
   ⚠️ safe-area ถูกบวกไว้ใน --x10m-tabbar-h แล้วผ่าน padding ของ .app จึงไม่บวกซ้ำที่นี่
      (บวกซ้ำ = เหลือช่องว่างเปล่าใต้แถบพิมพ์บนเครื่องที่มี home indicator) */
body.chead-panel.in-room .composer {
  margin-bottom: calc(var(--x10m-tabbar-h) + var(--x10m-safe-b));
}
/* ข้อความบรรทัดสุดท้ายต้องไม่จมใต้แถบพิมพ์ที่ยกขึ้นมา */
body.chead-panel.in-room .messages { padding-bottom: 8px; }

/* 🔴 2026-09-09 15:05 (Boss + รูป: "แท็บเก่ามา ... ยังลบไม่ได้หมดอีกหรอ")
   ในรูปเห็นการ์ดลอยมีปุ่ม ✕ ซ้อนกันหลายใบด้านขวา = `.notif-wrap` (การ์ดแจ้งเตือนลอย)
   แผ่นในโหมด panel เป็น **หน้าต่างเล็ก** อยู่แล้ว การ์ดลอยซ้อนบนนั้น:
     · กินพื้นที่ที่มีน้อยอยู่แล้ว · ทับเนื้อหาที่กำลังอ่าน
     · ซ้ำซ้อน — ข้อความใหม่เห็นในตัวแผ่นเอง + มีฟอง native อยู่นอกแอปแล้ว
   ⚠️ ซ่อนเฉพาะโหมด panel — เว็บมือถือ/คอม/แอปเต็มจอ ยังเด้งการ์ดเหมือนเดิม
   ⚠️ ห้ามซ่อน `.toast` (แจ้งผลการกระทำ เช่น "ส่งแล้ว/ผิดพลาด") ผู้ใช้ต้องเห็น */
body.chead-panel .notif-wrap { display: none !important; }

/* ============================================================
   📷 หน้าถ่ายรูปในเว็บ — เต็มจอ ปุ่มใหญ่นิ้วกดติด (mobile first 360x780)
   ใช้ได้ทั้งในแอปและเบราว์เซอร์ จึงไม่ผูกกับ body.x10m
   ============================================================ */
.x10cam {
  position: fixed; inset: 0; z-index: 100000;
  background: #000; display: flex; flex-direction: column;
}
.x10cam.hidden { display: none !important; }
body.x10cam-on { overflow: hidden; }          /* กันหน้าหลังเลื่อนตามนิ้ว */
#x10cam-v {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; background: #000;
}
.x10cam-top {
  position: relative; z-index: 2;
  display: flex; align-items: center; gap: 10px;
  padding: calc(env(safe-area-inset-top, 0px) + 10px) 12px 10px;
}
.x10cam-x {
  width: 44px; height: 44px; border: 0; border-radius: 50%;
  background: rgba(0, 0, 0, .5); color: #fff; font-size: 20px; cursor: pointer;
}
.x10cam-rec {
  color: #fff; background: rgba(220, 38, 38, .9);
  padding: 6px 12px; border-radius: 999px; font-size: 14px; font-weight: 600;
}
.x10cam-rec.hidden { display: none !important; }
.x10cam-bar {
  position: relative; z-index: 2; margin-top: auto;
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 28px calc(env(safe-area-inset-bottom, 0px) + 28px);
}
.x10cam-flip, .x10cam-sp { width: 52px; height: 52px; flex-shrink: 0; }
.x10cam-flip {
  border: 0; border-radius: 50%;
  background: rgba(0, 0, 0, .5); color: #fff; font-size: 22px; cursor: pointer;
}
/* ปุ่มชัตเตอร์ทรงกลมแบบแอปกล้อง — 72px นิ้วโป้งกดไม่พลาด */
.x10cam-shot {
  width: 72px; height: 72px; border-radius: 50%; cursor: pointer;
  background: #fff; border: 4px solid rgba(255, 255, 255, .45);
  box-shadow: 0 0 0 2px rgba(0, 0, 0, .25);
}
.x10cam-shot.rec { background: #dc2626; border-radius: 18px; }   /* กำลังอัด = สี่เหลี่ยมแดง */

/* ════════════════════════════════════════════════════════════════
   🔴 (2026-09-14) iPhone: องค์ประกอบที่ปักขอบล่างลอยขึ้นตอนแป้นพิมพ์เปิด
   ----------------------------------------------------------------
   เหตุ: `position:fixed` ผูกกับ **layout viewport** ไม่ใช่ visual viewport
        iOS ตอนแป้นเปิดจะ "เลื่อน layout viewport ขึ้น" = visualViewport.offsetTop
        ⇒ ของที่ bottom:0 ถูกยกตามขึ้นไปด้วย ทั้งที่ควรอยู่ติดขอบจอ
   Android หด viewport แทนการเลื่อน offsetTop=0 จึงไม่เคยเป็น
        = ตรงกับอาการ "แอนดรอยทำได้ iPhone ไม่ได้"

   `--x10m-vvtop` mobile.js คำนวณให้อยู่แล้ว (แป้นปิด = 0px)
   แต่เดิม**มีที่เดียวในทั้งแอป**ที่เอาไปใช้ (.thrpanel) ที่เหลือตกหล่นหมด

   ⚠️⚠️ ใช้ translateY ไม่ใช่แก้ `bottom` — เพราะแต่ละตัว bottom ไม่เท่ากัน
        (บางตัว 0 · บางตัวบวก tabbar+safe-b) แก้ bottom ตรง ๆ = ต้องไล่ทีละสูตร
        translate ขยับจากตำแหน่งที่คำนวณเสร็จแล้ว = สูตรเดิมไม่ต้องแตะเลย
   ⚠️⚠️ ตัวที่มี transform เป็นของตัวเอง (.x10m-sheet สไลด์เข้า/ออก) **ห้ามใส่**
        เดี๋ยวทับ transform เดิมจนแอนิเมชันพัง — ใส่เฉพาะตัวที่ไม่มี transform
   ⚠️ แป้นปิด --x10m-vvtop = 0px ⇒ translateY(0) = ไม่มีผลใด ๆ กับสภาพปกติ
   ════════════════════════════════════════════════════════════════ */
body.x10m.plat-ios.kb-open .x10m-tabbar,
body.x10m.plat-ios.kb-open .atsheet,
body.x10m.plat-ios.kb-open .x10m-offbar,
body.x10m.plat-ios.kb-open #ntf-perm-bar,
body.x10m.plat-ios.kb-open .x10m-pushnag {
  transform: translateY(var(--x10m-vvtop, 0px));
}

/* ════════════════════════════════════════════════════════════════
   🔴 (2026-09-14 รอบ3) iOS: เลื่อนในโมดัลจนสุด แล้วแรงทะลุไปลากหน้าหลัง
   ----------------------------------------------------------------
   "scroll chaining" — กล่องที่เลื่อนสุดแล้ว iOS ส่งแรงต่อให้ตัวแม่
   ⇒ ปัดอ่านรายชื่อในโมดัลจนสุด แล้วหน้าแชทข้างหลังเลื่อนตาม
     ปิดโมดัลมาแล้วงงว่าทำไมตำแหน่งที่อ่านค้างไว้หายไป + rubber-band ทั้งหน้า
   ⚠️ ทั้ง style.css (8,787 บรรทัด) ไม่มี overscroll-behavior เลยสักจุด
      ส่วน mobile.css มีแล้วที่ .side-scroll/.op-grid-wrap = ทีมรู้จักท่านี้
      แต่ **ตกหล่นที่ .modal ซึ่งผู้ใช้เจอบ่อยที่สุด** (โมดัลทั้งแอป 48 ใบ)
   ⚠️⚠️ ใช้ `contain` ไม่ใช่ `none`:
      · contain = กันแรงทะลุออกนอก แต่ยัง rubber-band ในกล่องตัวเองได้ (ดูเป็นธรรมชาติ)
      · none    = ห้าม rubber-band ด้วย = แข็งผิดจริตแอป iOS
   ⚠️ ใส่ที่ตัวที่ "เลื่อนได้จริง" เท่านั้น (มี overflow-y:auto) ใส่มั่วไม่มีผล
   ════════════════════════════════════════════════════════════════ */
body.x10m .modal,
body.x10m .psel-list,
body.x10m .announce-item .a-body,
body.x10m .brw-list,
body.x10m .msg-menu,
body.x10m .x10m-sheet {
  overscroll-behavior: contain;
}

/* ════════════════════════════════════════════════════════════════
   🟠 (2026-09-14 รอบ3) iOS: ปุ่มแตะแล้ว "นิ่งสนิท" ไม่รู้ว่ากดติดไหม
   ----------------------------------------------------------------
   มือถือไม่มี :hover และ **iOS แทบไม่ยิง :focus-visible จากการแตะ**
   (Safari สงวนไว้ให้คีย์บอร์ดเป็นหลัก) ⇒ พึ่ง :focus-visible ไม่ได้เลยบนมือถือ
   ของเดิมมี `:active` แค่ `.btn.primary` ⇒ **ปุ่ม "ยกเลิก"/"ปิด" (.btn.ghost)
   ในทุกโมดัลแตะแล้วไม่มีอะไรตอบสนอง** ผู้ใช้ไม่แน่ใจว่ากดติด เลยกดซ้ำ
   ⚠️ ใช้ opacity+scale ไม่แตะ background — ปุ่มแต่ละชนิดสีพื้นต่างกัน
      เขียนทับสีจะพังธีมมืด/สว่างไม่เท่ากัน
   ⚠️ transition สั้น (.06s) ให้รู้สึกทันมือ ยาวกว่านี้จะเหมือนแอปหน่วง
   ⚠️ ต้องไม่ใส่กับปุ่มที่ถูก disabled (กดไม่ได้อยู่แล้ว ไม่ควรตอบสนอง)
   ════════════════════════════════════════════════════════════════ */
body.x10m .btn:not(:disabled):active,
body.x10m button:not(:disabled):active,
body.x10m .x10m-tab:active,
body.x10m .chan-item:active {
  opacity: .62;
  transform: scale(.97);
}
body.x10m .btn, body.x10m button {
  transition: opacity .06s ease, transform .06s ease;
}

/* ════════════════════════════════════════════════════════════════
   🔴🔴 (2026-09-14) iPhone: "ปุ่มส่งต่อกดไม่ได้" — Boss แจ้ง
   ----------------------------------------------------------------
   อาการ: เปิดโมดัลส่งต่อ แตะช่องพิมพ์ข้อความแนบ → แป้นพิมพ์ขึ้น
          → **ปุ่มส่งจมอยู่ใต้แป้นพิมพ์ แตะไม่ถึงเลย** (ไม่ใช่แค่กดยาก)
   ต้นเหตุ: `body.x10m .modal { max-height: 90vh }` — **`vh` ไม่หดตอนแป้นเปิดบน iOS**
          (แป้นทับหน้าจอ layout viewport เท่าเดิม · มีแต่ visualViewport ที่หด)
          วัดจริงบน 16 Pro Max: จอ 956 แป้นกิน 336 เหลือเห็น 620
          แต่โมดัลสูง **1142px** ปุ่มส่งไปอยู่ y=2069 = นอกพื้นที่มองเห็นคนละโลก
   Android หด viewport จริง (resize) `vh` จึงเล็กลงตาม = ไม่เคยเจอ
   = ตระกูลเดียวกับบั๊ก .thrpanel ที่แก้ไปแล้ว แต่ **โมดัลทั้งหมดตกหล่น**

   แก้: ตอนแป้นเปิด ผูกเพดานโมดัลกับ `--x10m-vv` (ความสูงที่มองเห็นจริง)
        แล้วหักความสูงแป้นออกจากตำแหน่ง — ปุ่มท้ายโมดัลจึงลอยเหนือแป้นเสมอ
   ⚠️ `--x10m-vv` มีค่าเฉพาะเมื่อมี visualViewport (iOS13+) — ใส่ fallback 90vh ไว้
   ⚠️ ต้องมี overflow-y:auto อยู่แล้ว (มีที่ style.css:532) เนื้อหาจึงเลื่อนดูได้
   ⚠️ ใช้ 92% ของ vv ไม่ใช่ 100% — เผื่อขอบบน ไม่ให้โมดัลชนขอบจอพอดีจนอึดอัด
   ════════════════════════════════════════════════════════════════ */
body.x10m.kb-open .modal {
  max-height: calc(var(--x10m-vv, 90vh) * 0.92);
}
/* 🔴🔴 ลดความสูงอย่างเดียว **ไม่พอ** — backdrop เป็น `align-items: flex-end`
   (บรรทัด 965) = โมดัลปักก้น **layout viewport** ซึ่งอยู่ใต้แป้นพิมพ์
   ⇒ ต้องยกก้น backdrop ขึ้นเท่าความสูงแป้น ปุ่มท้ายโมดัลจึงจะโผล่เหนือแป้น
   (บทเรียนเดียวกับ .thrpanel: "ตัวแปรสำคัญคือ bottom ไม่ใช่ height")
   ⚠️ --x10m-kb = ความสูงแป้นที่ mobile.js วัดให้ · แป้นปิด = 0px
   ⚠️ ต้องหัก --x10m-vvtop ด้วย (iOS เลื่อน layout viewport ขึ้นตอนแป้นเปิด)
      ไม่งั้นโดนยก 2 ชั้นเหมือนบั๊กแถบแท็บล่างที่แก้ไปแล้ว */
body.x10m.kb-open .modal-backdrop {
  bottom: calc(var(--x10m-kb, 0px) + var(--x10m-vvtop, 0px));
}
/* รายการห้องในโมดัลส่งต่อต้องยุบลงด้วย ไม่งั้นมันกินที่จนปุ่มถูกดันตกอยู่ดี
   (ของเดิม 34vh คิดจากจอเต็ม = ยังสูงเกินไปเมื่อแป้นขึ้น) */
body.x10m.kb-open .fw-list { max-height: calc(var(--x10m-vv, 34vh) * 0.30); }
body.x10m.kb-open .fw-note { max-height: 60px; }
/* แถบท้าย (ปุ่มส่ง) ต้องไม่ถูกบีบหาย — เนื้อหาส่วนอื่นหดแทน */
body.x10m .fw-foot { flex: 0 0 auto; }

/* ════════════════════════════════════════════════════════════════
   🔴🔴 (2026-09-14) ปุ่มจมใต้แป้นพิมพ์ — อีก 3 แผง (Boss: "บางปุ่มกดไม่ได้")
   ----------------------------------------------------------------
   ตระกูลเดียวกับโมดัลส่งต่อที่เพิ่งแก้: แผงเป็น `position:fixed` ผูกกับ
   **layout viewport** ซึ่ง iOS **ไม่หด**ตอนแป้นขึ้น (แป้นแค่ทับทับบนหน้า)
   ⇒ แถวพิมพ์ที่อยู่ก้นแผง (ช่องพิมพ์ + ปุ่มส่ง + 📎 😊) จมอยู่ใต้แป้น แตะไม่ถึงเลย
   Android หด viewport จริง จึงไม่เคยเจอ = "แอนดรอยได้ iPhone ไม่ได้"

   ท่าแก้มาตรฐานของแอปนี้: ตอน `kb-open` ยกก้นแผงขึ้นเท่าความสูงแป้น
     `--x10m-kb`    = ความสูงแป้นที่ mobile.js วัดให้ (แป้นปิด = 0px)
     `--x10m-vvtop` = ระยะที่ iOS เลื่อน layout viewport ขึ้น (ต้องบวกชดเชย)
   ⚠️ ห้ามแก้แค่ height — ก้นแผงยังปักที่เดิม ปุ่มก็ยังจมอยู่ดี (บทเรียน .thrpanel)
   ════════════════════════════════════════════════════════════════ */

/* ① หน้าแจ้งเตือน + หน้า "บันทึกไว้" 🔖 — ปุ่ม "ส่ง" ตอบกลับในเธรด
   ⚠️⚠️ `.ntf-dt-foot` มี padding-bottom เผื่อแถบแท็บล่าง (tabbar+safe-area)
        ตอนแป้นเปิด **แถบแท็บถูกแป้นทับไปแล้ว** ไม่ต้องเว้นที่ให้อีก
        ถ้าไม่หักออก ปุ่มจะยังจมลึกกว่าที่ควรอีก ~80px */
/* 🔴🔴 (2026-09-20) แก้ท่า: แผงนี้ **สูงเต็มจอ** (`position:fixed; inset:0` → top:0)
   ยึด `bottom` อย่างเดียวไม่พอ — `bottom = kb + vvtop` เป็นค่าคงที่ (kb หัก offsetTop ไปแล้ว)
   ก้นแผงถูกตรึงจริง แต่ **หัวแผงยังผูก layout viewport ที่ iOS เลื่อนขึ้น** เท่า offsetTop
   ⇒ ปุ่ม ← ย้อนกลับ ที่หัวแผงหลุดขึ้นเหนือขอบจอ **กดออกจากเธรดไม่ได้เลยตอนพิมพ์**
   (คอมเมนต์ข้างบนเตือนเรื่องนี้ไว้เองแล้ว แต่ท่าที่ใช้จริงคือครึ่งเดียวของท่าที่ถูก)
   🔑 ท่าที่ถูก = เหมือน .thrpanel รอบ 11: ยึด top กับ vvtop + สูงเท่า visual viewport
   เทส WebKit 390x844 (offsetTop=140 vvH=508): ก่อนแก้หัวแผง 0→50 (เหนือจอ 90px) */
body.x10m.kb-open .ntf-detail {
  top: var(--x10m-vvtop, 0px);
  bottom: auto;
  height: var(--x10m-vv, 100dvh);
  max-height: var(--x10m-vv, 100dvh);
}
body.x10m.kb-open .ntf-dt-foot { padding-bottom: 9px; }

/* ② แผงแชทในห้องประชุม — ปุ่มส่ง + 📎 แนบไฟล์ + 😊 อิโมจิ
   (Enter ยังส่งได้เพราะมี onkeydown แต่ 📎/😊 หายจริง) */
/* 🟠 (2026-09-20) ตัวนี้เป็นแผง "เตี้ย" จริง → ยึด bottom ถูกแล้ว
   แต่ `height` เดิมผูก `--x10m-vv` (สูงเท่าจอที่เห็น) **ทับกับ bottom ที่ดันขึ้นมาแล้ว**
   ⇒ พอแป้นสูง ก้นแผงถูกดันขึ้นเกินกว่าที่ height ชดเชย หัวแผง+ปุ่มปิด ✕ ทะลุขอบบน ~84px
   🔑 เพดานต้องเป็น "ที่ว่างที่เหลือจริงเหนือก้นแผง" = vv − kb − meet-bar − เว้นขอบ
      (ไม่ใช่ vv ทั้งก้อน) แล้วแผงเลื่อนดูในตัวเองได้ตามปกติ */
body.x10m.kb-open .meet-side {
  bottom: calc(var(--meet-bar-h, 84px) + var(--x10m-kb, 0px) + var(--x10m-vvtop, 0px));
  height: min(62vh, calc(var(--x10m-vv, 100%) - var(--x10m-kb, 0px) - var(--meet-bar-h, 84px) - 56px));
}

/* ③ แผ่น Chat Head (ฟองแชทลอย) — ปุ่ม ➤ ส่ง + 📎 🏷️ 😀 🎤 */
body.x10m.kb-open .chead-sheet {
  bottom: calc(var(--x10m-kb, 0px) + var(--x10m-vvtop, 0px));
  /* 🟠 (2026-09-20) โหมดพับ: `top: 13dvh` คิดจาก **layout viewport** ที่ iOS เลื่อนขึ้น
     ⇒ หัวแผ่น (ปุ่ม ✕ ปิด) เลยขอบบนที่ตามองเห็นไปเล็กน้อยตอนแป้นเปิด
     ต้องบวก vvtop เข้าไป ให้ 13% นับจากขอบบน "ที่เห็นจริง" (เทสวัดได้ 4px ก่อนแก้) */
  top: calc(var(--x10m-vvtop, 0px) + 13dvh);
}
/* ⚠️⚠️ โหมด solo/card บังคับ `inset:0 !important` (บรรทัด ~2150)
   กฎธรรมดาแพ้ !important ⇒ ต้องประกาศแยกและใส่ !important สู้กลับ
   ไม่งั้นฟองแชทแบบเต็มจอจะยังพังอยู่ทั้งที่แก้ตัวหลักแล้ว */
/* 🔴🔴 (2026-09-20) solo/card = แผ่นเต็มจอ (`inset:0 !important`) ⇒ ยึด top เหมือน .ntf-detail
   เดิมยึด bottom + height:auto → **หัวแผ่นทั้งแถบ (รูปโปรไฟล์ ชื่อ ปุ่ม ✕ ปิด ⤢ ขยาย โทร)
   หลุดขึ้นเหนือจอ กดปิดไม่ได้เลยตอนพิมพ์** ผู้ใช้นึกว่าแอปค้าง (ต้องกดแป้นลงก่อน)
   เทส WebKit: โหมด solo หัวแผ่นอยู่ที่ 0→52 ขณะที่แถบมองเห็นเริ่ม 140 = นอกจอ 100% */
body.x10m.kb-open.chead-solo .chead-sheet,
body.x10m.kb-open.chead-card .chead-sheet {
  top: var(--x10m-vvtop, 0px) !important;
  bottom: auto !important;
  height: var(--x10m-vv, 100dvh) !important;
  max-height: var(--x10m-vv, 100dvh) !important;
}

/* ════════════════════════════════════════════════════════════════
   🔴 (2026-09-14) ปุ่มที่โผล่เฉพาะตอน :hover = **แตะไม่ได้เลยบนมือถือ**
   ----------------------------------------------------------------
   iPhone/Android ไม่มี hover จริง ⇒ ปุ่มที่ซ่อนด้วย `display:none` หรือ
   `opacity:0` แล้วรอ `:hover` มาเปิด จะ **ไม่มีวันโผล่** บนมือถือ
   (iOS ยิง :hover จำลองตอนแตะครั้งแรกบ้าง แต่เชื่อถือไม่ได้และต้องแตะ 2 ครั้ง)
   ⚠️ ที่อื่นในแอปทำถูกแล้ว: `.msg-actions` มี `.show-actions` (แตะฟองข้อความ)
      และ `.chan-fav`/`.rtab-x` ใช้ opacity .35-.5 = ยังเห็นและกดได้ ไม่ต้องแก้
   ⇒ เหลือ 2 ตัวนี้ที่ตกหล่นจริง (ยืนยันด้วย WebKit: display:none / opacity:0)
   ════════════════════════════════════════════════════════════════ */

/* ① ปุ่มลบสติกเกอร์ — เดิม `display:none` + `:hover` เท่านั้น
   ⇒ **ลบสติกเกอร์บน iPhone ไม่ได้เลย** ไม่มีทางอื่นด้วย
   ⚠️ ขยายเป็น 24px (ของเดิม 18px เล็กเกินสำหรับนิ้ว) แต่ยังไม่บังรูปสติกเกอร์ */
body.x10m .sticker-cell .st-del {
  display: block;
  width: 24px; height: 24px; font-size: 13px; line-height: 1;
  opacity: .92;
}

/* ② ปุ่มคัดลอกตาราง — เดิม opacity:0 รอ :hover ที่ตัวห่อตาราง
   ⇒ มือถือมองไม่เห็นว่ามีปุ่มนี้อยู่ (ตารางในข้อความคัดลอกไม่ได้เลย) */
body.x10m .msg-text .tbl-copy { opacity: .75; }

/* 🔴 2026-09-20 — วิดีโอมีตัวครอบ .vdo-wrap แล้ว (ปุ่มบันทึก)
   กฎมือถือด้านบนจับ `body.x10m .msg video.msg-video` ซึ่งยังใช้ได้
   แต่ wrapper ต้องไม่บีบ/ไม่ทาพื้นทับ ไม่งั้นเห็นเป็น "จอมืด"
   ⚠️ object-fit: cover + background เข้ม = ถ้า video ไม่ได้ขนาด จะเห็นแต่พื้นเข้ม */
body.x10m .msg .vdo-wrap {
  max-width: 100% !important;
  width: auto;
  background: transparent !important;
}
body.x10m .msg .vdo-wrap > video.msg-video {
  object-fit: contain;            /* คลิปไม่ถูกครอบตัด เห็นเต็มเฟรม */
  background: #000;               /* แถบดำข้างคลิปแนวตั้ง = ปกติของวิดีโอ */
}
