/* ============================================================
   ฟอนต์ในเครื่อง (self-host) — ไม่พึ่ง Google ตอนรัน
   Kanit = ไทย+อังกฤษ (Cadson Demak) · Noto Sans = พม่า/ไทใหญ่ · เขมร · ลาว
   ไทใหญ่ (shn) ใช้อักษรพม่า จึงใช้ฟอนต์ Myanmar ตัวเดียวกัน
   อัปเดตไฟล์: tools/getfonts.sh
   ============================================================ */
/* Tlwg Mono — monospace ที่ "มีอักษรไทย" (ทุก glyph กว้าง 600 เท่ากัน
   สระ/วรรณยุกต์กว้าง 0 ซ้อนบนตัวก่อนหน้า) → ตารางไทยในบล็อก ``` ตรงคอลัมน์
   Boss 2026-08-27: ตารางเหลื่อมเพราะ Kanit เป็น proportional */
@font-face {
  font-family: 'Tlwg Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/tlwgmono-400.woff2) format('woff2');
}
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(fonts/kanit-thai-300.woff2) format('woff2');
  unicode-range: U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC;
}
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(fonts/kanit-latin-300.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/kanit-thai-400.woff2) format('woff2');
  unicode-range: U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC;
}
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/kanit-latin-400.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/kanit-thai-500.woff2) format('woff2');
  unicode-range: U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC;
}
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/kanit-latin-500.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(fonts/kanit-thai-600.woff2) format('woff2');
  unicode-range: U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC;
}
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(fonts/kanit-latin-600.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/kanit-thai-700.woff2) format('woff2');
  unicode-range: U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC;
}
@font-face {
  font-family: 'Kanit';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/kanit-latin-700.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Noto Sans Myanmar';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/mya-myanmar-400.woff2) format('woff2');
  unicode-range: U+1000-109F, U+200C-200D, U+25CC, U+A92E, U+A9E0-A9FE, U+AA60-AA7F, U+116D0-116E3;
}
@font-face {
  font-family: 'Noto Sans Myanmar';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/mya-myanmar-400.woff2) format('woff2');
  unicode-range: U+1000-109F, U+200C-200D, U+25CC, U+A92E, U+A9E0-A9FE, U+AA60-AA7F, U+116D0-116E3;
}
@font-face {
  font-family: 'Noto Sans Khmer';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/khm-khmer-400.woff2) format('woff2');
  unicode-range: U+1780-17FF, U+19E0-19FF, U+200C-200D, U+25CC;
}
@font-face {
  font-family: 'Noto Sans Khmer';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/khm-khmer-400.woff2) format('woff2');
  unicode-range: U+1780-17FF, U+19E0-19FF, U+200C-200D, U+25CC;
}
@font-face {
  font-family: 'Noto Sans Lao';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/lao-lao-400.woff2) format('woff2');
  unicode-range: U+0E81-0EDF, U+200C-200D, U+25CC;
}
@font-face {
  font-family: 'Noto Sans Lao';
  font-style: normal;
  font-weight: 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/lao-lao-400.woff2) format('woff2');
  unicode-range: U+0E81-0EDF, U+200C-200D, U+25CC;
}

/* โหมดมืด — เทาอมน้ำเงินเข้ม ไม่ใช้ดำสนิท (จอมือถือถูกๆ อ่านง่ายกว่า)
   แถบข้างกลมกลืนกับพื้นหลัง ไม่ใช่บล็อกน้ำเงินลอย */
html[data-theme="dark"] {
  --blue: #4D9BE0; --blue-dark: #7FBAEC; --blue-light: #1B2A3A;
  --bg: #0E1621; --card: #172231; --text: #E5EAF0; --muted: #94A3B8;
  --border: #2A3849; --green: #34D399; --red: #F87171; --amber: #FBBF24;
  --pane-split: #3A4B60;   /* เส้นแบ่งบานแยก — เข้มกว่า --border ให้เห็นชัดบนพื้นมืด */
  --shadow: 0 1px 3px rgba(0,0,0,.4);

  --side-bg: #121C28; --side-text: #E5EAF0; --side-muted: #8FA1B5;
  --side-section: #7D8FA3; --side-item: #C3CEDB;
  --side-hover: rgba(255,255,255,.06); --side-raise: rgba(255,255,255,.05);
  --side-input: rgba(255,255,255,.07); --side-ph: #7D8FA3;
  --side-active: #1D3A5C; --side-presence: #4A5A6D;

  --sunken: #1E2A3A;
  /* บับเบิลข้อความ — ต้องสว่างกว่าพื้น #0E1621/#111c28 พอให้เห็นเป็น "ก้อน"
     (เดิมไม่มีนิยาม เลยตกไปใช้ rgba(127,127,127,.1) ที่จางจนกลืนพื้น = ดูเหมือนกระทู้) */
  --bubble: #24354A; --bubble-mine: #2F6DB0; --msg-hover: rgba(255,255,255,.055);
  --amber-bg: #3A2E12; --amber-bd: #574319; --amber-soft: #2A2210;
  --green-bg: #12331F; --green-soft: #10281B;
  --red-bg: #3A1A1A;
  --hot: #1E3A57;
  --online: #34D399; --online-text: #06331F;
  --toast-bg: #E5EAF0; --toast-text: #0E1621;
  --backdrop: rgba(0,0,0,.62);
  --call-bg: #0A121C; --call-tile: #1B2A3A;
  --shadow-pop: 0 8px 24px rgba(0,0,0,.5);
  --shadow-modal: 0 20px 60px rgba(0,0,0,.6);
  --on-brand: #0B1520;
  color-scheme: dark;         /* ปฏิทิน/dropdown/scrollbar ของเบราว์เซอร์เป็นโทนมืดตาม */
}
* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; }
body {
  /* มินิมอล: Kanit นำ · Noto ต่อท้ายรับอักษรพม่า/เขมร/ลาว · ระบบเป็นตัวสำรอง */
  font-family: 'Kanit', 'Noto Sans Myanmar', 'Noto Sans Khmer', 'Noto Sans Lao',
    'Segoe UI', 'Leelawadee UI', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;   /* มินิมอลต้องเส้นบาง ไม่หนาเป็นก้อน */
  -moz-osx-font-smoothing: grayscale;
  /* Kanit ตัวสูงกว่าฟอนต์ระบบ ถ้าไม่เพิ่ม line-height สระบน/ล่างไทยจะชนกันเวลาข้อความหลายบรรทัด */
  line-height: 1.55;
  background: var(--bg); color: var(--text); font-size: 14.5px; overflow: hidden;
}
/* พม่า/ไทใหญ่ ต้องการ line-height สูงกว่า */
html[lang="my"] body, html[lang="shn"] body { line-height: 1.8; }
.hidden { display: none !important; }
.muted { color: var(--muted); }
.w100 { width: 100%; }
.small-text { font-size: 12px; }
.error-text { color: var(--red); font-size: 13px; margin-top: 8px; min-height: 18px; text-align: center; }
.divider { border-top: 1px solid var(--border); margin: 12px 0; }
.big-emoji { font-size: 56px; }
.mini-hint { font-weight: 400; font-size: 10px; }

/* ---------- buttons / inputs ---------- */
.btn {
  border: 1px solid var(--border); background: var(--card); color: var(--text);
  padding: 9px 16px; border-radius: 8px; font-size: 14px; cursor: pointer; font-family: inherit;
}
.btn.primary { background: var(--blue); border-color: var(--blue); color: var(--on-brand); }
.btn.primary:active { background: var(--blue-dark); }
.btn.danger { background: var(--red); border-color: var(--red); color: var(--on-brand); }
.btn.ghost { background: transparent; }
.btn.small { padding: 5px 10px; font-size: 13px; }
.icon-btn {
  border: none; background: transparent; font-size: 19px; cursor: pointer;
  padding: 7px; border-radius: 8px; line-height: 1; color: var(--text);
}
.icon-btn:active { background: var(--blue-light); }
.icon-btn.send { color: var(--blue); font-size: 22px; }
.icon-btn.recording { background: var(--red); color: var(--on-brand); border-radius: 50%; animation: pulse 1s infinite; }
@keyframes pulse { 50% { opacity: .6; } }
input, textarea, select {
  width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px;
  font-size: 15px; font-family: inherit; background: var(--card); color: var(--text); margin-bottom: 8px;
}
input:focus, textarea:focus, select:focus { outline: 2px solid var(--blue); outline-offset: -1px; }
input[type=color] { height: 42px; padding: 4px; }
input[type=checkbox], input[type=radio] { width: auto; margin: 0 6px 0 0; }
label { font-size: 14px; }

/* ---------- login ---------- */
.login-screen {
  position: fixed; inset: 0; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(150deg, var(--blue) 0%, var(--blue-dark) 100%); padding: 16px;
}
.login-card {
  background: var(--card); border-radius: 16px; padding: 32px 28px; width: 100%; max-width: 380px;
  text-align: center; box-shadow: 0 12px 40px rgba(0,0,0,.25);
}
.login-logo { font-size: 52px; }
.login-card h1 { color: var(--blue); margin: 4px 0 2px; }
.login-card p { margin-bottom: 18px; }
.login-card .btn { margin-top: 8px; }

/* ---------- layout ---------- */
.app { display: flex; height: 100%; height: 100dvh; }
.sidebar {
  width: 280px; background: var(--side-bg); color: var(--side-text); display: flex; flex-direction: column;
  flex-shrink: 0; z-index: 40;
}
.sidebar-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 14px 8px; }
.brand { font-weight: 700; font-size: 17px; }
.sidebar .icon-btn { color: var(--side-text); }
.sidebar-me {
  display: flex; gap: 10px; align-items: center; margin: 0 10px 8px; padding: 8px;
  border-radius: 10px; background: var(--side-raise); cursor: pointer;
}
.me-name { font-weight: 600; font-size: 14px; }
.me-status { font-size: 12px; color: var(--side-muted); }
.side-nav { display: flex; gap: 4px; margin: 0 10px 8px; }
.side-nav .nav-btn {
  flex: 1; border: none; background: var(--side-raise); color: var(--side-text); font-size: 17px;
  padding: 7px 0; border-radius: 8px; cursor: pointer;
}
.side-nav .nav-btn.active { background: var(--side-active); }
/* ปุ่มผู้ดูแลระบบ: แยกแถวของตัวเอง โชว์ชื่อเต็ม ไม่ใช่ไอคอนเปล่า จะได้รู้ว่ากดไปหน้าอะไร */
.side-admin { display: flex; margin: 0 10px 8px; }
.side-admin .nav-btn-wide {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: none; background: var(--side-raise); color: var(--side-text);
  padding: 8px 10px; border-radius: 8px; cursor: pointer; font-size: 15px;
}
.side-admin .nav-btn-wide.active { background: var(--side-active); }
.side-admin .nav-btn-label { font-size: 13px; font-weight: 600; white-space: nowrap; }
/* ป้ายนับคำขอรออนุมัติ บนปุ่มผู้ดูแลระบบ */
.nav-badge {
  background: #DC2626; color: #fff; font-size: 10px; font-weight: 700; line-height: 1;
  min-width: 16px; padding: 3px 4px; border-radius: 999px; text-align: center;
}
.side-search { margin: 0 10px 8px; width: calc(100% - 20px); background: var(--side-input); border: none; color: var(--side-text); }
/* แถวค้นหา + ปุ่ม DM (Boss สั่ง 2026-09-04) — สกินพื้นฐาน (ไม่ใช่ v3) */
.side-search-row { display: flex; align-items: center; gap: 8px; margin: 0 10px 8px; }
.side-search-row .side-search { margin: 0; width: 0; flex: 1 1 0; min-width: 0; }
.side-dm-btn {
  position: relative; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 8px; cursor: pointer;
  border: none; background: var(--side-input); color: var(--side-text); font-size: 16px;
}
.side-dm-btn:hover { background: var(--side-hover); }
.side-dm-badge {
  position: absolute; top: -4px; right: -4px; min-width: 16px; height: 16px;
  padding: 0 4px; border-radius: 999px; background: var(--red, #e01e5a); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}
.side-dm-badge.hidden { display: none; }
.side-search::placeholder { color: var(--side-ph); }
.side-scroll { flex: 1; overflow-y: auto; padding-bottom: 12px; }
.side-section {
  font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--side-section);
  padding: 12px 14px 4px; font-weight: 700;
}
.chan-item, .user-item {
  display: flex; align-items: center; gap: 8px; padding: 8px 14px; cursor: pointer; font-size: 14px;
  color: var(--side-item);
}
.chan-item:active, .chan-item:hover, .user-item:hover { background: var(--side-hover); }
.chan-item.active { background: var(--side-active); color: var(--side-text); font-weight: 600; }
.chan-item .dot { margin-left: auto; width: 9px; height: 9px; border-radius: 50%; background: var(--amber); flex-shrink: 0; }
.user-item .presence { width: 9px; height: 9px; border-radius: 50%; background: var(--side-presence); flex-shrink: 0; }
.user-item .presence.on { background: var(--online); }
.online-badge { background: var(--online); color: var(--online-text); font-size: 11px; padding: 1px 7px; border-radius: 10px; margin-left: 4px; }
.avatar {
  width: 34px; height: 34px; border-radius: 50%; color: #fff; font-weight: 700; font-size: 14px;
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
}

.main { flex: 1; display: flex; flex-direction: column; min-width: 0; position: relative; }
.page { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.page-head {
  display: flex; align-items: center; gap: 10px; padding: 12px 16px; background: var(--card);
  border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
.page-head h2 { font-size: 17px; color: var(--blue); }
.head-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }
/* ปุ่ม "ไปช่องแชท" มุมขวาหัวหน้า DM (Boss สั่ง 2026-08-30) */
.dmp-home { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.dmp-home svg { width: 15px; height: 15px; }
/* หน้าแจ้งเตือนมี .head-actions (margin-left:auto) อยู่แล้ว — ถ้าปุ่มนี้ auto ด้วย
   ตัวแรกจะกินที่ว่างไปหมดแล้วดันปุ่มไปกองกลาง ๆ ไม่ติดกลุ่มขวาสักฝั่ง
   → ที่นี่ให้เกาะชิดชื่อหน้าไปเลย แล้วปล่อยกลุ่มปุ่มขวาทำงานตามเดิม
   ⚠️ ห้ามแก้ที่ .dmp-home ตัวแม่ — หน้า DM ไม่มี .head-actions ต้องใช้ auto ต่อไป */
.ntf-home { margin-left: 0; }
.head-actions select { width: auto; margin: 0; padding: 6px 8px; font-size: 13px; }
.page-body { flex: 1; overflow-y: auto; padding: 14px; }

/* ---------- chat ---------- */
.chat-empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; color: var(--muted); }
.chat-room { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.chat-head {
  display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: var(--card);
  border-bottom: 1px solid var(--border);
}
.chat-title { flex: 1; min-width: 0; cursor: pointer; }
.chat-name { font-weight: 700; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-topic { font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-actions { display: flex; }
.meeting-bar {
  display: flex; align-items: center; gap: 8px; padding: 7px 12px; background: var(--amber-bg);
  border-bottom: 1px solid var(--amber-bd); font-size: 13px; flex-wrap: wrap;
}
.meeting-bar input { flex: 1; min-width: 140px; margin: 0; padding: 6px 10px; font-size: 13px; }
.messages { flex: 1; overflow-y: auto; padding: 12px 12px 4px; display: flex; flex-direction: column;
  /* ⚠️⚠️ (Boss 2026-09-16) กันจอกระชากระดับเบราว์เซอร์ ก่อนที่ JS จะต้องมาชดเชยเอง
     overflow-anchor: auto = เบราว์เซอร์ล็อกข้อความที่กำลังอ่านไว้เอง เมื่อเนื้อหา "ด้านบน"
       โตขึ้น (โหลดข้อความเก่า/รูปเหนือจอโหลดเสร็จ) — ค่า default ก็ auto แต่ประกาศไว้ชัด
       กันโดน `overflow-anchor: none` จากกฎอื่นทับโดยไม่ตั้งใจ
     scrollbar-gutter: stable = จองที่ scrollbar ไว้ตลอด ไม่งั้นตอนมันโผล่/หาย
       ความกว้างเนื้อหาเปลี่ยน = ข้อความขยับซ้ายขวา (อาการ "จอกระตุก" บน PC) */
  overflow-anchor: auto;
  scrollbar-gutter: stable;
}
.msg { display: flex; gap: 8px; margin-bottom: 2px; padding: 3px 6px; border-radius: 8px; position: relative; }
.msg:hover { background: var(--blue-light); }
.msg .avatar { width: 32px; height: 32px; font-size: 13px; margin-top: 2px; }
.msg.compact .avatar { visibility: hidden; height: 0; margin: 0; }
.msg-body { flex: 1; min-width: 0; }
.msg-head { display: flex; gap: 8px; align-items: baseline; }
.msg-name { font-weight: 700; font-size: 13.5px; }
.msg-time { font-size: 11px; color: var(--muted); }
.msg-text { font-size: 14.5px; word-wrap: break-word; white-space: pre-wrap; }
.msg-text.deleted { color: var(--muted); font-style: italic; }
/* บล็อกตาราง/โค้ด ``` — ต้อง monospace ไม่งั้นคอลัมน์เหลื่อม · แคบกว่าตารางให้เลื่อนแนวนอน */
.msg-text .msg-pre {
  /* 'Tlwg Mono' ต้องมาก่อน — เป็นตัวเดียวที่มีอักษรไทยและกว้างคงที่
     ถ้าเอา Cascadia ขึ้นก่อน ละตินจะกว้าง 1 หน่วยแต่ไทย fallback ไป Kanit = เหลื่อม */
  font-family: 'Tlwg Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', 'Courier New', monospace;
  font-size: 13px; line-height: 1.5; margin: 6px 0 2px;
  background: var(--sunken); border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px; overflow-x: auto; white-space: pre; -webkit-overflow-scrolling: touch;
}
.msg-edited { font-size: 11px; color: var(--muted); }
.msg-reply {
  font-size: 12px; color: var(--muted); border-left: 3px solid var(--blue); padding: 2px 8px;
  margin-bottom: 2px; background: var(--blue-light); border-radius: 4px; cursor: pointer;
}
/* ⚠️ แก้ 2026-09-05: มี max-width แต่ "ไม่มี max-height" → รูปแนวตั้งสูงทะลุจอ
   (วัดจริงบนคอม 1440x900: รูป 400x1600 แสดงสูง 1040px = ต้องเลื่อน 2 จอเพื่อดูใบเดียว)
   ฝั่งมือถือแก้ไปแล้วด้วย --x10m-media-max: 46vh ตั้งแต่ 2026-09-05 (เฟส 1)
   ฝั่งคอมใช้ 62vh — จอคอมสูงกว่า และมักดูรูปคู่กับข้อความรอบ ๆ
   object-fit: contain = ไม่บิดสัดส่วน · กดเปิดดูเต็มใน lightbox ได้เหมือนเดิม */
.msg img.msg-image, .msg video.msg-video {
  max-width: min(320px, 75%); max-height: 62vh; object-fit: contain; object-position: left top;
  border-radius: 10px; margin-top: 4px; display: block; cursor: pointer;
  height: auto;   /* 2026-09-24 คู่กับ width/height ที่ JS ใส่จากขนาดที่จำไว้ (imgDimAttr) = จองที่ไม่บิดสัดส่วน */
}
.msg img.msg-sticker { width: 120px; height: 120px; object-fit: contain; }
.msg audio { margin-top: 4px; max-width: 260px; height: 40px; }
.msg-file { display: inline-flex; gap: 8px; align-items: center; background: var(--blue-light); padding: 8px 12px; border-radius: 10px; margin-top: 4px; font-size: 13px; color: var(--blue); text-decoration: none; }
.msg.system { justify-content: center; }
.msg.system .msg-sys {
  background: var(--sunken); color: var(--muted); font-size: 12.5px; padding: 6px 14px; border-radius: 14px;
  max-width: 92%; white-space: pre-wrap; overflow-wrap: break-word;
}
.msg-actions {
  position: absolute; top: -14px; right: 8px; background: var(--card); border: 1px solid var(--border);
  border-radius: 8px; display: none; box-shadow: var(--shadow); z-index: 5;
}
.msg:hover .msg-actions { display: flex; }
.msg-actions button { border: none; background: none; padding: 5px 8px; cursor: pointer; font-size: 14px; }
.msg-actions button:hover { background: var(--blue-light); }
.day-sep { text-align: center; font-size: 12px; color: var(--muted); margin: 12px 0 6px; }
.day-sep span { background: var(--bg); padding: 2px 12px; border-radius: 10px; border: 1px solid var(--border); }
.typing-bar { min-height: 18px; font-size: 12px; color: var(--muted); padding: 0 16px 2px; }
.reply-bar {
  display: flex; align-items: center; gap: 8px; padding: 6px 12px; background: var(--blue-light);
  font-size: 13px; border-top: 1px solid var(--border);
}
.reply-bar span { flex: 1; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.composer {
  display: flex; align-items: flex-end; gap: 2px; padding: 8px 8px calc(8px + env(safe-area-inset-bottom));
  background: var(--card); border-top: 1px solid var(--border);
}
.composer textarea {
  flex: 1; margin: 0; resize: none; max-height: 120px; border-radius: 20px; padding: 9px 14px; font-size: 15px;
}

/* ---------- calls ---------- */
/* ⚠️ พาเนลโทรต้อง "สูงไม่เกินจอ" และแถวปุ่มต้องอยู่ในจอเสมอ
   เดิมไม่จำกัดความสูง + ช่องวิดีโอ aspect-ratio 4/3 ยืดเต็มความกว้าง
   → พาเนลสูงเกินจอ ดันปุ่ม "🔴 วางสาย" ตกใต้ขอบล่าง กดไม่ได้
   = โทรแล้ววางเองไม่ได้ ต้อง hard refresh (Boss แจ้ง 2026-08-30 พร้อมรูป) */
.call-panel {
  background: var(--call-bg); padding: 10px;
  display: flex; flex-direction: column; gap: 8px;
  max-height: min(60vh, 460px); overflow: hidden; flex: 0 0 auto;
}
.video-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 8px;
  flex: 1 1 auto; min-height: 0; overflow-y: auto;   /* ล้นแล้วเลื่อนในตัว ไม่ดันปุ่ม */
  align-content: start;
}
.video-tile { position: relative; background: var(--call-tile); border-radius: 10px; overflow: hidden; aspect-ratio: 4/3; }
.video-tile video { width: 100%; height: 100%; object-fit: cover; }
.video-tile .vt-name {
  position: absolute; bottom: 4px; left: 6px; color: #fff; font-size: 12px;
  background: rgba(0,0,0,.45); padding: 2px 8px; border-radius: 8px;
}
.video-tile.audio-only { display: flex; align-items: center; justify-content: center; color: #fff; font-size: 30px; }
.call-controls {
  display: flex; gap: 8px; justify-content: center; flex-wrap: wrap;
  flex: 0 0 auto;            /* ห้ามถูกบีบ/ดันหาย — ต้องกด "วางสาย" ได้เสมอ */
}

/* ---------- cards / pages ---------- */
.card { background: var(--card); border-radius: var(--radius); padding: 14px; box-shadow: var(--shadow); margin-bottom: 14px; }
.card h3 { font-size: 15px; color: var(--blue); margin-bottom: 10px; }
.card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; flex-wrap: wrap; gap: 8px; }
.card-head h3 { margin: 0; }
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; margin-bottom: 14px; }
.tile { background: var(--card); border-radius: var(--radius); padding: 12px 14px; box-shadow: var(--shadow); }
.tile .t-num { font-size: 24px; font-weight: 800; color: var(--blue); }
.tile .t-label { font-size: 12px; color: var(--muted); }
.list-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 4px; border-bottom: 1px solid var(--border); font-size: 14px;
}
.list-row:last-child { border-bottom: none; }
.list-row .bar { height: 8px; background: var(--blue); border-radius: 4px; }
.list-row .grow { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- filters ---------- */
.filter-card { padding: 10px 14px; }
.filter-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; font-size: 13px; }
.filter-row input[type=date] { width: auto; margin: 0; padding: 5px 8px; font-size: 13px; }
.f-drop { position: relative; }
.f-drop summary {
  cursor: pointer; padding: 6px 12px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--card); list-style: none; user-select: none;
}
.f-drop[open] summary { background: var(--blue-light); border-color: var(--blue); }
.f-drop .check-list {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 30; background: var(--card);
  border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-pop);
  padding: 8px; min-width: 200px; max-height: 260px; overflow-y: auto;
}
.check-list label { display: flex; align-items: center; padding: 5px 6px; border-radius: 6px; cursor: pointer; font-size: 13.5px; }
.check-list label:hover { background: var(--blue-light); }
.check-list.tall { max-height: 200px; overflow-y: auto; border: 1px solid var(--border); border-radius: 8px; padding: 6px; }
.check-col label { display: flex; align-items: center; padding: 7px 4px; }
.radio-row { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; }
.radio-row label { display: flex; align-items: center; }

/* ---------- pivot ---------- */
.pivot-wrap { overflow: auto; max-height: 60vh; }
.pivot-wrap table { border-collapse: collapse; font-size: 12.5px; min-width: 100%; }
.pivot-wrap th, .pivot-wrap td { border: 1px solid var(--border); padding: 5px 9px; text-align: right; white-space: nowrap; }
.pivot-wrap th { background: var(--blue-light); color: var(--blue); position: sticky; top: 0; text-align: center; }
.pivot-wrap td:first-child, .pivot-wrap th:first-child { text-align: left; position: sticky; left: 0; background: var(--card); font-weight: 600; }
.pivot-wrap td.hot { background: var(--hot); font-weight: 700; }

/* ---------- tables (control panel) ---------- */
.tab-bar { display: flex; gap: 6px; margin-bottom: 12px; flex-wrap: wrap; }
.tab {
  border: 1px solid var(--border); background: var(--card); padding: 7px 14px; border-radius: 20px;
  cursor: pointer; font-size: 13.5px; font-family: inherit;
}
.tab.active { background: var(--blue); color: var(--on-brand); border-color: var(--blue); }
/* ตัวเลขคำขอค้างบนหัวแท็บ (สิทธิ์เลขา) — แดงเสมอ อ่านออกทั้งบนแท็บ active และไม่ active */
.tab-badge {
  display: inline-block; margin-left: 6px; background: #DC2626; color: #fff;
  font-size: 10px; font-weight: 700; line-height: 1; min-width: 16px;
  padding: 3px 4px; border-radius: 999px; text-align: center;
}
.tbl-wrap { overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.tbl th, .tbl td { padding: 8px 10px; border-bottom: 1px solid var(--border); text-align: left; white-space: nowrap; }
.tbl th { color: var(--muted); font-size: 12px; }
.pill { font-size: 11.5px; padding: 2px 9px; border-radius: 10px; background: var(--blue-light); color: var(--blue); }
.pill.green { background: var(--green-bg); color: var(--green); }
.pill.red { background: var(--red-bg); color: var(--red); }
.pill.amber { background: var(--amber-bg); color: var(--amber); }
code.key-code { background: var(--sunken); padding: 2px 7px; border-radius: 6px; font-size: 12px; word-break: break-all; white-space: normal; }

/* ---------- stickers ---------- */
.sticker-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px; max-height: 50vh; overflow-y: auto; }
.sticker-cell { text-align: center; cursor: pointer; padding: 6px; border-radius: 10px; position: relative; }
.sticker-cell:hover { background: var(--blue-light); }
.sticker-cell img { width: 100%; aspect-ratio: 1; object-fit: contain; }
.sticker-cell .st-name { font-size: 11px; color: var(--muted); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.sticker-cell .st-del { position: absolute; top: 0; right: 0; font-size: 11px; background: var(--red); color: var(--on-brand); border: none; border-radius: 50%; width: 18px; height: 18px; cursor: pointer; display: none; }
.sticker-cell:hover .st-del { display: block; }
.sticker-pack-head { grid-column: 1/-1; font-size: 12px; font-weight: 700; color: var(--blue); margin-top: 4px; }
.attach-preview { max-height: 220px; overflow: hidden; text-align: center; margin-bottom: 8px; }
.attach-preview img, .attach-preview video { max-width: 100%; max-height: 200px; border-radius: 10px; }

/* ---------- modals / toast ---------- */
.modal-backdrop {
  position: fixed; inset: 0; background: var(--backdrop); z-index: 100;
  display: flex; align-items: center; justify-content: center; padding: 14px;
}
.modal {
  background: var(--card); border-radius: 16px; padding: 20px; width: 100%; max-width: 420px;
  max-height: 88vh; overflow-y: auto; box-shadow: var(--shadow-modal);
}
.modal.wide { max-width: 680px; }
.modal h3 { color: var(--blue); margin-bottom: 12px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
/* .side-section เป็นคลาสของแถบข้าง (padding 12px 14px + สีของ sidebar)
   พอเอามาใช้ในโมดัลจะเยื้องผิดและใช้สีผิดพื้น → override ให้เข้ากับพื้นโมดัล
   (กระทบ modal-newchannel เดิมด้วย = แก้ให้ตรงกันทั้งคู่) */
.modal .side-section { padding: 4px 0; color: var(--muted); }
/* ปุ่มสุ่มรหัส/ปุ่มเดี่ยวในโมดัล ต้องมีระยะห่างจาก input ด้านบน */
.modal > .btn.small { margin-top: 8px; margin-bottom: 4px; }
.modal .radio-row { margin: 4px 0; }
/* แถบชื่อผู้ใช้+สิทธิ์ในโมดัลโปรไฟล์ (อ่านเท่านั้น) */
.pf-whoami { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 2px 0 6px; }
.pf-whoami .pf-user { font-size: 14px; font-weight: 600; word-break: break-all; }
/* รหัสประจำตัว + แผนก ในโมดัลโปรไฟล์ (อ่านเท่านั้น) */
.pf-orginfo { display: flex; flex-direction: column; gap: 4px; font-size: 14px; padding: 0 0 8px; }
.pf-orginfo .pf-k { color: var(--muted); font-size: 12px; }
.modal select { width: 100%; }
/* สถานะพร้อมอีโมจิ */
.emoji-row { display: flex; flex-wrap: wrap; gap: 6px; padding: 2px 0 6px; }
.emoji-chip {
  font-size: 20px; line-height: 1; padding: 6px 8px; cursor: pointer;
  background: var(--sunken); border: 1px solid var(--border); border-radius: 8px; color: inherit;
}
.emoji-chip:hover { background: var(--side-hover); }
.status-line { display: flex; gap: 8px; align-items: stretch; }
.status-line .emoji-input { width: 56px; text-align: center; font-size: 18px; flex-shrink: 0; }
.status-line input:not(.emoji-input) { flex: 1; min-width: 0; }
/* รูปโปรไฟล์ในโมดัล */
.pf-avatar-row { display: flex; align-items: center; gap: 14px; padding: 4px 0 8px; }
.pf-avatar-btns { display: flex; flex-direction: column; gap: 6px; }
.pf-avatar-btns .btn { text-align: center; cursor: pointer; }
img.avatar { object-fit: cover; }
.clickable { cursor: pointer; }
.clickable:hover { opacity: .82; }
.msg-name.clickable:hover { text-decoration: underline; }
/* โมดัลดูโปรไฟล์คนอื่น */
.up-head { display: flex; gap: 14px; align-items: center; padding: 4px 0 12px; }
.up-name { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.up-display { font-size: 18px; font-weight: 700; word-break: break-word; }
.up-status { font-size: 14px; }
.up-name .pill { align-self: flex-start; }
.up-rows { display: flex; flex-direction: column; gap: 8px; }
.up-row { display: flex; gap: 10px; font-size: 14px; align-items: baseline; }
.up-row .up-k { color: var(--muted); font-size: 12px; min-width: 92px; flex-shrink: 0; }
/* แถบตัวอย่างรูปที่วางด้วย Ctrl+V (เหนือช่องพิมพ์) */
.paste-bar {
  display: flex; flex-direction: column; gap: 8px; padding: 8px 12px;
  background: var(--sunken); border-top: 1px solid var(--border);
}
/* คิวไฟล์แนบ: เลื่อนแนวนอนเมื่อไฟล์เยอะ ไม่ดันจอแชท */
.paste-queue { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 2px; }
.pq-item {
  position: relative; flex-shrink: 0; width: 92px;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 6px 4px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg);
}
.pq-item img { width: 48px; height: 48px; object-fit: cover; border-radius: 6px; }
.pq-icon { font-size: 34px; line-height: 48px; }
.pq-name {
  font-size: 11px; color: var(--muted); max-width: 84px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pq-x {
  position: absolute; top: -6px; right: -6px; width: 20px; height: 20px; padding: 0;
  border: 1px solid var(--border); border-radius: 50%; background: var(--bg);
  color: var(--text); font-size: 11px; cursor: pointer; line-height: 1;
}
.paste-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.paste-foot .small-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* มือถือ 360px: ข้อความบอกใบ้ยาวกว่าที่ว่าง โดนตัดเป็น "พิมพ์ข้อค…"
   → ให้ขึ้นบรรทัดเต็มความกว้างของตัวเอง ปุ่มไปอยู่แถวล่าง อ่านครบ */
@media (max-width: 520px) {
  .paste-foot .small-text { flex: 1 0 100%; white-space: normal; }
}
/* ปุ่มลบ ✕ เดิมล้นออกนอกการ์ด (top/right -6px) ไปทับการ์ดข้างบน
   ย้ายเข้ามาในกรอบ + ทึบแสง แตะได้ชัดบนมือถือ */
.pq-item { padding-top: 10px; overflow: visible; }
.pq-x { top: 2px; right: 2px; width: 22px; height: 22px; box-shadow: 0 1px 3px rgba(0,0,0,.18); }
/* --- ปรับให้ใช้ง่ายขึ้นบนมือถือ (Boss 2026-08-28 รอบ 2) --- */
/* ＋เพิ่มไฟล์ กับ ส่ง เคยอยู่ติดกัน นิ้วโป้งพลาดกดผิด = ส่งออกไปแล้วถอนไม่ได้
   ดันปุ่มส่งไปชิดขวาสุด เว้นช่องว่างจริงระหว่างสองปุ่ม */
/* ถอดปุ่ม "ส่ง" ในแถบคิวออกแล้ว (ซ้ำกับปุ่มเครื่องบินที่ composer)
   เหลือ ＋เพิ่มไฟล์ ชิดซ้าย · ✕ ยกเลิก ชิดขวา */
.paste-foot .btn.ghost { margin-right: auto; }
@media (max-width: 520px) {
  /* ปุ่มสูงพอให้นิ้วโป้งกดไม่พลาด */
  .paste-foot .btn { min-height: 40px; padding-inline: 14px; }
}
/* ตัวเลือกคุณภาพยุบเก็บ — ไม่กินครึ่งจอตอนเปิดโมดัล */
.atc-qwrap { margin: 10px 0 2px; }
.atc-qwrap > summary {
  cursor: pointer; font-size: 13px; color: var(--muted);
  padding: 8px 2px; list-style: none; user-select: none;
}
.atc-qwrap > summary::before { content: '⚙️ '; }
.atc-qwrap > summary::-webkit-details-marker { display: none; }
.atc-qwrap[open] > summary { color: var(--text); }
/* ปุ่มยกเลิกไม่ควรแข่งสายตากับปุ่มหลัก — เบาลงและแคบกว่า */
.atc-actions .atc-cancel { flex: 0 0 auto; opacity: .72; }
.atc-actions .btn.primary { flex: 1; }
/* ปุ่มรูปตรงๆ บน composer */
#btn-quick-pic { color: var(--brand, #0f4c81); }
/* จอแคบ: มี 4 ปุ่มรอบช่องพิมพ์ (＋ รูป ไมค์ ส่ง) เบียดจนช่องพิมพ์เหลือ ~160px
   บีบปุ่มให้แคบลงเล็กน้อย คืนพื้นที่ให้ช่องพิมพ์ แต่ยังสูง 40px+ กดไม่พลาด */
@media (max-width: 420px) {
  .composer .icon-btn { width: 36px; min-width: 36px; padding: 0; }
  .composer #msg-input { min-width: 0; }
}

/* ลากไฟล์มาวาง: overlay คลุมทั้งหน้าจอ — pointer-events:none ไม่ให้กินคลิก/บล็อก drop */
.drop-overlay {
  position: fixed; inset: 0; z-index: 400; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  background: rgba(15, 76, 129, .18); backdrop-filter: blur(1.5px);
}
.drop-overlay.hidden { display: none; }
.drop-box {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 28px 40px; border-radius: 16px; border: 2.5px dashed var(--primary, #0F4C81);
  background: var(--card); color: var(--text); font-size: 15px; font-weight: 600;
  box-shadow: 0 10px 40px rgba(0,0,0,.25);
}
.drop-icon { font-size: 38px; }
.drop-box .small-text { font-weight: 400; }
.paste-info { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.paste-info span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* การ์ดแก้ไขห้องในแผงจัดการห้อง */
.ra-label { display: flex; flex-direction: column; gap: 4px; margin: 8px 0; font-size: 13px; color: var(--muted); }
.ra-label input, .ra-label select { color: var(--text); }
.ra-label select { width: auto; min-width: 160px; }
.toast {
  position: fixed; bottom: 80px; left: 50%; transform: translateX(-50%); background: var(--toast-bg); color: var(--toast-text);
  padding: 10px 20px; border-radius: 24px; font-size: 14px; z-index: 200; box-shadow: 0 6px 20px rgba(0,0,0,.3);
  max-width: 90vw; text-align: center;
}

/* ---------- meetings page ---------- */
.meeting-item { cursor: pointer; }
.meeting-item:hover { outline: 2px solid var(--blue-light); }
.summary-md { font-size: 14px; line-height: 1.65; white-space: pre-wrap; word-wrap: break-word; }
.summary-md h1, .summary-md h2 { color: var(--blue); margin: 10px 0 4px; font-size: 16px; }

/* ---------- v2: ภาษา / threads / mention / nested comments / schedule ---------- */
.lang-row { display: flex; gap: 6px; justify-content: center; margin: 6px 0 12px; flex-wrap: wrap; }
.lang-btn {
  padding: 5px 12px; border-radius: 16px; border: 1px solid var(--border); background: var(--card);
  cursor: pointer; font-size: 13px; font-family: inherit; color: var(--text);
}
.lang-btn.active { background: var(--blue); color: var(--on-brand); border-color: var(--blue); }
.modal .lang-row, .sidebar .lang-row { justify-content: flex-start; }

/* Boss 2026-09-01: กระดิ่งโชว์ "จำนวน" แทนจุดแดงเปล่า
   ⚠️ #threads-dot-m ยังใช้คลาสนี้ (id เดิมมีโค้ดอื่นอ้างอยู่) จึงต้องรับตัวเลขได้
      ของเดิมเป็นวงกลม 9x9 ตายตัว ใส่เลขไปก็มองไม่เห็น */
.nav-dot {
  position: absolute; top: 2px; right: 4px;
  min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px;
  background: var(--red); border: 2px solid var(--card);
  color: #fff; font-size: 10px; font-weight: 800; font-variant-numeric: tabular-nums;
  line-height: 13px; text-align: center;
}
/* ไม่มีเลข (ของเก่าที่ยังใช้เป็นจุดล้วน) = กลับไปเป็นวงกลมเล็กเหมือนเดิม */
.nav-dot:empty {
  min-width: 0; width: 9px; height: 9px; padding: 0; border-radius: 50%;
  top: 4px; right: 8px;
}
.side-nav .nav-btn, .bottom-nav .nav-btn { position: relative; }

/* ---- คอมเมนต์แบบ Facebook: กล่องคอมเมนต์ + เส้นแนวตั้งเส้นเดียว ---- */
/* หัวข้อ "N คอมเมนต์" เหนือกลุ่ม */
/* แถวบน: จำนวนคอมเมนต์ชิดขวา (เฟส) */
.cmt-topline { display: flex; justify-content: flex-end; padding: 2px 4px 0 46px; }
.cmt-count { font-size: 12.5px; font-weight: 600; color: var(--muted); }
/* แถบเรียงลำดับคอมเมนต์ */
.cmt-bar { display: flex; padding: 2px 4px 6px 46px; }
.cmt-sorts { display: flex; gap: 16px; }
.cmt-sort {
  border: none; background: none; padding: 0; cursor: pointer; font-family: inherit;
  font-size: 13px; font-weight: 600; color: var(--muted);
}
.cmt-sort:hover { text-decoration: underline; }
.cmt-sort.active { color: var(--blue); font-weight: 700; }
/* ปุ่ม "ดูการตอบกลับอีก N รายการ" */
.cmt-more {
  border: none; background: none; padding: 4px 0; cursor: pointer; font-family: inherit;
  font-size: 13px; font-weight: 600; color: var(--text);
  display: flex; align-items: center; gap: 7px;
}
.cmt-more:hover { text-decoration: underline; }
.cmt-more-caret { font-size: 15px; color: var(--muted); }
/* ปุ่มขยายของการตอบซ้อน — เยื้องให้ตรงกับคอมเมนต์ชั้น 2 */
.cmt-more-wrap { padding-left: 34px; }
.cmt-group > .cmt-more { padding-left: 0; }
/* ช่องพิมพ์ตอบกลับท้ายกลุ่มคอมเมนต์ */
.cmt-composer {
  display: flex; align-items: center; gap: 9px; margin-top: 6px; cursor: text;
}
.cmt-composer .avatar { width: 30px; height: 30px; font-size: 11px; flex: none; }
.cmt-composer-ph {
  flex: 1; background: var(--bubble, rgba(127,127,127,.10));
  border-radius: var(--radius-pill); padding: 8px 15px;
  font-size: 13.5px; color: var(--muted);
}
.cmt-composer-send { color: var(--blue); font-size: 16px; padding-right: 6px; }
/* ช่องพิมพ์จริงเปิดอยู่ = ซ่อน placeholder ไม่ให้ขึ้นซ้อน 2 อัน (Boss แจ้ง 2026-08-21) */
#messages.ir-open .cmt-composer { display: none; }
/* กล่องครอบคอมเมนต์ทั้งก้อน — เส้นแนวตั้งเทาอ่อนเส้นเดียวยาวตลอดกลุ่ม */
.cmt-group {
  margin: 0 0 6px 46px; padding-left: 12px;
  border-left: 2px solid var(--border);
}
/* คอมเมนต์ในกล่อง: ไม่ต้องเยื้อง/ไม่ต้องมีเส้นของตัวเอง (กล่องจัดให้แล้ว) */
.cmt-group .msg.nested { margin-left: 0; padding-left: 0; margin-top: 0; margin-bottom: 2px; }
.cmt-group .msg.nested::before { content: none; }
/* ชั้น 2 เยื้องเข้าไปอีกขั้น อวตารเล็กลง */
.cmt-group .msg.nested[data-depth="2"] { margin-left: 34px; }
.msg.nested .avatar { width: 28px; height: 28px; font-size: 11px; }
.msg.nested[data-depth="2"] .avatar { width: 24px; height: 24px; font-size: 10px; }
/* บับเบิลเทากว้างเต็มแนว — ชื่อบรรทัดบน ข้อความบรรทัดล่าง */
.msg.nested .msg-bubble {
  background: var(--bubble, rgba(127,127,127,.10));
  border-radius: 14px; padding: 6px 12px 7px; max-width: 100%;
}
.msg.nested .msg-head { display: block; margin-bottom: 1px; }
.msg.nested .msg-name { font-size: 13px; font-weight: 700; }
.msg.nested .msg-text { font-size: 14px; }
.msg.nested[data-depth="2"] .msg-text { font-size: 13.5px; }
/* แถวปุ่มอยู่นอกบับเบิล (เฟส) */
/* แถวปุ่มอยู่ "นอก" บับเบิล (เฟส) — เยื้องเข้าให้ตรงกับข้อความในบับเบิล */
.msg.nested .msg-foot { margin: 4px 0 0; padding-left: 12px; gap: 14px; align-items: center; }
.msg.nested .msg-foot-btn { font-size: 11.5px; }
.msg-foot-time { font-size: 11.5px; color: var(--muted); }
.reply-to { font-size: 11.5px; font-weight: 600; color: var(--muted); }
.msg-comment-btn {
  border: none; background: none; color: var(--muted); font-size: 12px; cursor: pointer;
  padding: 1px 6px; font-weight: 600; font-family: inherit;
}
.msg-comment-btn:hover { color: var(--blue); }
.mention { color: var(--blue); font-weight: 700; background: var(--blue-light); border-radius: 4px; padding: 0 3px; }
/* ⚠️⚠️ bottom เป็นค่าคงที่ 64px = "เดา" ความสูง composer (Boss แจ้ง 2026-08-31 พร้อมรูป)
   composer จริงสูง 144px บนมือถือ / 89px บนคอม (แถบจัดข้อความ + textarea + แถวปุ่ม)
   แถม textarea ยืดตามบรรทัดที่พิมพ์ → ป๊อปอัพทับข้อความที่กำลังพิมพ์อยู่ 84px
   ⇒ ผูกกับความสูงจริงผ่านตัวแปร --composer-h (ตั้งค่าตอนรันใน positionMentionPop())
      ค่า fallback 150px เผื่อ JS ยังไม่ทัน — เกินดีกว่าทับ */
.mention-pop {
  position: absolute; bottom: calc(var(--composer-h, 150px) + 8px); left: 12px; right: 12px; max-width: 380px; max-height: 220px;
  overflow-y: auto; background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 -6px 24px rgba(0,0,0,.15); z-index: 60;
}
.mention-item { display: flex; align-items: center; gap: 8px; padding: 8px 12px; cursor: pointer; font-size: 14px; }
.mention-item:hover, .mention-item.sel { background: var(--blue-light); }

/* ---------- โหมด @แผนก : ลิสต์สั้น ไม่บังข้อความ (Boss แจ้ง 2026-08-31) ----------
   เดิมใช้แถวเดียวกับรายชื่อคน (สูง ~47px + avatar 22px) พอมี 26 แผนก
   ป๊อปอัพสูงเต็มจอบังข้อความที่กำลังพิมพ์ ทั้งที่แต่ละแถวมีแค่ชื่อสั้น ๆ กับตัวเลข
   → แถวเตี้ยลง + ไอคอนเล็กลง + 2 คอลัมน์บนจอกว้าง = เห็นครบเร็วขึ้นโดยไม่กินที่ */
.mention-pop.dept-mode { max-height: 172px; padding: 4px; }
.mention-pop.dept-mode .mention-item {
  padding: 5px 8px; font-size: 13px; gap: 6px; border-radius: 6px;
}
.mention-pop.dept-mode .mention-item span:first-of-type {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* หัวข้อบอกว่ากำลังดูอะไรอยู่ + นับรวม — กันงงว่าทำไมรายชื่อคนหายไป */
.mention-pop .dept-head {
  position: sticky; top: 0; z-index: 1; background: var(--card);
  padding: 6px 10px 5px; font-size: 11px; font-weight: 700; letter-spacing: .02em;
  color: var(--muted); border-bottom: 1px solid var(--border); margin: -4px -4px 4px;
}
/* จอกว้างพอ = เรียง 2 คอลัมน์ ลดความสูงลงครึ่งหนึ่ง */
@media (min-width: 480px) {
  .mention-pop.dept-mode { display: flex; flex-wrap: wrap; align-content: flex-start; }
  .mention-pop.dept-mode .dept-head { flex: 0 0 100%; }
  .mention-pop.dept-mode .mention-item { flex: 0 0 calc(50% - 2px); box-sizing: border-box; }
}
.chat-room { position: relative; }

.thread-item { cursor: pointer; }
.thread-item.unread { border-left: 4px solid var(--red); }
.thread-item:hover { outline: 2px solid var(--blue-light); }

/* ประกาศ: ย่อให้พอดีจอ (Boss 2026-08-28 "ป๊อปอัปใหญ่ไป")
   เดิมเนื้อหายาวดันโมดัลสูง 62-69% ของจอ → จำกัดความสูงเนื้อหา ให้เลื่อนในตัวเอง */
.announce-item { border-left: 3px solid var(--amber); padding: 8px 11px; margin-bottom: 8px; background: var(--amber-soft); border-radius: 8px; }
.announce-item h4 { color: var(--blue-dark); margin-bottom: 4px; font-size: 14px; }
.announce-item .a-body {
  white-space: pre-wrap; font-size: 13px; line-height: 1.55;
  max-height: 26vh; overflow-y: auto;      /* ยาวแค่ไหนก็ไม่ดันโมดัล */
  -webkit-overflow-scrolling: touch;
}
#modal-announce { max-width: 380px; padding: 16px; }
#modal-announce h3 { font-size: 15px; margin-bottom: 9px; }
#modal-announce .modal-actions { margin-top: 9px; }
@media (max-width: 560px) {
  .announce-item .a-body { max-height: 32vh; }
  #modal-announce { padding: 14px; }
}

/* v3: ปุ่มอัปโหลดใหญ่ + คำแปล + unread badge */
.upload-big {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  border: 2px dashed var(--blue); border-radius: 14px; padding: 26px 14px; cursor: pointer;
  background: var(--blue-light); margin-bottom: 10px; text-align: center; font-weight: 600; color: var(--blue-dark);
}
.upload-big:hover { background: var(--hot); }
.upload-big .up-icon { font-size: 40px; }
#share-result { display: flex; gap: 6px; margin-top: 8px; }
#share-result input { flex: 1; font-size: 13px; color: var(--blue-dark); }
.msg-translation {
  margin-top: 4px; padding: 6px 10px; border-left: 3px solid var(--green);
  background: var(--green-soft); border-radius: 6px; font-size: 14px; white-space: pre-wrap;
}
.msg-translation .tr-meta { font-size: 11px; color: var(--muted); margin-top: 2px; }
.chan-unread {
  background: var(--red); color: var(--on-brand); border-radius: 10px; font-size: 11px; font-weight: 700;
  padding: 1px 7px; margin-left: auto;
}
.speaking { color: var(--blue) !important; }

/* ---------- nav ---------- */
.bottom-nav { display: none; }
.only-mobile { display: none; }

/* ================= MOBILE ================= */
@media (max-width: 860px) {
  .two-col { grid-template-columns: 1fr; }
  .only-mobile { display: inline-flex; }
  .only-desktop { display: none; }
  .sidebar {
    position: fixed; inset: 0 22% 0 0; max-width: 320px; transform: translateX(-100%);
    /* .3s + ease-out — Boss สั่ง 2026-09-03 18:52 "ปรับช้าลงนิดนึง ให้เห็นอนิเมชันขยับออกมา"
       (เดิม .22s ease เร็วไปจนเหมือนโผล่ทันที) ease-out = ออกตัวเร็ว หน่วงตอนจบ ดูนุ่มกว่า */
    transition: transform .3s cubic-bezier(.22,.61,.36,1); box-shadow: 4px 0 24px rgba(0,0,0,.25);
  }
  .sidebar.open { transform: translateX(0); }
  .app { flex-direction: column; }
  .main { padding-bottom: 58px; }
  .bottom-nav {
    display: flex; position: fixed; bottom: 0; left: 0; right: 0; background: var(--card);
    border-top: 1px solid var(--border); z-index: 50; padding-bottom: env(safe-area-inset-bottom);
  }
  .nav-btn {
    flex: 1; border: none; background: none; padding: 7px 2px 5px; font-size: 19px; cursor: pointer;
    display: flex; flex-direction: column; align-items: center; gap: 1px; color: var(--muted); font-family: inherit;
  }
  .nav-btn span { font-size: 10px; }
  .nav-btn.active { color: var(--blue); font-weight: 700; }
  .msg-actions { display: flex; opacity: 0; pointer-events: none; }
  .msg.show-actions .msg-actions { opacity: 1; pointer-events: auto; }
  .messages { padding: 8px 6px 4px; }
  .page-body { padding: 10px; }
  /* mobile UX: ปุ่มใหญ่ กดง่าย + modal แบบ bottom sheet */
  .icon-btn { font-size: 22px; padding: 9px; }
  .composer textarea { font-size: 16px; }
  .msg-text { font-size: 15.5px; }
  .modal-backdrop { align-items: flex-end; padding: 0; }
  .modal { max-width: 100%; border-radius: 18px 18px 0 0; max-height: 92vh; padding: 18px 16px calc(18px + env(safe-area-inset-bottom)); }
  .btn { padding: 11px 18px; }
  .cmt-count { margin-left: 32px; }
  .cmt-group { margin-left: 32px; padding-left: 8px; }
  .cmt-group .msg.nested[data-depth="2"] { margin-left: 22px; }
  /* มือถือใช้ตัวแปรเดียวกัน — ห้ามกลับไป hardcode (composer สูง 144px) */
  .mention-pop { bottom: calc(var(--composer-h, 150px) + 8px); }
}

/* ---------- theme toggle / install (เพิ่มพร้อมโหมดมืด+PWA) ---------- */
.head-tools { display: flex; align-items: center; gap: 2px; }
.theme-fab {
  position: absolute; top: calc(10px + env(safe-area-inset-top)); left: 12px; z-index: 5;
  background: rgba(255,255,255,.16); color: #fff; backdrop-filter: blur(4px);
}
.theme-fab:active { background: rgba(255,255,255,.28); }

/* ---- ห้องล็อก / จัดการห้อง (roomlock 2026-08-19) ---- */
.chan-item.chan-locked { opacity: .62; }
.chan-item.chan-locked:hover { opacity: 1; }
.chan-pending { font-size: 12px; opacity: .8; }
.chan-sec { padding: 10px 12px 4px; font-size: 11px; letter-spacing: .04em;
  text-transform: uppercase; opacity: .55; }
.mg-body { max-height: 62vh; overflow: auto; }
.mg-body h4 { margin: 14px 0 6px; font-size: 13px; opacity: .8; }
.ra-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.ra-table th, .ra-table td { padding: 6px 8px; text-align: left;
  border-bottom: 1px solid rgba(127,127,127,.22); vertical-align: middle; }
.ra-key { font-family: ui-monospace, Menlo, monospace; font-size: 12px;
  word-break: break-all; }
.ra-pre { background: rgba(127,127,127,.12); padding: 10px; border-radius: 8px;
  font-size: 12px; overflow-x: auto; white-space: pre; }
.btn-mini { padding: 2px 7px; font-size: 12px; border-radius: 6px; cursor: pointer;
  border: 1px solid rgba(127,127,127,.35); background: transparent; color: inherit; }
.btn-mini:hover { background: rgba(127,127,127,.18); }
.btn-mini.danger { color: #EF4444; border-color: rgba(239,68,68,.45); }

.chan-sec-btn { cursor: pointer; display: flex; align-items: center; gap: 6px;
  user-select: none; }
.chan-sec-btn:hover { opacity: .9; }
.chan-sec-n { margin-left: auto; opacity: .6; font-size: 10px; }

/* ---- เลขา AI ส่วนตัว (2026-08-19) ---- */
.sec-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0;
  padding: 14px 16px; gap: 10px; }
.sec-head { display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; }
.sec-head h2 { margin: 0 0 2px; font-size: 18px; }
.sec-head-btns { display: flex; gap: 6px; flex-wrap: wrap; }
.sec-chat { flex: 1; min-height: 0; overflow-y: auto; display: flex;
  flex-direction: column; gap: 10px; padding: 6px 2px; }
.sec-empty { margin: auto; text-align: center; opacity: .5; font-size: 40px; }
.sec-empty p { font-size: 14px; margin-top: 8px; max-width: 380px; }
.sec-msg { display: flex; flex-direction: column; max-width: 86%; }
.sec-msg.me { align-self: flex-end; align-items: flex-end; }
.sec-msg.bot { align-self: flex-start; }
.sec-bubble { padding: 9px 13px; border-radius: 14px; line-height: 1.55;
  font-size: 14px; word-break: break-word; }
.sec-msg.me .sec-bubble { background: #0F4C81; color: #fff;
  border-bottom-right-radius: 4px; }
.sec-msg.bot .sec-bubble { background: rgba(127,127,127,.16);
  border-bottom-left-radius: 4px; }
.sec-bubble ul { margin: 6px 0; padding-left: 20px; }
.sec-bubble blockquote { margin: 6px 0; padding-left: 10px;
  border-left: 3px solid rgba(127,127,127,.4); opacity: .85; }
.sec-eng { font-size: 10px; opacity: .45; margin-top: 3px; padding-left: 4px; }
.sec-dots { display: flex; gap: 4px; align-items: center; }
.sec-dots span { width: 7px; height: 7px; border-radius: 50%;
  background: currentColor; opacity: .35; animation: secblink 1.2s infinite; }
.sec-dots span:nth-child(2) { animation-delay: .2s; }
.sec-dots span:nth-child(3) { animation-delay: .4s; }
@keyframes secblink { 0%,80%,100% { opacity: .25 } 40% { opacity: .9 } }
.sec-quick { display: flex; gap: 6px; flex-wrap: wrap; }
.sec-chip { padding: 5px 11px; border-radius: 999px; font-size: 12px;
  cursor: pointer; border: 1px solid rgba(127,127,127,.35);
  background: transparent; color: inherit; }
.sec-chip:hover { background: rgba(127,127,127,.15); }
.sec-input { display: flex; gap: 8px; align-items: flex-end; }
.sec-input textarea { flex: 1; resize: none; padding: 9px 12px; border-radius: 12px;
  font: inherit; font-size: 14px; }
.sec-input .btn { padding: 9px 16px; }
.sec-lb { display: block; margin: 10px 0 4px; font-size: 12px; opacity: .75; }
.mg-body input, .mg-body textarea { width: 100%; padding: 7px 10px;
  border-radius: 8px; font: inherit; font-size: 13px; }
.sec-factadd { display: flex; gap: 6px; align-items: center; margin-top: 8px; }
.sec-factadd input { flex: 1; }
.sec-ok { color: #10B981; font-size: 12px; }
.sec-wait { color: #F59E0B; font-size: 12px; }
.sec-no { color: #94A3B8; font-size: 12px; }
.sec-steps { list-style: none; padding: 0; margin: 8px 0; }
.sec-steps li { padding: 7px 0; border-bottom: 1px solid rgba(127,127,127,.15);
  font-size: 14px; }
.sec-step-done { opacity: .55; }
.sec-privacy { margin-top: 12px; padding: 8px 10px; border-radius: 8px;
  background: rgba(16,185,129,.1); font-size: 12px; }
@media (max-width: 640px) { .sec-msg { max-width: 94%; } }


/* ============================================================================
   UI/UX REDESIGN LAYER — 2026-08-19 (uiux-20260819-1255)
   งานนี้ "แก้หน้าตาเท่านั้น" ระบบการทำงานเดิมทุกอย่าง
   วางไว้ท้ายไฟล์เพื่อให้ override กฎเดิมด้วยลำดับ cascade ไม่ต้องรื้อ 616 บรรทัดข้างบน
   หลักการ: (1) พื้นผิวเดียว sidebar ไม่ใช่บล็อกน้ำเงินทึบอีก
            (2) น้ำเงิน X10 = accent เท่านั้น ไม่ใช่พื้นหลัง
            (3) type scale + spacing 4px grid
            (4) responsive 3 ระดับ: <720 / 720-1100 / >1100
   ========================================================================== */

:root {
  /* ---- โทนสีโหมดสว่าง (เพิ่ม 2026-08-22) ----
     ⚠️ เดิมตัวแปรชุดนี้นิยามไว้แค่ใน html[data-theme="dark"] และ html[data-accent="..."]
        โหมดสว่างปกติ (ไม่เลือกชุดสี) จึงไม่มีค่า → var(--blue) ว่าง สวิตช์เปิด/ปิดดูเหมือนกัน
        ค่าที่ใส่นี้ = สีที่แอปฮาร์ดโค้ดไว้อยู่แล้ว (#0F4C81 ใช้ 25 ที่, #E2E8F0 15 ที่, #64748B 12 ที่)
        จึงไม่เปลี่ยนหน้าตาเดิม แค่ทำให้ตัวแปรมีค่าจริง */
  --blue: #0F4C81; --blue-dark: #0B3A63; --blue-light: #EAF1F8;
  --bg: #F7F9FB; --card: #FFFFFF; --text: #1E293B; --muted: #64748B;
  --border: #E2E8F0; --sunken: #F4F6F9; --on-brand: #FFFFFF;
  --pane-split: #CBD5E1;   /* เส้นแบ่งบานแยก — เข้มกว่า --border ให้เห็นว่าคนละห้อง */
  --green: #047857; --red: #B91C1C; --amber: #B45309;
  --red-bg: #FEE2E2;
  --bubble: #EFF2F6; --bubble-mine: #0F4C81; --msg-hover: rgba(15,76,129,.055);

  /* ---- type scale (เดิมกระโดด 13.5/14.5/15.5 ไม่มีระบบ) ---- */
  --fs-xs: 11px; --fs-sm: 12.5px; --fs-md: 14px; --fs-base: 15px;
  --fs-lg: 17px; --fs-xl: 20px;
  --lh: 1.55;

  /* ---- spacing 4px grid ---- */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 20px; --s6: 24px;

  /* ---- รัศมี: อ่อนลง มินิมอลขึ้น ---- */
  --radius: 10px; --radius-sm: 8px; --radius-lg: 14px; --radius-pill: 999px;

  /* ---- เงา: บางลงมาก ใช้เส้นขอบเป็นตัวแบ่งหลักแทนเงา ---- */
  --shadow: 0 1px 2px rgba(16,24,40,.04);
  --shadow-pop: 0 4px 16px rgba(16,24,40,.10);
  --shadow-modal: 0 12px 40px rgba(16,24,40,.18);

  /* ---- พื้นผิวเดียว: sidebar เลิกเป็นน้ำเงินทึบ กลืนกับแอป ---- */
  --side-bg: #FFFFFF;
  --side-text: #1E293B;
  --side-muted: #64748B;
  --side-section: #94A3B8;
  --side-item: #334155;
  --side-hover: rgba(15,76,129,.06);
  --side-raise: transparent;
  --side-input: #F4F6F9;
  --side-ph: #94A3B8;
  --side-active: var(--blue-light);
  --side-presence: #CBD5E1;
  --side-border: #E6EBF1;

  --transition: 120ms cubic-bezier(.4,0,.2,1);
  --focus: 0 0 0 3px rgba(15,76,129,.28);

  /* 🔴🔴 toast: เดิมประกาศไว้**เฉพาะ `html[data-theme="dark"]`** (บรรทัด ~175)
     ธีมสว่างจึงได้ var ว่าง → background โปร่งใส = **ตัวหนังสือลอยทับพื้นหลัง อ่านไม่ออก**
     กระทบ toast ทุกตัวในแอป (ใช้ 424 ที่) ไม่ใช่แค่ของใหม่ — เจอตอนเทสแจ้งเตือนแท็ก 2026-09-12
     ธีมสว่างใช้พื้นเข้ม-ตัวอักษรสว่าง (กลับสี) แบบเดียวกับ toast ของ Slack/Gmail */
  --toast-bg: #1E293B; --toast-text: #F1F5F9;
}

html[data-theme="dark"] {
  --shadow: 0 1px 2px rgba(0,0,0,.30);
  --shadow-pop: 0 4px 16px rgba(0,0,0,.45);
  --shadow-modal: 0 12px 40px rgba(0,0,0,.60);

  --side-bg: #131D29;
  --side-text: #E5EAF0;
  --side-muted: #94A3B8;
  --side-section: #6B7B8F;
  --side-item: #C3CEDB;
  --side-hover: rgba(255,255,255,.05);
  --side-raise: transparent;
  --side-input: #1C2836;
  --side-ph: #6B7B8F;
  --side-active: #1A3350;
  --side-presence: #3A4759;
  --side-border: #24303F;

  --focus: 0 0 0 3px rgba(77,155,224,.34);
}

body { font-size: var(--fs-base); line-height: var(--lh); -webkit-font-smoothing: antialiased; }

/* โฟกัสมองเห็นได้ทุกที่ (เดิม outline ทับขอบ input จนดูเพี้ยน) */
:focus-visible { outline: none; box-shadow: var(--focus); }
input:focus, textarea:focus, select:focus { outline: none; border-color: var(--blue); box-shadow: var(--focus); }

/* ---------------- ปุ่ม / อินพุต: บางลง สม่ำเสมอ ---------------- */
.btn {
  border-radius: var(--radius-sm); font-size: var(--fs-md); font-weight: 500;
  padding: 9px 14px; transition: background var(--transition), border-color var(--transition);
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.btn:hover { background: var(--side-hover); }
.btn.primary { font-weight: 600; }
.btn.primary:hover { background: var(--blue-dark); border-color: var(--blue-dark); }
.btn.ghost { border-color: transparent; }
.btn.ghost:hover { background: var(--side-hover); }
.icon-btn {
  border-radius: var(--radius-sm); transition: background var(--transition);
  display: inline-flex; align-items: center; justify-content: center;
}
.icon-btn:hover { background: var(--side-hover); }
input, textarea, select {
  border-radius: var(--radius-sm); font-size: var(--fs-base);
  transition: border-color var(--transition), box-shadow var(--transition);
}

/* ---------------- Sidebar: พื้นผิวเดียว + เส้นแบ่ง ---------------- */
.sidebar {
  width: 264px; border-right: 1px solid var(--side-border);
  background: var(--side-bg); color: var(--side-text);
}
.sidebar-head { padding: var(--s3) var(--s3) var(--s2); }
.brand { font-size: var(--fs-base); font-weight: 700; letter-spacing: -.01em; }
.sidebar .icon-btn { color: var(--side-muted); }
.sidebar .icon-btn:hover { color: var(--side-text); }

.sidebar-me {
  margin: 0 var(--s2) var(--s2); padding: var(--s2);
  border-radius: var(--radius); background: transparent;
  border: 1px solid transparent; transition: background var(--transition);
}
.sidebar-me:hover { background: var(--side-hover); }
.me-name { font-size: var(--fs-md); font-weight: 600; }
.me-status { font-size: var(--fs-sm); }

/* ---- nav เดสก์ท็อป: แนวตั้ง มีป้ายชื่อ ไม่ใช่ไอคอนเปล่า 6 ช่อง ---- */
.side-nav {
  display: flex; flex-direction: column; gap: 1px;
  margin: 0 var(--s2) var(--s2);
}
.side-nav .nav-btn {
  flex: none; display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--radius-sm);
  background: transparent; color: var(--side-item);
  font-size: var(--fs-md); font-weight: 500; text-align: left;
  font-family: inherit; transition: background var(--transition), color var(--transition);
}
.side-nav .nav-btn:hover { background: var(--side-hover); color: var(--side-text); }
.side-nav .nav-btn.active {
  background: var(--side-active); color: var(--blue); font-weight: 600;
}
.side-nav .nav-icon { font-size: 16px; line-height: 1; width: 20px; text-align: center; flex-shrink: 0; }
.side-nav .nav-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.side-nav .nav-dot { position: static; margin-left: auto; border: none; }
.side-nav .nav-dot:empty { width: 8px; height: 8px; }   /* จุดล้วนคงเดิม · มีเลขให้ป้ายกว้างตามเลข */

.side-admin { margin: 0 var(--s2) var(--s2); padding-top: var(--s2); border-top: 1px solid var(--side-border); }
.side-admin .nav-btn-wide {
  justify-content: flex-start; gap: 10px; background: transparent; color: var(--side-item);
  padding: 8px 10px; border-radius: var(--radius-sm); font-size: var(--fs-md);
  transition: background var(--transition);
}
.side-admin .nav-btn-wide:hover { background: var(--side-hover); }
.side-admin .nav-btn-wide.active { background: var(--side-active); color: var(--blue); }
.side-admin .nav-btn-label { font-size: var(--fs-md); font-weight: 500; }
.side-admin .nav-btn-wide.active .nav-btn-label { font-weight: 600; }

.side-search {
  margin: 0 var(--s2) var(--s2); width: calc(100% - var(--s4));
  background: var(--side-input); border: 1px solid transparent;
  color: var(--side-text); font-size: var(--fs-md); padding: 8px 12px;
}
.side-search:focus { background: var(--card); border-color: var(--blue); }

.side-scroll { padding-bottom: var(--s3); scrollbar-width: thin; }
.side-scroll::-webkit-scrollbar { width: 8px; }
.side-scroll::-webkit-scrollbar-thumb { background: var(--side-presence); border-radius: 4px; }
.side-scroll::-webkit-scrollbar-track { background: transparent; }

.side-section {
  font-size: var(--fs-xs); letter-spacing: .05em; color: var(--side-section);
  padding: var(--s4) var(--s3) var(--s1); font-weight: 600;
}
.chan-item, .user-item {
  margin: 0 var(--s2) 1px; padding: 7px 10px; border-radius: var(--radius-sm);
  font-size: var(--fs-md); color: var(--side-item);
  transition: background var(--transition);
}
.chan-item:hover, .user-item:hover { background: var(--side-hover); }
.chan-item.active { background: var(--side-active); color: var(--blue); font-weight: 600; }
.avatar { width: 30px; height: 30px; font-size: 13px; }
.sidebar-me .avatar { width: 34px; height: 34px; }

/* ---------------- หัวหน้า / หัวห้อง ---------------- */
.page-head, .chat-head {
  padding: var(--s2) var(--s4); border-bottom: 1px solid var(--border);
  min-height: 54px; gap: var(--s2);
}
.page-head h2 { font-size: var(--fs-lg); font-weight: 650; color: var(--text); letter-spacing: -.01em; }
.chat-name { font-size: var(--fs-base); font-weight: 650; letter-spacing: -.01em; }
.chat-topic { font-size: var(--fs-sm); }
.chat-title { border-radius: var(--radius-sm); padding: 2px 6px; margin-left: -6px; transition: background var(--transition); }
.chat-title:hover { background: var(--side-hover); }
.chat-actions { gap: 2px; align-items: center; }
.page-body { padding: var(--s4); }

/* ---------------- ข้อความ: จำกัดความกว้างให้อ่านสบายบนจอกว้าง ---------------- */
.messages { padding: var(--s3) var(--s4) var(--s1); scroll-behavior: smooth; }
.msg { padding: var(--s1) var(--s2); border-radius: var(--radius-sm); gap: 10px; }
.msg:hover { background: var(--side-hover); }
.msg-name { font-size: var(--fs-md); font-weight: 650; }
.msg-time { font-size: var(--fs-xs); }
.msg-text { font-size: var(--fs-md); line-height: 1.55; }
.msg .avatar { width: 30px; height: 30px; }
.day-sep span {
  background: var(--card); border-color: var(--border); font-size: var(--fs-sm);
  padding: 3px 12px; border-radius: var(--radius-pill);
}
.msg-actions {
  border-radius: var(--radius-sm); box-shadow: var(--shadow-pop);
  top: -12px; right: var(--s3); overflow: hidden;
}
.msg-actions button { padding: 6px 9px; transition: background var(--transition); }
.msg-file, .msg-reply { border-radius: var(--radius-sm); }

/* ---------------- Composer: ปุ่มรองยุบใน ＋ ช่องพิมพ์กว้างขึ้น ---------------- */
.composer {
  gap: var(--s1); padding: var(--s2) var(--s3) calc(var(--s2) + env(safe-area-inset-bottom));
  align-items: flex-end;
}
.composer textarea {
  border-radius: var(--radius-lg); padding: 9px 14px; font-size: var(--fs-base);
  background: var(--side-input); border-color: transparent; line-height: 1.5;
}
.composer textarea:focus { background: var(--card); border-color: var(--blue); }
.icon-btn.send {
  background: var(--blue); color: var(--on-brand); font-size: 17px;
  width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0;
}
.icon-btn.send:hover { background: var(--blue-dark); }

/* popover ปุ่มรอง (＋ ใน composer, ⋯ ในหัวห้อง) */
.pop-menu {
  position: absolute; z-index: 70; background: var(--card);
  border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-pop); padding: var(--s1); min-width: 196px;
  display: flex; flex-direction: column; gap: 1px;
}
.pop-menu.hidden { display: none; }
.pop-menu button {
  display: flex; align-items: center; gap: 10px; width: 100%;
  border: none; background: transparent; color: var(--text);
  padding: 9px 10px; border-radius: var(--radius-sm); cursor: pointer;
  font-size: var(--fs-md); font-family: inherit; text-align: left;
  transition: background var(--transition);
}
.pop-menu button:hover { background: var(--side-hover); }
.pop-menu button .pm-icon { font-size: 16px; width: 20px; text-align: center; flex-shrink: 0; }
/* ออกจากห้อง — สีแดงและมีเส้นคั่น ให้ต่างจากเมนูปกติ กันกดพลาด (Boss สั่ง 2026-08-31) */
.pop-menu button.pm-danger { color: var(--red); border-top: 1px solid var(--border); margin-top: 4px; padding-top: 10px; }
.pop-menu button.pm-danger:hover { background: var(--red-bg); }
.pop-menu .pm-sep { height: 1px; background: var(--border); margin: var(--s1) 0; }
/* .composer เป็น containing block ของเมนู ＋ (ย้าย div เข้ามาข้างในแล้ว)
   position:absolute จึงหลุดจาก flex ไม่กินที่ในแถว */
.composer { position: relative; }
.composer-more { bottom: calc(100% + 6px); left: var(--s2); }
/* .chat-actions เป็น containing block ของเมนู ⋯ (ย้าย div เข้ามาข้างในแล้ว) */
.chat-actions { position: relative; }
.head-more { top: calc(100% + 6px); right: 0; }

/* ---------------- การ์ด / ตาราง / pill ---------------- */
.card {
  border-radius: var(--radius); padding: var(--s4); margin-bottom: var(--s3);
  border: 1px solid var(--border); box-shadow: none;
}
.card h3 { font-size: var(--fs-md); font-weight: 650; color: var(--text); }
.two-col { gap: var(--s3); }
.tile {
  border-radius: var(--radius); padding: var(--s3) var(--s4);
  border: 1px solid var(--border); box-shadow: none;
}
.tile .t-num { font-size: var(--fs-xl); font-weight: 700; letter-spacing: -.02em; }
.tile .t-label { font-size: var(--fs-sm); }
.tab {
  border-radius: var(--radius-pill); font-size: var(--fs-md); padding: 6px 14px;
  transition: background var(--transition), border-color var(--transition);
}
.tab:hover { background: var(--side-hover); }
.pill { font-size: var(--fs-xs); border-radius: var(--radius-pill); padding: 2px 8px; font-weight: 600; }
.tbl th { font-size: var(--fs-xs); font-weight: 600; letter-spacing: .04em; }
.tbl td { font-size: var(--fs-md); }

/* ---------------- โมดัล / toast ---------------- */
.modal { border-radius: var(--radius-lg); padding: var(--s5); }
.modal h3 { font-size: var(--fs-lg); font-weight: 650; color: var(--text); }
.modal-backdrop { backdrop-filter: blur(2px); }
.toast { border-radius: var(--radius-pill); font-size: var(--fs-md); box-shadow: var(--shadow-modal); }

/* ---------------- login: มินิมอล ไม่ใช้ gradient จัด ---------------- */
.login-screen { background: var(--bg); }
html[data-theme="dark"] .login-screen { background: var(--bg); }
.login-card {
  border-radius: var(--radius-lg); padding: var(--s6) var(--s5);
  border: 1px solid var(--border); box-shadow: var(--shadow-pop); max-width: 372px;
}
.login-logo { font-size: 42px; }
/* โลโก้จริงบนหน้าล็อกอิน (แทนไอคอนลายเส้น) — mobile first 360px แล้วค่อยขยายบนจอใหญ่ */
.login-logo-img {
  display: block; margin: 0 auto var(--s3); width: 76px; height: 76px;
  border-radius: 18px; object-fit: contain;
}
@media (min-width: 600px) { .login-logo-img { width: 96px; height: 96px; border-radius: 22px; } }

.login-card h1 { font-size: var(--fs-xl); color: var(--text); font-weight: 700; letter-spacing: -.02em; }
.theme-fab { background: transparent; color: var(--muted); backdrop-filter: none; }
.theme-fab:hover { background: var(--side-hover); }
.lang-btn { border-radius: var(--radius-pill); font-size: var(--fs-sm); transition: background var(--transition); }

/* ---------------- backdrop ของ sidebar มือถือ (เดิมไม่มี) ---------------- */
.side-backdrop {
  position: fixed; inset: 0; background: var(--backdrop); z-index: 39;
  opacity: 0; pointer-events: none; transition: opacity var(--transition);
}
.side-backdrop.show { opacity: 1; pointer-events: auto; }

/* ============================================================
   RESPONSIVE 3 ระดับ (เดิมมี breakpoint เดียวที่ 860px)
   ============================================================ */

/* ---- เดสก์ท็อปกว้าง: จำกัดความกว้างเนื้อหาให้อ่านสบาย ---- */
@media (min-width: 1101px) {
  .messages > * { width: 100%; max-width: 900px; margin-left: 0; margin-right: auto; }
  /* กล่องพิมพ์กว้างเต็มห้อง (Boss สั่ง 2026-08-30) — เดิมถูกตัดที่ 900px เหลือที่ว่างด้านขวา
     (แก้ 2026-09-14) แผงตอบกลับเป็นชั้นลอยทับแล้ว ไม่ดัน padding-right ใส่ .app อีก
     กล่องพิมพ์จึงคงความกว้างเดิมตอนเปิดเธรด — ตามที่ Boss/พี่ปองสั่ง "ไม่ต้องบีบ" */
  .x10v3 .composer { max-width: none; margin-right: 0; }
  .composer { padding-left: var(--s4); padding-right: var(--s4); }
  .composer > * { align-self: flex-end; }
  .page-body > .card, .page-body > .two-col, .page-body > .tiles,
  .page-body > .side-section, .page-body > #threads-list {
    max-width: 1180px; margin-left: auto; margin-right: auto;
  }
  .sidebar { width: 272px; }
}

/* ---- แท็บเล็ต: sidebar ยุบเป็นแถบไอคอน ประหยัดพื้นที่แต่ยังเห็นห้อง ---- */
@media (min-width: 861px) and (max-width: 1100px) {
  .sidebar { width: 224px; }
  .side-nav .nav-btn { padding: 7px 8px; font-size: var(--fs-sm); }
  .chan-item, .user-item { font-size: var(--fs-sm); }
}

/* ---- มือถือ ---- */
@media (max-width: 860px) {
  .sidebar {
    inset: 0 auto 0 0; width: 84vw; max-width: 300px;
    border-right: 1px solid var(--side-border);
    box-shadow: 8px 0 32px rgba(16,24,40,.16);
    transition: transform 200ms cubic-bezier(.4,0,.2,1);
  }
  /* บนมือถือ nav อยู่ที่แถบล่างแล้ว ไม่ต้องมีซ้ำในแถบข้าง = ประหยัดที่ให้รายชื่อห้อง */
  .sidebar .side-nav { display: none; }
  .sidebar .side-admin { margin-top: 0; border-top: none; }

  .main { padding-bottom: 0; }
  .bottom-nav {
    background: var(--card); border-top: 1px solid var(--border);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .bottom-nav .nav-btn {
    padding: 7px 2px 5px; gap: 2px; font-size: 20px;
    transition: color var(--transition);
  }
  .bottom-nav .nav-btn span { font-size: 10.5px; font-weight: 500; letter-spacing: -.01em; }
  .bottom-nav .nav-btn.active { color: var(--blue); font-weight: 600; }
  .bottom-nav .nav-btn.active span { font-weight: 700; }

  /* แชทเต็มจอ: แถบล่างซ่อนตอนอยู่ในห้อง ให้ composer ติดขอบจอจริง */
  .page-head, .chat-head { min-height: 52px; padding: var(--s2) var(--s3); }
  .messages { padding: var(--s2) var(--s2) var(--s1); }
  .msg { padding: var(--s1) var(--s2); }
  .msg-text { font-size: var(--fs-base); }
  .composer { padding: var(--s2) var(--s2) calc(var(--s2) + env(safe-area-inset-bottom)); }
  .composer textarea { font-size: 16px; } /* กัน iOS zoom ตอนโฟกัส */
  .icon-btn { font-size: 21px; padding: 8px; min-width: 42px; min-height: 42px; } /* เป้าแตะ 42px */
  .icon-btn.send { width: 42px; height: 42px; font-size: 18px; }
  .btn { padding: 10px 16px; min-height: 42px; }

  .page-body { padding: var(--s3) var(--s2); }
  .card { padding: var(--s3); border-radius: var(--radius); }
  .modal { border-radius: var(--radius-lg) var(--radius-lg) 0 0; padding: var(--s4) var(--s4) calc(var(--s4) + env(safe-area-inset-bottom)); }
  .pop-menu { min-width: 210px; }
  .pop-menu button { padding: 11px 10px; font-size: var(--fs-base); }
  .composer-more { left: var(--s2); right: var(--s2); }
  .head-more { right: 0; }
  .toast { bottom: 84px; }
}

/* ---- จอเล็กมาก: ลดขนาดลงอีกขั้น ---- */
@media (max-width: 400px) {
  .bottom-nav .nav-btn span { font-size: 9.5px; }
  .chat-actions .icon-btn { min-width: 38px; padding: 7px; }
}

/* ---- ลดการเคลื่อนไหวถ้าผู้ใช้ตั้งค่าไว้ ---- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 1ms !important; animation-duration: 1ms !important; }
  .messages { scroll-behavior: auto; }
}

/* จุดแดงบนปุ่ม ⋯ / ＋ — .nav-dot เป็น absolute จึงต้องมี ancestor ที่ positioned */
.chat-actions .icon-btn, .composer .icon-btn { position: relative; }
#head-more-dot { top: 5px; right: 5px; border-color: var(--card); }
/* ปุ่ม ⋯ และ ＋ เป็นสัญลักษณ์ ไม่ใช่อีโมจิ — จัดให้อยู่กลางและหนาพอมองเห็น */
#btn-head-more, #btn-composer-more { font-size: 20px; font-weight: 600; line-height: 1; color: var(--muted); }
#btn-head-more:hover, #btn-composer-more:hover { color: var(--text); }

/* ============================================================
   แก้ทับซ้อนบนมือถือ (พบตอนทดสอบจริง 2026-08-19)
   เดิม .main มี padding-bottom:58px กันแถบล่างทับ — เลย์เอาต์ใหม่ให้
   composer ติดขอบจอ จึงต้องจัดการที่ระดับ layout ไม่ใช่ padding
   หลัก: อยู่ในห้องแชท = composer เป็นงานหลัก ซ่อนแถบล่าง (ยังมี ☰ + ปุ่มกลับ)
        หน้าอื่น = แถบล่างอยู่ในกระแส flex เลยไม่ทับอะไร
   ============================================================ */
@media (max-width: 860px) {
  /* .app เป็น flex column แล้ว: main ยืด, bottom-nav เป็นแถวปกติ ไม่ fixed
     => ไม่มีการทับซ้อนอีก และ 100dvh ยังคุมความสูงรวมให้พอดีจอ */
  .bottom-nav { position: static; z-index: 50; flex-shrink: 0; }
  .main { min-height: 0; }

  /* อยู่ในห้องแชท → ซ่อนแถบล่าง ให้ช่องพิมพ์เต็มจอ (คลาสใส่โดย app.js) */
  body.in-room .bottom-nav { display: none; }

  /* 7 ปุ่มใน 390px ป้ายชื่อเบียดอ่านไม่ออก → ให้ตัดคำด้วย ellipsis ไม่ดันกัน */
  .bottom-nav .nav-btn { min-width: 0; padding: 6px 1px 4px; }
  .bottom-nav .nav-btn span {
    max-width: 100%; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap; padding: 0 1px;
  }
}

/* ---- ย้ำกฎ show/hide ตามอุปกรณ์ ----
   .icon-btn{display:inline-flex} ในเลเยอร์นี้อยู่หลัง .only-mobile{display:none}
   (specificity เท่ากัน ตัวหลังชนะ) → ปุ่ม ☰ เคยโผล่บนเดสก์ท็อป */
.only-mobile { display: none !important; }
.only-desktop { display: inline-flex; }
@media (max-width: 860px) {
  .only-mobile { display: inline-flex !important; }
  .only-desktop { display: none !important; }
}

/* ============================================================
   ป้ายสถานะล็อกห้อง (Boss สั่ง 2026-08-19)
   - ห้องล็อก = ป้ายเหลือง 🔒 ล็อก / ห้องเปิด = ป้ายเขียว 🌐 เปิด
   - เจ้าของห้อง/แอดมินกดสลับได้ (คนอื่นเป็นป้ายเฉยๆ กดไม่ได้)
   ใช้ตัวแปรธีม (--amber/--green/--border) → โหมดมืดกลืนเองไม่ต้องเขียนซ้ำ
   ============================================================ */
.chat-name-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* ชื่อห้องยืด/ย่อได้ แต่ต้องเหลือที่ให้ป้าย — ไม่ใส่ shrink:1 ชื่อจะกินจนป้ายกว้าง 0 */
.chat-name-row .chat-name { min-width: 0; flex: 0 1 auto; }
.lock-badge {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 700; line-height: 1;
  padding: 3px 8px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--card); color: var(--muted);
  cursor: default; white-space: nowrap; font-family: inherit;
}
.lock-badge.is-locked { color: var(--amber); border-color: color-mix(in srgb, var(--amber) 40%, transparent); background: color-mix(in srgb, var(--amber) 12%, var(--card)); }
.lock-badge.is-open   { color: var(--green); border-color: color-mix(in srgb, var(--green) 40%, transparent); background: color-mix(in srgb, var(--green) 12%, var(--card)); }
/* กดสลับได้เฉพาะเจ้าของห้อง/แอดมิน */
.lock-badge.can-toggle { cursor: pointer; }
.lock-badge.can-toggle:hover { filter: brightness(1.06); transform: translateY(-1px); }
.lock-badge.can-toggle:active { transform: none; }
.lock-badge[disabled] { opacity: .6; cursor: progress; }
/* จอแคบ: เหลือแต่ไอคอน กันเบียดชื่อห้อง */
@media (max-width: 560px) { .lock-badge .lb-text { display: none; } .lock-badge { padding: 3px 6px; } }

/* ============================================================
   เมนูคำสั่ง "/" (Boss สั่ง 2026-08-19)
   ใช้โครง .mention-pop เดิม (ตำแหน่ง/เงา/โหมดมืดได้ฟรี) เพิ่มแค่ layout ต่อบรรทัด
   ============================================================ */
.cmd-pop { max-width: 460px; max-height: 260px; }
.cmd-item { display: flex; flex-direction: column; gap: 2px; padding: 7px 12px; cursor: pointer; font-size: 14px; }
.cmd-item:hover, .cmd-item.sel { background: var(--blue-light); }
.cmd-item .cmd-line { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.cmd-item .cmd-name { font-weight: 700; color: var(--blue); font-family: ui-monospace, monospace; }
.cmd-item .cmd-args { font-size: 12px; color: var(--muted); font-family: ui-monospace, monospace; }
.cmd-item .cmd-desc { font-size: 12px; color: var(--muted); }
/* ป้ายบอกว่าคำสั่งนี้สิทธิ์ระดับไหน — กันคนสงสัยว่าทำไมเพื่อนไม่มีคำสั่งนี้ */
.cmd-item .cmd-perm { font-size: 10px; font-weight: 700; padding: 1px 5px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--muted); }
.cmd-item .cmd-perm.p-admin { color: var(--red); border-color: color-mix(in srgb, var(--red) 40%, transparent); }
.cmd-item .cmd-perm.p-owner { color: var(--amber); border-color: color-mix(in srgb, var(--amber) 40%, transparent); }
/* ผลลัพธ์คำสั่งที่เห็นคนเดียว (ไม่ได้โพสต์ลงห้อง) */
.cmd-reply { white-space: pre-wrap; font-size: 13px; line-height: 1.5; }
@media (max-width: 560px) { .cmd-pop { max-width: none; } .cmd-item .cmd-desc { display: none; } }

/* ===== อัลบั้ม: หลายไฟล์ในข้อความเดียว ===== */
/* ⚠️ width คงที่ 332px + การ์ดหุ้มที่ max-width:100% = จอแคบกริดล้นออกนอกกรอบ
   (Boss 2026-08-28: "กรอบหลังรูปไม่ครอบคลุมรูปทั้งสองในมือถือ")
   ใช้ min() ให้กริดหดตามพื้นที่จริงเสมอ */
.album-grid { display: grid; gap: 3px; width: min(332px, 100%); border-radius: 8px; overflow: hidden; }
.album-img { width: 100%; aspect-ratio: 1; object-fit: cover; cursor: pointer; display: block; }
.album-grid:has(.album-img:only-child) .album-img { aspect-ratio: auto; max-height: 320px; object-fit: contain; }
.album-files { display: flex; flex-direction: column; gap: 4px; margin-top: 4px; }
/* การ์ดอัลบั้ม: รูป + ไฟล์ + ข้อความกำกับ = กล่องเดียว ไม่ให้ดูเหมือนหลายข้อความ */
.album-card {
  display: block; width: fit-content; max-width: min(340px, 100%); padding: 4px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--sunken);
  box-sizing: border-box;      /* padding+เส้นขอบต้องนับรวมใน max-width ไม่งั้นเกินไป 10px */
  overflow: hidden;            /* กันลูกใดๆ ทะลุกรอบมน */
}
.album-card .album-grid { border-radius: 7px; }
/* caption เหนือรูป: เว้นล่างให้ห่างกริด ไม่เว้นบนเกิน (ติดหัวข้อความ) */
.album-caption { margin: 2px 4px 6px; }
/* คำบรรยายของรูป/ไฟล์เดี่ยว — อยู่เหนือรูป เว้นช่องไฟไม่ให้แนบติด (Boss สั่ง 2026-08-28) */
.file-caption { margin: 2px 4px 6px; }
/* ป้ายจำนวนไฟล์ซ้อนมุมขวาบนของรูป — ผูกกับ gridwrap ไม่ใช่การ์ด กัน caption ยาวถูกทับ */
.album-gridwrap { position: relative; width: fit-content; max-width: 100%; }
.album-count {
  position: absolute; top: 6px; right: 6px; z-index: 1;
  background: rgba(0,0,0,.55); color: #fff; padding: 1px 7px; border-radius: 10px; font-size: 11px;
}
/* เอกสารล้วน (ไม่มีรูป) — ป้ายเป็นบรรทัดปกติ ไม่ลอยทับชื่อไฟล์ */
.album-count.inline {
  position: static; background: none; color: var(--muted); padding: 0 4px; font-size: 11px; margin-bottom: 2px;
}
/* ⬇ ปุ่มบันทึกรูปทั้งอัลบั้ม (2026-09-23) — ใต้กริด ขนาดนิ้วแตะได้ (สูง ≥ 36px) */
.album-dlall {
  display: inline-flex; align-items: center; gap: 6px; margin: 6px 2px 2px; min-height: 36px;
  padding: 6px 12px; border-radius: 18px; border: 1px solid var(--border);
  background: var(--card); color: var(--text); font-size: 13px; cursor: pointer;
}
.album-dlall:hover { filter: brightness(.96); }
.album-dlall[data-busy] { opacity: .7; cursor: progress; }
.album-dlall.ready { background: var(--blue); border-color: transparent; color: #fff; font-weight: 600; }

/* ดูรูปเต็มจอ */
.lightbox {
  position: fixed; inset: 0; z-index: 300; background: rgba(0,0,0,.9);
  display: flex; align-items: center; justify-content: center;
}
.lightbox.hidden { display: none; }
.lightbox img { max-width: 92vw; max-height: 88vh; object-fit: contain; display: block; }
/* ============================================================
   ดูรูป: ซูม + วาดทับ (Boss สั่ง 2026-08-30 — แจ้งบัคง่ายขึ้น)
   .lb-stage ครอบรูป+canvas ให้ขยับ/ซูมไปพร้อมกัน ลายเส้นจึงไม่หลุดจากรูป
   ============================================================ */
.lb-stage {
  position: relative; display: inline-block; line-height: 0;
  transform-origin: center center; transition: transform .12s ease-out; touch-action: none;
}
.lb-stage.lb-pannable { cursor: grab; }
.lb-stage.lb-pannable:active { cursor: grabbing; }
/* canvas ต้องทับรูปพอดีเป๊ะ — รูปถูกย่อด้วย max-width/height จึงต้องอิง 100% ของ .lb-stage */
.lb-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  cursor: crosshair; touch-action: none;
}
.lb-canvas.hidden { display: none; }
/* แถบเครื่องมือล่าง — หลบ safe-area ของมือถือ และเลื่อนแนวนอนได้เมื่อจอแคบ */
.lb-bar {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(12px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 6px; justify-content: flex-start;
  /* แถบเดียวเลื่อนแนวนอน — เดิม flex-wrap ทำให้ปุ่มเซฟตกลงไปแถวสอง หาไม่เจอ */
  max-width: 96vw; padding: 7px 9px; overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none;
  background: rgba(28,28,30,.94); border: 1px solid rgba(255,255,255,.14);
  border-radius: 12px; box-shadow: 0 6px 24px rgba(0,0,0,.45);
}
.lb-bar::-webkit-scrollbar { display: none; }
.lb-grp { display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }
.lb-grp + .lb-grp { border-left: 1px solid rgba(255,255,255,.16); padding-left: 7px; }
.lb-btn {
  min-width: 34px; height: 34px; padding: 0 8px;
  background: transparent; color: #fff; border: 0; border-radius: 8px;
  font-size: 15px; line-height: 1; cursor: pointer;
}
.lb-btn:hover { background: rgba(255,255,255,.14); }
.lb-btn.active { background: rgba(255,255,255,.24); }
.lb-btn:disabled { opacity: .5; cursor: default; }
.lb-btn-wide { font-size: 13px; font-weight: 600; padding: 0 12px; white-space: nowrap; }
.lb-zoom { color: #fff; font-size: 12.5px; min-width: 46px; text-align: center; }
.lb-colors { display: flex; gap: 4px; align-items: center; margin: 0 2px; }
.lb-sw {
  width: 20px; height: 20px; border-radius: 50%; cursor: pointer;
  border: 2px solid rgba(255,255,255,.35); padding: 0;
}
.lb-sw.active { border-color: #fff; box-shadow: 0 0 0 2px rgba(255,255,255,.35); }
.lb-bar .hidden { display: none; }
/* จอแคบ: ปุ่มเยอะ ต้องเล็กลงไม่ให้ล้นจอ
   ⚠️ ปุ่มเซฟ/คัดลอกลิงก์ = ปุ่มสำคัญที่สุด ห้ามให้ต้องเลื่อนหา
      → แยกเป็นแถวล่างตรึงไว้ ส่วนเครื่องมือวาดเลื่อนแนวนอนได้ */
@media (max-width: 620px) {
  .lb-btn { min-width: 30px; height: 30px; padding: 0 6px; font-size: 14px; }
  .lb-btn-wide { font-size: 12px; padding: 0 9px; }
  .lb-bar {
    gap: 4px; padding: 6px; flex-wrap: wrap; overflow-x: visible;
    left: 8px; right: 8px; transform: none; max-width: none;
  }
  /* กลุ่มเครื่องมือ (ซูม/วาด/สี) อยู่แถวบน — ให้ "ขึ้นบรรทัดใหม่" ไม่ใช่เลื่อนซ่อน
     ⚠️ เดิม overflow-x:auto ทำให้ปุ่ม 🗑 (ลบทั้งหมด) หลุดนอกจอ ต้องเลื่อนหาเอง มองไม่เห็น
        (พี่ป๋องแจ้ง 2026-08-31) — ปุ่มน้อย ให้ wrap แล้วเห็นครบดีกว่า */
  .lb-bar > .lb-grp:not(.lb-grp-end) { flex-wrap: wrap; justify-content: center; row-gap: 4px; }
  /* ⚠️ .lb-colors เป็น flex nowrap กว้าง ~140px ย่อไม่ได้ → แถวเครื่องมือไม่ยอม wrap
     ทำให้ 🗑 ล้นออกนอกจอ (356px > 360px vw) ต้องให้แถบสี wrap ได้ด้วย */
  #lb-tools { max-width: 100%; }
  #lb-colors { flex-wrap: wrap; justify-content: center; row-gap: 4px; }
  /* ปุ่มเซฟ/คัดลอก = เต็มแถว มองเห็นเสมอ */
  .lb-grp-end {
    flex: 1 0 100%; justify-content: center; gap: 8px;
    border-left: 0; padding-left: 0; padding-top: 5px;
    border-top: 1px solid rgba(255,255,255,.16);
  }
  .lb-grp-end .lb-btn-wide { flex: 1; max-width: 190px; height: 34px; }
}
.lb-nav {
  position: absolute; top: 50%; transform: translateY(-50%); width: 44px; height: 64px;
  background: rgba(0,0,0,.4); color: #fff; border: 0; font-size: 32px; cursor: pointer;
}
.lb-nav { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }  /* iOS: กดรัวไม่ซูมหน้า */
.lb-prev { left: max(8px, env(safe-area-inset-left)); } .lb-next { right: max(8px, env(safe-area-inset-right)); }  /* iPhone แนวนอน: หลบ notch */
/* ลูกศรต้องไม่บังแถบเครื่องมือล่าง (จอแคบแถบสูงขึ้น) */
@media (max-width: 620px) { .lb-nav { top: 42%; } }
/* แถบบนของ lightbox ต้องหลบ notch/status bar ไม่งั้นปุ่มปิดอยู่ใต้แถบเวลา กดไม่โดน
   (Boss 2026-08-27: มือถือหาปุ่มย้อนกลับไม่เจอ) */
.lb-pos {
  position: absolute; top: calc(14px + env(safe-area-inset-top)); left: 50%;
  transform: translateX(-50%); color: #fff; font-size: 14px;
}
.lb-close {
  position: absolute; top: calc(10px + env(safe-area-inset-top)); right: 12px;
  width: 36px; height: 36px;
  background: rgba(0,0,0,.4); color: #fff; border: 0; border-radius: 50%; font-size: 16px; cursor: pointer;
}
@media (max-width: 720px) {
  /* นิ้วต้องกดโดน: ขยายปุ่มปิด + เพิ่มความทึบให้เห็นชัดบนรูปพื้นสว่าง */
  .lb-close { width: 44px; height: 44px; background: rgba(0,0,0,.62); }
  .lb-nav { background: rgba(0,0,0,.32); }
}

/* ============================================================
   GTR SHELL — เปลือกหน้าตาใหม่ (2026-08-21)
   หลักการ: เปลี่ยนแค่ "หน้าตา" ไม่แตะ logic/API/DB — ทุกปุ่มยังเรียกฟังก์ชันเดิมของ v2
   สีทั้งหมดอ้าง CSS var เดิม → โหมดมืด/สว่างทำงานตามเดิมอัตโนมัติ
   ============================================================ */

/* ---- โลโก้: กล่อง X ขาวมุมมน ---- */
.brand { display: flex; align-items: center; gap: 10px; font-size: 17px; font-weight: 700; }
.brand-mark {
  width: 30px; height: 30px; border-radius: 9px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: #fff; color: var(--blue); font-weight: 800; font-size: 16px;
}

/* ---- ไอคอนหัว sidebar: เส้นบาง ไม่ใช่ emoji ---- */
.side-icon {
  color: var(--side-muted); font-size: 17px; line-height: 1;
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
}
.side-icon:hover { color: var(--side-text); background: var(--side-hover); }
.side-icon-round {
  border-radius: 50%; background: var(--side-raise);
  color: var(--side-text); font-size: 19px; font-weight: 400;
}
.side-icon-round:hover { background: rgba(255,255,255,.16); }

/* ---- nav 2 คอลัมน์ 3 แถว (ตามภาพ) · ซ่อนปุ่มแชทเพราะแชทเป็นหน้าหลัก ---- */
.side-nav-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 4px; }
.side-nav.side-nav-grid .nav-btn.nav-btn-chat { display: none; }
.side-nav.side-nav-grid .nav-btn {
  justify-content: flex-start; gap: 9px; padding: 7px 9px;
  border-radius: 8px; font-size: 13.5px; position: relative;
  min-width: 0;   /* ให้ชื่อยาวหดได้ ไม่ดันคอลัมน์ */
}
.side-nav.side-nav-grid .nav-btn .nav-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.side-nav-grid .nav-icon { font-size: 15px; opacity: .9; }
.side-nav-grid .nav-label { font-size: 13.5px; }

/* ---- แถบใต้ข้อความ: คอมเมนต์ · แท็กถึงคนนี้ · ปักหมุด ---- */
.msg-foot { display: flex; gap: 16px; margin-top: 5px; flex-wrap: wrap; }
.msg-foot-btn {
  border: none; background: none; padding: 0; cursor: pointer;
  font-size: 12.5px; font-weight: 600; color: var(--blue);
  font-family: inherit; line-height: 1.6;
}
.msg-foot-btn:hover { text-decoration: underline; }

/* ---- ปุ่มหัวห้อง: วงกลมขอบเทา (ตามภาพ) ---- */
.chat-actions .icon-btn {
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--card);
  display: inline-flex; align-items: center; justify-content: center;
}
.chat-actions .icon-btn:hover { background: var(--blue-light); border-color: var(--blue); }

/* ปุ่มส่ง: v2 เป็นวงกลมน้ำเงินอยู่แล้ว (.icon-btn.send) ตรงกับภาพ ไม่ต้องแก้ */

/* ---- ผู้ดูแลระบบ: ให้อยู่แถวเดียวกับ nav grid (ตามภาพ) ----
   ใช้ CSS ย้ายตำแหน่งด้วย order/margin ไม่ย้าย DOM — app.js ยังหา .side-admin ได้เหมือนเดิม */
.side-nav.side-nav-grid .nav-btn-wide {
  justify-content: flex-start; gap: 9px;
  padding: 7px 9px; border-radius: 8px; font-size: 13.5px; min-width: 0; width: auto;
}
.side-nav.side-nav-grid .nav-btn-label { font-size: 13.5px; font-weight: 500; }
/* ไอคอน nav: เส้นบาง รับสีจากตัวแปรธีม (ไม่ใช่ emoji ที่บังคับสีเอง) */
.side-nav .nav-icon {
  font-size: 15px; opacity: .85; width: 17px; text-align: center; flex: none;
}
.side-icon { font-family: system-ui, sans-serif; }

/* ตาราง markdown-pipe ในข้อความ — เส้นคม จัดคอลัมน์ด้วย layout จริง หัวเป็นไทยได้ */
.msg-text .msg-table-wrap {
  margin: 6px 0 2px; overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--border); border-radius: 8px; background: var(--sunken);
  max-width: 100%; width: fit-content;
}
@media (max-width: 640px) { .msg-text .msg-table-wrap { max-width: 78vw; } }
/* ===== ปุ่มคัดลอกตาราง (Boss สั่ง 2026-08-31 ข้อ 2 · ตามรูป Slack) =====
   ⚠️ .msg-table-wrap เป็น overflow-x:auto → ปุ่มแบบ absolute จะเลื่อนหนีไปกับตาราง
      ใช้ position:sticky + float:right ให้ปุ่มติดมุมขวาบนเสมอแม้เลื่อนตารางไปด้านข้าง */
.msg-text .msg-table-wrap { position: relative; }
.msg-text .tbl-copy {
  position: sticky; top: 4px; right: 4px; float: right; z-index: 2;
  width: 26px; height: 26px; margin-left: 4px;
  display: grid; place-items: center; cursor: pointer;
  font-size: 13px; line-height: 1;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--card); color: var(--muted);
  opacity: 0; transition: opacity .12s;
}
.msg-text .msg-table-wrap:hover .tbl-copy { opacity: 1; }
.msg-text .tbl-copy:hover { color: var(--text); border-color: var(--blue); }
/* มือถือไม่มี hover — โชว์จางๆ ไว้เลย ไม่งั้นกดไม่ได้ทั้งที่ปุ่มมีอยู่ */
@media (hover: none) {
  .msg-text .tbl-copy { opacity: .55; }
}
.msg-text table.msg-table {
  border-collapse: collapse; font-size: 12.5px; line-height: 1.5; width: auto; min-width: 100%;
  font-variant-numeric: tabular-nums;
}
.msg-text table.msg-table th, .msg-text table.msg-table td {
  padding: 6px 10px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
.msg-text table.msg-table th {
  font-weight: 600; background: var(--blue-light); color: var(--text);
  position: sticky; top: 0;
}
.msg-text table.msg-table tbody tr:last-child td { border-bottom: none; }
.msg-text table.msg-table tbody tr:nth-child(even) td { background: rgba(127, 127, 127, .06); }
.msg-text table.msg-table .ta-left { text-align: left; }
.msg-text table.msg-table .ta-right { text-align: right; }
.msg-text table.msg-table .ta-center { text-align: center; }

/* ============================================================
   หน้าโปรไฟล์และการตั้งค่า (หน้าเต็ม — แทนโมดัลเดิม)
   ============================================================ */
.pf-page { max-width: 980px; margin: 0 auto; padding-bottom: 32px; }
.pf-card {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius-lg); margin-bottom: 14px; overflow: hidden;
}
/* หัวการ์ดพื้นจาง แยกจากเนื้อการ์ด */
.pf-card-head {
  background: var(--sunken); border-bottom: 1px solid var(--border);
  padding: 12px 18px;
}
.pf-card-head h3 { margin: 0; font-size: 14.5px; font-weight: 700; }
.pf-card-note { margin: 3px 0 0; font-size: 12.5px; color: var(--muted); }
.pf-card-body { padding: 16px 18px; }

/* --- การ์ดหัว: อวาตาร์ + ชื่อ + สี --- */
.pf-hero { display: flex; align-items: flex-start; gap: 18px; padding: 18px; flex-wrap: wrap; }
.pf-hero-av .avatar { width: 72px; height: 72px; font-size: 26px; }
.pf-hero-main { flex: 1; min-width: 180px; }
.pf-hero-name { font-size: 19px; font-weight: 700; line-height: 1.3; }
.pf-hero-sub { font-size: 13.5px; color: var(--muted); margin: 2px 0 10px; }
.pf-hero-btns { display: flex; gap: 8px; flex-wrap: wrap; }
.pf-hero-colors { text-align: right; }
.pf-colors-label { font-size: 12.5px; color: var(--muted); margin-bottom: 7px; }
.pf-swatches { display: flex; gap: 9px; }
.pf-sw {
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
  border: 2px solid transparent; padding: 0; transition: transform .12s;
}
.pf-sw:hover { transform: scale(1.08); }
/* วงที่เลือก: ขอบสีข้อความเว้นช่องขาว เห็นชัดทั้งสองธีม */
.pf-sw.active { border-color: var(--text); box-shadow: 0 0 0 2px var(--card) inset; }

/* --- ช่องกรอกแบบมีป้ายชื่อบน --- */
.pf-grid2, .pf-grid3 { display: grid; gap: 14px 18px; }
.pf-grid2 { grid-template-columns: 1fr 1fr; }
.pf-grid3 { grid-template-columns: 1fr 1fr 1fr; }
.pf-field { display: flex; flex-direction: column; gap: 5px; }
.pf-label { font-size: 12.5px; color: var(--muted); }
.pf-field input, .pf-field select {
  width: 100%; background: var(--sunken); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 10px 13px; font-size: 14.5px;
  color: var(--text); font-family: inherit;
}
.pf-field input:focus, .pf-field select:focus { outline: 2px solid var(--blue); outline-offset: -1px; }
.pf-field input[readonly] { color: var(--muted); cursor: default; }

/* --- แถวสถานะ: ไอคอน / ข้อความ / ถึงเวลา --- */
.pf-status-row { display: grid; grid-template-columns: 78px 1fr 190px; gap: 14px; }
.pf-f-emoji input { text-align: center; font-size: 19px; padding: 8px 4px; }
.pf-card-body .emoji-row { margin-top: 12px; }

/* --- แถวตัวเลือก: ข้อความซ้าย pill ขวา --- */
.pf-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 14px 0; flex-wrap: wrap;
}
.pf-row + .pf-row { border-top: 1px solid var(--border); }
.pf-row:first-child { padding-top: 0; }
.pf-row:last-child { padding-bottom: 0; }
.pf-row-txt b { display: block; font-size: 14px; }
.pf-row-txt .muted { font-size: 12.5px; color: var(--muted); }
.pf-pills { display: flex; gap: 8px; flex-wrap: wrap; }
/* pill ธีม/ภาษา — ตัวที่เลือกขอบฟ้าพื้นจาง */
.pf-pill, .pf-pills .lang-btn {
  border: 1px solid var(--border); background: var(--card); color: var(--text);
  border-radius: var(--radius-pill); padding: 6px 16px;
  font-size: 13px; font-weight: 600; cursor: pointer; font-family: inherit;
}
.pf-pill:hover, .pf-pills .lang-btn:hover { border-color: var(--blue); }
.pf-pill.active, .pf-pills .lang-btn.active {
  border-color: var(--blue); color: var(--blue); background: var(--blue-light);
}

/* --- ท้ายหน้า: ข้อมูลอ่านเท่านั้น + ปุ่ม --- */
.pf-card .pf-whoami, .pf-card .pf-orginfo {
  padding: 0 18px 14px; display: flex; align-items: center; gap: 9px;
  flex-wrap: wrap; font-size: 13px;
}
.pf-actions { display: flex; gap: 12px; margin-top: 4px; }
/* ออกจากระบบ: พื้นแดงจาง ไม่ใช่ปุ่มแดงเต็ม (ไม่ใช่ปุ่มหลักของหน้า) */
.btn.danger-soft {
  background: color-mix(in srgb, var(--red) 14%, transparent);
  color: var(--red); border: 1px solid transparent; font-weight: 700;
}
.btn.danger-soft:hover { background: color-mix(in srgb, var(--red) 22%, transparent); }

@media (max-width: 860px) {
  .pf-grid2, .pf-grid3 { grid-template-columns: 1fr; }
  .pf-status-row { grid-template-columns: 70px 1fr; }
  .pf-f-until { grid-column: 1 / -1; }
  .pf-hero { gap: 14px; }
  .pf-hero-colors { text-align: left; width: 100%; }
  .pf-row { align-items: flex-start; }
  .pf-actions .btn { flex: 1; }
}

/* ---- ป้ายต่อท้ายชื่อ + รีแอ็กชัน (แบบเฟส) ---- */
.name-dept { font-size: 12.5px; color: var(--muted); font-weight: 400; }
.tag-author, .tag-announce {
  font-size: 10.5px; font-weight: 700; border-radius: var(--radius-sm);
  padding: 1px 7px; letter-spacing: .2px;
}
.tag-author { color: var(--blue); background: var(--blue-light); }
.tag-announce { color: var(--amber); background: color-mix(in srgb, var(--amber) 16%, transparent); }
/* แถวใต้ข้อความ: ปุ่มซ้าย · ชิปรีแอ็กชันลอยขวา */
.msg-foot { position: relative; align-items: center; }
.msg-foot-btn.liked { color: var(--blue); font-weight: 800; }
/* แถวรีแอ็กชัน: เม็ดแยกต่ออีโมจิ (👍18 ✅6) อยู่ใต้ข้อความ เหนือแถวปุ่ม */
.react-row { display: flex; gap: 7px; flex-wrap: wrap; margin: 7px 0 2px; position: relative; }
.react-chip {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius-pill); padding: 3px 12px 4px;
  font-size: 12.5px; cursor: pointer; line-height: 1.5;
  font-family: inherit; color: var(--text);
}
/* ปุ่มเพิ่มอีโมจิอื่น — วงกลมจาง โผล่ชัดเมื่อ hover */
.react-add {
  border: 1px solid var(--border); background: var(--card); color: var(--muted);
  border-radius: 50%; width: 26px; height: 26px; cursor: pointer;
  font-size: 15px; line-height: 1; font-family: inherit; padding: 0;
}
.react-add:hover { border-color: var(--blue); color: var(--blue); }
.react-chip:hover { border-color: var(--blue); }
.react-chip.mine { border-color: var(--blue); background: var(--blue-light); }
.react-emojis { font-size: 13.5px; }
.react-count { color: var(--muted); font-weight: 600; }
.react-chip.mine .react-count { color: var(--blue); }
/* แถบเลือกอีโมจิ ลอยเหนือชิป */
.react-pick {
  /* position/top/left ตั้งจาก JS (fixed) — ห้ามใช้ absolute อีก จะถูกกล่องสกรอลล์ตัด
     visibility:hidden กันกระพริบมุมซ้ายบน 1 เฟรมก่อน JS วางตำแหน่ง */
  position: fixed; z-index: 320; visibility: hidden;
  display: flex; gap: 2px; background: var(--card);
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  padding: 4px 7px; box-shadow: 0 6px 18px rgba(0,0,0,.18);
}
.react-pick button {
  border: none; background: none; cursor: pointer; font-size: 19px;
  padding: 2px 4px; border-radius: 50%; line-height: 1;
}
.react-pick button:hover { transform: scale(1.25); background: var(--sunken); }

@media (max-width: 860px) {
  .cmt-topline, .cmt-bar { padding-left: 32px; }
  .cmt-sorts { gap: 12px; }
  .cmt-sort { font-size: 12px; }
  .cmt-composer-ph { font-size: 12.5px; padding: 7px 13px; }
}

/* ---------------- เมนู ⋯ ของข้อความ (2026-08-21) ---------------- */
/* ปุ่ม ⋯ : กล่องเดิม .msg-actions เหลือปุ่มเดียว */
.msg-actions .msg-dots {
  font-size: 17px; line-height: 1; padding: 3px 9px; color: var(--muted);
  letter-spacing: 1px; font-weight: 700;
}
.msg-actions .msg-dots:hover { color: var(--text); }

/* เมนู: position fixed (ไม่ถูก overflow ของ .messages ตัด) · วางตำแหน่งด้วย JS */
/* เดสก์ท็อป: เมนูคลิกขวาควรกระชับแบบเมนูระบบ (Boss ท้วง 2026-08-27 "ของคอมก็ใหญ่ไป")
   ใช้เมาส์เล็งแม่นกว่านิ้ว → แถวเตี้ยกว่ามือถือได้ */
.msg-menu {
  /* ⚠️ ต้องสูงกว่า .dm-dock (z-index:300) ไม่งั้นหน้าต่าง DM ลอยทับเมนูจนมองไม่เห็น
     — เห็นแค่เสี้ยวที่พ้นขอบขวาหน้าต่าง (Boss แจ้ง 2026-08-30 พร้อมรูป) */
  position: fixed; z-index: 500; min-width: 176px; max-width: 78vw;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 9px; box-shadow: var(--shadow-pop, 0 8px 28px rgba(0, 0, 0, .22));
  padding: 4px; max-height: var(--mm-max, 86vh); overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.msg-menu-item {
  display: flex; align-items: center; gap: 9px; width: 100%; border: none; background: none;
  padding: 6px 9px; cursor: pointer; text-align: left; border-radius: 6px;
  font-family: inherit; font-size: 13.5px; color: var(--text);
}
.msg-menu-item:hover { background: var(--blue-light); }
.msg-menu-item .mmi-ic {
  width: 17px; flex: 0 0 17px; text-align: center; font-size: 13px; color: var(--muted);
}
.msg-menu-item .mmi-tx { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.msg-menu-item.danger, .msg-menu-item.danger .mmi-ic { color: var(--red, #d92d20); }
.msg-menu-item.danger:hover { background: rgba(217, 45, 32, .1); }
.msg-menu-sep { height: 1px; background: var(--border); margin: 3px 4px; }

/* รายการห้องในโมดัลส่งต่อ */
.fw-list { display: flex; flex-direction: column; gap: 4px; max-height: 56vh; overflow-y: auto; }
.fw-room {
  display: flex; align-items: center; gap: 9px; width: 100%; border: 1px solid var(--border);
  background: var(--card); padding: 10px 12px; cursor: pointer; border-radius: 8px;
  font-family: inherit; font-size: 14.5px; color: var(--text); text-align: left;
}
.fw-room:hover { background: var(--blue-light); border-color: var(--blue); }
.fw-room .fw-ic { color: var(--muted); flex: 0 0 16px; text-align: center; }
/* ── ส่งต่อ: ค้นหา + ข้อความแนบ (2026-09-02) ── */
.fw-search {
  width: 100%; box-sizing: border-box; margin: 0 0 8px;
  padding: 9px 12px; font-size: 14px; font-family: inherit;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--card); color: var(--text);
}
.fw-search:focus { outline: none; border-color: var(--blue); }
.fw-list { max-height: 42vh; }                 /* เตี้ยลง เผื่อที่ให้ช่องค้นหา+ข้อความแนบ */
.fw-room .fw-nm { flex: 1 1 auto; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ป้ายหมวด — ห้องชื่อซ้ำกัน (Martech 4 ห้อง) ต้องแยกออกว่าอันไหนอยู่หมวดไหน */
.fw-room .fw-grp {
  flex: 0 0 auto; font-size: 11px; color: var(--muted);
  background: var(--bg); border: 1px solid var(--border);
  border-radius: 999px; padding: 1px 8px; max-width: 42%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fw-empty { padding: 18px 8px; text-align: center; color: var(--muted); font-size: 13px; }
.fw-note-wrap { margin-top: 8px; border-top: 1px solid var(--border); padding-top: 8px; }
.fw-note {
  width: 100%; box-sizing: border-box; resize: vertical;
  padding: 9px 12px; font-size: 14px; font-family: inherit; line-height: 1.5;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--card); color: var(--text);
}
.fw-note:focus { outline: none; border-color: var(--blue); }

/* มือถือ (mobile-first — ผู้ใช้ส่วนใหญ่อยู่มือถือ):
   เมนู 14 รายการเคยสูง 600px = 77% ของจอ 780px (Boss ท้วง 2026-08-27 "ใหญ่มากเลย")
   → บีบแถวลง แต่ยังกดง่าย (พื้นที่แตะ ~40px ตามเกณฑ์ที่นิ้วกดไม่พลาด) */
@media (max-width: 860px) {
  .msg-actions { display: flex; opacity: 1; pointer-events: auto; }
  .msg-menu {
    min-width: 54vw; max-width: 72vw;
    padding: 4px; border-radius: 12px;
    max-height: var(--mm-max, 70vh);
  }
  /* แถว ~36px — เล็กลงอีกขั้นตามที่ Boss ขอ แต่ยังกดไม่พลาด */
  .msg-menu-item {
    padding: 8px 9px; font-size: 13.5px; gap: 9px; border-radius: 7px;
  }
  .msg-menu-item .mmi-ic { width: 17px; flex: 0 0 17px; font-size: 13px; }
  .msg-menu-sep { margin: 3px 4px; }
}

/* ---- ช่องพิมพ์ตอบกลับแทรกใต้ข้อความ (Boss สั่ง 2026-08-21) ---- */
.inline-reply {
  margin: 6px 0 10px 44px; padding: 8px 0 0;
}
/* คอมเมนต์ที่ซ้อนอยู่ในกล่องแล้ว ไม่ต้องเยื้องซ้ำ */
.cmt-group .inline-reply { margin-left: 0; }
.cmt-group .msg.nested[data-depth="2"] + .inline-reply { margin-left: 34px; }
.ir-to { font-size: 12.5px; color: var(--muted); margin-bottom: 6px; }
.ir-row {
  display: flex; align-items: center; gap: 9px;
  border: 1px solid var(--border); background: var(--card);
  border-radius: 26px; padding: 5px 6px 5px 8px;
}
.ir-row:focus-within { border-color: var(--blue); }
.ir-row .avatar { width: 30px; height: 30px; font-size: 11px; flex: none; }
.ir-input {
  flex: 1; border: none; background: none; resize: none; outline: none;
  font-family: inherit; font-size: 14.5px; color: var(--text);
  padding: 6px 2px; max-height: 140px; line-height: 1.45;
}
.ir-send {
  border: none; background: var(--blue); color: #fff; cursor: pointer;
  border-radius: var(--radius-pill); padding: 7px 18px;
  font-size: 13.5px; font-weight: 700; font-family: inherit; flex: none;
}
.ir-send:hover { background: var(--blue-dark); }
.ir-send:disabled { opacity: .55; cursor: default; }
.ir-close {
  border: none; background: none; color: var(--muted); cursor: pointer;
  font-size: 17px; padding: 4px 8px; font-family: inherit; flex: none;
}
.ir-close:hover { color: var(--red); }

@media (max-width: 860px) {
  .inline-reply { margin-left: 30px; }
  .ir-send { padding: 7px 14px; font-size: 13px; }
  .ir-input { font-size: 16px; }   /* < 16px ทำให้ iOS ซูมหน้าจอตอนโฟกัส */
}

/* ---------------- หน้า TaskFlow ในแชท (2026-08-21) ---------------- */
.page-head .head-right { margin-left: auto; display: flex; gap: 6px; align-items: center; }
.tf-stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 8px; margin-bottom: 12px;
}
.tf-stat {
  background: var(--card); border: 1px solid var(--border); border-radius: 10px;
  padding: 10px 8px; text-align: center;
}
.tf-stat-n { font-size: 22px; font-weight: 700; line-height: 1.15; color: var(--text); }
.tf-stat-l { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.tf-stat.red .tf-stat-n { color: var(--red); }
.tf-stat.green .tf-stat-n { color: var(--green); }
.tf-stat.amber .tf-stat-n { color: var(--amber); }
.tf-stat.blue .tf-stat-n { color: var(--blue); }

.tf-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.tf-chip {
  font-size: 12px; padding: 3px 10px; border-radius: 999px;
  background: var(--sunken); border: 1px solid var(--border); color: var(--muted);
}
.tf-chip b { color: var(--text); margin-left: 2px; }

.tf-list { display: flex; flex-direction: column; }
.tf-item {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 9px 2px; border-bottom: 1px solid var(--border);
}
.tf-list .tf-item:last-child { border-bottom: none; }
.tf-item-main { flex: 1; min-width: 0; }
.tf-item-title { font-size: 14px; color: var(--text); word-break: break-word; }
.tf-item-sub { margin-top: 2px; }
.tf-item-side { display: flex; gap: 4px; align-items: center; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
.tf-late { color: var(--red); font-weight: 600; }

@media (max-width: 860px) {
  .tf-stats { grid-template-columns: repeat(3, 1fr); }
  .tf-item { flex-direction: column; gap: 4px; }
  .tf-item-side { justify-content: flex-start; }
}

/* ---- เชื่อมบัญชี TaskFlow (2026-08-21) ---- */
.tf-link-card { max-width: 420px; }
.tf-link-card h3 { margin: 0 0 6px; }
.tf-lbl { display: block; font-size: 12.5px; color: var(--muted); margin: 12px 0 4px; font-weight: 600; }
.tf-link-card input {
  width: 100%; padding: 10px 12px; border-radius: 8px; font-size: 15px;
  border: 1px solid var(--border); background: var(--side-input, var(--sunken)); color: var(--text);
}
.tf-link-card input:focus { background: var(--card); border-color: var(--blue); outline: none; }
.tf-link-actions { display: flex; gap: 8px; align-items: center; margin-top: 16px; }
.tf-link-note { margin: 10px 0 0; }
.tf-link-err {
  background: var(--red-bg); color: var(--red); border-radius: 8px;
  padding: 8px 10px; font-size: 13px; margin: 10px 0 0;
}
/* แถบบอกว่าเชื่อมกับใคร */
.tf-who {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  background: var(--sunken); border: 1px solid var(--border); border-radius: 8px;
  padding: 7px 10px; font-size: 13px; color: var(--muted); margin-bottom: 10px;
}
.tf-who-txt { flex: 1; min-width: 0; }
.tf-who b { color: var(--text); }
/* แท็บ งานของฉัน / ทั้งองค์กร */
.tf-scope { display: flex; gap: 6px; margin-bottom: 10px; }
.tf-tab {
  border: 1px solid var(--border); background: var(--card); color: var(--muted);
  padding: 6px 14px; border-radius: 999px; cursor: pointer; font-family: inherit;
  font-size: 13px; font-weight: 600;
}
.tf-tab.active { background: var(--blue); color: var(--on-brand, #fff); border-color: var(--blue); }
.tf-mine-dot { color: var(--blue); font-size: 10px; vertical-align: middle; }

/* ---- แท็กเพื่อนในช่องตอบคอมเมนต์ ---- */
.inline-reply { position: relative; }
/* รายชื่อลอยเหนือช่องพิมพ์ (ช่องอยู่กลางหน้า ถ้าลงล่างจะตกขอบจอ) */
.inline-reply .ir-pop.mention-pop {
  position: absolute; left: 40px; right: 40px; bottom: 100%; margin-bottom: 4px;
  max-width: none; z-index: 70; max-height: 220px; overflow-y: auto;
  box-shadow: 0 6px 24px rgba(0,0,0,.18);
}
.ir-tag {
  border: none; background: none; color: var(--muted); cursor: pointer;
  font-size: 17px; font-weight: 700; padding: 4px 7px; font-family: inherit; flex: none;
  border-radius: 50%;
}
.ir-tag:hover { color: var(--blue); background: var(--blue-light); }

/* แนบไฟล์ในคอมเมนต์ (Boss 2026-08-29) — ปุ่ม 📎 + แถบพรีวิวใต้ช่องพิมพ์ */
.ir-clip {
  border: none; background: none; cursor: pointer; flex: none;
  font-size: 15px; padding: 4px 6px; line-height: 1; opacity: .75;
}
.ir-clip:hover { opacity: 1; }
.ir-files {
  display: flex; flex-wrap: wrap; gap: 7px;
  margin: 7px 0 0 39px;               /* เยื้องให้ตรงกับช่องพิมพ์ (พ้นอวาตาร์ 30px) */
}
.ir-files.hidden { display: none; }
.ir-file { position: relative; flex: none; }
.ir-file img {
  width: 62px; height: 62px; object-fit: cover;
  border-radius: 9px; border: 1px solid var(--border); display: block;
}
.ir-file-doc {
  display: flex; align-items: center; gap: 6px; max-width: 190px;
  border: 1px solid var(--border); border-radius: 9px;
  padding: 7px 26px 7px 9px; background: var(--card);
}
.ir-file-ic { font-size: 15px; flex: none; }
.ir-file-nm {
  font-size: 12px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ir-file-x {
  position: absolute; top: -6px; right: -6px;
  width: 19px; height: 19px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--card); color: var(--muted);
  font-size: 11px; line-height: 1; cursor: pointer; padding: 0;
  display: flex; align-items: center; justify-content: center;
}
.ir-file-x:hover { color: var(--red); border-color: var(--red); }
/* มือถือ: ปุ่มแตะง่ายขึ้น + รูปเล็กลงกันล้นจอ 360px */
@media (max-width: 860px) {
  .ir-clip { font-size: 17px; padding: 6px 7px; }
  .ir-files { margin-left: 0; gap: 6px; }
  .ir-file img { width: 56px; height: 56px; }
  .ir-file-x { width: 22px; height: 22px; font-size: 12px; }
}

/* ---- ฝังหน้า TaskFlow จริง (iframe) 2026-08-21 ---- */
.tf-embed-tools { margin-left: auto; display: flex; gap: 6px; align-items: center; }
.tf-frame-wrap {
  position: relative; border: 1px solid var(--border); border-radius: 10px;
  overflow: hidden; background: var(--card);
  /* กินความสูงที่เหลือจริง ๆ (ไม่คำนวณเดา) — .page-body เป็น flex ให้ยืดเอง
     Boss ท้วง 2026-08-21: ของเดิม 100vh-210px เหลือที่ว่างเปล่า ต้องเลื่อนซ้อน 2 ชั้น */
  flex: 1; min-height: 320px;
}
/* หน้า TaskFlow: เลย์เอาต์เป็นคอลัมน์ยืด ไม่ต้อง scroll ตัวหน้า (iframe จัดการเอง) */
#page-taskflow .page-body {
  display: flex; flex-direction: column; overflow: hidden; padding: 8px; min-height: 0;
}
#page-taskflow #tf-body {
  flex: 1; min-height: 0; display: flex; flex-direction: column;
}
.tf-frame { width: 100%; height: 100%; border: 0; display: block; background: #0f0f23; }
.tf-frame-load { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 13px; }
@media (max-width: 860px) {
  #page-taskflow .page-body { padding: 6px; }
  .tf-frame-wrap { min-height: 300px; }
  /* มือถือที่แคบ: ย่อแถบบนให้เหลือที่ให้ตารางมากที่สุด */
  #page-taskflow .tf-who { padding: 5px 8px; font-size: 12px; }
}

/* ============================================================
   การ์ด BOX สลิป/ใบจอง (meta.card='slip') — Boss สั่ง 2026-08-21
   ⚠️ การ์ดนี้ "จัดกรอบ" ให้อ่านง่ายเท่านั้น ข้อมูลแสดงครบ 100% ทุกบรรทัด
      ห้ามใส่ max-height / overflow:hidden / line-clamp เด็ดขาด (จะซ่อนข้อมูล)
   ใช้ token ธีมล้วน → สลับสว่าง/มืดได้เอง
   ============================================================ */
.slip-card {
  margin-top: 6px; max-width: min(420px, 100%);
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--card); overflow: hidden;
}
/* พาดหัว = แถบสีแบรนด์ (เลขใบจอง + สถานะ) */
.slip-card .slip-head {
  padding: 8px 11px; font-weight: 700; line-height: 1.45;
  background: var(--blue-light); color: var(--text);
  border-bottom: 1px solid var(--border); word-break: break-word;
}
/* หัวข้อกลุ่ม เช่น "ข้อมูลลูกค้า" */
.slip-card .slip-sec-title {
  padding: 7px 11px 3px; font-size: 12px; font-weight: 700;
  color: var(--muted); text-transform: none; letter-spacing: .01em;
}
.slip-card .slip-sec { padding: 0 11px 6px; }
/* แต่ละบรรทัดข้อมูล — ตัดคำได้ ยาวแค่ไหนก็แสดงหมด ไม่ตัดท้าย */
.slip-card .slip-row {
  padding: 2px 0; line-height: 1.5; word-break: break-word; overflow-wrap: anywhere;
}
/* บรรทัดที่อยู่นอกกลุ่ม (เช่น ลิงก์ดูรายละเอียด / เวลาอนุมัติ / ยอดสลิป) */
.slip-card > .slip-row { padding: 3px 11px; }
.slip-card > .slip-row:last-child { padding-bottom: 9px; }
.slip-card .slip-row a { word-break: break-all; }
/* การ์ดสลิปต่อท้ายรูป/อัลบั้ม — ชิดกันเป็นก้อนเดียว ไม่ให้ดูเหมือน 2 ข้อความ */
.msg img.msg-image + .slip-card, .album-card + .slip-card { margin-top: 6px; }
@media (max-width: 860px) {
  .slip-card { max-width: 100%; }
}

/* แถวแท็บ TaskFlow: รวมชื่อคนที่เชื่อมไว้ในแถวเดียว ประหยัดความสูงให้ตาราง */
.tf-who-inline { font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 40vw; }
.tf-who-inline b { color: var(--text); }
#page-taskflow .tf-scope { margin-bottom: 6px; align-items: center; }

/* ============================================================
   ธีมส่วนตัวรายคน — ชุดสีหลัก (Boss สั่ง 2026-08-21)
   html[data-accent="<ชุด>"] ซ้อนบน html[data-theme="light|dark"] ที่มีอยู่เดิม
   ⚠️ กฎเหล็ก: ชุดสีแตะได้แค่ 4 token นี้เท่านั้น
        --blue        สีแบรนด์หลัก (ปุ่ม/ลิงก์/ชื่อ/ห้องที่เลือก)
        --blue-dark   เข้มขึ้น (hover ปุ่ม)
        --blue-light  อ่อนมาก (พื้นหัวการ์ด/พื้นอ่อน)
        --side-bg     พื้นแถบข้าง
      ห้ามแตะ --green/--red/--amber (สีสถานะ สื่อความหมาย เปลี่ยนแล้วอ่านผิด)
      ห้ามแตะ --bg/--card/--text/--border (พื้น/ตัวอักษร คุมคอนทราสต์การอ่าน)
   ค่าเริ่มต้น (ไม่มี data-accent หรือ = blue) ใช้ :root เดิม ไม่ต้องเขียนซ้ำ
   ============================================================ */

/* ---- เขียวมรกต ---- */
html[data-accent="emerald"] {
  --blue: #0F766E; --blue-dark: #115E56; --blue-light: #E6F4F1; --side-bg: #0B4F49;
}
html[data-accent="emerald"][data-theme="dark"] {
  --blue: #3FBFAE; --blue-dark: #6FD6C8; --blue-light: #16292A; --side-bg: #101F22;
}
/* ---- ม่วง ---- */
html[data-accent="violet"] {
  --blue: #6D28D9; --blue-dark: #571FAE; --blue-light: #F0EAFB; --side-bg: #43227E;
}
html[data-accent="violet"][data-theme="dark"] {
  --blue: #A78BFA; --blue-dark: #C4B0FC; --blue-light: #241C39; --side-bg: #1A1526;
}
/* ---- เทาอมน้ำเงิน ---- */
html[data-accent="slate"] {
  --blue: #475569; --blue-dark: #334155; --blue-light: #EDF0F4; --side-bg: #2C3A4B;
}
html[data-accent="slate"][data-theme="dark"] {
  --blue: #94A9C4; --blue-dark: #B4C4D8; --blue-light: #1D2530; --side-bg: #151C25;
}
/* ---- ส้มอิฐ ---- */
html[data-accent="terracotta"] {
  --blue: #B4531F; --blue-dark: #904118; --blue-light: #FBEDE5; --side-bg: #7C3A15;
}
html[data-accent="terracotta"][data-theme="dark"] {
  --blue: #E8935F; --blue-dark: #F2AF85; --blue-light: #2E1F16; --side-bg: #241811;
}
/* ---- ชมพูบานเย็น ---- */
html[data-accent="magenta"] {
  --blue: #A21B62; --blue-dark: #81154E; --blue-light: #FBE9F2; --side-bg: #6E1243;
}
html[data-accent="magenta"][data-theme="dark"] {
  --blue: #EF7CAF; --blue-dark: #F5A0C6; --blue-light: #2E1622; --side-bg: #24121B;
}
/* ---- เทอร์คอยส์ ---- */
html[data-accent="teal"] {
  --blue: #0E7490; --blue-dark: #0B5A70; --blue-light: #E4F2F7; --side-bg: #0B4E62;
}
html[data-accent="teal"][data-theme="dark"] {
  --blue: #47B6D4; --blue-dark: #77CDE3; --blue-light: #142831; --side-bg: #101E26;
}
/* ---- แดงเลือดหมู ---- */
html[data-accent="maroon"] {
  --blue: #9B1C2E; --blue-dark: #7C1624; --blue-light: #FBE9EB; --side-bg: #6B1220;
}
html[data-accent="maroon"][data-theme="dark"] {
  --blue: #E8737F; --blue-dark: #F09AA3; --blue-light: #2E1519; --side-bg: #241114;
}

/* ---- คราม (indigo) ---- */
html[data-accent="indigo"] {
  --blue: #4338CA; --blue-dark: #362BA5; --blue-light: #ECEAFB; --side-bg: #2E2585;
}
html[data-accent="indigo"][data-theme="dark"] {
  --blue: #8B90F8; --blue-dark: #ABAFFB; --blue-light: #1D1E38; --side-bg: #161629;
}
/* ---- เขียวป่า (forest) ---- */
html[data-accent="forest"] {
  --blue: #2F6B34; --blue-dark: #245328; --blue-light: #E9F3E9; --side-bg: #1F4A23;
}
html[data-accent="forest"][data-theme="dark"] {
  --blue: #74C57C; --blue-dark: #99D89F; --blue-light: #172618; --side-bg: #111C12;
}
/* ---- ทอง (amberg) ---- */
html[data-accent="amberg"] {
  --blue: #92610C; --blue-dark: #744C08; --blue-light: #FBF1DE; --side-bg: #63400A;
}
html[data-accent="amberg"][data-theme="dark"] {
  --blue: #E0B054; --blue-dark: #EDC77E; --blue-light: #2C2312; --side-bg: #221B0E;
}
/* ---- น้ำเงินเข้ม (navy) ---- */
html[data-accent="navy"] {
  --blue: #1E3A8A; --blue-dark: #172E6D; --blue-light: #E7ECF8; --side-bg: #14264F;
}
html[data-accent="navy"][data-theme="dark"] {
  --blue: #7DA2E8; --blue-dark: #A3BEF0; --blue-light: #17203A; --side-bg: #101728;
}
/* ---- ชมพูกุหลาบ (rose) ---- */
html[data-accent="rose"] {
  --blue: #BE255A; --blue-dark: #991C48; --blue-light: #FCE9EF; --side-bg: #7E1740;
}
html[data-accent="rose"][data-theme="dark"] {
  --blue: #F489A9; --blue-dark: #F8AAC2; --blue-light: #30171F; --side-bg: #251218;
}
/* ---- ม่วงอมเทา (plum) ---- */
html[data-accent="plum"] {
  --blue: #6B356B; --blue-dark: #552A55; --blue-light: #F3EAF3; --side-bg: #4A244A;
}
html[data-accent="plum"][data-theme="dark"] {
  --blue: #C88AC8; --blue-dark: #DBABDB; --blue-light: #2A1B2A; --side-bg: #1F141F;
}

/* ---- วงกลมเลือกชุดสีในหน้าโปรไฟล์ ---- */
.pf-accents { display: flex; flex-wrap: wrap; gap: 9px; }
.pf-accent {
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer; padding: 0;
  border: 2px solid var(--border); position: relative;
  transition: transform .12s;
}
.pf-accent:hover { transform: scale(1.08); }
/* ชุดที่เลือกอยู่: วงแหวนสีแบรนด์ + เครื่องหมายถูก */
.pf-accent.active { border-color: var(--text); box-shadow: 0 0 0 2px var(--card) inset; }
.pf-accent.active::after {
  content: '✓'; position: absolute; inset: 0; display: grid; place-items: center;
  color: #fff; font-size: 16px; font-weight: 700; text-shadow: 0 1px 2px rgba(0,0,0,.5);
}

/* ============================================================
   หน้าเลขา 3 แท็บ (2026-08-21 ตามรูปที่ Boss ให้)
   ============================================================ */
.sec-head-right { margin-left: auto; }
.sec-badge {
  font-size: 12px; color: var(--muted); background: var(--sunken);
  border: 1px solid var(--border); border-radius: 999px; padding: 4px 12px; white-space: nowrap;
}
.sec-tabs { display: flex; gap: 18px; border-bottom: 1px solid var(--border); padding: 0 2px; margin-bottom: 12px; }
.sec-tab {
  border: none; background: none; padding: 8px 2px 10px; cursor: pointer; font-family: inherit;
  font-size: 14.5px; color: var(--muted); border-bottom: 2px solid transparent; font-weight: 600;
}
.sec-tab.active { color: var(--text); border-bottom-color: var(--blue); }
.sec-sect { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.sec-sect.hidden { display: none; }
#sec-sect-guide, #sec-sect-setup { overflow-y: auto; }

/* การ์ดสั่งงานเร็ว 4 ใบ */
.sec-quick { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; }
.sec-card {
  display: flex; flex-direction: column; gap: 3px; text-align: left; cursor: pointer;
  background: var(--card); border: 1px solid var(--border); border-radius: 10px;
  padding: 12px 14px; font-family: inherit;
}
.sec-card:hover { border-color: var(--blue); background: var(--blue-light); }
.sec-card-t { font-size: 14.5px; font-weight: 700; color: var(--text); }
.sec-card-d { font-size: 12.5px; color: var(--muted); }
.sec-chat-tools { display: flex; justify-content: flex-end; padding-top: 6px; }

/* ไกด์เริ่มงาน */
.sec-guide-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 10px; }
.sec-guide-head h3 { margin: 0 0 2px; }
.sec-guide-count { margin-left: auto; font-size: 13px; font-weight: 700; color: var(--muted); white-space: nowrap; }
.sec-bar { height: 6px; background: var(--sunken); border-radius: 999px; overflow: hidden; margin-bottom: 6px; }
.sec-bar span { display: block; height: 100%; background: var(--blue); border-radius: 999px; transition: width .3s; }
.sec-steps2 { display: flex; flex-direction: column; }
.sec-step { display: flex; align-items: center; gap: 12px; padding: 12px 2px; border-bottom: 1px solid var(--border); }
.sec-steps2 .sec-step:last-child { border-bottom: none; }
.sec-step-box {
  width: 20px; height: 20px; flex: 0 0 20px; border: 2px solid var(--border); border-radius: 5px;
  display: flex; align-items: center; justify-content: center; font-size: 13px; color: #fff;
}
.sec-step.done .sec-step-box { background: var(--green); border-color: var(--green); }
.sec-step-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sec-step-t { font-size: 14.5px; font-weight: 600; color: var(--text); }
.sec-step-d { font-size: 12.5px; color: var(--muted); }
.sec-step.done .sec-step-t { color: var(--muted); }

/* รูทีน Co-work */
.sec-rt { display: flex; align-items: center; gap: 12px; padding: 12px 2px; border-bottom: 1px solid var(--border); }
.sec-rt-card .sec-rt:last-child { border-bottom: none; }
.sec-rt-main { flex: 1; min-width: 0; }
.sec-rt-when, .sec-rt-do { font-size: 13.5px; color: var(--muted); }
.sec-rt-when b, .sec-rt-do b { color: var(--text); }

/* สวิตช์ */
.sec-sw { position: relative; display: inline-block; width: 42px; height: 24px; flex-shrink: 0; }
.sec-sw input { opacity: 0; width: 0; height: 0; position: absolute; }
.sec-sw span {
  position: absolute; inset: 0; background: var(--border); border-radius: 999px;
  cursor: pointer; transition: background .2s;
}
.sec-sw span::before {
  content: ''; position: absolute; width: 18px; height: 18px; left: 3px; top: 3px;
  background: #fff; border-radius: 50%; transition: transform .2s; box-shadow: 0 1px 3px rgba(0,0,0,.3);
}
.sec-sw input:checked + span { background: var(--blue); }
.sec-sw input:checked + span::before { transform: translateX(18px); }

/* ตั้งค่าผู้ช่วย */
.sec-set-card { margin-bottom: 12px; }
.sec-set-head { padding-bottom: 10px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.sec-set-head h3 { margin: 0 0 2px; }
.sec-set-row { display: flex; align-items: center; gap: 12px; padding: 12px 2px; border-bottom: 1px solid var(--border); }
.sec-set-card .sec-set-row:last-child { border-bottom: none; }
.sec-set-main { flex: 1; min-width: 0; }
.sec-set-t { font-size: 14.5px; font-weight: 600; color: var(--text); }
.sec-set-d { font-size: 12.5px; color: var(--muted); }
.sec-set-ctrl { flex-shrink: 0; }
.sec-pills { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.sec-pill {
  border: 1px solid var(--border); background: var(--card); color: var(--muted);
  padding: 5px 13px; border-radius: 999px; cursor: pointer; font-family: inherit; font-size: 13px;
}
.sec-pill.active { border-color: var(--blue); color: var(--blue); font-weight: 700; }
.sec-set-save { display: flex; justify-content: flex-end; padding-top: 10px; }
.sec-rooms { display: flex; flex-wrap: wrap; gap: 8px 16px; padding: 8px 0; }
.sec-room { display: flex; align-items: center; gap: 6px; font-size: 13.5px; cursor: pointer; }

@media (max-width: 860px) {
  .sec-quick { grid-template-columns: 1fr; }
  .sec-tabs { gap: 14px; }
  .sec-set-row, .sec-step, .sec-rt { align-items: flex-start; }
  .sec-pills { justify-content: flex-start; }
  .sec-badge { font-size: 11px; padding: 3px 9px; }
}

/* ============================================================
   Window Controls Overlay — ให้ PWA เดสก์ท็อปดูเหมือนแอปจริง
   (Boss สั่ง 2026-08-21: แถบชื่อของ Windows ทำให้ดูเหมือนเว็บในกรอบ)

   manifest มี display_override:["window-controls-overlay","standalone"]
   → OS ยกแถบชื่อออก เหลือแค่ปุ่ม ─ ◻ ✕ ลอยมุมขวา แล้วแอปวาดหัวเองแทน

   ⚠️ ทุกกฎในบล็อกนี้อยู่ใต้ @media (display-mode: window-controls-overlay)
      → ในแท็บเบราว์เซอร์ปกติและบนมือถือ "ไม่มีผลอะไรเลย" (ที่นั่นไม่มีแถบชื่ออยู่แล้ว)
   env(titlebar-area-*) = พื้นที่ที่ OS ยกให้เราวาด (ไม่รวมที่ปุ่ม ─ ◻ ✕)
   ============================================================ */
@media (display-mode: window-controls-overlay) {
  /* ความสูงแถบหัวจาก OS · เผื่อ 33px กรณีอ่านค่าไม่ได้ */
  :root { --titlebar-h: env(titlebar-area-height, 33px); }

  /* แถบหัวไซด์บาร์ = พื้นที่ลากย้ายหน้าต่าง (เหมือนลากแถบชื่อเดิม) */
  .sidebar-head {
    -webkit-app-region: drag; app-region: drag;
    /* สูงพอๆ กับแถบ OS ให้แบรนด์อยู่ระดับเดียวกับปุ่ม ─ ◻ ✕ */
    min-height: var(--titlebar-h);
    padding-top: 6px;
  }
  /* ปุ่มในแถบต้องกดได้ ไม่ใช่กลายเป็นที่ลาก (ไม่งั้นกดสลับธีม/สร้างห้องไม่ได้) */
  .sidebar-head .head-tools,
  .sidebar-head .icon-btn,
  .sidebar-head button {
    -webkit-app-region: no-drag; app-region: no-drag;
  }

  /* ฝั่งขวา: หัวหน้าเพจ/หัวห้อง ต้องเว้นที่ให้ปุ่ม ─ ◻ ✕ ที่ลอยมุมขวาบน
     ไม่งั้นปุ่ม ⋯ / ค้นหา ของเราจะอยู่ใต้ปุ่มปิดหน้าต่าง = กดปิดโดยไม่ตั้งใจ */
  .main .page-head, .main .chat-head {
    padding-top: max(8px, calc(var(--titlebar-h) - 20px));
    -webkit-app-region: drag; app-region: drag;
  }
  /* แต่ของที่กดได้ในหัวห้องต้องกดได้ตามปกติ */
  .main .page-head *, .main .chat-head * {
    -webkit-app-region: no-drag; app-region: no-drag;
  }
  /* ช่องว่างขวาสุดเท่าความกว้างปุ่มหน้าต่าง — คำนวณจากความกว้างที่ OS ยกให้ */
  .main .page-head { padding-right: calc(100% - env(titlebar-area-width, 100%) + 16px); }
  .main .chat-head { padding-right: calc(100% - env(titlebar-area-width, 100%) + 12px); }

  /* ---- หน้า login / รอตั้งรหัส: ยังไม่มีไซด์บาร์ให้ลาก ----
     ถ้าไม่ทำ = ตอนยังไม่ล็อกอินจะ "ลากหน้าต่างไม่ได้เลย" (ไม่มีแถบชื่อแล้ว)
     → ทำแถบลากใสๆ พาดด้านบนเต็มความกว้างที่ OS ยกให้ */
  /* (#mustpw-screen มี class .login-screen อยู่แล้ว → ครอบคลุมทั้งสองหน้า) */
  .login-screen::before {
    content: ''; position: fixed; top: 0; left: 0;
    width: env(titlebar-area-width, 100%); height: var(--titlebar-h);
    -webkit-app-region: drag; app-region: drag;
    z-index: 4;   /* ต่ำกว่า .theme-fab (z-index:5) ปุ่มยังกดได้ */
  }
  /* ปุ่มสลับธีมมุมซ้ายบนของหน้า login เดิมอยู่ที่ top:10px = ใต้แถบ OS พอดี
     เลื่อนลงมาให้พ้นแถบ ไม่ให้ทับกันจนกดไม่ได้ */
  .theme-fab {
    top: calc(var(--titlebar-h) + 8px);
    -webkit-app-region: no-drag; app-region: no-drag;
  }
}

/* ---- หน้าตั้งค่าผู้ใช้งาน (ละเอียด) 2026-08-21 ----
   ทุกช่องมีป้ายถาวรซ้ายมือ + คำอธิบายใต้ช่อง (placeholder หายตอนพิมพ์ = กรอกผิดช่อง) */
.uf-card { max-width: 620px; }
.uf-sec {
  font-size: 12px; font-weight: 700; letter-spacing: .04em; color: var(--blue);
  text-transform: uppercase; margin: 16px 0 6px; padding-bottom: 5px;
  border-bottom: 1px solid var(--border);
}
.uf-sec:first-child { margin-top: 4px; }
.uf-row { display: flex; gap: 14px; align-items: flex-start; padding: 9px 0; }
.uf-lb {
  flex: 0 0 168px; font-size: 13.5px; font-weight: 600; color: var(--text);
  padding-top: 9px; line-height: 1.35;
}
.uf-req { color: var(--red); }
.uf-in { flex: 1; min-width: 0; }
.uf-in input, .uf-in select { width: 100%; margin: 0; }
.uf-hint { font-size: 12px; color: var(--muted); margin-top: 4px; line-height: 1.45; }
.uf-ro {
  padding: 9px 12px; border-radius: 8px; background: var(--sunken);
  border: 1px dashed var(--border); color: var(--muted); font-size: 14px;
}
.uf-err { color: var(--red); font-size: 13px; min-height: 18px; margin: 8px 0 0; }
.tbl .nowrap { white-space: nowrap; }
@media (max-width: 700px) {
  /* มือถือ: ป้ายขึ้นบรรทัดบนช่อง ไม่บีบช่องให้แคบ */
  .uf-row { flex-direction: column; gap: 4px; padding: 8px 0; }
  .uf-lb { flex: none; padding-top: 0; }
}

/* ============================================================
   รายชื่อผู้ใช้ + หน้าจัดการผู้ใช้ (ตามรูปที่ Boss ให้ 2026-08-21)
   ============================================================ */
.uf-search {
  width: 100%; margin: 0 0 10px; padding: 10px 13px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--sunken); color: var(--text); font-size: 14px;
}
.ul-list { display: flex; flex-direction: column; }

/* แถวรายชื่อ 1 คน */
.cpu-row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 4px; border-bottom: 1px solid var(--border);
}
.ul-list .cpu-row:last-child { border-bottom: none; }
.cpu-row.off { opacity: .55; }
.cpu-row.hidden { display: none; }
.cpu-av { flex: 0 0 auto; display: flex; }
.cpu-main { flex: 1; min-width: 0; }
.cpu-name { display: flex; align-items: center; gap: 7px; font-size: 14.5px; color: var(--text); }
.cpu-name b { font-weight: 700; }
.cpu-sub { font-size: 12.5px; color: var(--muted); margin-top: 1px; }
.cpu-dot { width: 8px; height: 8px; border-radius: 50%; background: #64748B; flex: 0 0 8px; }
.cpu-dot.on { background: var(--green); }

/* ป้ายระดับตำแหน่ง — สีต่างกันให้กวาดตาเห็นไว */
.cpu-rank {
  font-size: 12px; font-weight: 600; padding: 4px 12px; border-radius: 999px;
  background: var(--sunken); color: var(--muted); white-space: nowrap; flex: 0 0 auto;
}
.cpu-rank.rank-staff  { background: var(--blue-light); color: var(--blue); }
.cpu-rank.rank-lead   { background: var(--amber-bg); color: var(--amber); }
.cpu-rank.rank-admin  { background: var(--green-bg); color: var(--green); }
.cpu-rank.rank-exec   { background: rgba(139,92,246,.16); color: #A78BFA; }
.cpu-rank.rank-system { background: var(--sunken); color: var(--muted); }

/* ---- โมดัลจัดการผู้ใช้ ---- */
.cu-wrap { max-width: 680px; }
.cu-hero {
  display: flex; align-items: center; gap: 14px; padding-bottom: 14px;
  border-bottom: 1px solid var(--border); margin-bottom: 4px;
}
.cu-hero-name { font-size: 17px; font-weight: 700; color: var(--text); }
.cu-hero-sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.cu-sec { padding: 14px 0 4px; border-bottom: 1px solid var(--border); }
.cu-wrap .cu-sec:last-of-type { border-bottom: none; }
.cu-sec-h { margin-bottom: 10px; }
.cu-sec-h b { font-size: 14.5px; color: var(--text); display: block; }
.cu-sec-h span { font-size: 12.5px; color: var(--muted); }
/* ช่องกรอก 2 คอลัมน์ — ป้ายชื่ออยู่บนช่อง (ไม่ใช้ placeholder เดี่ยว) */
.cu-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; }
.cu-f { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.cu-lb { font-size: 12.5px; font-weight: 600; color: var(--muted); }
.cu-lb i { color: var(--red); font-style: normal; }
.cu-f input, .cu-f select { width: 100%; margin: 0; }
.cu-f input[readonly] { background: var(--sunken); color: var(--muted); border-style: dashed; }
/* ปุ่มเลือกระดับสิทธิ์ */
.cu-pills { display: flex; flex-wrap: wrap; gap: 7px; }
.cu-pill {
  border: 1px solid var(--border); background: var(--card); color: var(--muted);
  padding: 6px 15px; border-radius: 999px; cursor: pointer; font-family: inherit; font-size: 13px;
}
.cu-pill.active { border-color: var(--blue); color: var(--blue); font-weight: 700; background: var(--blue-light); }
.cu-sw-row { display: flex; align-items: center; gap: 12px; padding: 12px 0 2px; font-size: 14px; }
.cu-sw-row > span { flex: 1; color: var(--text); }
/* ห้องที่เข้าถึงได้ */
.cu-rooms { display: flex; flex-wrap: wrap; gap: 8px; }
.cu-room {
  display: flex; align-items: center; gap: 7px; cursor: pointer; font-size: 13.5px;
  border: 1px solid var(--border); border-radius: 8px; padding: 7px 12px; color: var(--muted);
}
.cu-room.on { border-color: var(--blue); color: var(--text); background: var(--blue-light); }
/* รายการตำแหน่งงาน — ใช้ flex ไม่ใช่ตาราง เพราะบนมือถือ 360px ตารางดันปุ่มลบตกขอบ
   ต้องเลื่อนข้างถึงจะเห็น (วัดจริง: ตารางกว้าง 364px แต่ช่องมองเห็น 318px) */
.jt-list { display: flex; flex-direction: column; }
.jt-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 2px; border-bottom: 1px solid var(--border);
}
.jt-row:last-child { border-bottom: 0; }
.jt-nm { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; font-size: 14px; }
.jt-ct { flex: 0 0 auto; }
.jt-ct.muted { color: var(--muted); font-size: 13px; min-width: 22px; text-align: center; }
.jt-btns { flex: 0 0 auto; display: flex; gap: 6px; }
.jt-btns .btn { min-height: 34px; }
@media (max-width: 700px) {
  /* มือถือ: ปุ่มอยู่แถวเดียวกับชื่อ ไม่ตกบรรทัด — ปุ่มเต็มความกว้างกินที่เกินไป
     เห็นได้แค่ 5 ตำแหน่งต่อหน้าจอ ทั้งที่มี 24 ตำแหน่ง */
  .jt-row { gap: 8px; padding: 10px 2px; }
  .jt-nm { font-weight: 600; }
  .jt-btns .btn { min-height: 38px; padding: 6px 10px; font-size: 12.5px; }
}

/* ตำแหน่งงาน: ดรอปดาวน์ + ปุ่ม ＋ เพิ่มตำแหน่งใหม่ (Boss สั่ง 2026-08-31) */
.cu-job-row { display: flex; gap: 6px; align-items: stretch; }
.cu-job-row select { flex: 1 1 auto; min-width: 0; }
.cu-job-row .cu-job-add { flex: 0 0 auto; min-width: 40px; min-height: 40px; font-size: 16px; line-height: 1; }
.cu-actions { display: flex; gap: 8px; align-items: center; padding-top: 16px; }
.cu-actions .cu-susp { margin-left: auto; }
/* ลบถาวร — อยู่ขวาสุดคู่กับปุ่มระงับ ให้เห็นว่าเป็นคนละระดับความรุนแรง */
.cu-actions .cu-del { flex: 0 0 auto; }
.btn.danger-soft { background: var(--red-bg); color: var(--red); border-color: transparent; }

@media (max-width: 700px) {
  .cu-grid2 { grid-template-columns: 1fr; }
  .cpu-row { flex-wrap: wrap; gap: 8px; }
  .cpu-main { flex: 1 1 100%; order: 2; }
  .cu-actions { flex-wrap: wrap; }
  .cu-actions .cu-susp { margin-left: 0; }
  /* มือถือ: ปุ่มอันตราย 2 ตัวลงบรรทัดล่าง เต็มความกว้าง กันกดพลาดตอนเลื่อน */
  .cu-actions .cu-susp, .cu-actions .cu-del { flex: 1 1 calc(50% - 4px); min-height: 40px; }
}

/* ---- ไอคอนบอกสถานะห้อง: เปิด / ล็อก / ยังไม่ได้เข้า (Boss ท้วง 2026-08-21 "ขึ้นล็อกหมดเลย มองยาก") ----
   ไม่พึ่งรูปอีโมจิเดี่ยว ๆ เพราะ 🔐 กับ 🔒 หน้าตาใกล้กันเกินไป → แยกด้วย "สี + รูปทรง" */
.chan-ic {
  width: 17px; flex: 0 0 17px; text-align: center; font-size: 12px; line-height: 1;
  font-weight: 700;
}
.chan-ic.ic-open { color: var(--green); font-size: 14px; }   /* # = ห้องเปิด เข้าอ่านได้เลย */
.chan-ic.ic-lock { color: var(--amber); font-size: 11px; }   /* 🔒 = ล็อก ต้องเป็นสมาชิก */
.chan-ic.ic-no   { color: var(--muted); opacity: .5; }        /* · = ยังไม่ได้เข้าห้อง */

/* ============================================================
   DM: แถบพับได้ + หน้าต่างแชทลอยล่างขวา (แบบเฟส) — Boss สั่ง 2026-08-21
   ============================================================ */
.dm-bar {
  display: flex; align-items: center; gap: 9px; width: 100%; cursor: pointer;
  background: var(--side-input, rgba(127,127,127,.12)); border: 1px solid transparent;
  border-radius: 10px; padding: 10px 12px; margin: 6px 0 4px;
  font-family: inherit; font-size: 13.5px; font-weight: 600; color: var(--side-text, var(--text));
}
.dm-bar:hover { border-color: var(--blue); }
.dm-bar-ic { font-size: 14px; opacity: .85; }
.dm-bar-tx { flex: 1; text-align: left; }
.dm-bar-badge {
  background: var(--red); color: #fff; font-size: 11px; font-weight: 700;
  min-width: 18px; height: 18px; border-radius: 9px; display: flex;
  align-items: center; justify-content: center; padding: 0 5px;
}
.dm-bar-arrow { font-size: 10px; opacity: .6; }

/* ที่วางหน้าต่าง — ลอยมุมขวาล่าง เรียงจากขวาไปซ้าย */
.dm-dock {
  /* หน้าต่างแชทอยู่ "มุมขวาล่าง" (Boss ยืนยัน 2026-08-21) — ไม่ทับแถบข้าง/เนื้อหา
     ส่วนกล่องรายชื่อ (.dm-list-top) เป็น flyout ข้างปุ่มซ้าย คนละตัวกัน */
  position: fixed; right: 14px; bottom: 0; z-index: 300;
  display: flex; align-items: flex-end; gap: 10px; pointer-events: none;
}
.dm-dock > * { pointer-events: auto; }
.dmw {
  /* Boss ท้วง 2026-08-27 "ช่องมันเล็กไป" — 272x268 แคบเกินสำหรับคอม
     ข้อความไทยตัดคำแปลกๆ · รูปบีบ · ขยายเป็น 340x400 (ยังไม่บังจอ) */
  width: 340px; display: flex; flex-direction: column;
  background: var(--card, #fff); border: 1px solid var(--border, #E2E8F0);
  border-radius: 10px 10px 0 0; box-shadow: 0 -2px 18px rgba(0, 0, 0, .28);
  overflow: hidden;
}
.dmw-head {
  display: flex; align-items: center; gap: 7px; padding: 8px 9px; cursor: pointer;
  /* fallback #0F4C81: โหมดสว่างของแอปยังไม่มีค่า --blue (ปัญหาระดับแอป) ถ้าไม่ใส่จะขาวบนขาว */
  background: var(--blue, #0F4C81); color: var(--on-brand, #fff);
}
.dmw-name { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dmw-dot { width: 8px; height: 8px; border-radius: 50%; background: rgba(255,255,255,.45); flex: 0 0 8px; }
.dmw-dot.on { background: #34D399; }
.dmw-btn {
  border: none; background: none; color: inherit; cursor: pointer; font-size: 13px;
  padding: 2px 4px; opacity: .85; font-family: inherit; line-height: 1;
}
.dmw-btn:hover { opacity: 1; }
.dmw.min { width: 210px; }
.dmw.min .dmw-head { border-radius: 10px 10px 0 0; }
.dmw-body {
  height: 400px; overflow-y: auto; padding: 10px; display: flex; flex-direction: column; gap: 8px;
  background: var(--bg, #F4F6F9);
}
.dmw-empty { color: var(--muted); font-size: 12.5px; text-align: center; margin: auto; }
.dmw-msg { display: flex; gap: 7px; align-items: flex-start; }
/* ของเราเอง: ทุกอย่างย้ายไปขวาพร้อมกัน (อวตาร+ชื่อ+ข้อความ) เหมือนในห้องแชท */
.dmw-msg.me { flex-direction: row-reverse; justify-content: flex-start; margin-left: auto; }
.dmw-av { flex: 0 0 auto; display: flex; cursor: pointer; }
.dmw-av .avatar { width: 26px; height: 26px; font-size: 10px; }
/* ⚠️ ชื่อคนส่งในข้อความ ต้องใช้คลาสแยก — .dmw-name ถูกใช้เป็น "ชื่อห้อง" บนหัวหน้าต่างแล้ว
   (มี flex:1 ทำให้ชื่อในข้อความยืดเต็มแถว จัดตำแหน่งเพี้ยน) */
.dmw-who { font-size: 11px; font-weight: 700; color: var(--muted); }
.dmw-msg.me .dmw-who { display: none; }   /* ของเราไม่ต้องโชว์ชื่อตัวเองซ้ำทุกใบ */
/* หน้าต่าง DM เป็นกล่องแคบ (340px) — ถ้าไม่มีพื้นบับเบิลจะแยกไม่ออกว่าใครพูด
   (ต่างจากห้องแชทที่กว้าง ระยะซ้าย-ขวาเห็นชัดอยู่แล้ว) Boss ท้วง 2026-08-27 "รูปแบบมันแปลกๆ"
   → คืนบับเบิลให้หน้าต่าง DM: ของเราน้ำเงิน · คนอื่นเทา แบบ Messenger */
.dmw-bub {
  max-width: 100%; padding: 6px 10px; border-radius: 14px;
  font-size: 13.5px; line-height: 1.45;
  background: var(--sunken); color: var(--text, #1B2A3A); word-break: break-word;
}
.dmw-msg.me .dmw-bub {
  background: var(--blue); color: #fff; text-align: left;
}
.dmw-msg.me .dmw-bub a { color: #fff; text-decoration: underline; }
/* กล่องห่อ = บับเบิล + แถวเวลา/เครื่องมือ (ให้เหมือนห้องแชท) */
.dmw-wrap { display: flex; flex-direction: column; max-width: 86%; min-width: 0; }
.dmw-msg.me .dmw-wrap { align-items: flex-end; }
.dmw-wrap .dmw-bub { max-width: 100%; }
.dmw-under { display: flex; align-items: center; gap: 6px; }
.dmw-time { font-size: 10px; color: var(--muted); }
/* ปุ่มเครื่องมือในหน้าต่าง DM เล็กกว่าห้องแชทเล็กน้อย (หน้าต่างแคบ) */
.dmw-under .msg-tool { padding: 2px; }
/* 🔴 2026-09-08 Boss: "ในแชทที่เปิดมา กดสติ๊กเกอร์/จุดสามจุด/ตอบกลับไม่ได้เลย"
   ต้นเหตุ: กฎมือถือ `@media (hover:none) .msg-tool{padding:7px}` ถูกกฎบรรทัดบนนี้
   (`.dmw-under .msg-tool` — specificity สูงกว่า + มาทีหลัง) ทับกลับเป็น 2px
   → วัดจริงบนจอ 360px ได้ปุ่ม 🙂/↩ แค่ **21x21px** (⋯ ได้ 30px จากกฎ last-child)
   เกณฑ์นิ้วจริงต้อง ≥44px — ปุ่มเห็นอยู่แต่ "แตะไม่โดน" ไม่ใช่ปุ่มหาย
   ⚠️ ห้ามแก้ที่ `.msg-tool` ตัวกลาง จะไปขยายปุ่มในห้องแชทปกติด้วย
   ⚠️ ขยายด้วย padding อย่างเดียวทำให้แถวสูงขึ้นจนบับเบิลห่าง — ใช้ min-w/h + margin ลบ
      ให้พื้นที่แตะโตแต่ที่ทางที่กินยังเท่าเดิม */
@media (hover: none) {
  .dmw-under .msg-tools { gap: 4px; }
  .dmw-under .msg-tool {
    padding: 2px;
    min-width: 44px; min-height: 44px;
    margin-top: -11px; margin-bottom: -11px;   /* กันแถวสูงขึ้น (44-22)/2 */
  }
  /* ⋯ ยังต้องเด่นกว่าเพื่อน (เป็นทางเข้าเมนูหลักบนมือถือ) แต่ต้องแตะถนัดเท่ากัน
     🔴 2026-09-08 Boss: "วงกลมรอบตัวสามจุดใหญ่ไป เหมือนจะบัค"
        กฎ `.msg-tools .msg-tool:last-child{background:var(--sunken)}` + `border-radius:50%`
        วาดวงกลมสีเทาเต็มขนาดปุ่ม พอผมดันปุ่มเป็น 44px เพื่อให้แตะโดน
        **วงกลมก็โตตาม 44px** = ก้อนเทาใหญ่ผิดสัดส่วน (อีก 2 ปุ่มพื้นใส เลยยิ่งเห็นชัด)
     แก้: พื้นที่แตะคง 44px (โปร่งใส) แต่ย้ายวงกลมที่ "มองเห็น" ไปวาดด้วย ::before
     ขนาด 30px ตรงกลาง — ได้ทั้งแตะถนัดและหน้าตาสมส่วน
     ⚠️ ห้ามลดขนาดปุ่มลงเพื่อให้วงกลมเล็ก จะกลับไปเป็นบั๊ก "กดไม่โดน" อีก */
  .dmw-under .msg-tools .msg-tool:last-child {
    min-width: 44px; min-height: 44px;
    background: none;                 /* ยกเลิกวงกลมเต็มปุ่มของกฎมือถือ */
    position: relative; z-index: 0;
  }
  .dmw-under .msg-tools .msg-tool:last-child::before {
    content: ''; position: absolute; z-index: -1;
    top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: 30px; height: 30px; border-radius: 50%;
    background: var(--sunken);
  }
}
.dmw-foot { display: flex; gap: 6px; padding: 8px; border-top: 1px solid var(--border, #E2E8F0); background: var(--card, #fff);
  align-items: flex-end; }   /* ช่องพิมพ์สูงขึ้นได้ → ปุ่มเกาะขอบล่างไว้ */
.dmw-in {
  flex: 1; margin: 0; padding: 8px 11px; border-radius: 16px; font-size: 13.5px;
  border: 1px solid var(--border); background: var(--sunken); color: var(--text);
  /* พิมพ์ยาวแล้วขยายเองได้ (เดิมเป็น <input> บรรทัดเดียว ข้อความไหลเลยขอบ) */
  resize: none; font-family: inherit; line-height: 1.45;
  min-height: 34px; max-height: 136px; overflow-y: hidden;
  white-space: pre-wrap; word-break: break-word;
}
.dmw-in:focus { border-color: var(--blue, #0F4C81); background: var(--card, #fff); outline: none; }
.dmw-send { border: none; background: none; color: var(--blue, #0F4C81); cursor: pointer; font-size: 16px; padding: 0 4px; }

@media (max-width: 860px) {
  /* มือถือ: เปิดทีละอัน กว้างเกือบเต็มจอ · ยกขึ้นเหนือแถบล่าง */
  .dm-dock { right: 6px; left: 6px; bottom: 58px; gap: 6px; }
  .dmw { width: 100%; }
  .dmw ~ .dmw { display: none; }
  .dmw-body { height: 46vh; }
  /* 📱 มือถือใช้ Chat Head แทนหน้าต่างลอยทั้งหมด (Boss 2026-09-07)
     ปิดรางไว้เลย เผื่อมีเส้นเก่าที่ยังเรียก openDmWin() หลุดมา หรือหน้าต่างค้าง
     จากตอนที่ยังเป็นจอกว้างแล้วผู้ใช้หมุนจอ/ย่อหน้าต่าง */
  .dm-dock { display: none !important; }
}

/* รูป/สื่อในหน้าต่าง DM (Boss ท้วง "รูปไม่ขึ้น" 2026-08-21) */
.dmw-bub.media { padding: 4px; background: transparent; }
.dmw-msg.me .dmw-bub.media { background: transparent; }
/* 🔴 2026-10-03 พี่ปองแจ้ง (/p/FPZUEX7vNZJD) "ส่งไฟล์แนบ มันขึ้นเป็นสีขาว มองไม่เห็นข้อความ"
   ฝั่งเรา (.me) ลิงก์ถูกบังคับเป็นขาว (กฎบน — ไว้อ่านบนบับเบิลน้ำเงิน) แต่ใบสื่อ/ไฟล์ (.media) พื้นโปร่งใส
   ⇒ ลิงก์ชื่อไฟล์ + ลิงก์ในคำบรรยาย = ขาวบนพื้นขาว · ใช้สีหลักของธีม (--blue เปลี่ยนตามธีม/โหมดมืดเอง) */
.dmw-msg.me .dmw-bub.media a { color: var(--blue); }
/* ✅ 2026-10-03 13:10 Boss สั่งใช้กับทุกคน (ทดสอบคนเดียวผ่าน ?filebub=1 มาก่อน)
   ไฟล์แนบ = บับเบิลสีเดียวกับข้อความธรรมดา + ชื่อไฟล์ฟ้าอ่อนบนชิปเข้ม · ทุกธีม/ทุกโหมด
   ⚠️ ใบไฟล์มีคลาส "media file" — กฎชุดนี้ขึ้นต้นด้วย html เพื่อให้ชนะกฎ .media (พื้นโปร่ง) ด้านบน */
html .dmw-bub.file { padding: 6px 10px; background: var(--sunken); }
html .dmw-msg.me .dmw-bub.file { background: var(--blue); }
html .dmw-msg.me .dmw-bub.file .dmw-cap { color: #fff; }
html .dmw-bub.file .dmw-file {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  margin-top: 2px; padding: 4px 9px; border-radius: 8px;
  font-weight: 600; text-decoration: underline; word-break: break-all;
}
html .dmw-bub.file .dmw-file::before { content: '📎'; text-decoration: none; flex: none; }
html .dmw-msg.me .dmw-bub.file .dmw-file { color: #BFE6FF; background: rgba(0, 0, 0, .22); }
html[data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, .42); }   /* บับเบิลโหมดมืดสว่างกว่า */
html .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: var(--blue); background: rgba(0, 0, 0, .05); }
/* ปรับรายชุดสี (Boss 2026-10-03 13:02): ชื่อไฟล์ต้องต่างจากตัวหนังสือ/พื้นจนชัด — เป้า contrast ≥ 7
   ตัวที่ได้ ≥ 7 อยู่แล้วไม่แตะ · ของเรา = เข้มพื้นชิปขึ้น (ชื่อไฟล์ยังฟ้าอ่อน #BFE6FF) · ของคนอื่น = สีชื่อไฟล์รายชุดสี
   ค่าคำนวณจาก --blue/--blue-dark ของแต่ละ data-accent (สูตร WCAG) — เพิ่มชุดสีใหม่ต้องคำนวณเพิ่ม */
html[data-accent="emerald"]:not([data-theme="dark"]) .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.33); }
html[data-accent="emerald"]:not([data-theme="dark"]) .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #0F554D; }
html[data-accent="emerald"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.59); }
html[data-accent="emerald"][data-theme="dark"] .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #6FD6C8; }
html[data-accent="violet"]:not([data-theme="dark"]) .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #571FAE; }
html[data-accent="violet"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.56); }
html[data-accent="violet"][data-theme="dark"] .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #C4B0FC; }
html[data-accent="slate"]:not([data-theme="dark"]) .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #1E40AF; }   /* โทนเทาเดียวกับตัวหนังสือ (ΔE 10.8) → ใช้น้ำเงินแทน */
html[data-accent="slate"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.58); }
html[data-accent="slate"][data-theme="dark"] .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #93C5FD; }
html[data-accent="terracotta"]:not([data-theme="dark"]) .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.37); }
html[data-accent="terracotta"]:not([data-theme="dark"]) .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #793714; }
html[data-accent="terracotta"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.58); }
html[data-accent="terracotta"][data-theme="dark"] .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #F2AF85; }
html[data-accent="magenta"]:not([data-theme="dark"]) .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #81154E; }
html[data-accent="magenta"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.57); }
html[data-accent="magenta"][data-theme="dark"] .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #F5A0C6; }
html[data-accent="teal"]:not([data-theme="dark"]) .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.34); }
html[data-accent="teal"]:not([data-theme="dark"]) .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #0A5165; }
html[data-accent="teal"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.59); }
html[data-accent="teal"][data-theme="dark"] .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #77CDE3; }
html[data-accent="maroon"]:not([data-theme="dark"]) .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #7C1624; }
html[data-accent="maroon"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.54); }
html[data-accent="maroon"][data-theme="dark"] .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #F19EA7; }
html[data-accent="indigo"]:not([data-theme="dark"]) .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #362BA5; }
html[data-accent="indigo"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.55); }
html[data-accent="indigo"][data-theme="dark"] .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #ABAFFB; }
html[data-accent="forest"]:not([data-theme="dark"]) .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.26); }
html[data-accent="forest"]:not([data-theme="dark"]) .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #245328; }
html[data-accent="forest"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.61); }
html[data-accent="amberg"]:not([data-theme="dark"]) .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.35); }
html[data-accent="amberg"]:not([data-theme="dark"]) .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #684407; }
html[data-accent="amberg"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.62); }
html[data-accent="navy"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.57); }
html[data-accent="navy"][data-theme="dark"] .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #A3BEF0; }
html[data-accent="rose"]:not([data-theme="dark"]) .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.30); }
html[data-accent="rose"]:not([data-theme="dark"]) .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #901A44; }
html[data-accent="rose"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.59); }
html[data-accent="rose"][data-theme="dark"] .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #F8AAC2; }
html[data-accent="plum"][data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.56); }
html[data-accent="plum"][data-theme="dark"] .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #DBABDB; }
html:not([data-accent])[data-theme="dark"] .dmw-msg.me .dmw-bub.file .dmw-file { background: rgba(0, 0, 0, 0.53); }
html:not([data-accent])[data-theme="dark"] .dmw-msg:not(.me) .dmw-bub.file .dmw-file { color: #7FBAEC; }
.dmw-img { max-width: 100%; max-height: 240px; border-radius: 10px; display: block; cursor: pointer; }
.dmw-sticker { width: 90px; height: 90px; object-fit: contain; display: block; }
.dmw-album { display: grid; grid-template-columns: 1fr 1fr; gap: 3px; position: relative; }
.dmw-album img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 7px; cursor: pointer; }
.dmw-more {
  position: absolute; right: 4px; bottom: 4px; background: rgba(0,0,0,.65); color: #fff;
  font-size: 11px; padding: 1px 7px; border-radius: 9px;
}
/* caption อยู่เหนือสื่อ → เว้นระยะด้านล่างแทนด้านบน (Boss สั่ง 2026-08-28) */
.dmw-cap { display: block; font-size: 12.5px; margin-bottom: 4px; color: var(--text); }
.dmw-msg.me .dmw-bub.media .dmw-cap { color: var(--text); }
/* ปุ่ม "ดูเพิ่ม" ในรายชื่อสมาชิก */
.user-more {
  text-align: center; font-size: 12.5px; color: var(--blue); cursor: pointer;
  padding: 7px; font-weight: 600;
}
.user-more:hover { text-decoration: underline; }

/* กล่องรายชื่อ DM = หน้าต่างลอยออกข้างขวาของปุ่ม (Boss สั่ง 2026-08-21)
   ไม่ดันเนื้อหาในแถบข้างลงแล้ว · แถบข้างต้อง position:relative ให้ absolute อ้างอิงถูก */
.dm-wrap { position: relative; }
.dm-list-top {
  position: absolute; left: calc(100% + 8px); top: 50%; transform: translateY(-50%); z-index: 260;
  width: 288px; max-height: 62vh; overflow-y: auto;
  background: var(--card, #fff); border: 1px solid var(--border, #E2E8F0);
  border-radius: 12px; box-shadow: 0 10px 34px rgba(0, 0, 0, .32);
  padding: 8px;
}
.dm-search-wrap { padding: 2px 0 6px; }
.dm-search {
  width: 100%; margin: 0; padding: 7px 11px; border-radius: 8px; font-size: 13px;
  border: 1px solid var(--border, #E2E8F0);
  background: var(--side-input, rgba(127,127,127,.12)); color: var(--side-text, var(--text, #1B2A3A));
}
.dm-search:focus { border-color: var(--blue, #0F4C81); outline: none; }
.dm-search::placeholder { color: var(--side-muted, var(--muted, #64748B)); }
.dm-new {
  font-size: 10px; font-weight: 700; color: var(--blue, #0F4C81);
  background: var(--blue-light, #E6EEF7); border-radius: 8px; padding: 1px 6px;
}

@media (max-width: 860px) {
  /* มือถือ: ไม่มีที่ลอยข้าง → กลับมาเป็นกล่องใต้ปุ่มเต็มความกว้าง */
  .dm-list-top {
    position: static; width: auto; max-height: 42vh; box-shadow: none;
    border: none; border-radius: 0; padding: 0; background: transparent;
  }
}

/* ============================================================
   การ์ดแจ้งเตือนข้อความใหม่ แบบเฟสบุ๊ก (Boss สั่ง 2026-08-21)
   ============================================================ */
.notif-wrap {
  position: fixed; right: 14px; bottom: 14px; z-index: 400;
  display: flex; flex-direction: column-reverse; gap: 8px; pointer-events: none;
}
.ntf {
  pointer-events: auto; cursor: pointer; width: 320px; max-width: 88vw;
  display: flex; align-items: flex-start; gap: 10px; padding: 11px 12px;
  background: var(--card, #fff); border: 1px solid var(--border, #E2E8F0);
  border-radius: 12px; box-shadow: 0 8px 28px rgba(0, 0, 0, .3);
  /* เด้งเข้าจากขวา */
  opacity: 0; transform: translateX(20px); transition: opacity .2s, transform .2s;
}
.ntf.in { opacity: 1; transform: translateX(0); }
.ntf:hover { border-color: var(--blue, #0F4C81); }
.ntf-av { flex: 0 0 auto; display: flex; }
.ntf-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ntf-top { font-size: 13.5px; color: var(--text, #1B2A3A); display: flex; gap: 6px; align-items: baseline; flex-wrap: wrap; }
.ntf-room { font-size: 11.5px; color: var(--muted, #64748B); }
.ntf-body {
  font-size: 12.8px; color: var(--muted, #64748B); line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ntf-x {
  border: none; background: none; color: var(--muted, #64748B); cursor: pointer;
  font-size: 12px; padding: 2px 3px; line-height: 1; flex: 0 0 auto;
}
.ntf-x:hover { color: var(--text, #1B2A3A); }
@media (max-width: 860px) {
  /* มือถือ: เด้งบนสุด ไม่ทับหน้าต่างแชท/แถบล่าง
     ⚠️⚠️ ต้องบวก safe-area-inset-top (Boss แจ้งบัค 2026-09-04)
        iPhone ที่มีรอยบาก/Dynamic Island: top:8px เฉยๆ = การ์ดมุดใต้แถบสถานะ อ่านไม่ได้
        โปรเจกต์ใช้ env(safe-area-inset-top) ที่อื่นอยู่แล้ว (ดู .x10-back บรรทัด ~893) */
  .notif-wrap {
    right: 8px; left: 8px; top: calc(8px + env(safe-area-inset-top));
    bottom: auto; flex-direction: column;
  }
  .ntf { width: auto; max-width: none; }
  /* ⚠️ การ์ดกางเต็มกว้างแล้ว เด้งเข้าจากขวา = เห็นกระตุกด้านข้าง → เปลี่ยนเป็นเลื่อนลงจากบน */
  .ntf { transform: translateY(-12px); }
  .ntf.in { transform: translateY(0); }
  /* ⚠️⚠️ ปุ่มปิดเดิม padding 2px/3px = พื้นที่กดราว 18x15px กดไม่ติดบนมือถือ
        กดพลาดแล้วการ์ดพาเข้าห้องแทน · โปรเจกต์กำหนดขั้นต่ำ 44px (mobile.css:248)
     ⚠️⚠️ ต้องเจาะจง `.notif-wrap .ntf-x` — คลาส `.ntf-x` **ใช้ร่วมกัน 2 คอมโพเนนต์**
        (การ์ดป๊อปอัพนี้ + แถวในหน้ารายการแจ้งเตือน `.ntf-row` บรรทัด ~3416)
        และมีกฎทับอยู่ท้ายไฟล์: บรรทัด ~2952 (38px) กับ ~6222 (40px) ซึ่งมาหลัง = ชนะ
        ถ้าเขียน `.ntf-x` เฉยๆ จะถูกทับเหลือ 40px (ทดสอบยืนยันแล้ว) และถ้าไปแก้ 6222
        จะกระทบหน้ารายการแจ้งเตือนด้วย → เจาะจงเฉพาะในการ์ดจึงปลอดภัยที่สุด */
  .notif-wrap .ntf-x {
    min-width: 44px; min-height: 44px; font-size: 16px;
    display: flex; align-items: center; justify-content: center;
    margin: -8px -6px -8px 0;   /* ขยายพื้นที่กดแต่ไม่ดันการ์ดให้สูงขึ้น */
  }
}

/* ============================================================
   เมนูเดียว: แถบ + กล่องสี่เหลี่ยม + รายชื่อ DM (Boss สั่ง 2026-08-21)
   ============================================================ */
.mn-wrap { position: relative; padding: 0 0 4px; }
.mn-bar {
  display: flex; align-items: center; gap: 10px; width: 100%; cursor: pointer;
  background: rgba(255,255,255,.10);
  border: 1px solid rgba(255,255,255,.20);
  border-radius: 10px; padding: 11px 13px; font-family: inherit;
  font-size: 14px; font-weight: 700; color: #fff;
}
.mn-bar:hover { border-color: #7FBAEC; }
.mn-bar-ic { font-size: 15px; opacity: .9; }
.mn-bar-tx { flex: 1; text-align: left; }
.mn-bar-badge {
  background: var(--red, #DC2626); color: #fff; font-size: 11px; font-weight: 700;
  min-width: 20px; height: 20px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center; padding: 0 6px;
}
.mn-bar-arrow { font-size: 10px; opacity: .65; }

.mn-panel {
  margin-top: 6px; padding: 10px;
  background: rgba(0,0,0,.16);
  border: 1px solid rgba(255,255,255,.16); border-radius: 12px;
  max-height: 66vh; overflow-y: auto;
}
/* กล่องสี่เหลี่ยม 3 คอลัมน์ */
.mn-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.mn-tile {
  position: relative; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 7px; padding: 16px 6px; cursor: pointer;
  background: rgba(255,255,255,.07);
  border: 1px solid rgba(255,255,255,.22);
  border-radius: 10px; font-family: inherit;
  color: #fff;
}
.mn-tile:hover { border-color: #7FBAEC; background: rgba(255,255,255,.13); }
/* ไทล์ที่เป็นลิงก์จริง (ติดตั้งแอป) — <a> ไม่ได้ขนาด/ตัวอักษรเท่า <button> เอง */
a.mn-tile { text-decoration: none; box-sizing: border-box; }
.mn-tile.active { border-color: #7FBAEC; background: rgba(127,186,236,.22); }
.mn-tile-ic { font-size: 19px; opacity: .92; }
.mn-tile-tx { font-size: 12px; text-align: center; line-height: 1.3; }
.mn-tile-badge {
  position: absolute; top: 6px; right: 6px; background: var(--red, #DC2626); color: #fff;
  font-size: 10.5px; font-weight: 700; min-width: 18px; height: 18px; border-radius: 9px;
  display: flex; align-items: center; justify-content: center; padding: 0 5px;
}
.mn-tile-dot {
  position: absolute; top: 8px; right: 8px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--amber, #FBBF24);
}
.mn-div { height: 1px; background: rgba(255,255,255,.18); margin: 12px 2px 10px; }
.mn-dm-head {
  font-size: 11.5px; font-weight: 700; letter-spacing: .03em;
  color: rgba(255,255,255,.6); margin-bottom: 6px;
}
.mn-newdm {
  display: flex; align-items: center; gap: 7px; width: 100%; margin-top: 6px;
  background: none; border: none; cursor: pointer; font-family: inherit;
  font-size: 13px; font-weight: 600; color: #7FBAEC; padding: 8px 4px;
}
.mn-newdm:hover { text-decoration: underline; }
/* รายชื่อ DM ในเมนู (ทับสไตล์ flyout เดิม) */
.mn-panel #dm-rows .chan-item { border-radius: 8px; }
@media (max-width: 860px) {
  .mn-tiles { grid-template-columns: repeat(2, 1fr); }
  .mn-panel { max-height: 56vh; }
}

/* รายชื่อ DM ในเมนู — บังคับสีให้อ่านออกบนพื้นแถบข้าง (โหมดสว่างไม่มีค่า var) */
.mn-panel #dm-rows .chan-item { color: #fff; }
.mn-panel #dm-rows .chan-item:hover { background: rgba(255,255,255,.10); }
.mn-panel .dm-search {
  background: rgba(255,255,255,.10); border-color: rgba(255,255,255,.22); color: #fff;
}
.mn-panel .dm-search::placeholder { color: rgba(255,255,255,.55); }
.mn-panel .chan-item.muted { color: rgba(255,255,255,.5); }

/* ============================================================
   มือถือ: รองรับ iOS + Android ทุกรุ่น (Boss สั่ง 2026-08-21)
   ตรวจจริงด้วย WebKit (iOS) + Chromium (Android) 7 รุ่น: 320/360/375/390/412/430/768
   แก้ 2 เรื่องที่วัดได้จริง — ไม่แตะเลย์เอาต์เดสก์ท็อป
   ============================================================ */
@media (max-width: 860px) {
  /* ---- 1) iOS ซูมหน้าจอเองเวลาแตะช่องกรอกที่ font-size < 16px ----
     Safari ซูมเข้าแล้วไม่ซูมกลับ ผู้ใช้ต้องซูมออกเองทุกครั้ง
     16px คือเกณฑ์ตายตัวของ WebKit (บังคับทุกช่อง ไม่เว้น) */
  input, textarea, select,
  .pf-field input, .pf-field select,
  #msg-input, #channel-search, .ir-input, .cu-f input, .cu-f select {
    font-size: 16px !important;
  }
  /* ช่องพิมพ์แชทสูงขึ้นเล็กน้อยให้สมดุลกับตัวอักษรที่โตขึ้น */
  .composer textarea { line-height: 1.4; }

  /* ---- 2) เป้ากดต้องใหญ่พอ — Apple HIG 44px · Android 48dp ----
     ของเดิมแถวปุ่มใต้ข้อความสูงแค่ 20px นิ้วโป้งกดพลาดง่าย
     ขยายด้วย padding (พื้นที่กดโต) แต่คุมตัวอักษรไม่ให้เทอะทะ */
  .msg-foot { gap: 4px; flex-wrap: wrap; }
  .msg-foot-btn {
    min-height: 40px; display: inline-flex; align-items: center;
    padding: 0 10px; font-size: 13px;
  }
  .msg.nested .msg-foot-btn { font-size: 12.5px; padding: 0 8px; }
  /* ปุ่ม ⋯ เดิม 13x18px เล็กเกินจะกดติด */
  .msg-actions .msg-dots { min-width: 40px; min-height: 40px; font-size: 18px; }
  /* แถบแท็บในหน้าผู้ดูแลระบบ/อื่นๆ — เดิมสูง 33px */
  .tab { min-height: 42px; display: inline-flex; align-items: center; }
  /* หัวข้อกลุ่มห้องในแถบข้าง กดพับ/กาง */
  .chan-sec { min-height: 42px; display: flex; align-items: center; }
  /* วงสีในหน้าโปรไฟล์ (เดิม 34px) — .pf-accent เป็นตัวเลือกสีธีมของอีก session */
  .pf-sw, .pf-accent { width: 42px; height: 42px; }
  /* pill ธีม/ภาษา เดิมสูง 31px */
  .pf-pill, .pf-pills .lang-btn { min-height: 40px; display: inline-flex; align-items: center; }
  /* ป้ายล็อกห้อง — ขยายเฉพาะตัวที่กดได้จริง (can-toggle) ตัวที่เป็นป้ายเฉยๆ ปล่อยเล็กไว้ */
  .lock-badge.can-toggle { min-height: 36px; padding: 0 12px; display: inline-flex; align-items: center; }
  /* ชิปอีโมจิสถานะ (เดิม 41x32) */
  .emoji-chip { min-height: 40px; min-width: 40px; }
  /* แถบเรียงคอมเมนต์ */
  .cmt-sort { min-height: 38px; display: inline-flex; align-items: center; }
  /* ปุ่มขยายคอมเมนต์ */
  .cmt-more { min-height: 40px; }
  /* ปุ่มเลือกวัน (dj-btn) + ปุ่มปิดแจ้งเตือน (ntf-x) — ของงานอีก session เดิม 30px/16px */
  .dj-btn { min-height: 40px; display: inline-flex; align-items: center; }
  .ntf-x { min-width: 38px; min-height: 38px; display: inline-flex; align-items: center; justify-content: center; }

  /* ---- 3) กันข้อความยาวๆ ดันจอ (ชื่อไฟล์/ลิงก์ไม่มีช่องว่าง) ---- */
  .msg-text, .msg-bubble, .cpu-sub, .cu-hero-sub { overflow-wrap: anywhere; }
  /* ตาราง/บล็อกโค้ดยังเลื่อนแนวนอนในกล่องตัวเอง ไม่ดันหน้า */
  .msg-text .msg-pre { max-width: 100%; }
}

/* จอเล็กมาก (iPhone SE รุ่น 1 = 320px) — ยังมีคนใช้ ต้องไม่พัง */
@media (max-width: 360px) {
  .msg-foot { gap: 2px; }
  .msg-foot-btn { padding: 0 7px; font-size: 12.5px; }
  .cmt-topline, .cmt-bar { padding-left: 26px; }
  .cmt-group { margin-left: 26px; padding-left: 6px; }
  /* จอ 320px: 7 ปุ่มล่างป้ายชื่อถูกตัดหมด (งาน/N... TaskFl...) — ย่อตัวอักษรลง
     ให้อ่านได้ครบคำ ดีกว่าเห็นจุดสามจุด */
  .bottom-nav .nav-btn span { font-size: 8.5px; letter-spacing: -.02em; padding: 0; }
  .bottom-nav .nav-btn { padding: 6px 0 4px; }
  .pf-hero { gap: 10px; }
  .pf-sw, .pf-accent { width: 38px; height: 38px; }
}

/* ---- iOS เท่านั้น: กันเด้ง/เลื่อนหลุดตอนคีย์บอร์ดขึ้น ---- */
@supports (-webkit-touch-callout: none) {
  /* ความสูงจอ: .app ใช้ 100dvh อยู่แล้ว (บรรทัด 235) ไม่ต้องทับที่ html/body
     ทับแล้วเสี่ยงตีกับ height:100% เดิม */
  /* โมดัลยาวๆ ต้องเลื่อนได้ลื่นด้วยนิ้ว ไม่ใช่ค้าง */
  .modal, .page-body, #messages { -webkit-overflow-scrolling: touch; }
}

/* ---- ย้อนดูแชทตามวัน (Boss สั่ง 2026-08-21) ---- */
.datejump { position: absolute; top: 66px; right: 18px; z-index: 40; }
.dj-btn {
  display: flex; align-items: center; gap: 6px; cursor: pointer; font-family: inherit;
  font-size: 12.5px; font-weight: 600; padding: 6px 13px; border-radius: 999px;
  background: var(--card, #fff); border: 1px solid var(--border, #E2E8F0);
  color: var(--text, #1B2A3A); box-shadow: 0 2px 8px rgba(0,0,0,.14);
}
.dj-btn:hover { border-color: var(--blue, #0F4C81); }
.dj-caret { font-size: 9px; opacity: .6; }
.dj-menu {
  position: absolute; right: 0; top: calc(100% + 6px); min-width: 208px;
  background: var(--card, #fff); border: 1px solid var(--border, #E2E8F0);
  border-radius: 11px; box-shadow: 0 10px 30px rgba(0,0,0,.3); padding: 6px;
}
.dj-head {
  font-size: 11.5px; font-weight: 700; color: var(--muted, #64748B);
  padding: 7px 10px 6px;
}
.dj-menu button {
  display: block; width: 100%; text-align: left; border: none; background: none;
  cursor: pointer; font-family: inherit; font-size: 13.5px; padding: 9px 10px;
  border-radius: 7px; color: var(--text, #1B2A3A);
}
.dj-menu button:hover { background: var(--blue-light, #E6EEF7); }
.dj-menu button.dj-pick { color: var(--blue, #0F4C81); font-weight: 700; }
.dj-div { height: 1px; background: var(--border, #E2E8F0); margin: 5px 4px; }
.dj-date { position: absolute; opacity: 0; pointer-events: none; width: 1px; height: 1px; }
/* มือถือกด "เลือกวันที่เอง" ไม่ขึ้น (Boss 2026-09-24): iOS/WebView ไม่เปิด picker จาก showPicker()
   บน input ที่ pointer-events:none → จอสัมผัสให้ input จริงทับปุ่มเต็มพื้นที่ นิ้วแตะ = เปิด picker ของเครื่องเอง
   font-size 16px กัน iOS ซูมหน้าตอนโฟกัส */
.dj-pickwrap { position: relative; }
@media (hover: none), (pointer: coarse) {
  .dj-pickwrap .dj-date {
    top: 0; left: 0; width: 100%; height: 100%; margin: 0; padding: 0; border: 0;
    pointer-events: auto; z-index: 1; font-size: 16px; -webkit-appearance: none; appearance: none;
  }
}
@media (max-width: 860px) {
  .datejump { top: 58px; right: 10px; }
  .dj-btn { font-size: 11.5px; padding: 5px 10px; }
}

/* ============================================================
   iOS: รอยบาก / Dynamic Island ทับแถบบน (Boss แจ้ง 2026-08-21)
   เดิมใช้ safe-area-inset-bottom 7 จุด แต่ inset-top แค่ 1 จุด (ปุ่มหน้า login)
   → หัวห้อง/หัวเพจ/แถบข้าง ไปอยู่ใต้กล้องหน้า อ่านไม่เห็น กดไม่ได้
   จำกัดที่ WebKit (@supports -webkit-touch-callout) เพราะ Android ไม่มีรอยบากทับ
   ============================================================ */
@supports (-webkit-touch-callout: none) {
  @media (max-width: 860px) {
    /* ปุ่ม "วันนี้" ลอยแบบ absolute ด้วย top คงที่ (66px/58px) ไม่รู้เรื่องรอยบาก
       หัวห้องสูงขึ้นตาม safe-area แล้ว ปุ่มนี้จึงไปทับแถบสถานะ (นาฬิกา/แบต)
       → บวก inset เข้าไปให้เลื่อนลงตามหัวห้อง */
    /* 2026-08-29: มีแถบแท็บมาคั่นแล้ว → ใช้ค่าที่ JS วัดจริง (รวม inset ไว้แล้ว) */
    .datejump { top: var(--rt-dj-top, calc(94px + env(safe-area-inset-top))); }
    /* หัวห้องแชท + หัวเพจ — ดันลงมาพ้นรอยบาก
       max() กันจอที่ไม่มีรอยบาก (inset=0) ไม่ให้ padding หายไปเลย */
    .page-head, .chat-head {
      padding-top: max(var(--s2), env(safe-area-inset-top));
    }
    /* แถบข้าง (รายชื่อห้อง) เปิดจากซ้าย หัวแถบก็ชนรอยบากเหมือนกัน */
    .sidebar-head { padding-top: max(14px, calc(env(safe-area-inset-top) + 6px)); }
    /* หน้าเลขา AI มีหัวข้อของตัวเอง */
    .sec-head { padding-top: max(0px, env(safe-area-inset-top)); }
    /* โมดัลเต็มจอ (มือถือเปิดจากล่าง) — ตัวที่สูงเต็มจอต้องเว้นบนด้วย */
    .modal { margin-top: env(safe-area-inset-top); }
    /* แนวนอน: รอยบากย้ายไปข้าง — เว้นซ้าย/ขวาไม่ให้เนื้อหาหลุดใต้กล้อง */
    .app { padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }
  }
}

/* ============================================================
   iOS safe-area รอบสอง — ให้เหมือนภาพที่ Boss ส่ง (2026-08-21 21:35)
   ต้นเหตุจริง: <meta apple-mobile-web-app-status-bar-style="black-translucent">
   = iOS วาดหน้าเว็บ "ใต้แถบสถานะ" ตั้งแต่ y=0 → ทุกอย่างบนสุดทับนาฬิกา/เกาะ
   รอบแรก (บล็อกด้านบน) เว้นให้แค่ .page-head/.chat-head/.sidebar-head/.sec-head
   ยังเหลือ: หน้า login, ตัวไซด์บาร์เอง (แถบเมนู .mn-wrap), แถบสถานะไม่มีพื้นสี
   ============================================================ */
@supports (-webkit-touch-callout: none) {
  @media (max-width: 860px) {
    /* --- แถบสถานะมีพื้นสีทึบ ---
       standalone + black-translucent = นาฬิกา/แบต ลอยบนเนื้อหาที่เลื่อนผ่าน
       อ่านไม่ออกเวลาข้อความสีเข้มเลื่อนขึ้นมาใต้มัน
       → วางแถบสีพื้นหัวห้อง (--card) ทับพื้นที่ inset ไว้ตายตัว ให้อ่านออกทุกกรณี
       ⚠️ z-index ต้อง "ต่ำกว่าไซด์บาร์ (40)" ไม่ใช่สูงกว่า:
       ฝั่งเนื้อหาใช้ --card (สว่าง) แต่ไซด์บาร์ใช้ --side-bg (เข้ม)
       ถ้าแถบเดียวทับหมด เวลาเปิดไซด์บาร์จะเห็นแถบสว่างคาดบนพื้นเข้ม = เพี้ยน
       → แถบนี้ z-index:30 (ใต้ไซด์บาร์ 40, ใต้ bottom-nav 50) แล้วให้ไซด์บาร์
         ทาสีพื้นที่ inset ของตัวเองด้วย padding-top (มี background เต็มตัวอยู่แล้ว) */
    body::before {
      content: ''; position: fixed; top: 0; left: 0; right: 0;
      height: env(safe-area-inset-top);
      background: var(--card); z-index: 30; pointer-events: none;
    }

    /* --- ไซด์บาร์ (รายชื่อห้อง + แถบเมนูเดียวที่เพิ่มวันนี้) ---
       ทำที่ x10-ui.css แล้ว (.x10v3 .sidebar) — ที่นี่แค่ถอน
       padding-top ที่รอบแรกใส่ไว้ที่ .sidebar-head ไม่ให้เว้นซ้ำสองชั้น */
    .sidebar-head { padding-top: 14px; }

    /* --- หน้า login: ทำที่ x10-ui.css แล้ว (.x10v3 .login-screen) --- */

    /* --- ปุ่ม "วันนี้" ลอยในห้องแชท ---
       รอบแรกใช้ฐาน 58px (ค่าใน @media มือถือ) ถูกแล้ว — คงไว้ ไม่แก้ซ้ำ */
  }
}

/* ===== wizard ลงทะเบียนเลขา AI (2026-08-22) ===== */
/* ใช้ตัวแปรของแอปเท่านั้น (--blue สลับตาม data-accent) ห้ามฮาร์ดโค้ดสี */
.sec-wiz { padding: var(--s3); max-width: 620px; margin: 0 auto; }
.sec-wiz-card { padding: var(--s5) var(--s4) var(--s4); }
.sec-wiz-head h3 { margin: 0 0 2px; }
.sec-wiz-steps { display: flex; align-items: center; justify-content: center; gap: 6px; margin: var(--s4) 0 var(--s1); }
.sec-wiz-dot { width: 30px; height: 30px; border-radius: var(--radius-pill); display: grid; place-items: center;
  border: 1.5px solid var(--border, #E2E8F0); color: var(--muted, #64748B); font-size: var(--fs-sm); font-weight: 600; background: var(--card, #FFFFFF); }
.sec-wiz-dot.on { border-color: var(--blue, #0F4C81); color: var(--on-brand, #FFFFFF); background: var(--blue, #0F4C81); }
.sec-wiz-dot.done { border-color: var(--blue, #0F4C81); color: var(--blue, #0F4C81); }
.sec-wiz-line { flex: 0 0 34px; height: 1.5px; background: var(--border, #E2E8F0); }
.sec-wiz-lbls { display: flex; justify-content: center; gap: 28px; font-size: var(--fs-xs); color: var(--muted, #64748B); margin-bottom: var(--s4); }
.sec-wiz-body { min-height: 210px; }
.sec-wiz-av { width: 92px; height: 92px; margin: 6px auto var(--s3); border-radius: var(--radius-pill);
  display: grid; place-items: center; color: var(--blue, #0F4C81);
  background: var(--blue-light, #EAF1F8); border: 1.5px solid var(--blue, #0F4C81); }
.sec-wiz-av svg { width: 46px; height: 46px; }
.sec-wiz-avpick { display: flex; gap: var(--s2); justify-content: center; flex-wrap: wrap; margin-bottom: var(--s4); }
.sec-wiz-avb { width: 44px; height: 44px; border-radius: var(--radius-pill); display: grid; place-items: center;
  border: 1.5px solid var(--border, #E2E8F0); background: var(--card, #FFFFFF); color: var(--muted, #64748B); cursor: pointer;
  transition: var(--transition); padding: 0; }
.sec-wiz-avb svg { width: 22px; height: 22px; }
.sec-wiz-avb:hover { border-color: var(--blue, #0F4C81); }
.sec-wiz-avb.active { border-color: var(--blue, #0F4C81); color: var(--blue, #0F4C81); background: var(--blue-light, #EAF1F8); }
.sec-wiz-namerow { display: flex; gap: var(--s2); }
.sec-wiz-namerow input { flex: 1; min-width: 0; }
.sec-wiz-roles { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.sec-wiz-role { display: flex; flex-direction: column; gap: 3px; padding: var(--s3) 11px; text-align: left;
  border: 1.5px solid var(--border, #E2E8F0); border-radius: var(--radius); background: var(--card, #FFFFFF);
  cursor: pointer; color: var(--text, #1E293B); transition: var(--transition); }
.sec-wiz-role:hover { border-color: var(--blue, #0F4C81); }
.sec-wiz-role.active { border-color: var(--blue, #0F4C81); background: var(--blue-light, #EAF1F8); }
.sec-wiz-remo { font-size: 19px; line-height: 1.2; }
.sec-wiz-rlb { font-weight: 600; font-size: var(--fs-md); }
.sec-wiz-rtn { font-size: var(--fs-xs); color: var(--muted, #64748B); }
.sec-wiz-skills { display: flex; flex-direction: column; gap: 0; }
.sec-wiz-skill { display: flex; align-items: center; gap: var(--s3); padding: 11px 2px; border-bottom: 1px solid var(--border, #E2E8F0); }
.sec-wiz-skill:last-child { border-bottom: none; }
.sec-wiz-skmain { flex: 1; min-width: 0; }
.sec-wiz-sklb { font-weight: 600; font-size: var(--fs-md); }
.sec-wiz-skd { font-size: var(--fs-xs); color: var(--muted, #64748B); line-height: 1.45; }
.sec-wiz-gate { font-size: 10px; padding: 1px 6px; border-radius: var(--radius-pill); vertical-align: middle;
  border: 1px solid var(--amber, #B45309); color: var(--amber, #B45309); font-weight: 500; white-space: nowrap; }
.sec-wiz-sum { display: flex; align-items: center; gap: 13px; margin-top: var(--s4); padding: 13px;
  border-radius: var(--radius); background: var(--sunken, #F4F6F9); border: 1px solid var(--border, #E2E8F0); }
.sec-wiz-sumav { width: 46px; height: 46px; flex: 0 0 46px; border-radius: var(--radius-pill); display: grid;
  place-items: center; color: var(--blue, #0F4C81); border: 1.5px solid var(--blue, #0F4C81); }
.sec-wiz-sumav svg { width: 24px; height: 24px; }
.sec-wiz-sumn { font-weight: 700; font-size: var(--fs-base); }
.sec-wiz-nav { display: flex; justify-content: space-between; align-items: center; margin-top: var(--s4);
  padding-top: var(--s3); border-top: 1px solid var(--border, #E2E8F0); }
@media (max-width: 430px) {
  .sec-wiz { padding: var(--s2); }
  .sec-wiz-roles { grid-template-columns: 1fr; }
  .sec-wiz-lbls { gap: var(--s3); font-size: 10.5px; }
  .sec-wiz-av { width: 76px; height: 76px; }
  .sec-wiz-av svg { width: 38px; height: 38px; }
}

/* ===== โทเค็นที่เลขาใช้ รายคน — ผู้ดูแล (2026-08-22) ===== */
.tok-sum { display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap;
  padding: var(--s3) 0 var(--s4); border-bottom: 1px solid var(--border, #E2E8F0); margin-bottom: var(--s3); }
.tok-kpi { display: flex; flex-direction: column; gap: 1px; }
.tok-kpi-n { font-size: var(--fs-xl); font-weight: 700; color: var(--blue, #0F4C81);
  font-variant-numeric: tabular-nums; line-height: 1.15; }
.tok-engs { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.tbl-wrap { overflow-x: auto; }
.tok-tbl { width: 100%; min-width: 660px; }
.tok-tbl th.num, .tok-tbl td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tok-barcell { min-width: 118px; white-space: nowrap; }
.tok-bar { display: inline-block; width: 74px; height: 6px; border-radius: 999px;
  background: var(--sunken, #F4F6F9); overflow: hidden; vertical-align: middle; margin-right: 6px; }
.tok-bar > span { display: block; height: 100%; background: var(--blue, #0F4C81); border-radius: 999px; }
.tok-note { margin-top: var(--s3); padding-top: var(--s2); border-top: 1px solid var(--border, #E2E8F0); }
@media (max-width: 430px) {
  .tok-sum { gap: var(--s3); }
  .tok-engs { margin-left: 0; width: 100%; }
}

/* ---- #sec-main: ตัวครอบที่แทรกเพิ่มตอนทำ wizard ต้องส่งความสูงต่อ ----
   ⚠️ .sec-wrap เป็น flex column height:100% และ .sec-sect เป็น flex:1
      ถ้า #sec-main ไม่ส่งความสูงต่อ กล่องแชท (.sec-chat flex:1) จะยุบเหลือ ~120px */
/* ---- ปุ่มเลือกภาษา: เดิม 12.5px แตะยากบนมือถือ → ขยายให้กดง่าย (2026-08-22) ----
   บรรทัด ~1126 ทับ font-size เป็น --fs-sm ไว้ ต้องประกาศทีหลังจึงชนะ */
.lang-row { gap: 6px; flex-wrap: nowrap; }
.lang-btn {
  font-size: var(--fs-md, 14px); padding: 9px 11px; min-height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1.2; white-space: nowrap;
}
/* ปุ่มภาษาในโปรไฟล์ (.pf-pills) มีสไตล์ของตัวเอง ไม่แตะ */
.pf-pills .lang-btn { font-size: var(--fs-sm, 12.5px); padding: 6px 16px; }

#sec-main { flex: 1; min-height: 0; display: flex; flex-direction: column; }
#sec-main.hidden { display: none; }

/* ---- รูปเลขา: อัปโหลดรูปจริงได้ (2026-08-22) ---- */
.sec-wiz-av.has-img, .sec-wiz-sumav.has-img { background: none; overflow: hidden; padding: 0; }
.sec-wiz-av img, .sec-wiz-sumav img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sec-wiz-avup { display: flex; gap: var(--s2); justify-content: center; flex-wrap: wrap; margin-bottom: var(--s2); }
.sec-wiz-or { text-align: center; margin: 0 0 var(--s2); }

/* ---- ปุ่มเปิดชุดอีโมจิใน footer ข้อความ (2026-08-22) ----
   เดิมปุ่ม + อยู่ใน .react-row ซึ่งโผล่เฉพาะข้อความที่ "มีรีแอ็กแล้ว"
   → ข้อความใหม่จึงกดอีโมจิอื่นนอกจาก 👍 ไม่ได้เลย · ปุ่มนี้อยู่ตลอด */
.msg-foot-btn.react-open { display: inline-flex; align-items: center; gap: 4px; }
.msg-foot-btn.react-open:hover { text-decoration: none; color: var(--blue, #0F4C81); }
/* จอแคบ: เหลือแต่หน้ายิ้ม ไม่กินที่ */
@media (max-width: 480px) {
  .msg-foot-btn.react-open .react-open-lb { display: none; }
}
/* แถบเลือกอีโมจิ ต้องลอยเหนือทุกอย่างและไม่ถูก overflow ตัด
   ⚠️⚠️ Boss แจ้ง 2026-09-02 "สติกเกอร์กดไม่ได้เหมือนเดิม" (ในแผงตอบกลับ)
     ต้นเหตุ: บรรทัดนี้ z-index:30 มาทับค่า 320 ที่ตั้งไว้ข้างบน (บรรทัด ~1823)
     — ค่า 30 เป็นของเก่าสมัยแผงยังเป็น position:absolute เกาะอยู่ในข้อความ
     พอแผงเธรด `.thrpanel` เป็น z-index:79 → แผงอีโมจิ (30) ไปอยู่ "ใต้" แผงเธรด
     วัดได้จริง: elementFromPoint กลางแผง คืน .thr-body = คลิกไม่โดนปุ่มเลย
     ต้องสูงกว่า .thrpanel(79) และ .dm-win(300) → ใช้ 320 ตามที่ตั้งใจไว้แต่แรก */
.react-pick { z-index: 320; }

/* ===== ลากวางแถบเมนูห้อง + ห้องที่ใช้บ่อย (2026-08-23) ===== */
.chan-item[draggable="true"] { cursor: grab; }
.chan-item.dragging, .chan-sec.dragging { opacity: .45; }
.chan-drop.drop-on { outline: 2px dashed var(--amber, #F0B429); outline-offset: -2px; border-radius: 6px; }
.chan-item.drop-before { box-shadow: inset 0 2px 0 0 var(--amber, #F0B429); }
.chan-body { min-height: 6px; }
.chan-fav { opacity: .35; font-size: 13px; padding: 0 2px; cursor: pointer; flex-shrink: 0; }
.chan-fav:hover { opacity: 1; }
.chan-fav.on { opacity: 1; color: var(--amber, #F0B429); }
.chan-item.active .chan-fav { opacity: .7; }
.chan-item.active .chan-fav.on { opacity: 1; }
.chan-drop-hint { margin: 2px 10px 6px; padding: 8px 10px; font-size: 11px; opacity: .45;
  border: 1px dashed currentColor; border-radius: 6px; text-align: center; }

/* ===== แนบรูป/ไฟล์ในหน้าต่าง DM ลอย (2026-08-23) ===== */
.dmw-foot { align-items: center; }
/* เมนู ☰ ของหน้าต่าง DM ลอย (พี่ปอง 2026-09-17 "เพิ่ม 3 ขีดเพื่อซ่อนปุ่ม")
   ⚠️ .dmw-body ข้างบนเป็น overflow-y:auto — วางเมนูใน flow ปกติจะโดนตัด
      ต้อง absolute เกาะ .dmw-more-wrap แล้วกางขึ้น (bottom:100%) เพราะอยู่ท้ายกล่อง
   ⚠️ ชิดซ้าย (left:0) กันล้นขอบขวา กล่องกว้างแค่ 340px */
.dmw-more-wrap { position: relative; flex: 0 0 auto; display: flex; align-items: center; }
.dmw-pop { position: absolute; bottom: 100%; left: 0; z-index: 60; min-width: 168px; margin-bottom: 6px; }
/* แผงอีโมจิของกล่องนี้เอง — กางขึ้นเหนือปุ่ม ไม่ใช่ลงล่างซึ่งจะตกนอกจอ
   ⚠️ ต้องเขียนหน้าตาเอง (พื้น/กรอบ/ขนาด) เหมือน .thr-emoji-pop ของเธรด
      `.emoji-pop` ไม่มีกฎฐาน — ตัว #emoji-pop เดิมได้ตำแหน่งจาก CSS ของ
      composer ห้องหลัก ใส่แค่ position จะกางเป็นแถบยาวโปร่งทับตัวข้อความ
   ⚠️ กว้างคงที่ 248px: กล่องกว้าง 340px ถ้า left+right จะเบียดจนกริดเหลือ 3 คอลัมน์ */
.dmw-emoji-pop {
  position: absolute; bottom: 100%; left: 0; margin-bottom: 6px;
  width: 248px; max-width: calc(100vw - 32px); z-index: 62;
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 -6px 24px rgba(0,0,0,.18);
  padding: 8px; display: flex; flex-direction: column; gap: 7px;
}
.dmw-emoji-pop.hidden { display: none; }
/* กริดต้องเลื่อนได้ ไม่งั้นแผงยืดสูงเกินกล่อง */
.dmw-emoji-pop .emoji-grid { max-height: 190px; overflow-y: auto; }
/* แท็บ สติกเกอร์ | อิโมจิ ในแผงเดียวกัน (พี่ปอง: "มันอันเดียวกัน") */
.dmw-stk-tabs { display: flex; gap: 4px; }
.dst-tab { flex: 1; border: 1px solid var(--border); background: transparent; color: var(--text);
  font: inherit; font-size: 12.5px; padding: 5px 8px; border-radius: 8px; cursor: pointer; opacity: .65; }
.dst-tab.on { background: var(--blue-light, #E3EDF7); border-color: var(--blue, #0F4C81); opacity: 1; font-weight: 700; }
.dmw-stk-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px;
  max-height: 212px; overflow-y: auto; }
.dmw-stk-grid.hidden, .dmw-emo-wrap.hidden { display: none; }
.dmw-emo-wrap { display: flex; flex-direction: column; gap: 7px; }
/* หัวชื่อชุดกินเต็มแถว ไม่งั้นแทรกกลางกริดแล้วสติกเกอร์เลื่อนตำแหน่ง */
.dst-pack { grid-column: 1 / -1; font-size: 11px; color: var(--muted, #64748b); padding: 2px 0 0; }
.dst-cell { border: 1px solid transparent; background: transparent; padding: 2px; cursor: pointer;
  border-radius: 8px; aspect-ratio: 1; display: flex; align-items: center; justify-content: center; }
.dst-cell:hover { background: var(--hover, rgba(0,0,0,.06)); }
.dst-cell img { width: 100%; height: 100%; object-fit: contain; display: block; }
.dmw-att { border: none; background: none; cursor: pointer; font-size: 15px; padding: 0 2px;
  opacity: .6; flex-shrink: 0; line-height: 1; }
.dmw-att:hover { opacity: 1; }
.dmw-queue { display: none; gap: 6px; flex-wrap: wrap; padding: 6px 8px 0; }
.dmw-queue.on { display: flex; }
.dmq-it { position: relative; width: 46px; height: 46px; border-radius: 6px; overflow: hidden;
  border: 1px solid var(--border, #E2E8F0); background: var(--bg, #F1F5F9); flex-shrink: 0; }
.dmq-it img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dmq-doc { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; font-size: 20px; }
.dmq-x { position: absolute; top: 0; right: 0; border: none; cursor: pointer; line-height: 1;
  background: rgba(0,0,0,.6); color: #fff; font-size: 10px; padding: 2px 4px; border-radius: 0 0 0 5px; }
.dmw.dz { outline: 2px dashed var(--blue, #0F4C81); outline-offset: -3px; }
.dmw.dz .dmw-body { opacity: .6; }

/* ===== แท็บ KPI ในหน้าเลขา (2026-08-23) ===== */
.sec-kpi-list { display: flex; flex-direction: column; gap: 8px; padding: 10px; overflow-y: auto; }
.sec-kpi-empty { padding: 24px 12px; text-align: center; opacity: .6; font-size: 13px; }
.sec-kpi-card { border: 1px solid var(--border, #E2E8F0); border-radius: 10px; background: var(--card, #fff); overflow: hidden; }
.sec-kpi-head { display: flex; align-items: center; gap: 8px; padding: 10px 12px; cursor: pointer;
  font-weight: 600; font-size: 13.5px; background: var(--sunken, #F8FAFC); }
/* --- แท็บ KPI อ่านง่ายขึ้น (Boss 2026-08-28 "ดูไม่รู้เรื่องเลย") --- */
/* เดิม 35 ใบเป็นแถบเปล่าเหมือนกันหมด วันที่ซ้ำ 6 รอบ → จัดกลุ่มวัน + ชิปกรอง + คำโปรย */
/* ===== แท็บ KPI แบบเรียบง่าย (Boss 2026-08-28 รอบ3 "ขอแบบดูง่ายๆ มันเละ") =====
   รอบก่อนโชว์ 35 ใบพร้อมกัน = ~150 แถวรวด → รอบนี้ทีละวัน + 3 ตัวเลขเด่นต่อใบ */
/* แถบวันที่ — แถวเดียวเตี้ยๆ (Boss 2026-08-28: "บนสุดใหญ่ไป") เดิมซ้อน 3 บรรทัดสูง ~72px */
.kpi-nav {
  display: flex; align-items: center; gap: 8px; margin-bottom: 10px;
  padding: 5px 8px; border-radius: 10px;
  background: var(--sunken); border: 1px solid var(--border, #E2E8F0);
  position: sticky; top: 0; z-index: 2;
  flex: 0 0 auto;        /* บั๊กเดียวกับ .kpi-card — flex item ในคอลัมน์ถูกบีบจนตัวหนังสือโดนตัด */
}
/* วันที่อยู่บรรทัดเดียวกับตัวเลข ไม่ซ้อนกันแล้ว */
.kpi-navmid {
  flex: 1; min-width: 0; display: flex; align-items: baseline;
  justify-content: center; gap: 7px; overflow: hidden;
}
.kpi-navmid b { font-size: 13.5px; white-space: nowrap; }
.kpi-navmid .muted { font-size: 11.5px; white-space: nowrap; }
.kpi-navbtn {
  width: 30px; height: 30px; flex: 0 0 auto; cursor: pointer; font-size: 12px;
  border-radius: 8px; border: 1px solid var(--border, #E2E8F0);
  background: var(--card, #fff); color: var(--text);
  display: inline-flex; align-items: center; justify-content: center; padding: 0;
}
.kpi-navbtn:disabled { opacity: .3; cursor: default; }
/* การ์ดหนึ่งแหล่ง = หัวข้อ + ตัวเลขเด่น 3 ตัว */
.kpi-card {
  border: 1px solid var(--border, #E2E8F0); border-radius: 12px;
  background: var(--card, #fff); margin-bottom: 10px; overflow: hidden;
  /* ⚠️⚠️ Boss 2026-08-28 "ข้อความโดนตัดครึ่ง":
     `.sec-kpi-list` เป็น flex column → การ์ดเป็น flex item ที่ **ถูกบีบ** (flex-shrink:1)
     เมื่อเนื้อรวมสูงกว่ากล่อง · วัดได้ว่าโดนบีบ 38–65px ต่อใบ
     พอมี overflow:hidden = ตัดท้ายการ์ดทิ้ง → ปุ่ม "ดูทั้งหมด" โดนเฉือนครึ่งตัวอักษร
     แก้: ห้ามหด และสูงตามเนื้อจริงเสมอ */
  flex: 0 0 auto;
}
/* หัวการ์ด = ปุ่มพับ (Boss 2026-08-28 "แต่ละตัวของ api สามารถพับได้") */
.kpi-h {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 11px 14px; font-weight: 700; font-size: 14px; text-align: left;
  background: none; border: 0; cursor: pointer; color: var(--text);
}
.kpi-h:active { background: var(--sunken); }
.kpi-card.folded .kpi-h { padding-bottom: 11px; }
.kpi-caret { margin-left: auto; opacity: .5; font-size: 12px; flex: 0 0 auto; }
/* พับแล้วยังเห็นตัวเลขเด่นตัวแรก — กวาดตาหาใบที่สนใจได้โดยไม่ต้องกางทุกใบ */
.kpi-mini { font-weight: 600; font-size: 12.5px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 45%; }
.kpi-foldall {
  background: none; border: 0; cursor: pointer; padding: 4px 6px; flex: 0 0 auto;
  font-size: 11.5px; color: var(--blue, #0F4C81); font-weight: 600; white-space: nowrap;
}
.kpi-rows { padding: 0 14px 4px; }
/* แต่ละตัวเลข = 1 บรรทัด ชื่อซ้าย ค่าขวา — กวาดตาลงมาอ่านได้เร็ว */
.kpi-row {
  display: flex; align-items: baseline; gap: 8px;
  padding: 7px 0; border-top: 1px solid var(--border, #E2E8F0);
}
.kpi-row:first-child { border-top: 0; }
.kpi-k { flex: 1; min-width: 0; font-size: 12.5px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kpi-row .kpi-v { font-size: 14px; font-weight: 700; white-space: nowrap; }
.kpi-row .kpi-c { font-size: 11.5px; white-space: nowrap; color: var(--muted); }
.kpi-row .kpi-c.up { color: #16A34A; }
.kpi-row .kpi-c.down { color: #EF4444; }
.kpi-sum { padding: 0 14px 10px; font-size: 12.5px; color: var(--muted); line-height: 1.5; }
.kpi-toggle {
  width: 100%; padding: 9px; cursor: pointer; font-size: 12.5px;
  border: 0; border-top: 1px solid var(--border, #E2E8F0);
  background: var(--sunken); color: var(--blue, #0F4C81); font-weight: 600;
}
.kpi-full {
  padding: 12px 14px; font-size: 13px; line-height: 1.6;
  white-space: pre-wrap; word-break: break-word;
  border-top: 1px solid var(--border, #E2E8F0);
  /* ⚠️ Boss 2026-08-28: "ข้อมูลล้นกรอบ" — เนื้อเต็มของ Agoda/Trip มีบล็อก ``` ตารางกว้าง 434px
     แต่การ์ดกว้าง 316px · .msg-pre เดิม scope ไว้แค่ .msg-text จึงไม่มีตัวคุมตรงนี้
     min-width:0 = ให้ flex/grid item หดได้จริง · overflow-x = กันลูกดันกรอบ */
  min-width: 0; max-width: 100%; overflow-x: hidden;
}
.kpi-full .msg-table-wrap { white-space: normal; max-width: 100%; overflow-x: auto; }
/* บล็อกตาราง monospace: เลื่อนแนวนอน "ในกรอบตัวเอง" ไม่ดันการ์ด */
.kpi-full .msg-pre {
  font-family: 'Tlwg Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', 'Courier New', monospace;
  font-size: 12px; line-height: 1.5; margin: 6px 0 2px;
  background: var(--sunken); border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px; white-space: pre; -webkit-overflow-scrolling: touch;
  display: block; max-width: 100%; overflow-x: auto;
}
.kpi-full img { max-width: 100%; height: auto; }
.kpi-card { min-width: 0; }
@media (max-width: 560px) {
  .kpi-h { font-size: 13.5px; }
  .kpi-row { flex-wrap: wrap; gap: 4px 8px; }
  .kpi-k { flex: 1 0 100%; }
}

.kpi-day {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; font-weight: 700; color: var(--muted);
  margin: 12px 2px 6px; text-transform: none;
}
.kpi-day::after { content: ''; flex: 1; height: 1px; background: var(--border, #E2E8F0); }
.kpi-day-n {
  order: 3; background: var(--sunken); border: 1px solid var(--border);
  border-radius: 999px; padding: 0 7px; font-size: 11px; font-weight: 600;
}
.kpi-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* คำโปรย: บรรทัดแรกของรายงาน เห็นเลยว่าข้างในคืออะไร ไม่ต้องกดเปิดทีละใบ */
.kpi-peek {
  padding: 0 12px 9px; font-size: 12.5px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sec-kpi-card.open .kpi-peek { display: none; }
.sec-kpi-head:hover { filter: brightness(.97); }
.sec-kpi-arrow { transition: transform .15s; opacity: .5; }
.sec-kpi-card.open .sec-kpi-arrow { transform: rotate(180deg); }
.sec-kpi-body { display: none; padding: 10px 12px; font-size: 13px; line-height: 1.6;
  white-space: pre-wrap; word-break: break-word; border-top: 1px solid var(--border, #E2E8F0); }
.sec-kpi-card.open .sec-kpi-body { display: block; }
.sec-kpi-body .msg-table-wrap { white-space: normal; }
.sec-kpi-imgs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.sec-kpi-imgs img { width: 150px; border-radius: 6px; cursor: pointer; border: 1px solid var(--border, #E2E8F0); }

/* ================= ศูนย์แจ้งเตือน + แท็บสถานะ (2026-08-23) =================
   ใช้ตัวแปรธีมทั้งหมด (--card/--text/--muted/--border/--blue) → โหมดมืดตามมาเอง
   ⚠️ ห้ามฮาร์ดโค้ดสี ไม่งั้นโหมดมืดพัง (บทเรียนเดิมจาก staffquest) */
.ntf-tabs {
  display: flex; gap: var(--s1); background: var(--sunken); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--s1); margin-bottom: var(--s3);
  overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.ntf-tabs::-webkit-scrollbar { display: none; }
.ntf-tab {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px var(--s2); border: 0; background: transparent; color: var(--muted);
  font: inherit; font-size: var(--fs-md); font-weight: 600; cursor: pointer;
  border-radius: var(--radius-sm); white-space: nowrap;
}
.ntf-tab:hover { color: var(--text); }
.ntf-tab.active { background: var(--card); color: var(--blue); box-shadow: var(--shadow); }
.ntf-tab-n {
  min-width: 20px; padding: 1px 6px; border-radius: var(--radius-pill);
  background: var(--border); color: var(--muted); font-size: var(--fs-xs); font-weight: 700;
}
.ntf-tab.active .ntf-tab-n { background: var(--blue-light); color: var(--blue); }
.ntf-tab-n.red:not(:empty) { background: var(--red); color: #fff; }
.ntf-tab-n.red.zero { background: var(--border); color: var(--muted); }

/* ชิปกรองชนิด — เลื่อนแนวนอนได้บนมือถือ ไม่ดันหน้าจอ */
.ntf-kinds { display: flex; gap: 6px; overflow-x: auto; padding-bottom: var(--s2); margin-bottom: var(--s2); }
.ntf-kinds::-webkit-scrollbar { height: 0; }
.ntf-chip {
  flex: 0 0 auto; padding: 5px 11px; border: 1px solid var(--border); background: var(--card);
  color: var(--muted); border-radius: var(--radius-pill); font-size: var(--fs-sm); cursor: pointer;
  font-family: inherit; white-space: nowrap;
}
.ntf-chip.active { border-color: var(--blue); background: var(--blue-light); color: var(--blue); font-weight: 600; }

/* รายการ — ยังไม่อ่านมีแถบซ้ายสีน้ำเงิน + พื้นอ่อน อ่านแล้วจาง */
.ntf-list { display: flex; flex-direction: column; gap: 6px; }
.ntf-item {
  display: flex; gap: var(--s3); align-items: flex-start; padding: var(--s3);
  background: var(--card); border: 1px solid var(--border); border-left: 3px solid transparent;
  border-radius: var(--radius); cursor: pointer;
}
.ntf-item:hover { border-color: var(--blue); }
.ntf-item.unread { border-left-color: var(--blue); background: var(--blue-light); }
.ntf-item.read { opacity: .72; }
.ntf-ico { flex: 0 0 auto; font-size: 18px; line-height: 1.4; width: 24px; text-align: center; }
.ntf-main { flex: 1 1 auto; min-width: 0; }
.ntf-head { font-size: var(--fs-md); color: var(--text); line-height: 1.45; }
.ntf-body {
  font-size: var(--fs-sm); color: var(--muted); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.ntf-meta { font-size: var(--fs-xs); color: var(--muted); margin-top: 4px; }
.ntf-x {
  flex: 0 0 auto; border: 0; background: transparent; color: var(--muted);
  cursor: pointer; font-size: 15px; padding: 2px 4px; line-height: 1; border-radius: var(--radius-sm);
}
.ntf-x:hover { background: var(--border); color: var(--red); }
.ntf-empty { text-align: center; color: var(--muted); padding: var(--s6) var(--s4); font-size: var(--fs-md); }

/* กล่องเดิม (ยังไม่ได้อ่าน/รอตอบกลับ/เธรด) ยุบไว้ ไม่ให้แย่งสายตาจากรายการหลัก */
.ntf-more { margin-top: var(--s5); border-top: 1px solid var(--border); padding-top: var(--s3); }
.ntf-more > summary {
  cursor: pointer; color: var(--muted); font-size: var(--fs-sm); font-weight: 600;
  padding: var(--s2) 0; list-style: none;
}
.ntf-more > summary::before { content: '▸ '; }
.ntf-more[open] > summary::before { content: '▾ '; }
.ntf-more > summary::-webkit-details-marker { display: none; }

@media (max-width: 640px) {
  .ntf-tab { font-size: var(--fs-sm); padding: 8px 4px; }
  .ntf-item { padding: var(--s2) var(--s3); gap: var(--s2); }
}

/* ===== กระดิ่งแจ้งเตือน มุมขวาบน + แผงโปร่งใส (Boss สั่ง 2026-08-23) ===== */
.bell-wrap { position: relative; display: inline-flex; }
.bell-btn { position: relative; }
.bell-badge { position: absolute; top: -2px; right: -2px; min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 8px; background: #EF4444; color: #fff; font-size: 10px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; line-height: 1; }
/* 🔴 Boss แจ้ง 2026-09-06 (ภาพ IMG_8612): "หัวใจแจ้งเตือนโดนข้อความเบียดจนดูยาก"
   ป้าย "99+" กว้าง 30px แต่ยึด right:-2px = ยื่นออกขวาไปทับปุ่ม ⋯ (วัดจริงทุกเครื่อง)
   ต้นเหตุ: ป้าย 1 หลัก (16px) ออกแบบให้ยื่นมุมสวย ๆ แต่พอเป็น 3 ตัวอักษร
   ความกว้างขยายออกด้านขวาเรื่อย ๆ เพราะยึดขอบขวาไว้
   แก้: บนมือถือให้ยึด "ขอบขวาปุ่มพอดี" (right:0) แล้วขยายเข้าด้านใน + ย่อลงนิด
   ⚠️ ไม่ใช้ transform ย้าย เพราะป้ายต้องอยู่ในกรอบปุ่มเพื่อไม่ให้ทับปุ่มข้าง ๆ */
body.x10m .bell-badge {
  top: -1px; right: 0;
  height: 15px; min-width: 15px; padding: 0 3px;
  font-size: 9.5px; border-radius: 7.5px;
  box-shadow: 0 0 0 1.5px var(--v3-card, var(--card));  /* เส้นคั่นให้อ่านออกบนไอคอน */
}

/* โปร่งใส: พื้นหลังกึ่งโปร่ง + เบลอฉากหลัง เห็นเนื้อหาด้านหลังลางๆ ตามที่ Boss ขอ */
.bell-pop { position: absolute; top: calc(100% + 8px); right: 0; width: 380px; max-width: calc(100vw - 24px);
  z-index: 300; border-radius: 14px; overflow: hidden; display: flex; flex-direction: column;
  background: color-mix(in srgb, var(--card, #fff) 72%, transparent);
  -webkit-backdrop-filter: blur(16px) saturate(150%); backdrop-filter: blur(16px) saturate(150%);
  border: 1px solid color-mix(in srgb, var(--border, #E2E8F0) 70%, transparent);
  box-shadow: 0 16px 40px rgba(0, 0, 0, .22); }
.bell-pop.hidden { display: none; }
.bell-head { display: flex; align-items: center; gap: 8px; padding: 12px 14px 8px; font-size: 14px; }
.bell-new { font-size: 11.5px; opacity: .7; }
.bell-all { margin-left: auto; border: none; background: none; cursor: pointer;
  color: var(--blue, #0F4C81); font-size: 12px; font-weight: 600; }
.bell-all:hover { text-decoration: underline; }
.bell-chips { display: flex; gap: 6px; padding: 0 12px 8px; overflow-x: auto; scrollbar-width: none; }
/* Boss แจ้ง 2026-09-06 (ภาพ IMG_8612): แถบตัวกรอง "ดูยาก/เบียด"
   วัดจริงแล้ว **ไม่ได้ทับกัน** — ชิปล้นออกขวา 51-66px และเลื่อนได้ปกติ
   แต่ไม่มีอะไรบอกว่า "ยังมีต่อทางขวา" คนเลยนึกว่าจอเพี้ยน
   → ใส่เงาจาง ๆ ขอบขวาเป็นสัญญาณว่าเลื่อนได้ + เลื่อนลื่นแบบ native */
body.x10m .bell-chips {
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent 100%);
  mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent 100%);
}
body.x10m .bell-chip { scroll-snap-align: start; }


.bell-chips::-webkit-scrollbar { display: none; }
.bell-chip { flex-shrink: 0; border: 1px solid color-mix(in srgb, var(--border, #E2E8F0) 70%, transparent);
  background: color-mix(in srgb, var(--sunken, #F1F5F9) 55%, transparent); color: inherit;
  border-radius: 999px; padding: 4px 11px; font-size: 11.5px; cursor: pointer; }
.bell-chip.active { background: var(--blue, #0F4C81); color: #fff; border-color: transparent; }
.bell-list { max-height: 60vh; overflow-y: auto; padding: 0 8px 8px; }
.bell-item { display: flex; gap: 10px; align-items: flex-start; padding: 10px; border-radius: 10px; cursor: pointer; }
.bell-item:hover { background: color-mix(in srgb, var(--side-hover, #E2E8F0) 55%, transparent); }
.bell-item.unread { background: color-mix(in srgb, var(--blue, #0F4C81) 8%, transparent); }
.bell-ico { width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0; font-size: 15px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--sunken, #F1F5F9) 70%, transparent); }
.bell-main { flex: 1; min-width: 0; }
.bell-top { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.bell-who { font-size: 13px; }
.bell-kind { font-size: 10px; padding: 1px 6px; border-radius: 999px; opacity: .85;
  background: color-mix(in srgb, var(--blue, #0F4C81) 14%, transparent); }
.bell-body { font-size: 12.5px; opacity: .82; margin-top: 2px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.bell-meta { font-size: 11px; opacity: .55; margin-top: 2px; }
.bell-right { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex-shrink: 0; }
.bell-when { font-size: 11px; opacity: .55; white-space: nowrap; }
.bell-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--blue, #0F4C81); }
.bell-empty { padding: 26px 12px; text-align: center; opacity: .6; font-size: 12.5px; }
.bell-more { border: none; cursor: pointer; padding: 11px; font-size: 12.5px; font-weight: 600;
  color: var(--blue, #0F4C81); background: color-mix(in srgb, var(--sunken, #F1F5F9) 45%, transparent);
  border-top: 1px solid color-mix(in srgb, var(--border, #E2E8F0) 60%, transparent); }
.bell-more:hover { filter: brightness(.97); }
/* มือถือ: ตรึงแผงกับ "ขอบจอ" ไม่ใช่ขอบปุ่มกระดิ่ง
   เดิม right:-8px อิง .bell-wrap (position:relative) ซึ่งอยู่กลางแถบเครื่องมือ
   แผงกว้าง 100vw จึงล้นออกนอกจอด้านซ้าย = ข้อความโดนตัด (พี่อ้อมแจ้ง 2026-08-26) */
@media (max-width: 560px) {
  .bell-pop {
    position: fixed;
    /* --bell-top ตั้งค่าจาก JS ตอนเปิดแผง (ใต้ปุ่มกระดิ่งจริง) */
    top: var(--bell-top, 64px); right: 10px; left: 10px; width: auto; max-width: none;
    max-height: calc(100dvh - var(--bell-top, 64px) - 84px);
  }
  .bell-list { max-height: none; flex: 1 1 auto; }
}

/* ===== ไอคอนมินิมอล (SVG) — แทนอิโมจิทั้งแอป (Boss สั่ง 2026-08-23) ===== */
.ic { display: inline-block; vertical-align: -0.18em; flex-shrink: 0; }
/* ปุ่มไอคอนล้วน: จัดกึ่งกลางจริง (เดิมอาศัย line-height ของอิโมจิ) */
.icon-btn { display: inline-flex; align-items: center; justify-content: center; }
.pm-icon { display: inline-flex; align-items: center; justify-content: center; width: 20px; }
/* แถบล่างมือถือ: ไอคอนบน ข้อความล่าง */
.nav-btn { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; }
.nav-btn .ic { vertical-align: 0; }
/* การ์ดเมนู + ชนิดแจ้งเตือน */
.mn-tile-ic, .ntf-ico, .bell-ico { display: inline-flex; align-items: center; justify-content: center; }
/* ไอคอนหน้าห้องในแถบซ้าย — ให้ความสูงเท่าเดิมไม่ให้แถวขยับ */
.chan-ic { display: inline-flex; align-items: center; justify-content: center; width: 15px; opacity: .75; }
.chan-item.active .chan-ic { opacity: 1; }
/* ดาวห้องโปรด: กลวง = ยังไม่ติดดาว, ทึบ = ติดแล้ว */
.chan-fav .ic { fill: none; }
.chan-fav.on .ic { fill: currentColor; }
/* โลโก้หน้า login + หน้าจอว่าง */
.login-logo, .big-emoji { display: flex; align-items: center; justify-content: center; opacity: .9; }
.big-emoji { opacity: .35; }
.up-icon, .drop-icon { display: inline-flex; align-items: center; justify-content: center; }

/* ============================================================
   ธีมส่วนตัว รอบ 2 (Boss สั่ง 2026-08-24) — ฟอนต์ / ขนาดอักษร / พื้นหลังห้องแชท / บับเบิล
   ทุกอย่างเป็น attribute บน <html> ซ้อนกับ data-theme + data-accent ที่มีอยู่
   ⚠️ ฟอนต์ทั้งหมดต้องเป็นของที่มีในเครื่อง/ในโฟลเดอร์ fonts/ เท่านั้น
      ห้ามลิงก์ Google Fonts หรือ CDN (แอปนี้ต้องใช้ได้ตอนเน็ตช้า/หลุด)
   ⚠️ Noto Sans Myanmar/Khmer/Lao ต้องต่อท้ายทุกชุด ไม่งั้นพม่า/เขมร/ลาวเป็นสี่เหลี่ยม
   ============================================================ */

/* ---- ชุดฟอนต์ ---- */
/* ค่าเริ่มต้น (ไม่มี data-font) = Kanit ตาม body เดิม ไม่ต้องเขียนซ้ำ */
/* "อ่านสบาย" — Thai UI ที่มีติดเครื่องแทบทุก OS (Windows/mac/iOS/Android)
   ⚠️ เจตนาไม่ใส่ Sarabun / Noto Serif Thai: ไม่ได้บันเดิลมาใน fonts/ และไม่มีติดเครื่องส่วนใหญ่
      ใส่ไปก็ตกไปตัวสำรองเงียบๆ ผู้ใช้กดแล้วไม่เห็นอะไรเปลี่ยน */
html[data-font="sarabun"] body {
  font-family: 'Leelawadee UI', 'Thonburi', 'Noto Sans Thai', 'Sukhumvit Set',
    'Noto Sans Myanmar', 'Noto Sans Khmer', 'Noto Sans Lao',
    'Segoe UI', system-ui, sans-serif;
  line-height: 1.6;
}
html[data-font="system"] body {
  font-family: system-ui, -apple-system, 'Segoe UI', 'Leelawadee UI', 'Noto Sans Thai',
    'Noto Sans Myanmar', 'Noto Sans Khmer', 'Noto Sans Lao', Roboto, sans-serif;
  line-height: 1.6;
}
/* "มีหัว" — Thai serif ที่มีติดเครื่อง (Angsana/Browallia บน Windows) แล้วต่อ generic serif
   ตัวสูงเล็ก จึงต้องดัน font-size ขึ้นหน่อย ไม่งั้นอ่านยากกว่า Kanit */
html[data-font="serif"] body {
  font-family: 'Angsana New', 'Browallia New', 'Noto Serif Thai', Georgia, 'Times New Roman',
    'Noto Sans Myanmar', 'Noto Sans Khmer', 'Noto Sans Lao', serif;
  line-height: 1.6; font-size: 16px;
}
html[data-font="mono"] body {
  font-family: 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', 'Courier New',
    'Noto Sans Myanmar', 'Noto Sans Khmer', 'Noto Sans Lao', monospace;
  line-height: 1.6;
}

/* ---- ขนาดตัวอักษรในข้อความแชท ----
   แตะแค่ตัวข้อความ/ชื่อ/เวลา ในสายแชท ไม่ขยายทั้งแอป
   (ขยาย body ทั้งแอปจะทำให้เมนู/ตารางแตกบนมือถือ) */
html[data-size="s"]  .msg-text { font-size: 13.5px; }
html[data-size="s"]  .msg-name { font-size: 12.5px; }
html[data-size="l"]  .msg-text { font-size: 16px; }
html[data-size="l"]  .msg-name { font-size: 14.5px; }
html[data-size="xl"] .msg-text { font-size: 18px; }
html[data-size="xl"] .msg-name { font-size: 16px; }
html[data-size="xl"] .msg .avatar { width: 36px; height: 36px; font-size: 14px; }

/* ---- พื้นหลังห้องแชท ----
   วาดด้วย CSS gradient ล้วน ไม่มีไฟล์รูป = ไม่เพิ่ม request ไม่กินเน็ต
   ทุกลายวางบน var(--bg) เดิม แล้วซ้อนลายจางๆ ทับ คอนทราสต์การอ่านจึงไม่เสีย */
html[data-wall="dots"] .messages {
  background-image: radial-gradient(currentColor .8px, transparent .9px);
  background-size: 18px 18px;
  color: var(--border);          /* currentColor ของลาย = สีเส้นขอบ (จางพอดีทั้ง 2 ธีม) */
}
html[data-wall="dots"] .messages > * { color: var(--text); }
html[data-wall="grid"] .messages {
  background-image:
    linear-gradient(to right, var(--border) 1px, transparent 1px),
    linear-gradient(to bottom, var(--border) 1px, transparent 1px);
  background-size: 26px 26px;
  opacity: 1;
}
html[data-wall="paper"] .messages {
  background-image: repeating-linear-gradient(
    to bottom, transparent 0 27px, var(--border) 27px 28px);
}
html[data-wall="soft"] .messages {
  background-image:
    radial-gradient(120% 60% at 15% 0%, var(--blue-light) 0%, transparent 62%),
    radial-gradient(90% 50% at 100% 100%, var(--blue-light) 0%, transparent 58%);
  background-repeat: no-repeat;
  background-attachment: local;
}

/* ---- สไตล์บับเบิลข้อความ ---- */
/* ⚠️ Boss ท้วงหลายรอบ 2026-08-27: "พื้นหลังข้อความสีอ่อนลากเต็มจอ เอาออก"
   ต้นเหตุ = กฎ 2 ชุดนี้ทาพื้นให้ `.msg-body` ซึ่งมี `flex:1` → ยืดเต็มความกว้างแถว
   แก้: ย้ายกล่องไปทาที่ `.msg-bubble` (หุบพอดีข้อความ) ไม่ทา `.msg-body` อีก
   ผลคือกล่องล้อมแค่ตัวข้อความ ไม่เป็นแถบยาวขวางจอ */
html[data-bubble="round"] .messages .msg:not(.system) .msg-bubble {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 6px 12px 7px;
  box-shadow: var(--shadow);
}
/* แบบ "เหลี่ยม" (card) — กล่องเหลี่ยม มีขีดสีแบรนด์ซ้าย */
html[data-bubble="square"] .messages .msg:not(.system) .msg-bubble {
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--blue);
  border-radius: 4px;
  padding: 6px 12px 7px;
}
/* กันพื้นเดิมที่เคยทาไว้บน .msg-body หลุดมา (ธีมไหนก็ไม่ต้องมีแถบยาว) */
html[data-bubble="round"] .messages .msg:not(.system) .msg-body,
html[data-bubble="square"] .messages .msg:not(.system) .msg-body {
  background: transparent; border: none; box-shadow: none; padding: 0;
}
/* แบบ "ไม่มีกล่อง" = ค่าเริ่มต้นเดิมของแอป (Slack) — ไม่ต้องเขียน CSS */
/* กล่องแล้ว hover ทั้งแถวไม่ต้องระบายสีทับอีก จะซ้อนกันดูเลอะ */
html[data-bubble="round"] .messages .msg:hover,
html[data-bubble="square"] .messages .msg:hover { background: transparent; }

/* ---- ความหนาแน่นแถว ---- */
html[data-dense="tight"] .messages .msg { padding: 1px 6px; margin-bottom: 0; }
html[data-dense="tight"] .messages .msg-text { line-height: 1.42; }
html[data-dense="roomy"] .messages .msg { padding: 7px 6px; margin-bottom: 6px; }
html[data-dense="roomy"] .messages .msg-text { line-height: 1.7; }

/* ---- ตัวเลือกในหน้าโปรไฟล์: การ์ดตัวอย่าง ---- */
.pf-opts { display: flex; flex-wrap: wrap; gap: 8px; }
.pf-opt {
  border: 1px solid var(--border); background: var(--card); color: var(--text);
  border-radius: 10px; padding: 7px 12px; cursor: pointer; font-family: inherit;
  font-size: 13px; line-height: 1.3; text-align: center; min-width: 62px;
}
.pf-opt:hover { border-color: var(--blue); }
.pf-opt.active { border-color: var(--blue); box-shadow: 0 0 0 2px var(--blue-light); font-weight: 600; }
/* ตัวอย่างฟอนต์: ให้ปุ่มโชว์ด้วยฟอนต์ของตัวเอง เห็นก่อนกด */
.pf-opt[data-fontpreview] { font-size: 14px; }
/* ตัวอย่างลายพื้นหลัง: กล่องสี่เหลี่ยมเล็กโชว์ลายจริง */
.pf-opt.pf-wall { padding: 6px; min-width: 0; }
.pf-opt.pf-wall .pf-wall-sw {
  display: block; width: 54px; height: 34px; border-radius: 6px;
  background-color: var(--bg); border: 1px solid var(--border); margin-bottom: 4px;
}
.pf-opt.pf-wall .pf-wall-lbl { display: block; font-size: 11px; }
/* ตัวอย่างชุดไอคอนแถบราง (Boss สั่ง 2026-09-01 "อยากมีตัวเลือก icon มากกว่านี้")
   โชว์ไอคอนจริง 3 ตัวของแต่ละชุด — ชื่อชุดอย่างเดียวเดาหน้าตาไม่ออก
   ⚠️ ปุ่มมี svg อยู่ข้างใน ต้อง line-height:0 ที่กล่อง ไม่งั้นมีช่องว่างใต้ไอคอน */
.pf-opt.pf-ico { padding: 7px 9px 6px; min-width: 0; }
.pf-opt.pf-ico .pf-ico-sw {
  display: flex; align-items: center; justify-content: center; gap: 5px;
  line-height: 0; margin-bottom: 4px; min-height: 22px; font-size: 17px;
}
.pf-opt.pf-ico .pf-ico-sw .ic { width: 20px; height: 20px; }
.pf-opt.pf-ico .pf-ico-lbl { display: block; font-size: 11px; }
/* ปุ่มสีเอง: วงกลมเหมือน .pf-accent แต่มีเส้นทแยงสีรุ้งบอกว่าเลือกเองได้ */
.pf-accent.pf-custom {
  background: conic-gradient(#EF4444, #F59E0B, #10B981, #3B82F6, #8B5CF6, #EF4444);
}
.pf-custom-wrap { display: inline-flex; align-items: center; gap: 8px; }
.pf-custom-wrap input[type="color"] {
  width: 34px; height: 34px; padding: 0; border: 2px solid var(--border);
  border-radius: 50%; background: none; cursor: pointer; margin-bottom: 0;
}
/* ลายบน swatch ตัวอย่าง — ต้องเขียนซ้ำเพราะ swatch อยู่นอก .messages */
.pf-wall-sw[data-w="dots"]  { background-image: radial-gradient(var(--border) .8px, transparent .9px); background-size: 9px 9px; }
.pf-wall-sw[data-w="grid"]  { background-image: linear-gradient(to right, var(--border) 1px, transparent 1px), linear-gradient(to bottom, var(--border) 1px, transparent 1px); background-size: 11px 11px; }
.pf-wall-sw[data-w="paper"] { background-image: repeating-linear-gradient(to bottom, transparent 0 8px, var(--border) 8px 9px); }
.pf-wall-sw[data-w="soft"]  { background-image: radial-gradient(120% 70% at 15% 0%, var(--blue-light) 0%, transparent 62%), radial-gradient(90% 60% at 100% 100%, var(--blue-light) 0%, transparent 58%); }

/* ===== การ์ด SOS ขอความช่วยเหลือ + ปุ่มรับงาน (Boss 2026-08-24) ===== */
.sos-card {
  margin-top: 6px; max-width: min(420px, 100%);
  border: 1px solid var(--border); border-left: 3px solid #DC2626; border-radius: 10px;
  background: var(--card); overflow: hidden;
}
.sos-card .sos-head {
  padding: 8px 11px; font-weight: 700; line-height: 1.45;
  background: rgba(220, 38, 38, .10); color: var(--text);
  border-bottom: 1px solid var(--border); word-break: break-word;
}
.sos-card .sos-body { padding: 7px 11px 3px; }
.sos-card .sos-row {
  padding: 2px 0; line-height: 1.5; word-break: break-word; overflow-wrap: anywhere;
}
.sos-card .sos-kv { display: flex; gap: 8px; padding: 3px 0; line-height: 1.5; }
.sos-card .sos-k { flex: none; min-width: 58px; color: var(--muted); font-size: 12.5px; }
.sos-card .sos-v { flex: 1; word-break: break-word; overflow-wrap: anywhere; }
.sos-card .sos-foot {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  padding: 8px 11px; border-top: 1px solid var(--border); background: var(--bg);
}
.sos-card .sos-btn {
  border: none; border-radius: 7px; padding: 6px 14px;
  font-family: inherit; font-size: 13px; font-weight: 700;
  background: #16A34A; color: #fff; cursor: pointer;
}
.sos-card .sos-btn:hover { background: #15803D; }
.sos-card .sos-btn:disabled { opacity: .6; cursor: default; }
.sos-card .sos-taken { font-size: 13px; font-weight: 700; color: #15803D; }
.sos-card .sos-link {
  margin-left: auto; font-size: 12.5px; font-weight: 600;
  color: var(--blue); text-decoration: none;
}

/* ===== การ์ด Requirement (guestservice) — Boss สั่งจัดหน้าเหมือนการ์ด SOS 2026-08-30 =====
   "ให้ง่าย ไม่รก": รายละเอียดเป็นบรรทัดใหญ่เด่น · ป้ายกำกับตัวเล็กสีจาง · ค่าตัวหนา */
.req-card {
  margin-top: 6px; max-width: min(420px, 100%);
  border: 1px solid var(--border); border-left: 3px solid #2563EB; border-radius: 10px;
  background: var(--card); overflow: hidden;
}
.req-card .req-head {
  display: flex; align-items: center; gap: 7px;
  padding: 8px 11px; font-weight: 700; line-height: 1.45;
  background: rgba(37, 99, 235, .10); color: var(--text);
  border-bottom: 1px solid var(--border); word-break: break-word;
}
.req-card .req-badge {
  flex: none; background: #2563EB; color: #fff;
  font-size: 10px; font-weight: 800; letter-spacing: .3px;
  padding: 2px 6px; border-radius: 4px; line-height: 1.5;
}
.req-card .req-body { padding: 10px 11px 6px; }
/* บรรทัดใหญ่ = เนื้องานจริง อ่านจบในบรรทัดเดียวไม่ต้องกวาดตาหาในตาราง */
.req-card .req-detail {
  font-size: 15px; line-height: 1.5; color: var(--text);
  margin-bottom: 8px; word-break: break-word; overflow-wrap: anywhere;
}
.req-card .req-row { padding: 2px 0; line-height: 1.5; word-break: break-word; overflow-wrap: anywhere; }
.req-card .req-kv { display: flex; gap: 10px; padding: 3px 0; line-height: 1.55; }
.req-card .req-k { flex: none; min-width: 68px; color: var(--muted); font-size: 12.5px; }
.req-card .req-v { flex: 1; font-weight: 600; word-break: break-word; overflow-wrap: anywhere; }
.req-card .req-foot {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  padding: 8px 11px; border-top: 1px solid var(--border); background: var(--bg);
}
.req-card .req-btn {
  border: none; border-radius: 7px; padding: 7px 15px; min-height: 34px;
  font-family: inherit; font-size: 13px; font-weight: 700;
  background: #16A34A; color: #fff; cursor: pointer;
}
.req-card .req-btn:hover { background: #15803D; }
.req-card .req-btn:disabled { opacity: .6; cursor: default; }
.req-card .req-taken { font-size: 13px; font-weight: 700; color: #15803D; }
.req-card .req-link {
  margin-left: auto; font-size: 12.5px; font-weight: 600;
  color: var(--blue); text-decoration: none;
}

/* การ์ด KDS (Kitchen Display System) — สีหัวการ์ดเปลี่ยนตาม kds_type ผ่าน --kds-c */
.kds-card {
  margin-top: 6px; max-width: min(420px, 100%);
  border: 1px solid var(--border); border-left: 3px solid var(--kds-c, #EA580C); border-radius: 10px;
  background: var(--card); overflow: hidden;
}
.kds-card .kds-head {
  display: flex; align-items: center; gap: 7px;
  padding: 8px 11px; font-weight: 700; line-height: 1.45;
  background: color-mix(in srgb, var(--kds-c, #EA580C) 12%, transparent); color: var(--text);
  border-bottom: 1px solid var(--border); word-break: break-word;
}
.kds-card .kds-badge {
  flex: none; background: var(--kds-c, #EA580C); color: #fff;
  font-size: 11px; font-weight: 800; letter-spacing: .2px;
  padding: 2px 7px; border-radius: 4px; line-height: 1.6; white-space: nowrap;
}
.kds-card .kds-body { padding: 8px 11px 6px; }
.kds-card .kds-item {
  padding: 3px 0; line-height: 1.5; font-size: 14px;
  word-break: break-word; overflow-wrap: anywhere;
}
.kds-card .kds-row { padding: 2px 0; line-height: 1.5; color: var(--muted); font-size: 13px; word-break: break-word; overflow-wrap: anywhere; }
.kds-card .kds-kv { display: flex; gap: 10px; padding: 3px 0; line-height: 1.55; }
.kds-card .kds-k { flex: none; min-width: 68px; color: var(--muted); font-size: 12.5px; }
.kds-card .kds-v { flex: 1; font-weight: 600; word-break: break-word; overflow-wrap: anywhere; }


/* ปุ่มเลือกสีเอง: Chromium ไม่ยอมมนขอบ swatch ด้านใน ต้องสั่งที่ ::-webkit-color-swatch เอง
   ไม่งั้นวงกลมชุดสีเรียงกันสวยๆ แล้วมีสี่เหลี่ยมโดดมาอันเดียว */
.pf-custom-wrap input[type="color"] { overflow: hidden; }
.pf-custom-wrap input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; border-radius: 50%; }
.pf-custom-wrap input[type="color"]::-webkit-color-swatch { border: none; border-radius: 50%; }
.pf-custom-wrap input[type="color"]::-moz-color-swatch { border: none; border-radius: 50%; }
/* เลือกสีเองอยู่ = วงแหวนเหมือน .pf-accent.active */
.pf-custom-wrap input[type="color"].active { border-color: var(--text); }

/* ================= แผนของเรา (ourplan) ================= */
/* ใช้เฉพาะตัวแปรที่มีนิยามจริง (--card/--text/--muted/--border/--bg/--sunken/--blue/--red)
   เคยเจอบั๊กโหมดมืดพังเพราะอ้างตัวแปรผี — ห้ามเพิ่มชื่อใหม่ที่ไม่ได้ประกาศ */
.op-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; margin-bottom: 6px; }
.op-title { color: var(--blue-dark); margin: 0 0 2px; }
.op-head-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.op-month { display: flex; align-items: center; gap: 2px; background: var(--sunken); border: 1px solid var(--border); border-radius: 999px; padding: 2px 4px; }
.op-range { font-size: 13px; color: var(--text); padding: 0 6px; white-space: nowrap; }
.op-pane { margin-top: 10px; }

.op-legend { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
.op-lg { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
.op-badge { display: inline-block; min-width: 30px; text-align: center; padding: 2px 7px; border-radius: 6px;
  font-size: 11px; font-weight: 700; color: #fff; line-height: 1.5; }

/* ---- หน้าตาเหมือนชีตต้นฉบับ (Boss ส่งภาพ 2026-08-31) ----
   กรอบดำหนา · หัวเรื่องกลาง · เส้นตารางเทาบาง · คอลัมน์ชื่อพื้นครีม
   Boss สั่งก่อนหน้า "ให้เห็นทั้งเดือน 30 วันเลย" → table-layout:fixed + width:100%
   (เดิม width:max-content ทำตารางกว้าง 1957px บนจอ 360px เห็นแค่ 3 วัน) */
.op-grid-wrap { overflow: auto; max-height: 74vh; }
.op-sheet { border: 2px solid #000; background: #fff; }
.op-sheet-t { text-align: center; font-weight: 700; font-size: 15px; color: #000;
  padding: 6px 4px; border-bottom: 2px solid #000; background: #fff; }
table.op-grid { border-collapse: collapse; table-layout: fixed; width: 100%;
  font-size: 11px; color: #000; background: #fff; }
table.op-grid th, table.op-grid td { border: 1px solid #9aa0a6; padding: 0;
  text-align: center; vertical-align: middle; overflow: hidden; }
table.op-grid thead th { position: sticky; top: 0; z-index: 3; background: #fff;
  font-weight: 700; height: 34px; line-height: 1.1; }
.op-dwk { display: block; font-size: 8px; color: #5f6368; font-weight: 500; }
.op-dnum { display: block; font-size: 12px; font-weight: 700; color: #000; }
/* คอลัมน์ชื่อคน — พื้นครีมแบบชีต + ตรึงซ้าย (ต้องมีพื้นทับ ไม่งั้นช่องไหลผ่าน)
   width คงที่ ไม่ใช่ min-width ไม่งั้น table-layout:fixed แบ่งพื้นที่ผิด */
table.op-grid .op-rowh { position: sticky; left: 0; z-index: 2; background: #fff2cc; color: #000;
  font-weight: 700; text-align: center; width: 78px; font-size: 11px; height: 23px;
  overflow: hidden; text-overflow: ellipsis; }
table.op-grid thead .op-rowh { z-index: 4; background: #fff; font-size: 13px; }
.op-cell { height: 23px; line-height: 1.05; cursor: default; }
.op-m { display: block; font-size: 10px; font-weight: 700; white-space: nowrap; }
/* ข้อความยาว (เช่น "หมู่บ้าน") กว้างเกินช่อง ~28px — บีบตามแนวนอนให้พอดี
   ปล่อยล้นแบบชีตไม่ได้ เพราะช่องข้าง ๆ มีสีพื้นทับ อ่านไม่ออกทั้งคู่ */
.op-m.op-fit { font-size: 7.5px; transform: scaleX(.85); }
/* บรรทัดล่าง (วันที่ EX / เลขสลับ) ต้องย่อไม่ให้ถูกตัด */
.op-s { display: block; font-size: 6.5px; font-weight: 600; line-height: 1;
  transform: scaleX(.92); white-space: nowrap; }
/* เส้นหนาแบ่งสัปดาห์ (เสาร์) · วันนี้เน้นด้วยกรอบ ไม่ใช่พื้น เพราะพื้นเป็นของชีต */
.op-sat { border-right: 2px solid #5f6368 !important; }
table.op-grid thead th.op-today { box-shadow: inset 0 -3px 0 var(--red); }
table.op-grid td.op-today { box-shadow: inset 0 0 0 2px var(--red); }

@media (max-width: 700px) {
  /* จอแคบ: 30 คอลัมน์เหลือช่องละ ~8px — ใส่ตัวหนังสือลงไปอ่านไม่ออกและทับกัน
     เหลือ "แถบสี" แบบดูภาพรวมในชีต · แตะช่องเพื่อดูรายละเอียด (Boss: mobile first) */
  .op-sheet-t { font-size: 12px; }
  table.op-grid .op-rowh { width: 56px; font-size: 9.5px; }
  table.op-grid thead .op-rowh { font-size: 11px; }
  table.op-grid thead th { height: 22px; }
  .op-dwk { display: none; }              /* ซ่อนชื่อวัน เหลือแต่เลขวันที่ */
  .op-dnum { font-size: 8px; }
  .op-cell { height: 20px; font-size: 0; color: transparent; }
  .op-cell .op-m, .op-cell .op-s { font-size: 0; line-height: 0; }
}
.op-editing .op-cell { cursor: pointer; }
.op-editing .op-cell:hover { background: var(--blue-light); outline: 1px solid var(--blue); }

/* ===== แผนของเรา แบบ Excel: สีต่อช่อง / แก้ในช่อง / ปุ่มเพิ่ม (2026-08-24) ===== */
/* ช่องที่ลงสีเอง: สีมาจาก inline style ตอน render → hover ห้ามทับสี ใช้แค่เส้นขอบบอกว่าเล็งอยู่ */
.op-editing .op-cell.op-painted:hover { background: inherit; outline: 2px solid var(--blue); }
/* สีตัวหนังสือของช่องที่ลงสีมาจาก opFg() ใน inline style (คำนวณจากความสว่างพื้น)
   ห้ามใส่ color ทับที่นี่ — ช่องพื้นเข้ม (#434343) จะกลายเป็นตัวดำอ่านไม่ออก */
.op-editing-cell { padding: 0 !important; }
.op-inline { width: 100%; min-width: 60px; box-sizing: border-box; border: 2px solid var(--blue);
  border-radius: 3px; background: var(--card); color: var(--text); font: inherit; font-size: 11px;
  padding: 2px 4px; outline: none; }
/* จานสีในป๊อปอัพช่อง */
.op-pal-wrap { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 10px; }
.op-pal-h { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.op-pal { display: flex; flex-wrap: wrap; gap: 6px; }
.op-sw { width: 26px; height: 26px; border-radius: 6px; border: 1px solid var(--border); cursor: pointer; padding: 0; }
.op-sw:hover { transform: scale(1.12); }
.op-sw.on { outline: 2px solid var(--blue); outline-offset: 1px; }
.op-pal-row { display: flex; align-items: center; gap: 12px; margin-top: 10px; flex-wrap: wrap; }
.op-pal-own { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
.op-pal-own input[type=color] { width: 34px; height: 26px; padding: 0; border: 1px solid var(--border);
  border-radius: 6px; background: transparent; cursor: pointer; }
.op-clear { border: 1px solid var(--border); background: var(--card); color: var(--muted);
  border-radius: 8px; padding: 5px 12px; cursor: pointer; font-size: 12px; }
.op-clear:hover { border-color: var(--red); color: var(--red); }
.op-kind-list button.on { border-color: var(--blue); background: var(--blue-light); }
/* ปุ่ม + เพิ่มแถว/คอลัมน์/ตาราง */
.op-addh { width: 34px; text-align: center; background: var(--sunken); }
.op-addbtn { border: 1px dashed var(--border); background: transparent; color: var(--muted);
  border-radius: 6px; cursor: pointer; font-size: 14px; line-height: 1; padding: 3px 8px; }
.op-addbtn:hover { border-color: var(--blue); color: var(--blue-dark); border-style: solid; }
.op-addbtn.wide { font-size: 12px; padding: 6px 14px; }
.op-addrow { margin-top: 8px; }

.op-teams { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0; }
.op-team { padding: 5px 14px; border-radius: 999px; border: 1px solid var(--border); background: var(--card);
  color: var(--muted); font-size: 13px; cursor: pointer; }
.op-team.active { border-color: var(--blue); color: var(--blue-dark); background: var(--blue-light); }
.op-chip { display: inline-block; padding: 2px 9px; margin: 1px; border-radius: 999px; background: var(--sunken);
  border: 1px solid var(--border); font-size: 11px; color: var(--text); }
.op-chip-row { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0; min-height: 24px; }
.op-chip-x { display: inline-flex; align-items: center; gap: 5px; }
.op-chip-x button { border: 0; background: transparent; color: var(--red); cursor: pointer; font-size: 13px; line-height: 1; padding: 0; }
.op-special { color: var(--red); font-weight: 700; font-size: 11px; }
.op-kind-list { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
.op-kind-list button { border: 1px solid var(--border); background: var(--card); border-radius: 8px;
  padding: 7px 10px; cursor: pointer; color: var(--text); }
.op-pick-list { max-height: 210px; overflow: auto; display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.op-pick-list button { border: 1px solid var(--border); background: var(--card); color: var(--text);
  border-radius: 999px; padding: 4px 11px; cursor: pointer; font-size: 12px; }
.op-pick-list button:hover { border-color: var(--blue); color: var(--blue-dark); }
.op-adm-body { margin-top: 12px; max-height: 60vh; overflow: auto; }
.op-adm-row { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border); }
.op-adm-row input[type=text] { flex: 1; min-width: 90px; }
.op-adm-add { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }

@media (max-width: 860px) {
  .op-head { flex-direction: column; }
  .op-grid-wrap { max-height: 68vh; }
  /* ห้ามใส่ min-width/padding ให้ช่องที่นี่ — table-layout:fixed จะแบ่งพื้นที่ผิด
     แล้วตารางกว้างเกินจอ (เคยเป็นบั๊ก "เห็นแค่ 3 วัน") ขนาดจอแคบอยู่ที่บล็อก 700px */
}

/* ---- แถวเลือกสีเอง แถบข้าง / แถบบน+พื้นหลัง (Boss สั่ง 2026-08-24) ----
 * ใช้วงสีเดียวกับชุดสีธีม (.pf-accent) + ปุ่ม "ตามธีม" (.pf-opt) ในแถวเดียวกัน */
.pf-colrow { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; }
.pf-colrow .pf-accent { width: 30px; height: 30px; }
@media (max-width: 780px) { .pf-colrow .pf-accent { width: 38px; height: 38px; } }

/* ===== ปุ่มลัดของห้อง + การ์ดโหวต (Boss สั่ง 2026-08-26) ===== */
.pm-sep { height:1px; background:var(--line); margin:6px 4px; }
.tool-form { display:flex; flex-direction:column; gap:8px; }
.tool-form label { font-size:13px; color:var(--muted); }
.tool-form input[type=text], .tool-form input[type=date], .tool-form textarea {
  width:100%; padding:9px 10px; border:1px solid var(--line); border-radius:8px;
  background:var(--card); color:var(--ink); font:inherit; font-size:15px;
}
.tool-poll-opt { margin-bottom:6px; }
.tool-hint { font-size:12px; color:var(--muted); }
.tool-err { font-size:13px; color:#dc2626; min-height:18px; }
.btn.wide { width:100%; }

.poll-card { border:1px solid var(--line); border-radius:12px; padding:10px 12px; background:var(--card); max-width:420px; }
.poll-q { font-weight:600; margin-bottom:8px; }
.poll-opts { display:flex; flex-direction:column; gap:6px; }
.poll-opt {
  position:relative; display:flex; align-items:center; gap:8px; width:100%;
  padding:9px 10px; border:1px solid var(--line); border-radius:8px;
  background:transparent; color:var(--ink); font:inherit; font-size:14px;
  text-align:left; cursor:pointer; overflow:hidden;
}
.poll-opt:disabled { cursor:default; opacity:.85; }
.poll-opt.picked { border-color:#2563eb; }
/* แถบสัดส่วนอยู่หลังตัวหนังสือ — ต้องไม่กินคลิก ไม่งั้นกดโหวตไม่ติดตรงที่แถบทับ */
.poll-bar { position:absolute; inset:0 auto 0 0; background:rgba(37,99,235,.14); pointer-events:none; transition:width .25s; }
.poll-opt-txt { position:relative; flex:1; }
.poll-opt-n { position:relative; color:var(--muted); font-size:13px; min-width:20px; text-align:right; }
.poll-foot { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-top:8px; }
.poll-count, .poll-closed { font-size:12px; color:var(--muted); }
.poll-close-btn { background:transparent; border:0; color:var(--muted); font:inherit; font-size:12px; cursor:pointer; text-decoration:underline; }

/* ============================================================
   หน้า "แชท" (DM) แบบ Messenger — Boss สั่ง 2026-08-27
   แถวเต็มความกว้าง แตะง่ายบนมือถือ · เรียงคุยล่าสุดขึ้นก่อน
   ============================================================ */
.dmp-list { display: flex; flex-direction: column; }
.dmp-sec {
  font-size: 12px; font-weight: 700; color: var(--muted); letter-spacing: .02em;
  padding: 14px 4px 6px;
}
.dmp-list .dmp-sec:first-child { padding-top: 2px; }
.dmp-row {
  display: flex; align-items: center; gap: 12px; cursor: pointer;
  padding: 9px 8px; border-radius: 12px;
}
.dmp-row:hover { background: var(--sunken); }
.dmp-row:active { background: var(--sunken); }
.dmp-av { position: relative; flex: 0 0 auto; display: flex; }
/* จุดเขียว "ออนไลน์" เกาะมุมล่างขวาของรูป (แบบ Messenger) */
.dmp-on {
  position: absolute; right: -1px; bottom: -1px; width: 13px; height: 13px;
  border-radius: 50%; background: var(--green); border: 2.5px solid var(--card);
}
.dmp-mid { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dmp-name {
  font-size: 15px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dmp-prev {
  font-size: 13px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dmp-prev i { font-style: normal; opacity: .75; }
/* ป้าย "ร่าง:" ในรายชื่อแชท (แบบ Messenger) */
.dmp-draft { color: #e0245e; font-weight: 600; }
.dmp-row.unread .dmp-draft { color: #e0245e; }
.dmp-right { display: flex; flex-direction: column; align-items: flex-end; gap: 5px; flex: 0 0 auto; }
.dmp-time { font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.dmp-badge {
  min-width: 19px; height: 19px; padding: 0 5px; border-radius: 999px;
  background: var(--blue); color: #fff; font-size: 11.5px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
/* ยังไม่อ่าน = ชื่อกับข้อความเข้มขึ้น (Messenger ใช้วิธีนี้แทนไอคอน) */
.dmp-row.unread .dmp-name { font-weight: 700; }
.dmp-row.unread .dmp-prev { color: var(--text); font-weight: 600; }
.dmp-empty { padding: 34px 10px; text-align: center; color: var(--muted); font-size: 13.5px; }

@media (max-width: 700px) {
  .dmp-row { padding: 9px 4px; gap: 11px; }
  .dmp-name { font-size: 15.5px; }
}

/* ============================================================
   บับเบิลข้อความหลัก (Boss ท้วง 2026-08-27 "เหมือนพันทิป มองยาก")
   ------------------------------------------------------------
   เดิม: ข้อความชั้นบนสุดไม่มีบับเบิล — ตัวหนังสือลอยบนพื้นมืดกว้างเต็มแนว
         + ปุ่ม 5 ตัวเป็นข้อความล้วนใต้ทุกใบ → อ่านเหมือนกระทู้ฟอรัม
   ใหม่: ห่อเป็นบับเบิลจริง · ของเราสีน้ำเงินชิดขวา · ของคนอื่นสีเทาชิดซ้าย
         ปุ่มใต้ข้อความจางลง โผล่ชัดเมื่อ hover/แตะ (ไม่แย่งสายตาจากเนื้อหา)
   ⚠️ ใช้เฉพาะข้อความชั้นบนสุด — คอมเมนต์ (.msg.nested) มีบับเบิลของตัวเองแล้ว
   ============================================================ */
.msg:not(.nested):not(.system) .msg-bubble {
  background: transparent;   /* Boss สั่ง 2026-08-27: ไม่ต้องมีทั้งพื้นหลังและเส้นกรอบ มันรก */
  border: none;
  padding: 2px 0 0;
  display: inline-block;
  max-width: min(620px, 92%);
  text-align: left;
}
/* ข้อความของเราเอง: ทุกอย่างย้ายไปฝั่งขวาพร้อมกัน — รูปโปรไฟล์ · ชื่อ · ข้อความ
   (Boss สั่ง 2026-08-27: "ชื่อผมกับรูปโปรไฟล์ควรจะย้ายตาม")
   ใช้ margin-left:auto ที่ .msg เพื่อดัน "ทั้งแถว" ไปขวา แล้วสลับให้อวตารอยู่ขวาสุด
   (ไม่ใช่ row-reverse บน .msg เดิมที่ทำให้บับเบิลลอยกลางจอ เพราะ .msg-body มี flex:1) */
.msg:not(.nested):not(.system).mine {
  flex-direction: row-reverse;
  justify-content: flex-start;   /* หลัง reverse = ชิดขวาจริง */
}
/* .msg-body ยัง flex:1 (เต็มที่เหลือ) แต่จัดลูกไปขวา → บับเบิลชิดขวาติดอวตาร */
.msg:not(.nested):not(.system).mine .msg-body {
  display: flex; flex-direction: column; align-items: flex-end;
}
.msg:not(.nested):not(.system).mine .msg-head { flex-direction: row-reverse; }
.msg:not(.nested):not(.system).mine .msg-bubble { margin-left: auto; }
.msg:not(.nested):not(.system).mine .msg-bubble { background: transparent; border: none; }
.msg:not(.nested):not(.system).mine .msg-bubble .msg-time { opacity: .7; }
/* ชื่อของเราเอง: โชว์ตามปกติ (Boss สั่งคืน 2026-08-27) */
/* รูป/วิดีโอ — เพดาน 320px (เท่าเดิม)
   ⚠️ บับเบิลเป็น inline-block ที่กว้างกว่ารูป → รูปเกาะซ้ายในบับเบิล
      = "รูปของเราลอยกลางจอ" (Boss ท้วง 2026-08-27)
      แก้ด้วย width:fit-content ให้บับเบิลหุบมาเท่าสื่อ แล้วดันสื่อชิดขวา */
.msg:not(.nested):not(.system) .msg-bubble > img.msg-image,
.msg:not(.nested):not(.system) .msg-bubble > video.msg-video { max-width: min(320px, 100%); }
.msg:not(.nested):not(.system) .msg-bubble { width: fit-content; }
.msg:not(.nested):not(.system).mine .msg-bubble > img.msg-image,
.msg:not(.nested):not(.system).mine .msg-bubble > video.msg-video,
.msg:not(.nested):not(.system).mine .msg-bubble > .album-card,
.msg:not(.nested):not(.system).mine .msg-bubble > .album-gridwrap { margin-left: auto; }
/* ไม่ต้องมีสีพื้นตอนเลื่อนเมาส์ผ่าน (Boss สั่งเอาออก 2026-08-27)
   แถบสีฟ้าลากเต็มความกว้างจอ ดูเหมือนบัค — เอาออกทั้งหมด
   (กฎเดิม .msg:hover บรรทัด ~333 ทา var(--blue-light) ต้อง override ทับ) */
.msg:not(.nested):not(.system):hover { background: transparent; }
/* คอมเมนต์ก็ไม่ต้องมีแถบสีตอนชี้ (มีบับเบิลของตัวเองอยู่แล้ว) */
.msg.nested:hover { background: transparent; }

/* แถวปุ่ม 5 ตัวใต้ทุกข้อความ = ต้นเหตุที่ Boss บอก "เหมือนพันทิป"
   → เอาออกจากข้อความชั้นบนสุด ย้ายไปเมนู "กดค้าง / คลิกขวา" (ครบกว่าเดิมด้วย)
   คอมเมนต์ (.msg.nested) ยังมีแถวปุ่มเหมือนเดิม ไม่แตะ */
.msg:not(.nested):not(.system) .msg-foot { display: none; }

/* แถวเล็กใต้บับเบิล: เวลา + ปุ่มถูกใจไอคอนเดียว (ที่เหลืออยู่ในเมนูกดค้าง) */
.msg-under { display: flex; align-items: center; gap: 7px; margin-top: 2px; padding: 0 4px; }
.msg:not(.nested):not(.system).mine .msg-under { justify-content: flex-end; }
.msg-under-time { font-size: 10.5px; color: var(--muted); }
/* แถวเครื่องมือข้างเวลา แบบ Messenger (Boss สั่ง 2026-08-27 แทนปุ่ม 👍):
   🙂 ใส่อิโมจิ · ↩ ตอบกลับ · ⋯ เมนูเพิ่มเติม — ไอคอนเส้น ไม่ใช่อีโมจิ
   จางไว้ ชัดตอนชี้ (คอม) / แตะที่ข้อความ (มือถือ) */
/* คอมให้เหมือนมือถือ (Boss สั่ง 2026-08-27 "ในตัวแชทของคอมปรับให้เหมือนมือถือ"):
   โชว์จางๆ ไว้ตลอด ให้รู้ว่ากดได้ ไม่ต้องเดาว่าต้องเอาเมาส์ไปชี้ก่อน */
.msg-tools { display: inline-flex; align-items: center; gap: 2px; opacity: .4; transition: opacity .15s;
  position: relative; }   /* จุดอ้างอิงให้ .react-pick (position:absolute) เกาะได้ถูกที่ */
.msg:hover .msg-tools,
.msg.show-actions .msg-tools { opacity: 1; }
/* ⚠️ แก้ 2026-09-05 (Boss แจ้ง "อิโมจิที่โพสหาย" บนคอม)
   `line-height: 0` ทำให้ปุ่มที่เนื้อหาเป็น "ตัวอักษร/อีโมจิ" (⧉ 🔖) สูงแค่ 6px
   จนแทบมองไม่เห็น — ส่วนปุ่มที่เป็น <svg> ไม่โดนเพราะ svg มีความสูงของตัวเอง
   (วัดได้: ปุ่มตัวอักษร 16 ตัว สูง 6px · ปุ่ม svg 24 ตัว สูง 21px)
   ใช้ line-height: 1 แทน — ยังไม่ทำให้ปุ่ม svg สูงเกิน เพราะ align-items:center อยู่แล้ว */
.msg-tool {
  border: none; background: none; padding: 3px; cursor: pointer;
  color: var(--muted); display: inline-flex; align-items: center;
  justify-content: center; border-radius: 50%; line-height: 1;
  min-width: 21px; min-height: 21px;
}
.msg-tool:hover { background: var(--sunken); color: var(--blue); }
/* มือถือไม่มี hover — โชว์จางๆ ไว้ให้เห็นว่ากดได้ */
@media (hover: none) {
  /* มือถือใช้ปุ่ม ⋯ เป็นทางเข้าเมนูหลัก (เลิกกดค้าง — พี่ป๋องแจ้ง 2026-08-31)
     จึงต้องเห็นชัด ไม่จาง และแตะได้ถนัด */
  .msg-tools { opacity: 1; }
  .msg.show-actions .msg-tools { opacity: 1; }
  .msg-tool { padding: 7px; color: var(--muted); }
  /* ⋯ = ปุ่มตัวสุดท้ายในแถว: เน้นให้เด่นกว่าเพื่อน ๆ ให้รู้ว่ากดตรงนี้มีเมนู */
  .msg-tools .msg-tool:last-child {
    color: var(--text); background: var(--sunken);
    min-width: 30px; min-height: 30px; justify-content: center;
  }
}
/* เวลาในหัวบับเบิล — เล็กลง ไม่แย่งสายตาจากชื่อ */
.msg:not(.nested):not(.system) .msg-bubble .msg-time { font-size: 10.5px; opacity: .65; margin-left: 6px; }

@media (max-width: 700px) {
  .msg:not(.nested):not(.system) .msg-bubble { max-width: 84%; padding: 7px 12px 8px; }
}

/* ============================================================
   โมดัลส่งไฟล์ — ปรับ UI (Boss ท้วง 2026-08-27 "ใช้ยากนิดนึง") · mobile first
   ปัญหาเดิม: ปุ่ม "Choose Files" ดิบของเบราว์เซอร์ (อังกฤษ ไม่เข้าธีม)
              + มีที่เลือกไฟล์ 2 กล่องหน้าตาคล้ายกัน แยกไม่ออกว่าอันไหนส่งเข้าแชท
   ============================================================ */
/* กล่องแตะเลือกไฟล์ */
.atc-drop {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 20px 14px; margin: 4px 0 12px; cursor: pointer;
  border: 1.5px dashed var(--border); border-radius: 14px;
  background: var(--sunken); color: var(--text); text-align: center;
  transition: border-color .15s, background .15s;
}
.atc-drop:active, .atc-drop:hover { border-color: var(--blue); background: var(--blue-light); }
.atc-drop-ic { color: var(--blue); display: inline-flex; }
.atc-drop-tx { font-size: 14.5px; font-weight: 600; }
.atc-drop-hint { font-size: 12px; }
.atc-drop.sm { padding: 13px 12px; margin: 8px 0; }
.atc-drop.sm .atc-drop-tx { font-size: 13.5px; }
/* ชื่อไฟล์ที่เลือกแล้ว */
.atc-files:empty { display: none; }
.atc-files {
  margin-top: 4px; padding: 4px 11px; border-radius: 999px;
  background: var(--card); border: 1px solid var(--border);
  font-size: 12.5px; color: var(--blue); font-weight: 600;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* คุณภาพ = การ์ด 2 ใบกดเลือก (เดิมเป็น radio จุดเล็กๆ มองไม่ออกว่าเลือกอันไหน) */
.atc-qual { display: flex; gap: 8px; margin: 0 0 12px; }
.atc-q { flex: 1; min-width: 0; cursor: pointer; }
.atc-q input { position: absolute; opacity: 0; pointer-events: none; }
.atc-q-box {
  display: flex; flex-direction: column; gap: 1px;
  padding: 9px 11px; border-radius: 11px;
  border: 1.5px solid var(--border); background: var(--card);
  transition: border-color .15s, background .15s;
}
.atc-q-box b { font-size: 13.5px; font-weight: 700; color: var(--text); }
.atc-q-box i { font-size: 11.5px; font-style: normal; color: var(--muted); }
.atc-q input:checked + .atc-q-box {
  border-color: var(--blue); background: var(--blue-light);
}
.atc-q input:checked + .atc-q-box b { color: var(--blue); }
/* ส่วน "ลิงก์ดาวน์โหลด" ยุบไว้ กดกางเมื่อต้องใช้ */
.atc-more { margin-top: 14px; border-top: 1px solid var(--border); padding-top: 10px; }
.atc-more > summary {
  cursor: pointer; font-size: 13px; font-weight: 700; color: var(--muted);
  padding: 4px 2px; list-style: none;
}
.atc-more > summary::-webkit-details-marker { display: none; }
.atc-more > summary::before { content: '▸ '; color: var(--blue); }
.atc-more[open] > summary::before { content: '▾ '; }
.atc-more > summary:hover { color: var(--blue); }

@media (max-width: 700px) {
  .atc-drop { padding: 24px 12px; }        /* มือถือกล่องใหญ่ขึ้น แตะง่าย */
  .atc-qual { gap: 7px; }
  .atc-q-box { padding: 10px; }
}

/* แผงเลือกอิโมจิที่เปิดจากแถวเครื่องมือ (🙂)
   ⚠️ .msg-tools กว้างแค่ ~30px → เกาะ right:0 ก็ยังล้นขอบจอ
      ใช้ transform ดึงกลับเข้ามา + ตรึงไม่ให้กว้างเกินจอ */
.msg-tools .react-pick {
  left: auto; right: 0;
  transform: translateX(0);
  max-width: calc(100vw - 24px);
  flex-wrap: nowrap;
}
@media (max-width: 480px) {
  .react-pick { padding: 4px 5px; gap: 0; }
  .react-pick button { font-size: 17px; padding: 2px 3px; }
}

/* ============================================================
   รีแอ็กชันเป็นสติกเกอร์พลูโต (Boss สั่ง 2026-08-27)
   เก็บใน DB เป็นโค้ด 'pluto:xxx' แล้วเรนเดอร์เป็น <img> ที่นี่
   ============================================================ */
.react-pluto { display: block; object-fit: contain; }
/* ชิปที่มีรูปพลูโต: กระชับกว่าอีโมจิตัวอักษร */
.react-chip .react-pluto { margin: -1px 0; }
.react-chip .react-emojis { display: inline-flex; align-items: center; }
/* แผงเลือก: ปุ่มใหญ่พอให้นิ้วกด และรูปไม่บีบ */
.react-pick button { display: inline-flex; align-items: center; justify-content: center; }
.react-pick .react-pluto { width: 28px; height: 28px; }
@media (max-width: 480px) {
  /* มือถือ: 8 ตัวต้องพอในจอ 360 — ย่อรูปแต่ยังกดติด */
  .react-pick .react-pluto { width: 24px; height: 24px; }
  .react-pick button { padding: 2px; }
}

/* ============================================================
   คอมเมนต์: ย่อขนาดลง (Boss ท้วง 2026-08-27 "คอมเมนต์ทำไมมันใหญ่แบบนั้น")
   ปัญหา: บับเบิล max-width:100% → พิมพ์ "lol" คำเดียวก็ลากเต็มความกว้างแถว
          + แถวปุ่ม 5 ตัว + ช่องตอบกลับกว้างเต็ม = กินพื้นที่กว่าโพสต์จริง
   แนวทาง: บับเบิลหุบพอดีข้อความ · ตัวอักษร/ระยะเล็กลง · ปุ่มซ่อนไว้แบบโพสต์
   ============================================================ */
/* บับเบิลหุบพอดีข้อความ ไม่ลากเต็มแถว */
.msg.nested .msg-bubble {
  width: fit-content;
  max-width: min(460px, 88%);
  padding: 5px 11px 6px;
  border-radius: 13px;
}
.msg.nested .msg-name { font-size: 12.5px; }
.msg.nested .msg-text { font-size: 13.5px; }
.msg.nested[data-depth="2"] .msg-text { font-size: 13px; }
/* อวตารคอมเมนต์เล็กลงอีกขั้น */
.msg.nested .avatar { width: 24px; height: 24px; font-size: 10px; }
.msg.nested[data-depth="2"] .avatar { width: 21px; height: 21px; font-size: 9px; }
/* แถวปุ่มใต้คอมเมนต์: ซ่อนไว้ โผล่เมื่อชี้/แตะ (เหมือนโพสต์) ลดความรก */
.msg.nested .msg-foot {
  opacity: 0; transition: opacity .15s;
  margin: 2px 0 0; padding-left: 10px; gap: 11px;
}
.msg.nested:hover .msg-foot,
.msg.nested.show-actions .msg-foot { opacity: 1; }
.msg.nested .msg-foot-btn { font-size: 11px; }
@media (hover: none) { .msg.nested .msg-foot { opacity: .5; } }
/* หัวข้อ/แถบเรียง/ช่องตอบกลับ — ย่อลงให้สมส่วนกับคอมเมนต์ */
.cmt-count { font-size: 11.5px; }
.cmt-sort { font-size: 12px; }
.cmt-sorts { gap: 12px; }
.cmt-bar { padding-bottom: 4px; }
.cmt-composer { gap: 7px; margin-top: 4px; }
.cmt-composer .avatar { width: 24px; height: 24px; font-size: 10px; }
/* ช่องตอบกลับ: ต้องกว้างพอเห็นข้อความ "ตอบกลับ <ชื่อ>..." ครบ
   (เคยตั้ง flex:0 1 auto แล้วหุบเหลือ 151px ตัดข้อความทิ้ง) */
.cmt-composer-ph {
  padding: 6px 13px; font-size: 12.5px;
  flex: 1 1 auto; max-width: min(430px, 100%); min-width: 200px;
}
.cmt-composer-send { font-size: 14px; }
/* กล่องครอบเยื้องน้อยลง — คอมเมนต์ไม่ถูกดันไปขวาไกล */
.cmt-group { margin-left: 38px; padding-left: 10px; }
.cmt-group .msg.nested[data-depth="2"] { margin-left: 28px; }

@media (max-width: 700px) {
  .msg.nested .msg-bubble { max-width: 84%; }
  .cmt-group { margin-left: 26px; padding-left: 7px; }
  .cmt-composer-ph { max-width: none; flex: 1; }
}

/* ============================================================
   คอมเมนต์: ยุบไว้ + อยู่ฝั่งเดียวกับโพสต์แม่ (Boss สั่ง 2026-08-27)
   "มันต้องอยู่ตรงกับข้อความที่เรากด" + "ควรแสดงเมื่อเรากดดู"
   ============================================================ */
/* ปุ่ม "N คอมเมนต์" = สวิตช์เปิด/ปิด */
.cmt-toggle {
  border: none; background: none; cursor: pointer; font-family: inherit;
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 700; color: var(--muted);
  padding: 3px 8px; border-radius: 999px;
}
.cmt-toggle:hover { color: var(--blue); background: var(--sunken); }
.cmt-caret { font-size: 13px; line-height: 1; }

/* โพสต์ของคนอื่น (ซ้าย) — คอมเมนต์ชิดซ้ายใต้โพสต์ */
.cmt-topline { justify-content: flex-start; padding: 2px 4px 0 38px; }
.cmt-bar { padding: 2px 4px 4px 38px; }

/* โพสต์ของเราเอง (ขวา) — คอมเมนต์ย้ายไปฝั่งขวาให้ตรงกับโพสต์ */
.cmt-topline.mine { justify-content: flex-end; padding: 2px 38px 0 4px; }
.cmt-bar.mine { justify-content: flex-end; padding: 2px 38px 4px 4px; }
.cmt-group.mine {
  margin-left: auto; margin-right: 38px; padding-left: 0; padding-right: 10px;
  border-left: none; border-right: 2px solid var(--border);
  width: fit-content; max-width: min(520px, 82%);
}
.cmt-group.mine .msg.nested { flex-direction: row-reverse; }
.cmt-group.mine .msg.nested .msg-body { align-items: flex-end; }
.cmt-group.mine .msg.nested .msg-head { flex-direction: row-reverse; }
.cmt-group.mine .msg.nested .msg-foot { justify-content: flex-end; padding-right: 10px; padding-left: 0; }
.cmt-group.mine .cmt-composer { flex-direction: row-reverse; }
.cmt-group.mine .msg.nested[data-depth="2"] { margin-left: 0; margin-right: 28px; }

@media (max-width: 700px) {
  .cmt-topline { padding-left: 26px; }
  .cmt-bar { padding-left: 26px; }
  .cmt-topline.mine { padding-right: 26px; padding-left: 4px; }
  .cmt-bar.mine { padding-right: 26px; padding-left: 4px; }
  .cmt-group.mine { margin-right: 26px; max-width: 88%; }
}

/* ============================================================
   ตอบกลับแบบ Messenger (Boss สั่ง 2026-08-27 "คอมเมนต์ดูยาก")
   เลิกระบบคอมเมนต์แบบเฟส → ทุกข้อความเรียงตามเวลาแถวเดียว
   ข้อความที่ตอบใครมีกล่องอ้างอิงเล็กๆ อยู่เหนือข้อความ
   ============================================================ */
/* กล่องอ้างอิง (โชว์เฉพาะตอนต้นเรื่องไม่อยู่ในจอ) — กลับเป็นแบบเดิมตามที่ Boss สั่ง 2026-08-27
   คอมเมนต์ที่อยู่ในกลุ่มแล้วไม่ต้องมีกล่องนี้ เพราะเห็นจากการจัดกลุ่มอยู่แล้ว */
.msg-reply {
  font-size: 12px; color: var(--muted); border-left: 3px solid var(--blue); padding: 2px 8px;
  margin-bottom: 2px; background: var(--blue-light); border-radius: 4px; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}


/* ============================================================
   กล่องแก้ไขข้อความ / เติมคำอธิบายรูป (Boss สั่ง 2026-08-27) · mobile first
   เดิมใช้ prompt() เบราว์เซอร์ — บรรทัดเดียว ขึ้นบรรทัดใหม่ไม่ได้ ไม่เห็นรูป
   ============================================================ */
.edit-wrap { display: flex; flex-direction: column; gap: 10px; }
/* พรีวิวสื่อ ให้รู้ว่ากำลังแก้ใบไหน */
.edit-pv {
  max-width: 100%; max-height: 180px; border-radius: 10px; display: block;
  margin: 0 auto; object-fit: contain;
}
.edit-pv-row { display: flex; gap: 5px; align-items: center; justify-content: center; flex-wrap: wrap; }
.edit-pv.sm { width: 74px; height: 74px; object-fit: cover; margin: 0; }
.edit-pv-more { font-size: 12.5px; font-weight: 700; color: var(--muted); }
.edit-pv-file {
  display: flex; align-items: center; gap: 8px; padding: 9px 12px;
  background: var(--sunken); border-radius: 10px; font-size: 13px; color: var(--text);
}
/* ช่องพิมพ์หลายบรรทัด */
.edit-input {
  width: 100%; margin: 0; resize: vertical; min-height: 84px;
  padding: 11px 13px; border-radius: 11px; font-family: inherit;
  font-size: 14.5px; line-height: 1.5;
  border: 1px solid var(--border); background: var(--sunken); color: var(--text);
}
/* ⚠️ 2026-09-23 ธีมสีบางชุด (data-accent) ไม่ได้ตั้ง --sunken → ตกไปใช้ค่าโหมดสว่าง #F4F6F9
   แต่ --text เป็นสีอ่อนของธีมมืด = ช่องขาว ตัวหนังสือขาว อ่านไม่ออก
   (เดิมไม่มีใครเห็นเพราะเปิดมาโฟกัสทันที :focus ใช้ --card · ตอนนี้มือถือไม่โฟกัสเองแล้ว)
   ⇒ ใช้ --card ซึ่งทุกธีมตั้งไว้ครบ */
html[data-accent] .edit-input, html[data-theme="dark"] .edit-input { background: var(--card); }
.edit-input:focus { border-color: var(--blue); background: var(--card); outline: none; }
.edit-hint { font-size: 11.5px; }
@media (max-width: 700px) {
  .edit-input { font-size: 15px; min-height: 96px; }   /* มือถือ: 16px กัน iOS ซูมเอง */
  .edit-pv { max-height: 150px; }
}

/* ไฮไลต์ตอนกดกล่องอ้างอิงแล้วเด้งไปหาต้นฉบับ (jumpToMsg) */
.msg-flash { animation: msgFlash 1.6s ease-out; border-radius: 10px; }
@keyframes msgFlash {
  0%, 40% { background: var(--blue-light); }
  100%    { background: transparent; }
}

/* ============================================================
   ตอบกลับในหน้าต่าง DM ลอย — แบบแอป Messenger (Boss สั่ง 2026-08-27)
   ป้าย "คุณได้ตอบกลับ X" + ข้อความเดิมในกล่องเทา เหนือบับเบิลจริง
   ============================================================ */
.dmw-re { display: flex; flex-direction: column; gap: 2px; margin-bottom: 2px; }
.dmw-re-lb {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 10px; color: var(--muted); font-weight: 600;
}
.dmw-re-box {
  font-size: 12px; color: var(--muted);
  background: var(--sunken); border-radius: 13px; padding: 5px 10px;
  cursor: pointer; opacity: .8;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.dmw-re-box:hover { opacity: 1; }
/* ของเราเอง: ป้าย+กล่องชิดขวา */
.dmw-msg.me .dmw-re { align-items: flex-end; }

/* แถบ "กำลังตอบกลับ ..." เหนือช่องพิมพ์ (แบบ Messenger) */
.dmw-replybar {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; border-top: 1px solid var(--border);
  background: var(--sunken);
}
.dmw-replybar.hidden { display: none; }
.dmrb-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; border-left: 3px solid var(--blue); padding-left: 8px; }
.dmrb-lb { font-size: 10.5px; font-weight: 700; color: var(--blue); }
.dmrb-text { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dmrb-x {
  border: none; background: none; cursor: pointer; color: var(--muted);
  font-size: 15px; line-height: 1; padding: 3px 5px; border-radius: 50%; flex: none;
}
.dmrb-x:hover { background: var(--card); color: var(--red); }

/* ปุ่มเปลี่ยนภาษาในแผ่นเมนูมือถือ (Boss ถาม 2026-08-27) */
.x10m-langrow { display: flex; flex-direction: column; gap: 7px; padding: 10px 4px 4px; }
.x10m-langlb { font-size: 13px; font-weight: 700; color: var(--muted); }
.x10m-langrow .lang-row { display: flex; flex-wrap: wrap; gap: 6px; }

/* ============================================================
   4 ฟีเจอร์ใหม่ (Boss 2026-08-28): ค้นหา · คลังรูป · ผู้อ่าน · สถานะแจ้งเตือน
   ============================================================ */
/* ---- ค้นหาข้อความ ---- */
.sr-filters { margin: 6px 0 10px; }
.sr-filters > summary { cursor: pointer; color: var(--muted); font-size: 13px; padding: 6px 2px; }
.sr-dates { display: flex; gap: 8px; }
.sr-dates .ra-label { flex: 1; min-width: 0; }
/* กฎรวม input{width:100%} ดันช่องติ๊กเต็มบรรทัด ข้อความเลยหลุดไปคนละฝั่ง — ล็อกขนาดกล่องติ๊ก */
.sr-chk { display: flex; align-items: center; gap: 8px; font-size: 14px; margin: 8px 0 4px; }
.sr-chk input[type=checkbox] { width: 18px; height: 18px; flex: 0 0 auto; margin: 0; }
.sr-n { font-size: 12px; margin: 8px 0 6px; }
.sr-item {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--sunken); border: 1px solid var(--border); border-radius: 10px;
  padding: 9px 11px; margin-bottom: 7px; color: var(--text);
}
.sr-item:active { background: var(--blue-light); }
.sr-head { display: flex; gap: 8px; align-items: baseline; font-size: 12px; margin-bottom: 3px; flex-wrap: wrap; }
.sr-head .sr-ch { color: var(--blue); }
.sr-head .sr-at { color: var(--muted); margin-left: auto; }
.sr-body { font-size: 13.5px; line-height: 1.45; word-break: break-word; }

/* ---- คลังรูปของห้อง ---- */
.gal-day { font-size: 12px; color: var(--muted); margin: 12px 2px 6px; font-weight: 600; }
.gal-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.gal-cell {
  position: relative; padding: 0; border: 0; cursor: pointer; background: var(--sunken);
  border-radius: 8px; overflow: hidden; aspect-ratio: 1;
}
.gal-cell img, .gal-cell video { width: 100%; height: 100%; object-fit: cover; display: block; }
.gal-vid {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.28); color: #fff; font-size: 20px;
}
@media (min-width: 640px) { .gal-grid { grid-template-columns: repeat(4, 1fr); } }

/* ---- ใครอ่านแล้ว ---- */
.rd-n { font-size: 12px; margin-bottom: 8px; }
.rd-list { display: flex; flex-direction: column; gap: 2px; max-height: 52vh; overflow-y: auto; }
.rd-row { display: flex; align-items: center; gap: 9px; padding: 7px 4px; font-size: 14px; }

/* ---- สถานะแจ้งเตือน (แผงแอดมิน) ---- */
.pn-sum { display: flex; gap: 10px; margin: 6px 0 10px; }
.pn-stat {
  flex: 1; text-align: center; padding: 10px 6px; border-radius: 10px;
  background: var(--sunken); border: 1px solid var(--border);
}
.pn-stat b { display: block; font-size: 22px; line-height: 1.15; }
.pn-stat span { font-size: 11px; color: var(--muted); }
.pn-stat .pn-on { color: #16A34A; }
.pn-stat .pn-off { color: #EF4444; }
.pn-bar { height: 8px; border-radius: 4px; background: var(--border); overflow: hidden; margin-bottom: 8px; }
.pn-bar > span { display: block; height: 100%; background: #16A34A; }
/* แถบชวนเปิดแจ้งเตือนบนคอม (มือถือใช้ .x10m-pushnag ของ mobile.js) */
.pushbar {
  position: fixed; right: 18px; bottom: 18px; z-index: 350; max-width: 380px;
  display: flex; align-items: center; gap: 11px; padding: 12px 14px;
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: var(--shadow-modal);
}
.pushbar-ic { font-size: 22px; line-height: 1; }
.pushbar-tx { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pushbar-tx b { font-size: 14px; }
.pushbar-tx span { font-size: 12px; color: var(--muted); }

/* ===== แจ้งเตือน: ตั้งค่า + จัดการรายห้อง (Boss 2026-08-28) ===== */
.pf-row-col { flex-direction: column; align-items: stretch; gap: 8px; }
.ntf-tones { display: flex; flex-wrap: wrap; gap: 6px; }
.ntf-tone {
  padding: 7px 13px; border-radius: 999px; cursor: pointer; font-size: 12.5px;
  border: 1px solid var(--border, #E2E8F0); background: var(--card, #fff); color: var(--text);
}
.ntf-tone.on { background: var(--blue, #0F4C81); color: #fff; border-color: transparent; }
.ntf-vol { width: 170px; margin: 0; }
.ntf-q { margin: 0; }
.ntf-rooms { max-height: 320px; overflow-y: auto; border: 1px solid var(--border, #E2E8F0); border-radius: 10px; }
.ntf-rooms-sum { padding: 8px 12px; border-bottom: 1px solid var(--border, #E2E8F0); }
/* แถวห้อง: ชื่อซ้าย สวิตช์ขวา — ติ๊ก = เปิดแจ้งเตือน */
.ntf-room {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px; cursor: pointer;
  border-top: 1px solid var(--border, #E2E8F0);
}
.ntf-room:first-of-type { border-top: 0; }
.ntf-room:active { background: var(--sunken); }
.ntf-room-n { flex: 1; min-width: 0; font-size: 13.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* แถวแจ้งเตือนในเมนู ⋯ ของห้อง (ไอคอนสลับ 🔔/🔕 ในตัว) */
#btn-ntf-room .pm-icon { font-size: 15px; }
@media (max-width: 560px) {
  .ntf-vol { width: 100%; }
  .ntf-rooms { max-height: 260px; }
}

/* ป้าย "มีข้อความใหม่" — ลอยเหนือช่องพิมพ์ ตอนอ่านค้างอยู่ด้านบน (Boss 2026-08-28) */
.newmsg-pill {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: 84px; z-index: 30; cursor: pointer;
  display: flex; align-items: center; gap: 5px;
  padding: 8px 15px; border-radius: 999px; border: 0;
  background: var(--blue, #0F4C81); color: #fff;
  font-size: 12.5px; font-weight: 600;
  box-shadow: 0 3px 12px rgba(0,0,0,.28);
}
.newmsg-pill.hidden { display: none; }
.newmsg-pill:active { filter: brightness(.92); }
@media (max-width: 560px) { .newmsg-pill { bottom: 92px; } }

/* ============================================================
   สร้างประชุม (prep meeting) — เช็กลิสต์เตรียมงาน
   มือถือมาก่อน (360x780): แถวเป็นบล็อกซ้อน · จอ ≥700px ค่อยเป็นแถวเดียว
   ============================================================ */
.prep-card { cursor: pointer; }
.prep-bars { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.prep-prog { flex: 1; min-width: 0; }
.prep-lab { display: flex; justify-content: space-between; font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.prep-bar { height: 8px; border-radius: 99px; background: var(--border); overflow: hidden; }
.prep-bar > i { display: block; height: 100%; background: var(--blue); border-radius: 99px; transition: width .3s; }
.prep-bar.gold > i { background: var(--green); }

.prep-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.prep-grid { display: grid; grid-template-columns: 1fr; gap: 10px; margin-top: 4px; }
.prep-grid label { display: block; }
.prep-grid label > span { display: block; font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.prep-grid input { width: 100%; }

.prep-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.prep-chip { display: inline-flex; align-items: center; gap: 6px; background: var(--blue-light);
  border-radius: 99px; padding: 4px 6px 4px 11px; font-size: 13px; }
.prep-chip small { color: var(--muted); font-size: 11px; }
.prep-chip button { background: rgba(148,163,184,.3); border: none; border-radius: 50%; width: 20px; height: 20px;
  color: inherit; font-size: 13px; line-height: 1; display: grid; place-items: center; cursor: pointer; }

.prep-switch { display: flex; gap: 8px; margin-bottom: 12px; }
.prep-switch button { flex: 1; border: 1px solid var(--border); background: transparent;
  border-radius: 10px; padding: 10px 12px; font: inherit; font-size: 13px; color: var(--muted); cursor: pointer; }
.prep-switch button.active { background: var(--blue); border-color: var(--blue); color: var(--on-brand); font-weight: 500; }

.prep-cat-head { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.prep-cat-idx { width: 28px; height: 28px; border-radius: 8px; background: var(--blue); color: var(--on-brand);
  display: grid; place-items: center; font-weight: 600; font-size: 13px; flex-shrink: 0; }
.prep-chev { color: var(--muted); font-size: 12px; }
.prep-items { margin-top: 10px; }

/* แถวหัวข้อ: มือถือซ้อนเป็นบล็อก — ติ๊ก 2 ช่องกว้าง 44px แตะง่าย */
.prep-item { padding: 10px 0; border-top: 1px solid var(--border); }
.prep-item.done { background: rgba(47,158,111,.08); border-radius: 8px; padding: 10px 8px; }
.prep-detail { font-size: 14px; }
.prep-meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 5px; }
.prep-team { background: rgba(148,163,184,.18); border-radius: 6px; padding: 2px 7px; font-size: 11px; color: var(--muted); }
.prep-note-btn { background: none; border: none; padding: 4px 2px; font: inherit; font-size: 12px;
  color: var(--muted); cursor: pointer; min-height: 28px; }
.prep-note-btn.has { color: var(--blue); }
.prep-note { margin-top: 6px; font-size: 12.5px; white-space: pre-wrap;
  border-left: 3px solid var(--blue); padding: 5px 9px; border-radius: 0 6px 6px 0;
  background: rgba(148,163,184,.12); }
.prep-ticks { display: flex; gap: 14px; margin-top: 8px; }
.prep-tick { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px;
  color: var(--muted); min-height: 44px; cursor: pointer; }
.prep-tick input { width: 22px; height: 22px; }
.prep-who { width: 100%; margin-top: 6px; font-size: 13px; }
.prep-who.unset { color: var(--muted); }
.prep-add { margin-top: 10px; }

.prep-kind { cursor: pointer; align-items: flex-start; }
.prep-kind-ic { font-size: 26px; width: 38px; text-align: center; flex-shrink: 0; }
.prep-userpick { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 8px; max-height: 46vh; overflow-y: auto; }
.prep-uchip { display: inline-flex; align-items: center; gap: 7px; padding: 8px 12px; font-size: 13px;
  border: 1px solid var(--border); border-radius: 99px; cursor: pointer; min-height: 40px; }
.prep-uchip.on { border-color: var(--blue); background: rgba(59,130,246,.12); }
.prep-uchip input { width: 17px; height: 17px; }

@media (min-width: 700px) {
  .prep-bars { flex-direction: row; gap: 18px; }
  .prep-grid { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
  .prep-item { display: grid; grid-template-columns: 1fr 170px 190px; gap: 12px; align-items: start; }
  .prep-ticks { margin-top: 0; }
  .prep-tick { min-height: 32px; }
  .prep-who { margin-top: 0; }
  .prep-switch button { flex: 0 0 auto; }
}

/* ===== ตั้งค่าเสียงรายห้อง บนหน้า "การแจ้งเตือน" (Boss 2026-08-28) ===== */
.ntfmgr {
  margin: 0 0 10px; border: 1px solid var(--border, #E2E8F0);
  border-radius: 12px; background: var(--card, #fff); overflow: hidden;
}
.ntfmgr > summary {
  display: flex; align-items: center; gap: 9px; cursor: pointer;
  padding: 11px 14px; font-weight: 600; font-size: 13.5px; list-style: none;
}
.ntfmgr > summary::-webkit-details-marker { display: none; }
.ntfmgr > summary::after { content: '▾'; margin-left: auto; opacity: .5; font-size: 12px; }
.ntfmgr[open] > summary::after { content: '▴'; }
.ntfmgr > summary:active { background: var(--sunken); }
.ntfmgr-ic { font-size: 15px; }
.ntfmgr-sum { font-size: 11.5px; font-weight: 400; }
.ntfmgr-body { padding: 0 12px 12px; border-top: 1px solid var(--border, #E2E8F0); }
.ntfmgr-top { display: flex; gap: 6px; align-items: center; padding: 10px 0; flex-wrap: wrap; }
.ntfmgr-top .ntf-q { flex: 1; min-width: 140px; }
.ntfmgr .ntf-rooms { max-height: 300px; }
@media (max-width: 560px) {
  .ntfmgr-top .ntf-q { flex: 1 0 100%; }
  .ntfmgr .ntf-rooms { max-height: 260px; }
}
.prep-info > summary { cursor: pointer; font-size: 13px; color: var(--muted); padding: 6px 0; }
.prep-info[open] > summary { margin-bottom: 4px; }
/* หัวหน้า meetings บนมือถือ: ปุ่มไม่บีบหัวข้อให้ตกบรรทัด */
.mt-new-btn { flex: 0 0 auto; white-space: nowrap; }
@media (max-width: 420px) { #page-meetings .page-head h2 { font-size: 15px; } }

/* ประกาศหลายภาษา: แท็บเลือกภาษาในฟอร์มแอดมิน (Boss 2026-08-28) */
.an-langs { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 8px; }
.an-lang {
  padding: 6px 12px; border-radius: 999px; cursor: pointer; font-size: 12.5px;
  border: 1px solid var(--border, #E2E8F0); background: var(--card, #fff); color: var(--text);
}
.an-lang.on { background: var(--blue, #0F4C81); color: #fff; border-color: transparent; }
.an-hint { margin-left: auto; }
.an-pane.hidden { display: none; }

/* สรุปเช้า: ต้องเห็นหลายบรรทัด (bell-body เดิมตัด 2 บรรทัด) — Boss 2026-08-28 */
.bell-body.bell-digest {
  white-space: pre-wrap; -webkit-line-clamp: unset; display: block;
  max-height: 40vh; overflow-y: auto; line-height: 1.6; opacity: .95;
}

/* ป้าย "ยังไม่มีใครอ่าน" ท้ายเวลาข้อความของตัวเอง (Boss 2026-08-28) */
.unread-tag {
  font-size: 10.5px; padding: 1px 7px; border-radius: 999px; cursor: pointer;
  margin-left: 6px; white-space: nowrap; vertical-align: middle;
  background: var(--sunken); color: var(--muted); border: 1px solid var(--border, #E2E8F0);
}
.unread-tag:hover { border-color: var(--blue, #0F4C81); color: var(--blue, #0F4C81); }
/* ยังไม่มีใครอ่านเลย = เตือนด้วยสีส้ม (ไม่ใช้แดง จะดูเหมือน error) */
.unread-tag.none { background: var(--amber-soft); color: #B45309; border-color: transparent; font-weight: 600; }
.unread-tag.all { opacity: .55; }

/* สรุปเช้าในหน้า "การแจ้งเตือน" — ต้องเห็นครบ (.ntf-body เดิมตัด 2 บรรทัด เหมือน .bell-body)
   ⚠️ มี .ntf-body 2 ที่ในไฟล์ (2510 + 3099) ตัวหลังชนะ → ต้องประกาศท้ายสุดถึงจะทับได้ */
.ntf-body.ntf-digest {
  white-space: pre-wrap; -webkit-line-clamp: unset; display: block;
  overflow: visible; text-overflow: clip; line-height: 1.65;
  color: var(--text); opacity: .92; margin-top: 4px;
}

/* ============================================================
   แถบแท็บใต้หัวห้อง แบบ Slack (Boss สั่ง 2026-08-29 · เฟส 1)
   ดีไซน์ mobile-first 360x780 — แท็บเลื่อนข้างได้ ไม่ตัดคำ
   ============================================================ */
.room-tabs {
  display: flex; align-items: center; gap: 2px; position: relative;
  padding: 0 12px; border-bottom: 1px solid var(--border, #E2E8F0);
  background: var(--card, #fff);
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.room-tabs::-webkit-scrollbar { display: none; }
.rt-tab {
  display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
  border: none; background: none; cursor: pointer; font-family: inherit;
  font-size: 13px; font-weight: 600; color: var(--muted, #64748B);
  padding: 9px 10px; border-bottom: 2px solid transparent; white-space: nowrap;
}
.rt-tab:hover { color: var(--text, #1B2A3A); }
.rt-tab.rt-on { color: var(--text, #1B2A3A); border-bottom-color: var(--blue, #0F4C81); }
.rt-ic { display: inline-flex; width: 15px; height: 15px; opacity: .8; }
.rt-tab.rt-on .rt-ic { opacity: 1; }
.rt-add {
  /* ปักไว้ขวาสุดเสมอ — แท็บเยอะแล้วเลื่อนข้าง ปุ่ม + ต้องไม่หลุดขอบจนกดไม่ได้
     (เจอตอนเทส 2026-08-29: มี 4 แท็บบนจอ 360 ปุ่มก็หายแล้ว) */
  position: sticky; right: 0; z-index: 2;
  flex: 0 0 auto; border: none; cursor: pointer;
  font-family: inherit; font-size: 17px; line-height: 1;
  color: var(--muted, #64748B); padding: 6px 9px; border-radius: 7px; margin-left: 2px;
  background: var(--card, #fff);
  box-shadow: -8px 0 8px -6px rgba(0,0,0,.16);   /* เงาบอกว่ายังมีแท็บซ่อนอยู่ทางซ้าย */
}
.rt-add:hover { background: var(--blue-light, #E6EEF7); color: var(--blue, #0F4C81); }
.rt-menu {
  /* อยู่นอก .room-tabs (โดน overflow-x clip) → อ้างอิง .chat-room
     top วัดจากของจริงเหมือน .datejump */
  position: absolute; left: 12px; top: var(--rt-menu-top, 106px);
  min-width: 190px; z-index: 60;
}
@media (max-width: 860px) { .rt-menu { left: 8px; } }
.rt-menu-head {
  font-size: 11.5px; font-weight: 700; color: var(--muted, #64748B); padding: 7px 10px 6px;
}
.rt-menu button[disabled] { opacity: .55; cursor: default; }
.rt-menu button[disabled]:hover { background: none; }
.rt-soon {
  margin-left: auto; font-size: 10.5px; font-weight: 700;
  color: var(--muted, #64748B); background: var(--blue-light, #E6EEF7);
  padding: 1px 7px; border-radius: 999px;
}
/* ปุ่ม "วันนี้" เดิมลอย absolute ด้วย top คงที่ (66/58px) = เดาความสูงหัวห้อง
   ตอนนี้มีแถบแท็บมาคั่น และหัวห้องสูงไม่เท่ากันในแต่ละธีม (v3 สูงกว่า)
   → เลิกเดา ใช้ค่าที่ JS วัดจากของจริงใส่ไว้ใน --rt-dj-top แทน
   (ค่า fallback = ของเดิม + สูงแท็บ กันช่วงก่อน JS ทำงาน) */
.datejump { top: var(--rt-dj-top, 104px); }
@media (max-width: 860px) {
  .datejump { top: var(--rt-dj-top, 94px); }
  .rt-tab { font-size: 12.5px; padding: 8px 9px; }
  .room-tabs { padding: 0 8px; }
}

/* ---- ฟอร์มเพิ่ม/แก้แท็บลิงก์ (Boss 2026-08-29 · เฟส 2) ---- */
.rt-form { display: flex; flex-direction: column; gap: 6px; }
.rt-lb { font-size: 12.5px; font-weight: 700; color: var(--muted, #64748B); margin-top: 4px; }
.rt-inp { width: 100%; box-sizing: border-box; }
.rt-form-act { display: flex; gap: 8px; justify-content: flex-end; margin-top: 12px; }
.rt-form-act .btn { flex: 0 0 auto; }
/* แท็บที่คนเพิ่มเอง — หน้าตาเหมือนแท็บติดเครื่อง แต่มี title บอกปลายทาง */
.rt-tab.rt-custom { max-width: 160px; }
.rt-tab.rt-custom > span:last-child {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ============================================================
   Thread แบบ Slack (Boss 2026-08-29)
   มือถือมาก่อน: เต็มจอสไลด์ขึ้น · เดสก์ท็อป (≥861px): แผงข้างขวา
   ============================================================ */
/* ป้าย "n replies" ใต้ข้อความแม่ในห้องหลัก */
.thr-bar {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin: 3px 0 6px 46px; padding: 5px 10px 5px 7px;
  border: 1px solid transparent; border-radius: 16px;
  cursor: pointer; width: fit-content; max-width: calc(100% - 46px);
  transition: background .12s, border-color .12s;
}
.thr-bar:hover { background: var(--card); border-color: var(--border); }
.thr-bar.mine { margin-left: auto; margin-right: 46px; }
.thr-faces { display: flex; gap: -4px; }
.thr-faces .avatar {
  width: 22px; height: 22px; font-size: 9px; flex: none;
  border: 1.5px solid var(--bg); border-radius: 5px; margin-right: -5px;
}
/* คนตอบเกิน 5 คน โชว์ +n ไม่ให้แถบยาวเกิน (Boss สั่ง 2026-08-30) */
.thr-more { font-size: 11.5px; font-weight: 700; color: var(--muted); margin-left: 2px; }
.thr-count { font-size: 13px; font-weight: 700; color: var(--blue); }
.thr-last { font-size: 11.5px; color: var(--muted); }
.thr-go { color: var(--muted); font-size: 15px; margin-left: 2px; }

/* ฉากหลังทึบ */
/* ฉากหลัง: จางๆ พอให้รู้ว่าแผงเปิดอยู่ แต่ "ไม่กินสกรอลล์" ของห้องหลัก
   pointer-events:none = แตะ/เลื่อนทะลุไปโดนห้องหลักได้ตามปกติ
   (ปิดแผงใช้ปุ่ม ✕ หรือกด back แทนการแตะฉากหลัง) */
.thr-bd {
  position: fixed; inset: 0; background: rgba(0,0,0,.18);
  z-index: 78; pointer-events: none;
}
.thr-bd.hidden { display: none; }

/* แผง — มือถือ: เต็มจอ (Boss สั่ง 2026-09-18 "ให้เห็นหน้าจอเต็มๆ")
   ⚠️ เดิมเป็นแผ่นสูง 68dvh เห็นห้องหลักด้านบน (Boss 2026-08-29 ขอให้เลื่อนหน้าหลักได้)
      แต่พอเปิดแป้นพิมพ์ตอบคอมเมนต์ พื้นที่อ่านเธรดเหลือนิดเดียว อ่านไม่ออก
      → กลับมาเต็มจอ แต่คราวนี้มีปุ่ม ‹ ย้อนกลับในหัวแผง + back ของเครื่องปิดได้จริง
   ⚠️ ห้ามกลับไปใช้ height:68dvh เฉย ๆ — ดูกฎ body.kb-open ข้างล่างที่ผูกกับ --x10m-vv */
.thrpanel {
  position: fixed; left: 0; right: 0; bottom: 0; top: 0;
  height: auto;
  background: var(--bg); z-index: 79;
  border-radius: 0;                 /* เต็มจอแล้ว ไม่ต้องมีมุมโค้งแบบแผ่นเด้ง */
  box-shadow: 0 -4px 24px rgba(0,0,0,.18);
  display: flex; flex-direction: column;
  transform: translateY(100%); transition: transform .22s ease;
}
.thrpanel.open { transform: translateY(0); }
.thrpanel.hidden { display: none; }

.thr-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 12px 14px;
  border-bottom: 1px solid var(--border); background: var(--card);
  padding-top: max(12px, env(safe-area-inset-top));
}
.thr-head h3 { font-size: 17px; font-weight: 800; color: var(--text); }
/* หัวแผงเธรดบีบได้ — ไม่งั้นปุ่ม –/✕ (flex:none) ชนะ แล้วชื่อกลุ่มโดนตัดหาย
   (Boss แจ้ง 2026-09-06: "ควรต้องเห็นชื่อกลุ่มด้วย บางทีไม่รู้พิมพ์ผิดกลุ่มไหม")
   ⚠️ ต้องมี min-width:0 ทั้งพ่อและลูก ไม่งั้น ellipsis ไม่ทำงานใน flex */
.thr-head-tt { min-width: 0; flex: 1 1 auto; }
.thr-head h3 { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ชื่อกลุ่ม = ชิปเด่น ไม่ใช่ตัวจางใต้หัวข้อ (มือถือ 360px มองข้ามง่ายมาก) */
.thr-ch {
  display: inline-block; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 700; color: var(--accent, #2563EB);
  background: var(--accent-soft, rgba(37,99,235,.10));
  border-radius: 999px; padding: 1px 8px; font-size: 12px;
}
/* ============================================================
   ย่อ/หุบเธรด + เปิดค้างหลายอัน (Boss สั่ง 2026-08-30 — แบบ FB)
   รางอยู่ "ซ้ายของหน้าต่าง DM" จะได้ไม่ทับกัน (.dm-dock อยู่ right:14px)
   ============================================================ */
.thr-head-btns { display: flex; align-items: center; gap: 2px; flex: none; }
/* รางการ์ดเธรดที่ย่อไว้ (มุมล่างขวา) ถูกยกเลิก (Boss สั่ง 2026-09-07)
   ซ้ำซ้อนกับแท็บห้อง + แบ่งจอ 3 ช่อง · กฎนี้เป็นตาข่ายกันคนที่ app.js เก่ายังค้างในแคช */
.thr-dock { display: none !important; }

.thr-dock {
  position: fixed; right: 14px; bottom: 0; z-index: 299;
  display: flex; align-items: flex-end; gap: 8px; pointer-events: none;
  max-width: calc(100vw - 28px); flex-wrap: wrap-reverse; justify-content: flex-end;
}
.thr-dock.hidden { display: none; }
.thr-dock > * { pointer-events: auto; }
/* มีหน้าต่าง DM เปิดอยู่ = ขยับรางเธรดขึ้นไปไม่ให้ทับกัน (DM สูง ~46px ตอนย่อ) */
.dm-dock:not(:empty) ~ .thr-dock { bottom: 52px; }
/* การ์ดเธรดที่ย่อไว้ — อ่านออกใน 1 วินาที: ใครเริ่ม / เรื่องอะไร / กี่คำตอบ
   ออกแบบให้เหมือน "การ์ดข้อความที่พับเก็บไว้" ไม่ใช่แค่แถบสีทึบ
   แถบสีซ้าย = ตัวบอกสถานะ (ปกติ = สีแบรนด์ · มีคำตอบใหม่ = เหลืองอำพัน) */
/* สลับมุมมองรายการห้อง (Boss สั่ง 2026-08-30) — ปุ่มคู่เล็กๆ ที่หัวข้อ "กลุ่ม"
   ตั้งใจให้เงียบ: เป็นตัวควบคุมรอง ไม่ใช่พระเอกของแถบข้าง */
.side-section-row { display: flex; align-items: center; gap: 8px; }
.side-section-row .grow { flex: 1; min-width: 0; }
.chv-seg {
  display: inline-flex; flex: none; gap: 1px; padding: 2px;
  background: var(--v3-side-hover, rgba(255,255,255,.08));
  border-radius: 8px;
}
.chv-btn {
  border: 0; background: none; cursor: pointer;
  color: var(--v3-side-nav, #9FB6CC); font-size: 10.5px; font-weight: 700;
  padding: 3px 7px; border-radius: 6px; white-space: nowrap;
  transition: background .12s, color .12s;
}
.chv-btn:hover { color: var(--v3-side-strong, #fff); }
.chv-btn.on {
  background: var(--v3-side-active, rgba(255,255,255,.16));
  color: var(--v3-side-strong, #fff);
}
.chv-btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }

.thrm {
  position: relative; display: flex; align-items: center; gap: 10px;
  cursor: pointer; overflow: hidden;
  background: var(--card); color: var(--text);
  border: 1px solid var(--border); border-bottom: none;
  border-radius: 12px 12px 0 0; padding: 9px 11px 9px 13px;
  width: 268px; max-width: 268px;
  box-shadow: 0 -6px 22px rgba(0,0,0,.16);
  transition: transform .14s ease, box-shadow .14s ease, background .14s ease;
}
/* แถบสถานะซ้าย — องค์ประกอบเดียวที่ "จัดจ้าน" ที่เหลือเงียบหมด */
.thrm::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--blue); transition: background .18s ease;
}
.thrm:hover { transform: translateY(-2px); box-shadow: 0 -10px 26px rgba(0,0,0,.22); }
.thrm:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.thrm.fresh::before { background: #E8A33D; }

/* รูปคนเริ่มเธรด + จำนวนคำตอบซ้อนมุม */
.thrm-face { position: relative; flex: none; line-height: 0; }
.thrm-face .avatar { width: 30px; height: 30px; font-size: 11px; border-radius: 9px; }
.thrm-n {
  position: absolute; right: -5px; bottom: -4px; min-width: 17px; height: 17px;
  padding: 0 4px; border-radius: 9px;
  background: var(--blue); color: #fff;
  font-size: 10.5px; font-weight: 800; line-height: 17px; text-align: center;
  border: 2px solid var(--card);
}
.thrm.fresh .thrm-n { background: #E8A33D; color: #1B1204; }

.thrm-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.thrm-top { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.thrm-who {
  font-size: 12.5px; font-weight: 800; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.thrm-ch {
  flex: none; font-size: 10.5px; color: var(--muted); font-weight: 600;
  max-width: 92px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.thrm-tx {
  font-size: 12px; color: var(--muted); line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.thrm-x {
  flex: none; border: 0; background: none; color: var(--muted); opacity: .55;
  cursor: pointer; font-size: 13px; padding: 4px 5px; border-radius: 7px; line-height: 1;
  transition: opacity .12s, background .12s;
}
.thrm:hover .thrm-x { opacity: .9; }
.thrm-x:hover { opacity: 1; background: var(--sunken, rgba(0,0,0,.08)); color: var(--text); }
@media (prefers-reduced-motion: reduce) {
  .thrm, .thrm-x { transition: none; }
  .thrm:hover { transform: none; }
}
/* มือถือ: จอแคบมาก — โชว์แถบล่าสุดแถบเดียว (ที่เหลือซ่อนไว้ กดปิดทีละอันได้)
   ⚠️ ต้องยกขึ้นเหนือแถบแท็บล่าง (.x10m-tabbar) ไม่งั้นทับปุ่ม ห้อง/DM/งาน จนกดไม่ได้ */
@media (max-width: 620px) {
  .thr-dock {
    right: 8px; left: 8px; max-width: none; flex-wrap: nowrap;
    bottom: calc(var(--x10m-tabbar-h, 56px) + var(--x10m-safe-b, 0px) + 4px);
  }
  .thrm { max-width: none; flex: 1 1 100%; border-radius: 10px; }
  /* เกิน 1 แถบ = ซ่อนตัวเก่า ไม่ให้กินจอ (คลี่/ปิดตัวบนสุดก่อนถึงจะเห็นตัวถัดไป) */
  .thr-dock > .thrm:not(:last-child) { display: none; }
  /* ในห้องแชทแท็บล่างถูกซ่อน → รางกลับลงไปติดขอบล่างได้ */
  body.x10m.in-room .thr-dock { bottom: 6px; }
}
.thr-ch { margin-top: 1px; }


.thr-x {
  border: none; background: none; color: var(--muted); cursor: pointer;
  font-size: 19px; padding: 6px 9px; border-radius: 8px; flex: none;
  min-width: 40px; min-height: 40px;
}
.thr-x:hover { background: var(--bg); color: var(--text); }

/* ‹ ย้อนกลับ — มือถือเท่านั้น (แผงเต็มจอ) · คอมเป็นแผงข้างยังเห็นห้องหลักอยู่ ใช้ ✕ พอ
   ⚠️ ขนาด 44px ตามนิ้วจริง ไม่ใช่ 40px แบบ ✕ เพราะเป็นปุ่มออกหลักบน iPhone */
.thr-back {
  border: none; background: none; color: var(--text); cursor: pointer;
  font-size: 30px; line-height: 1; padding: 0 10px 3px 4px; border-radius: 8px;
  flex: none; min-width: 44px; min-height: 44px; margin-left: -4px;
}
.thr-back:active { background: var(--bg); }

.thr-body { flex: 1; overflow-y: auto; padding: 8px 0 12px; }
.thr-parent { border-bottom: 1px solid var(--border); padding-bottom: 6px; }
/* ต้นเรื่องในแผงชิดซ้ายเสมอ — แผงนี้ไม่ใช่ไทม์ไลน์ ไม่ต้องแยกซ้าย/ขวา */
.thr-body .msg.mine { flex-direction: row; }
.thr-body .msg.nested { margin-left: 0; }
.thr-body .thr-bar { display: none; }   /* ในแผงไม่ต้องมีป้ายซ้อนอีก */
.thr-sep {
  font-size: 12.5px; color: var(--muted); font-weight: 700;
  padding: 9px 16px 5px; border-bottom: 1px solid var(--border); margin-bottom: 4px;
}

.thr-composer {
  border-top: 1px solid var(--border); background: var(--card);
  padding: 10px 12px;
  /* (2026-09-07) ขั้นต่ำ 10→24px: เครื่องไม่มีรอยบากรายงาน env()=0
     ป้าย "ส่งไปยัง #ห้อง" ที่อยู่ท้าย composer จะไปชนแถบปัดขึ้นของระบบ */
  padding-bottom: max(24px, env(safe-area-inset-bottom));
}
/* รายชื่อแท็กในแผงเธรด — ต้องอยู่ใน .thr-composer ไม่ใช่ .thr-cbox
   (.thr-cbox เป็น overflow:hidden รายชื่อจะโดนตัดหายทันที) */
.thr-composer { position: relative; }
.thr-composer .thr-pop.mention-pop {
  position: absolute; left: 12px; right: 12px; bottom: 100%; margin-bottom: 6px;
  max-width: none; z-index: 70; max-height: 240px; overflow-y: auto;
  box-shadow: 0 -6px 24px rgba(0,0,0,.18);
}
.thr-cbox {
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--bg); overflow: hidden;
}
.thr-cbox:focus-within { border-color: var(--blue); }
.thr-input {
  width: 100%; border: none; background: none; outline: none; resize: none;
  font-family: inherit; font-size: 16px;   /* <16px ทำให้ iOS ซูมตอนโฟกัส */
  color: var(--text); padding: 10px 12px; min-height: 42px; max-height: 120px;
  line-height: 1.45;
}
.thr-cbox .ir-files { margin: 8px 0 0 12px; }
.thr-tools {
  display: flex; align-items: center; justify-content: space-between;
  padding: 5px 7px; border-top: 1px solid var(--border);
}
.thr-tool-l { display: flex; gap: 3px; }
.thr-tool {
  border: none; background: none; cursor: pointer; color: var(--muted);
  font-size: 16px; padding: 7px 9px; border-radius: 7px;
  min-width: 38px; min-height: 38px;
}
.thr-tool:hover { background: var(--card); color: var(--text); }
.thr-send {
  border: none; background: var(--blue); color: #fff; cursor: pointer;
  border-radius: var(--radius-pill); padding: 8px 16px;
  font-size: 14px; font-weight: 700; font-family: inherit;
  min-height: 38px;
}
.thr-send:hover { background: var(--blue-dark); }
.thr-send:disabled { opacity: .55; cursor: default; }
/* ติ๊ก "ส่งไปยัง #ห้อง" — (2026-09-07) แตะไม่ติดทั้ง iOS และ Android
   วัดจริง 5 เครื่อง (WebKit+Chromium): ป้ายสูงแค่ 17.8px (ต่ำกว่าขั้นต่ำ 44px)
   และขอบล่างชนขอบจอพอดี (bottom == innerHeight) = ทับแถบ home-bar iOS 34px
   → นิ้วปัดออกแอปแทนที่จะติ๊ก และ checkbox 16px ศูนย์กลางห่างขอบซ้ายแค่ 8px
   แก้: ย้ายป้ายเข้าไปใน .thr-composer (ได้ safe-area) + ขยายพื้นที่นิ้วเป็น 44px
   ⚠️ ห้ามลด min-height ต่ำกว่า 44px และห้ามเอา padding ซ้ายออก */
.thr-also {
  display: flex; align-items: center; gap: 10px;
  font-size: 13px; color: var(--muted); margin-top: 4px; cursor: pointer;
  min-height: 44px; padding: 0 10px 0 12px;
  border-radius: 10px; -webkit-tap-highlight-color: transparent;
  user-select: none; -webkit-user-select: none;
}
.thr-also:active { background: var(--blue-light); }
/* กันชนล่างสุด — เครื่องไม่มีรอยบากรายงาน env(safe-area-inset-bottom)=0
   จะเหลือระยะจากขอบจอแค่ 7px (แถบปัดขึ้นของ Android/iOS ยังกินอยู่)
   ⚠️ บวกเพิ่มจาก padding ของ .thr-composer ห้ามเอาออก */
.thr-also { margin-bottom: 10px; }
/* ขยายกล่องติ๊กให้นิ้วเห็น/กดง่าย — 16px เล็กเกินไปบนมือถือ */
.thr-also input {
  width: 20px; height: 20px; flex: 0 0 auto;
  accent-color: var(--blue); cursor: pointer; margin: 0;
}

/* เดสก์ท็อป: แผงข้างขวา ไม่ทับทั้งจอ */
@media (min-width: 861px) {
  /* เดสก์ท็อป: ไม่ต้องมีฉากหลังเลย — เลื่อน/กดห้องหลักได้ระหว่างเปิดแผง (Boss 2026-08-29)
     เดิมโปร่งใสแต่ยัง inset:0 ทับทั้งจอ = กินทั้งคลิกและสกรอลล์ */
  .thr-bd { display: none; }
  /* ⭐ Boss สั่ง 2026-09-14 (พี่ปอง): "เปิดคอมเมนต์แล้วโดนบีบ — ไม่ต้องบีบ"
     เดิมเปิดแผง = หด .sidebar 280px→10vw + ดัน padding-right 30vw ใส่ .app
     ⇒ ทั้งแถบห้องและห้องแชทขยับ/แคบลงทุกครั้งที่เปิดเธรด
     ตอนนี้แผงเธรดเป็น **ชั้นลอยทับด้านขวา** (position:fixed + z-index อยู่แล้ว)
     ไม่แตะ layout ด้านหลังเลย → แถบห้องกับห้องแชทคงขนาดเดิมเป๊ะ
     ⚠️ ห้ามใส่ padding-right/width กลับเข้ามาที่ body.thr-on อีก นั่นคือตัวที่ "บีบ"
     (กฎเดิมชุดตัดชื่อห้อง ...  ที่เคยต้องมีตอนแถบเหลือ 128px จึงถอดออกด้วย
      แถบไม่หดแล้ว ชื่อห้องแสดงเต็มเหมือนตอนปิดแผง) */
  .thrpanel {
    left: auto; width: 420px; max-width: 42vw;
    top: 0; bottom: 0; height: auto;
    border-radius: 0; border-left: 1px solid var(--border);
    box-shadow: -4px 0 20px rgba(0,0,0,.10);
    transform: translateX(100%);
  }
  /* แผง = 30% ของจอ ตรงกับ padding-right ที่หดไว้
     (Boss 2026-08-29 รอบ 2: 40% บีบห้องหลักมากไป — 900px เหลือ 608px ที่จอ 1280) */
  body.thr-on .thrpanel { width: 30vw; max-width: 30vw; min-width: 320px; }
  .thrpanel.open { transform: translateX(0); }
  /* คอม: แผงเป็นชั้นลอยด้านขวา ยังเห็นห้องหลัก → ปุ่ม ‹ ไม่จำเป็น ใช้ ✕ อย่างเดียว */
  .thr-back { display: none; }
  .thr-input { font-size: 15px; }
}

/* ============================================================
   โฟลเดอร์ในห้องแชท (Boss สั่ง 2026-08-29 · เฟส 3)
   อยู่ในโมดัลคลังรูป — mobile-first 360px
   ============================================================ */
.gal-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border, #E2E8F0); margin-bottom: 10px; }
.gal-tab {
  flex: 1; border: none; background: none; cursor: pointer; font-family: inherit;
  font-size: 13px; font-weight: 600; color: var(--muted, #64748B);
  padding: 8px 6px; border-bottom: 2px solid transparent;
}
.gal-tab.gal-on { color: var(--text, #1B2A3A); border-bottom-color: var(--blue, #0F4C81); }
.fd-list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.fd-row {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  border: 1px solid var(--border, #E2E8F0); border-radius: 10px; background: var(--card, #fff);
  cursor: pointer; font-family: inherit; font-size: 14px; color: var(--text, #1B2A3A);
  padding: 11px 12px;
}
.fd-row:hover { border-color: var(--blue, #0F4C81); background: var(--blue-light, #E6EEF7); }
.fd-ic { font-size: 17px; flex: 0 0 auto; }
.fd-nm { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.fd-ct {
  flex: 0 0 auto; font-size: 12px; font-weight: 700; color: var(--muted, #64748B);
  background: var(--blue-light, #E6EEF7); padding: 2px 9px; border-radius: 999px;
}
.fd-new { margin-top: 4px; }
.fd-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.fd-back {
  border: none; background: none; cursor: pointer; font-family: inherit;
  font-size: 13.5px; font-weight: 600; color: var(--blue, #0F4C81); padding: 4px 2px;
}
.fd-title { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fd-acts { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
/* ปุ่มลบไฟล์ออกจากโฟลเดอร์ — มุมขวาบนของรูป (แตะได้จริงบนมือถือ) */
.gal-cell { position: relative; }
.fd-x {
  position: absolute; top: 3px; right: 3px; z-index: 2;
  width: 24px; height: 24px; line-height: 24px; text-align: center;
  border-radius: 50%; background: rgba(0,0,0,.6); color: #fff; font-size: 13px; font-weight: 700;
}
.fd-x:hover { background: var(--red, #EF4444); }
/* โหมดเลือกไฟล์ */
.fd-tick {
  position: absolute; top: 4px; right: 4px; z-index: 2;
  width: 22px; height: 22px; line-height: 22px; text-align: center; border-radius: 50%;
  background: rgba(255,255,255,.85); border: 1.5px solid var(--border, #E2E8F0);
  color: transparent; font-size: 13px; font-weight: 800;
}
.fd-pk.fd-sel { outline: 3px solid var(--blue, #0F4C81); outline-offset: -3px; }
/* หน้าเลือกไฟล์มีรูปได้ถึง 60 ใบ — หัวข้อกับปุ่มบันทึกต้องไม่ถูกดันตกจอ
   (เจอตอนเทส 2026-08-29: เลือกรูปแล้วหาปุ่มบันทึกไม่เจอ ต้องเลื่อนสุดล่าง) */
#fd-out .fd-head { position: sticky; top: 0; z-index: 3; background: var(--card, #fff); padding: 6px 0; }
#fd-out .btn.primary.w100 {
  position: sticky; bottom: 0; z-index: 3; margin-top: 8px;
  box-shadow: 0 -8px 12px -8px rgba(0,0,0,.25);
}
.fd-pk.fd-sel .fd-tick { background: var(--blue, #0F4C81); border-color: var(--blue, #0F4C81); color: #fff; }

/* ============================================================
   แถบรางซ้ายสุด (rail) + บันทึกไว้อ่านทีหลัง — Boss สั่ง 2026-08-29
   ⚠️ เดสก์ท็อปเท่านั้น · มือถือซ่อน (แท็บล่าง mobile.js ทำหน้าที่แทน)
   ============================================================ */
/* สี/ไอคอนของรางปรับเองได้ (Boss สั่ง 2026-09-01) — token ทา inline บน <html> โดย
   paintBgPref('railcol') · ไม่ได้เลือก = ไม่มี token → fallback = สีเดิมเป๊ะๆ */
.rail {
  width: 70px; flex: 0 0 70px; height: 100%;
  background: var(--rail-bg, #3f0e40); color: var(--rail-txt, #d1d2d3);
  display: flex; flex-direction: column; align-items: center;
  gap: 4px; padding: 10px 0; overflow-y: auto; overflow-x: hidden;
  scrollbar-width: none; z-index: 40;
}
.rail::-webkit-scrollbar { display: none; }
.rail-item {
  position: relative; width: 56px; padding: 8px 2px 6px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border: 0; background: transparent; color: var(--rail-txt, #d1d2d3);
  font-family: inherit; border-radius: 8px; cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.rail-item:hover { background: var(--rail-hover, rgba(255,255,255,.08)); }
.rail-item.active { background: var(--rail-active, rgba(255,255,255,.15)); color: var(--rail-strong, #fff); }
.rail-ico { font-size: 24px; line-height: 1; display: block; position: relative; }
.rail-ico svg { width: 24px; height: 24px; display: block; }
.rail-lb { font-size: 11px; font-weight: 700; text-align: center; line-height: 1.15; }
.rail-key {
  position: absolute; top: 3px; right: 5px;
  font-size: 9px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--rail-key, rgba(255,255,255,.38));
}
.rail-item.active .rail-key { color: var(--rail-keyon, rgba(255,255,255,.6)); }
.rail-badge {
  position: absolute; top: -6px; left: 100%; margin-left: -8px;
  min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px;
  background: #e01e5a; color: #fff;
  font-size: 10px; font-weight: 800; font-variant-numeric: tabular-nums;
  /* ขอบป้ายเลขต้องเป็นสีพื้นราง ไม่ใช่ม่วงตายตัว ไม่งั้นเปลี่ยนสีรางแล้วเห็นวงม่วงค้าง */
  line-height: 17px; text-align: center; border: 2px solid var(--rail-bg, #3f0e40);
}
.rail-badge[hidden] { display: none !important; }

/* ---- ข้อความที่บันทึกไว้ (ในห้องแชท) ---- */
.msg.is-saved { background: #fff8e6; border-left: 3px solid #e8a33d; border-radius: 6px; }
[data-theme="dark"] .msg.is-saved { background: #2e2618; border-left-color: #c8862c; }
.saved-tag {
  display: inline-flex; align-items: center; gap: 5px; margin-top: 5px;
  padding: 2px 9px; border-radius: 11px;
  background: rgba(232,163,61,.2); color: #8a6011;
  font-size: 11.5px; font-weight: 500;
}
[data-theme="dark"] .saved-tag { color: #d9a24a; }
.msg-tool.saved-on { filter: none; opacity: 1; color: #e8a33d; }

/* ---- หน้า Later ---- */
.later-count { font-size: 12px; color: var(--muted); }
.later-list { display: flex; flex-direction: column; gap: 8px; }
.later-row {
  position: relative; display: grid; grid-template-columns: 38px minmax(0, 1fr) auto;
  gap: 11px; align-items: start; padding: 12px 14px;
  background: #fff8e6; border: 1px solid rgba(232,163,61,.35);
  border-left: 3px solid #e8a33d; border-radius: 9px;
  cursor: pointer; text-align: left; transition: border-color .12s ease;
}
[data-theme="dark"] .later-row { background: #2e2618; border-color: rgba(200,134,44,.4); border-left-color: #c8862c; }
.later-row:hover { border-color: #e8a33d; }
.later-where { font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.later-row .msg-time { margin-left: 7px; }
.later-x {
  border: 0; background: transparent; color: var(--muted);
  font-size: 16px; line-height: 1; padding: 4px 6px; border-radius: 5px; cursor: pointer;
}
.later-x:hover { background: rgba(224,30,90,.14); color: #e01e5a; }
/* หน้า Later แบบ 2 ฝั่ง (Boss สั่ง 2026-09-10 "ให้เหมือนใน /threads")
   ใช้คลาส .ntf-split/.ntf-detail/.ntf-dt-* ร่วมกับหน้าแจ้งเตือน — ที่นี่แค่เติมส่วนที่ต่าง
   ⚠️ #lt-split เป็นทั้ง .page-body (scroll) และ .ntf-split (flex 2 ฝั่ง) พร้อมกัน */
#lt-split { display: flex; gap: 14px; align-items: flex-start; }
#lt-split .later-list { gap: 8px; }
/* แถวที่กำลังเปิดดูอยู่ — ให้รู้ว่าฝั่งขวากำลังโชว์ใบไหน (เหมือน .ntf-item.active) */
.later-row.active { border-color: #e8a33d; box-shadow: inset 3px 0 0 #e8a33d; background: #fff2d4; }
/* ปุ่มสถานะบนแถว (Boss สั่ง 2026-09-10) — mobile first, นิ้วกดได้ */
.later-acts { display: flex; gap: 6px; margin-top: 8px; }
.later-row .msg-text { overflow-wrap: break-word; }
.lt-st, .lt-go { flex: 0 0 auto; white-space: nowrap; }
.lt-st, .lt-go {
  display: inline-flex; align-items: center; gap: 4px;
  border: 1px solid var(--border); background: var(--card); color: var(--muted);
  border-radius: 999px; padding: 5px 11px; min-height: 32px;
  font-size: 12.5px; line-height: 1; cursor: pointer;
}
.lt-st:hover, .lt-go:hover { border-color: var(--muted); color: var(--text); }
.lt-st.on { border-color: transparent; color: #fff; }
/* ⚠️ เดิมใช้ :first-child/:last-child จับปุ่ม เสร็จแล้ว/ยกเลิก — พอเพิ่มปุ่ม "ไปที่ข้อความ"
   มาเป็นใบแรก ตำแหน่งก็เลื่อนหมด → เปลี่ยนมาจับด้วยคลาสตรง ๆ ไม่ผูกกับลำดับอีก */
.later-row .lt-st.on.lt-done { background: #2e7d32; }          /* เสร็จแล้ว */
.later-row .lt-st.on.lt-cancel { background: #b0374a; }        /* ยกเลิก */
/* ไปที่ข้อความ = ทางลัดหลักของแถว ให้เด่นกว่าปุ่มสถานะนิดหนึ่ง (Boss สั่ง 2026-09-17) */
.lt-go { color: var(--accent, #2f6fd0); border-color: var(--accent, #2f6fd0); }
.lt-go:hover { background: var(--accent, #2f6fd0); color: #fff; border-color: transparent; }
/* แถวที่มีสถานะแล้ว = จางลง + ขีดฆ่าข้อความ ให้แยกออกจากงานที่ยังค้าง */
.later-row.st-done, .later-row.st-cancel { opacity: .72; }
.later-row.st-cancel .msg-text { text-decoration: line-through; }
@media (max-width: 480px) {
  .lt-st span { display: none; }        /* จอแคบเหลือแต่ไอคอน กันปุ่มดันแถวสูงเกิน */
  .lt-st { padding: 5px 12px; }
  /* ปุ่ม "ไปที่ข้อความ" คงตัวหนังสือไว้แม้จอแคบ — เป็นปุ่มหลักของแถว ไอคอน ↗ เปล่า ๆ เดายาก */
  .lt-go { padding: 5px 12px; }
}
[data-theme="dark"] .later-row.active { background: #3a2f1c; }

@media (max-width: 900px) {
  /* มือถือ: ฝั่งขวาสไลด์ทับเต็มจอ — กฎ .ntf-detail ใน media เดิมครอบให้แล้ว
     ที่นี่แค่คืน layout ฝั่งซ้ายให้เต็มความกว้าง */
  #lt-split { display: block; }
}
.later-empty { padding: 64px 20px; text-align: center; color: var(--muted); }
.later-empty .em-ico { font-size: 42px; display: block; margin-bottom: 12px; opacity: .5; }
.later-empty small { display: block; margin-top: 5px; font-size: 12.5px; opacity: .8; }

@keyframes x10flash { 0%,45% { background: #fff3c4; } 100% { background: transparent; } }
.msg.x10flash { animation: x10flash 1.5s ease-out; }
[data-theme="dark"] .msg.x10flash { animation: none; outline: 2px solid #c8862c; }

/* ============================================================
   หน้า "อนุมัติ" (Boss สั่ง 2026-09-01) — การ์ด 1 ใบ = 1 คำขอ
   ⚠️ มือถือเป็นหลัก (360px): ห้ามใช้ตาราง — ปุ่มต้องไม่หลุดขอบ/ไม่ต้องเลื่อนข้าง
      จอแคบ = ปุ่มลงไปอยู่บรรทัดล่างเต็มความกว้าง กดง่ายด้วยนิ้วโป้ง
   ============================================================ */
.ap-sect .card-head h3 { display: flex; align-items: center; gap: 7px; }
.ap-sect .card-head h3 svg { flex: 0 0 auto; opacity: .75; }

/* ---- โซนพับได้: 1 โซน = 1 หัวข้อ/แผนก (พี่ปองขอ 2026-09-12) ----
   ⚠️ หัวโซนเป็น <button> เต็มความกว้าง = เป้านิ้วโป้งทั้งแถบ ไม่ใช่แค่ลูกศรเล็กๆ
      (กฎมือถือมาก่อน 360px — ลูกศร 12px กดพลาดตลอด) */
.ap-zone { padding: 0; overflow: hidden; }
.ap-zhead {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 13px 14px; min-height: 48px;         /* 48px = เป้าแตะขั้นต่ำ */
  background: none; border: 0; cursor: pointer;
  font: inherit; font-weight: 700; color: inherit; text-align: left;
}
.ap-zhead:hover { background: var(--v3-hover, rgba(0,0,0,.04)); }
.ap-zhead svg { flex: 0 0 auto; opacity: .75; }
.ap-zcaret {
  flex: 0 0 auto; width: 14px; font-size: 13px; line-height: 1;
  color: var(--muted); transition: transform .15s ease;
}
.ap-zone.open .ap-zcaret { transform: rotate(90deg); }
/* ชื่อโซนยาว (ไทย) ต้องตัดบรรทัดได้ ไม่ใช่ดันป้ายเลขตกขอบจอ */
.ap-zname { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.ap-zbody { display: none; }
.ap-zone.open .ap-zbody { display: block; }
.ap-zempty { padding: 12px 14px 15px; color: var(--muted); font-size: 12.5px; }
/* โซนว่างยังต้องเห็น (พับไว้) แต่ไม่ควรเด่นเท่าโซนที่มีของค้าง */
.ap-badge.zero { background: var(--v3-hover, rgba(0,0,0,.07)); color: var(--muted); }

.ap-badge {
  min-width: 20px; padding: 1px 7px; border-radius: 10px;
  background: #e01e5a; color: #fff;
  font-size: 11.5px; font-weight: 800; font-variant-numeric: tabular-nums; text-align: center;
}
.ap-row {
  display: grid; grid-template-columns: 38px 1fr auto;
  gap: 11px; align-items: start;
  padding: 12px 14px; border-top: 1px solid var(--v3-bd, #e3e8ee);
}
.ap-row:first-of-type { border-top: 0; }
.ap-ava { grid-column: 1; }
.ap-main { min-width: 0; grid-column: 2; }       /* กันชื่อ/โน้ตยาวดันการ์ดกว้างเกินจอ */
/* ⚠️⚠️ การ์ดจากแอปอื่นไม่มีอวาตาร์ (แอปปลายทางส่งมาแค่ชื่อผู้ขอเป็นข้อความ)
   ถ้าไม่ดึงให้เริ่มคอลัมน์ 1 เนื้อหาจะไปตกในช่องอวาตาร์กว้าง 38px
   แล้วข้อความไทยตัดบรรทัดทีละคำจนอ่านไม่ได้ (เจอตอนเทสจอ 360px) */
.ap-row > .ap-main:first-child { grid-column: 1 / 3; }
.ap-name { font-weight: 700; }
.ap-meta { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.ap-meta code { font-size: 12px; }
.ap-note {
  margin-top: 6px; padding: 6px 9px; border-radius: 7px;
  background: var(--v3-hover, rgba(0,0,0,.04));
  font-size: 12.5px; overflow-wrap: anywhere;    /* โน้ตพิมพ์ติดกันยาวๆ ต้องตัดบรรทัด */
}
.ap-when { font-size: 11.5px; color: var(--muted); margin-top: 5px; }
.ap-act { display: flex; gap: 6px; align-items: center; }

/* ---- ยอดเงิน + อายุใบ บนหัวแถว (Boss 2026-09-22) ----
   ⚠️ ยอดเงินต้องเป็น tabular-nums ไม่งั้นหลักไม่ตรงกันเวลาไล่สายตาลงคอลัมน์ */
.ap-amt {
  margin-left: 6px; font-variant-numeric: tabular-nums;
  font-weight: 800; color: var(--blue);
}
/* "ค้าง N วัน" — เป็นข้อมูล ไม่ใช่คำเตือน จึงใช้สีจาง ไม่ใช่สีแดง
   (สีเตือนสงวนไว้ให้เรื่องที่ต้องลงมือจริง — ดู [[inv_page_help_box]]) */
.ap-age {
  margin-left: 6px; padding: 1px 7px; border-radius: 9px;
  background: var(--v3-hover, rgba(0,0,0,.05)); color: var(--muted);
  font-size: 11px; font-weight: 600; white-space: nowrap;
}
/* แถบสรุปหัวโซน */
.ap-zsum {
  padding: 8px 14px; border-bottom: 1px solid var(--v3-bd, #e3e8ee);
  background: var(--v3-hover, rgba(0,0,0,.03));
  font-size: 12.5px; color: var(--muted);
}
.ap-zsum b { color: var(--text, inherit); font-variant-numeric: tabular-nums; }

/* ---- ช่องกรอกเพิ่มตอนอนุมัติ (decide_fields) ---- */
.ap-field { margin-bottom: 12px; }
.ap-field > label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 4px; }
.ap-field input[type="text"], .ap-field input[type="number"] { width: 100%; }
.ap-field-hint { margin-top: 4px; font-size: 11.5px; }
.ap-field-prev { margin-top: 8px; }
.ap-field-prev img {
  max-width: 100%; max-height: 220px; border-radius: 8px;
  border: 1px solid var(--v3-bd, #e3e8ee);
}

@media (max-width: 560px) {
  /* ปุ่มลงบรรทัดใหม่ ใต้เนื้อหา กินความกว้างเท่ากันคนละครึ่ง */
  .ap-row { grid-template-columns: 38px 1fr; }
  .ap-row > .ap-main:first-child { grid-column: 1 / -1; }   /* ไม่มีอวาตาร์ = กินเต็มแถว */
  .ap-act { grid-column: 1 / -1; margin-top: 4px; }
  .ap-act .btn { flex: 1 1 0; }
}

@media (max-width: 860px) { .rail { display: none; } }
/* ผู้ใช้เลือกซ่อนแถบรางเอง (Boss สั่ง 2026-08-30) — ตั้งที่ โปรไฟล์ › การแสดงผล */
/* 🔴 2026-09-05 22:20 ถอนกลับ — เคยลองให้ default เป็น "ปิด" ตามที่ Boss สั่ง
   แต่ผู้ใช้จริงแจ้งทันทีว่า "แถบด้านข้างหายไป กดไปไหนไม่ได้เลย" → คืนกฎเดิม
   default = show (ไม่มี attribute = เห็นราง) · ซ่อนเมื่อผู้ใช้เลือก hide เองเท่านั้น */
html[data-railbar="hide"] .rail { display: none !important; }
html[data-menu="hide"] .mn-wrap { display: none !important; }
@media (prefers-reduced-motion: reduce) { .msg.x10flash { animation: none; outline: 2px solid #e8a33d; } }

/* รายชื่อแท็กในกล่องแก้ไขข้อความ (Boss แจ้ง 2026-08-29)
   ⚠️ .modal เป็น overflow-y:auto → ป๊อปอัปแบบ position:absolute โดนตัดหาย
      จึงวางในสายปกติใต้ช่องพิมพ์เลย (ไม่ absolute) แล้วให้ตัวมันเองเลื่อนได้ */
.edit-wrap { position: relative; }
.edit-wrap .ed-pop.mention-pop {
  position: static; max-width: none; max-height: 200px; overflow-y: auto;
  margin: -2px 0 0; box-shadow: none; border: 1px solid var(--border);
}
.edit-wrap .ed-pop.mention-pop.hidden { display: none; }

/* ── เลือกภาษาก่อนแปล (Boss 2026-08-29) — มือถือเป็นแผ่นเด้งล่าง / คอมเป็นกล่องกลางจอ ──
   ⚠️ ใช้ token ที่มีจริงเท่านั้น: --card --text --muted --border --sunken --msg-hover --backdrop
   (--ink/--line/--hover ไม่มีนิยามในแอปนี้ ใช้แล้วโหมดมืดตัวหนังสือจะจางจนอ่านไม่ออก) */
.trlang-wrap{position:fixed;inset:0;z-index:9999;background:var(--backdrop);
  display:flex;align-items:flex-end;justify-content:center}
.trlang-sheet{width:100%;max-width:480px;background:var(--card);color:var(--text);
  border:1px solid var(--border);border-bottom:0;
  border-radius:16px 16px 0 0;box-shadow:var(--shadow-modal);
  padding-bottom:env(safe-area-inset-bottom,0);max-height:80vh;overflow:auto}
.trlang-head{display:flex;align-items:center;justify-content:space-between;
  color:var(--text);font-weight:700;font-size:15px;padding:14px 16px;
  border-bottom:1px solid var(--border)}
.trlang-x{background:none;border:0;font-size:18px;line-height:1;color:var(--muted);
  cursor:pointer;padding:4px 8px;min-width:44px;min-height:44px}
.trlang-x:hover{color:var(--text)}
.trlang-list{padding:6px}
.trlang-item{display:flex;align-items:center;gap:12px;width:100%;min-height:52px;
  background:none;border:0;border-radius:10px;padding:10px 12px;cursor:pointer;
  text-align:left;color:var(--text);font:inherit}
.trlang-item:hover{background:var(--msg-hover)}
.trlang-item.on{background:var(--sunken)}
.trlang-ab{font-size:11px;font-weight:700;letter-spacing:.5px;color:var(--muted);
  background:var(--sunken);border:1px solid var(--border);border-radius:6px;
  min-width:38px;padding:4px 2px;text-align:center;flex:0 0 auto}
.trlang-item.on .trlang-ab{color:var(--on-brand);background:var(--blue);border-color:var(--blue)}
.trlang-tx{display:flex;flex-direction:column;flex:1 1 auto;min-width:0}
.trlang-tx b{font-size:15px;font-weight:600;color:var(--text)}
.trlang-tx small{font-size:12px;color:var(--muted)}
.trlang-chk{color:var(--green);font-weight:700;flex:0 0 auto}
@media (min-width:768px){
  .trlang-wrap{align-items:center}
  .trlang-sheet{border:1px solid var(--border);border-radius:14px;max-height:70vh}
}

/* ---- กลุ่ม Tag ผูกตำแหน่งงาน (2026-08-30 พี่ป๋อง) — มือถือ 360 เป็นหลัก ---- */
#modal-taggroups #tg-list { max-height: 34vh; overflow-y: auto; }
.tg-row { padding: 8px 0; border-bottom: 1px solid var(--line, #e5e7eb); }
.tg-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.tg-head b { word-break: break-all; }
.tg-count { font-size: 11px; opacity: .65; }
.tg-auto { font-size: 11px; padding: 1px 6px; border-radius: 10px; background: rgba(15,76,129,.12); }
.tg-names { margin-top: 2px; word-break: break-word; }
/* ปุ่มแก้/ลบอยู่แถวของตัวเอง — จอ 360 ถ้าวางชิดขวาแถวชื่อ ชื่อกลุ่มยาวจะดันปุ่มตกขอบ */
.tg-acts { display: flex; gap: 6px; margin-top: 6px; }
.tg-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 10px; max-height: 30vh; overflow-y: auto; }
.tg-chip { display: inline-flex; align-items: center; gap: 5px; padding: 5px 9px;
           border: 1px solid var(--line, #e5e7eb); border-radius: 14px; font-size: 12px; cursor: pointer; }
.tg-field { display: block; margin: 8px 0; }
.tg-field select { width: 100%; }
.btn.block { width: 100%; }
#tg-members.locked { opacity: .5; pointer-events: none; }


/* ============================================================
   ธีมสำเร็จรูป (Boss สั่ง 2026-08-30)
   ปุ่มธีม = ตัวอย่างสี 3 แถบ + ชื่อ · มือถือเป็นหลัก แตะได้เต็มนิ้ว
   ============================================================ */
.pf-packs { display: flex; flex-wrap: wrap; gap: 8px; }
.pf-pack {
  display: flex; flex-direction: column; gap: 6px; align-items: stretch;
  width: 96px; padding: 7px; cursor: pointer;
  border: 1.5px solid var(--v3-bd, var(--line, #d9dee5)); border-radius: 12px;
  background: var(--card, #fff); color: var(--text, #111);
  font: inherit; font-size: 12px; line-height: 1.25; text-align: center;
}
.pf-pack:hover { border-color: var(--blue, #0F4C81); }
.pf-pack.active { border-color: var(--blue, #0F4C81); box-shadow: 0 0 0 2px var(--blue, #0F4C81) inset; }
.pf-pack-sw { display: flex; height: 30px; border-radius: 7px; overflow: hidden; }
.pf-pack-sw i { flex: 1 1 0; display: block; }
.pf-pack-name { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 480px) {
  /* มือถือ 360px: 3 คอลัมน์พอดี ไม่ต้องเลื่อนข้าง */
  .pf-packs { display: grid; grid-template-columns: repeat(3, 1fr); }
  .pf-pack { width: auto; }
}

/* ---- ลายพื้นหลังห้องแชทของธีมใหม่ ----
   ทั้งหมดเป็น CSS gradient ล้วน ไม่โหลดรูป ไม่มี animation (กัน CPU บนมือถือ)
   ใช้ currentColor ไม่ได้ (ต่างธีมต่างพื้น) → คุมความจางด้วย alpha ต่ำ ใช้ได้ทั้งสว่าง/มืด */
html[data-wall="stars"] .messages {
  background-image:
    radial-gradient(1.4px 1.4px at 18% 22%, rgba(255,255,255,.85), transparent 60%),
    radial-gradient(1.2px 1.2px at 62% 14%, rgba(255,255,255,.65), transparent 60%),
    radial-gradient(1.6px 1.6px at 84% 46%, rgba(255,255,255,.80), transparent 60%),
    radial-gradient(1.1px 1.1px at 34% 68%, rgba(255,255,255,.55), transparent 60%),
    radial-gradient(1.5px 1.5px at 72% 82%, rgba(255,255,255,.70), transparent 60%),
    radial-gradient(1.2px 1.2px at 8% 88%, rgba(255,255,255,.60), transparent 60%);
  background-size: 220px 220px;
}
html[data-wall="clouds"] .messages {
  background-image:
    radial-gradient(60px 26px at 20% 30%, rgba(255,255,255,.55), transparent 70%),
    radial-gradient(80px 32px at 70% 62%, rgba(255,255,255,.45), transparent 70%),
    radial-gradient(50px 22px at 45% 86%, rgba(255,255,255,.40), transparent 70%);
  background-size: 300px 260px;
}
html[data-wall="hearts"] .messages {
  /* หัวใจ = วงกลม 2 ใบ + สี่เหลี่ยมหมุน 45° วาดด้วย gradient ล้วน */
  background-image:
    radial-gradient(6px 6px at 26% 30%, rgba(244,114,160,.28), transparent 62%),
    radial-gradient(6px 6px at 34% 30%, rgba(244,114,160,.28), transparent 62%),
    radial-gradient(6px 6px at 70% 68%, rgba(244,114,160,.22), transparent 62%),
    radial-gradient(6px 6px at 78% 68%, rgba(244,114,160,.22), transparent 62%);
  background-size: 130px 130px;
}
/* ตัวอย่างลายในหน้าตั้งค่า — ต้องมีคู่กันทุกลาย ไม่งั้นปุ่มโล่ง */
.pf-wall-sw[data-w="stars"]  { background: #0b1026; background-image:
  radial-gradient(1.3px 1.3px at 25% 30%, #fff, transparent 60%),
  radial-gradient(1.3px 1.3px at 65% 55%, #fff, transparent 60%),
  radial-gradient(1.3px 1.3px at 45% 78%, #fff, transparent 60%); }
.pf-wall-sw[data-w="clouds"] { background: #cfe6f7; background-image:
  radial-gradient(14px 7px at 35% 45%, #fff, transparent 70%),
  radial-gradient(12px 6px at 70% 68%, #fff, transparent 70%); }
.pf-wall-sw[data-w="hearts"] { background: #fff1f5; background-image:
  radial-gradient(3px 3px at 38% 42%, #f472a0, transparent 62%),
  radial-gradient(3px 3px at 46% 42%, #f472a0, transparent 62%),
  radial-gradient(3px 3px at 66% 70%, #f9a8c6, transparent 62%); }

/* ============================================================
   จัดระยะข้อความ ซ้าย/ขวา ให้ชัด (Boss สั่ง 2026-08-30)
   อาการเดิม (วัดจริงบนจอ 1000px): ซ้ายห่างขอบ 62px · ขวาห่าง 134px · แถวห่างกันแค่ 2px
   = ดูไม่ชิดสักฝั่ง เยื้องไม่เท่ากัน และข้อความอัดกันจนแยกคนพูดไม่ออก
   แก้ 3 จุด: (1) ดันชิดขอบทั้งสองฝั่ง (2) เพดานความกว้างวัดจากทั้งแถว (3) เพิ่มระยะห่างแถว
   ⚠️ ใช้ชุด .msg-* (ตัวที่เห็นจริงในห้องแชท) · .msg.nested/.system = คอมเมนต์/ระบบ ไม่แตะ
   ============================================================ */

/* (1) ระยะห่างระหว่างข้อความคนละคน — เดิม 2px อัดกันเป็นพืด
   ข้อความต่อเนื่องของคนเดิม (.compact) ให้ชิดกว่า เพื่อยังอ่านเป็นกลุ่มเดียว */
.msg:not(.nested):not(.system) { margin-bottom: 14px; }
.msg:not(.nested):not(.system).compact { margin-bottom: 4px; }

/* (2) ชิดซ้าย/ขวาให้สุดขอบจริง — ตัด padding แนวนอนของแถวออก
   ระยะขอบจอมาจาก .messages ที่เดียว ไม่ซ้อนกันหลายชั้นเหมือนเดิม */
.msg:not(.nested):not(.system) { padding-left: 0; padding-right: 0; }

/* (3) ⚠️ ต้นเหตุที่ "ขวาไม่ชิด" — .msg-body ยัง flex:1 (กว้างเต็มแถว)
   แล้ว .msg-bubble ตั้ง max-width:92% ซึ่งคิดจากความกว้าง "เต็มแถว" นั้น
   → เหลือช่องว่างขวา ~8% ของทั้งแถว = 134px ดันบับเบิลหลุดจากขอบตลอด
   แก้: ให้ body หุบมาเท่าเนื้อหา (ไม่ยืดเต็ม) แล้วดันทั้งก้อนไปชิดขอบ */
.msg:not(.nested):not(.system) .msg-body { flex: 0 1 auto; max-width: calc(100% - 44px); }
.msg:not(.nested):not(.system).mine .msg-body { margin-left: auto; }
.msg:not(.nested):not(.system):not(.mine) .msg-body { margin-right: auto; }
/* เพดานบับเบิลคิดจากตัว body ที่หุบแล้ว — ไม่ต้องหัก % ซ้ำอีกชั้น */
.msg:not(.nested):not(.system) .msg-bubble { max-width: 100%; }

/* มือถือ (Boss: มือถือมาก่อน) — จอแคบ ให้ข้อความกินพื้นที่ได้มากขึ้น
   อวตาร 32px + gap 8px = หัก 40px ก็พอ ไม่ต้องเผื่อเท่าคอม */
@media (max-width: 600px) {
  .msg:not(.nested):not(.system) { margin-bottom: 12px; }
  .msg:not(.nested):not(.system).compact { margin-bottom: 3px; }
  .msg:not(.nested):not(.system) .msg-body { max-width: calc(100% - 40px); }
}

/* ⚠️ ต้นเหตุจริงของ "ขวาไม่ชิด" บนจอกว้าง (เจอตอนวัดจริง 30 ส.ค.)
   กฎเดิมบรรทัด ~1210 ตัดทุกแถวไว้ที่ max-width:900px + margin-right:auto
   = แถวถูกดันไปกองซ้าย เหลือที่ว่างขวาค้างไว้ ข้อความของเราเลยไม่มีทางชิดขอบขวาเลย
   แก้: ให้แถวกว้างเต็มห้อง (ซ้าย-ขวาแยกกันสุดจริง) แต่ยังคุมความยาวบรรทัดที่ "บับเบิล"
   ไม่ใช่ที่ "แถว" — อ่านสบายเหมือนเดิม แต่แยกฝั่งชัด (แนวเดียวกับ Messenger/Slack) */
@media (min-width: 1101px) {
  .messages > * { max-width: none; margin-right: 0; }
  /* คุมความยาวบรรทัดตรงนี้แทน: ข้อความยาวๆ ไม่ลากเต็มจอจนอ่านยาก */
  .msg:not(.nested):not(.system) .msg-body { max-width: min(760px, calc(100% - 44px)); }
}

/* (2026-08-31) แผงอีโมจิในแผงเธรด — เกาะ .thr-composer แบบเดียวกับรายชื่อแท็ก
   (#emoji-pop ตัวเดิมเกาะช่องพิมพ์ของห้อง เปิดจากเธรดจะไปโผล่หลังแผงจนไม่เห็น) */
.thr-composer { position: relative; }
.thr-composer .thr-emoji-pop {
  position: absolute; left: 12px; right: 12px; bottom: 100%; margin-bottom: 6px;
  max-width: none; z-index: 71;
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 -6px 24px rgba(0,0,0,.18);
  padding: 8px; display: flex; flex-direction: column; gap: 7px;
}
.thr-composer .thr-emoji-pop.hidden { display: none; }

/* ============================================================
   แผ่นบันทึกรูป (มือถือ) — พี่ป๋องแจ้ง 2026-08-31
   "กดโหลดในคอมก็โหลดเข้าเครื่องเลย แต่มือถือเอาแบบที่เข้าใจง่าย"
   → โชว์รูปที่รวมลายเส้นแล้วเต็มจอ ให้กดค้างบันทึกตามที่คุ้นเคย
   ⚠️ z-index ต้องสูงกว่า .lightbox (300) ไม่งั้นโดนบัง
   ============================================================ */
.lb-sheet {
  position: fixed; inset: 0; z-index: 340; background: rgba(0,0,0,.94);
  display: flex; align-items: center; justify-content: center; padding: 14px;
}
.lb-sheet.hidden { display: none; }
.lb-sheet-in { display: flex; flex-direction: column; align-items: center; gap: 12px; max-height: 100%; }
.lb-sheet-tip {
  display: flex; align-items: center; gap: 8px;
  color: #fff; font-size: 15px; font-weight: 600; text-align: center;
  background: rgba(255,255,255,.14); border-radius: 999px; padding: 9px 16px;
}
.lb-sheet-hand { font-size: 18px; }
/* ⚠️ ต้องปล่อยให้กดค้างที่รูปได้ — ห้ามใส่ user-select:none / pointer-events:none
   ไม่งั้นเมนู "บันทึกรูปภาพ" ของระบบไม่ขึ้น = ฟีเจอร์นี้ตายทั้งอัน */
#lb-sheet-img {
  max-width: 100%; max-height: 62vh; object-fit: contain;
  border-radius: 10px; background: #fff;
  -webkit-touch-callout: default;
}
.lb-sheet-btns { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center;
  padding-bottom: env(safe-area-inset-bottom); }
.lb-sheet-btn {
  min-height: 44px; padding: 0 20px; border: 0; border-radius: 10px;
  background: #0a84ff; color: #fff; font-size: 15px; font-weight: 600; cursor: pointer;
}
.lb-sheet-btn.ghost { background: rgba(255,255,255,.18); }

/* ===== Workflow อัตโนมัติของแต่ละคน (Boss สั่ง 2026-08-31 ข้อ 3) =====
   mobile first (360x780) — การ์ดเรียงคอลัมน์เดียว จอกว้างค่อยแบ่ง 2 คอลัมน์ */
.wf-wrap { padding: 12px 14px 28px; max-width: 900px; }
.wf-list { display: grid; grid-template-columns: 1fr; gap: 10px; margin-bottom: 6px; }
.wf-card {
  border: 1px solid var(--border); border-radius: 12px; background: var(--card);
  padding: 11px 12px;
}
.wf-card.off { opacity: .62; }
.wf-card-top { display: flex; align-items: center; gap: 10px; }
.wf-nm { font-size: 14.5px; flex: 1; min-width: 0; overflow-wrap: anywhere; }
.wf-meta { margin-top: 4px; line-height: 1.5; overflow-wrap: anywhere; }
.wf-card-btns { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.wf-card-btns .btn.danger { color: var(--red, #e5484d); }

/* สวิตช์เปิด/ปิด */
.wf-sw { position: relative; display: inline-block; width: 40px; height: 22px; flex: 0 0 auto; }
.wf-sw input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.wf-sw span {
  position: absolute; inset: 0; border-radius: 999px;
  background: var(--border); transition: background .15s; pointer-events: none;
}
.wf-sw span::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
  border-radius: 50%; background: #fff; transition: transform .15s;
}
.wf-sw input:checked + span { background: var(--blue); }
.wf-sw input:checked + span::after { transform: translateX(18px); }

/* ---- สั่งงานเลขา + ประวัติ (Boss สั่ง 2026-09-02) ----
   mobile first: การ์ดเรียงลงมา ไม่มีผ้าใบให้ลาก จอ 360px จึงไม่ล้น
   สีทั้งหมดใช้ตัวแปรธีม ห้ามฮาร์ดโค้ด (ธีมสว่าง/มืด + สีที่ผู้ใช้เลือกเอง) */
.wf-tell {
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--card); padding: 11px 12px; margin-bottom: 6px;
}
.wf-ex { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.wf-exb {
  border: 1px solid var(--border); border-radius: 999px; background: var(--sunken);
  color: var(--text); padding: 5px 11px; font-size: 12.5px; cursor: pointer;
  font-family: inherit; text-align: left;
}
.wf-exb:hover { border-color: var(--blue); }
/* ช่องพิมพ์ + ปุ่มส่ง: มือถือซ้อนกัน (ปุ่มเต็มความกว้าง แตะง่าย) */
.wf-tell-row { display: flex; flex-direction: column; gap: 7px; }
.wf-tell-row textarea {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 44px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--sunken);
  color: var(--text); padding: 9px 10px; font: inherit; font-size: 14px;
}
.wf-tell-row .btn { width: 100%; }
.wf-reply { margin-top: 9px; font-size: 13.5px; white-space: pre-wrap; }
/* การ์ดเสนอคำสั่ง — ต้องเด่นเพราะต้องกดยืนยันก่อนถึงจะตั้งจริง */
.wf-prop {
  margin-top: 10px; border: 1px solid var(--blue); border-radius: 11px;
  background: var(--sunken); padding: 10px 11px;
}
.wf-prop-h { font-weight: 600; font-size: 13px; margin-bottom: 4px; }
.wf-prop-s { font-size: 13.5px; margin-bottom: 9px; word-break: break-word; }
.wf-prop-btns { display: flex; flex-wrap: wrap; gap: 6px; }
/* ประวัติ */
.wf-runs { display: flex; flex-direction: column; gap: 1px; }
.wf-run {
  display: flex; gap: 8px; align-items: flex-start;
  padding: 7px 9px; border-radius: 8px; background: var(--card);
}
.wf-run:nth-child(odd) { background: var(--sunken); }
.wf-run-ic { flex: 0 0 auto; }
.wf-run-tx { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; }
.wf-run-tx b { font-size: 13px; }
.wf-run-tx .small-text { word-break: break-word; }
.wf-run-t { flex: 0 0 auto; white-space: nowrap; }
/* คอมกว้างพอ: ช่องพิมพ์กับปุ่มอยู่บรรทัดเดียว */
@media (min-width: 641px) {
  .wf-tell-row { flex-direction: row; align-items: flex-end; }
  .wf-tell-row .btn { width: auto; flex: 0 0 auto; }
}

/* แกลเลอรีเทมเพลต — แบบหน้า Workflows ของ Slack */
.wf-tpl-grid { display: grid; grid-template-columns: 1fr; gap: 9px; }
.wf-tpl {
  display: flex; gap: 10px; align-items: flex-start; text-align: left;
  border: 1px solid var(--border); border-radius: 12px; background: var(--card);
  padding: 11px 12px; cursor: pointer; width: 100%;
}
.wf-tpl:hover { border-color: var(--blue); background: var(--sunken); }
.wf-tpl-ico { font-size: 20px; line-height: 1.1; flex: 0 0 auto; }
.wf-tpl-tx { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.wf-tpl-tx b { font-size: 13.5px; }

/* ฟอร์มในโมดัล */
#modal-wf .wf-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
#modal-wf .wf-row > select, #modal-wf .wf-row > input { flex: 1 1 120px; min-width: 0; }
#modal-wf .wf-step {
  border: 1px solid var(--border); border-radius: 10px; padding: 8px; margin-bottom: 7px;
  background: var(--sunken);
}
#modal-wf .wf-step textarea { margin-top: 6px; width: 100%; }
#modal-wf .btn.small { padding: 4px 9px; font-size: 12.5px; }

@media (min-width: 720px) {
  .wf-list, .wf-tpl-grid { grid-template-columns: 1fr 1fr; }
}

/* ===== หน้า Physical — สรุปรีวิว 🔴🟡🟢 (Boss สั่ง 2026-09-01) =========================
   mobile first 360x780: การ์ดต่อรายการ ไม่ใช่ตาราง (ตารางบนมือถือต้องเลื่อนข้าง)
   ⚠️ ใช้ตัวแปรสีของธีมเท่านั้น (--card/--border/--text/--muted) แอปนี้ให้ผู้ใช้
      เลือกสีเองได้ ฮาร์ดโค้ดสีคือพังตอนสลับธีม */
.phys-date { max-width: 42vw; padding: 5px 8px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--card); color: var(--text); font: inherit; font-size: 13px; }

.phys-top { display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px; flex-wrap: wrap; padding: 2px 2px 10px; }
.phys-date-lb { font-size: 17px; font-weight: 600; }
.phys-total { font-size: 13px; color: var(--muted); }
.phys-total b { color: var(--text); font-size: 15px; }

/* 3 ตัวเลขเด่น — กดเพื่อพับ/กางกลุ่มนั้น */
.phys-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 12px; }
.phys-tile { display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 10px 4px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--card); color: var(--text); cursor: pointer; }
.phys-tile.off { opacity: .5; }
.pt-ico { font-size: 18px; line-height: 1; }
.pt-n { font-size: 22px; font-weight: 700; line-height: 1.1; }
.pt-lb { font-size: 11px; color: var(--muted); }

.phys-sect { padding: 0; overflow: hidden; margin-bottom: 10px; }
.phys-head { display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 11px 12px; background: none; border: 0; color: var(--text);
  font: inherit; font-size: 15px; font-weight: 600; cursor: pointer; text-align: left; }
.ph-lb { flex: 1; }
.ph-n { font-size: 13px; color: var(--muted); font-weight: 600; }
.ph-caret { color: var(--muted); font-size: 12px; }

.phys-list { border-top: 1px solid var(--border); }
.phys-row { padding: 9px 12px; border-bottom: 1px solid var(--border); }
.phys-row:last-child { border-bottom: 0; }
.phys-r1 { display: flex; align-items: baseline; gap: 8px; }
.phys-villa { font-weight: 600; font-size: 14px; }
.phys-times { font-size: 11px; color: var(--muted); border: 1px solid var(--border);
  border-radius: 999px; padding: 1px 7px; white-space: nowrap; }
.phys-cat { font-size: 13px; color: var(--muted); margin-top: 1px; }
/* รายละเอียดยาวได้ ต้องตัดบรรทัดเอง ห้าม nowrap ไม่งั้นดันจอกว้าง */
.phys-detail { font-size: 13px; margin-top: 3px; line-height: 1.45; overflow-wrap: anywhere; }
.phys-none { padding: 12px; color: var(--muted); font-size: 13px; text-align: center; }

.phys-sheet { display: inline-block; margin: 6px 2px 20px; font-size: 13px; }

/* คอมจอกว้าง: การ์ด 3 กลุ่มเรียงข้างกันได้ ไม่ต้องเลื่อนยาว */
@media (min-width: 861px) {
  .phys-tiles { grid-template-columns: repeat(3, minmax(0, 180px)); }
  .phys-date { max-width: 200px; }
}

/* ปุ่ม 🔍 "เลือกห้อง" (Channel Browser) — อยู่ที่เดิมของปุ่ม 🙈 ที่เอาออก (2026-09-04)
   มือถือเป็นหลัก: กว้าง/สูงพอนิ้วกด แต่ไม่ดันแถบให้ยาวเกินจนชื่อหมวดโดนบีบ */
.chv-btn.chv-eye {
  font-size: 12px; line-height: 1; padding: 3px 6px;
  min-width: 26px; min-height: 22px;
  border-left: 1px solid var(--v3-side-hover, rgba(255,255,255,.14));
  border-radius: 6px; margin-left: 1px;
}
@media (max-width: 520px) {
  .chv-btn.chv-eye { min-width: 30px; min-height: 28px; font-size: 13px; }
}

/* ===== ฟอร์มสั่งงาน (Taskflow / Physical) — Boss สั่ง 2026-09-01 =====================
   มือถือเป็นหลัก: ช่องละบรรทัด · ปุ่ม 44px · ไม่ให้ jump ตอนโฟกัส (font-size 16px กัน iOS zoom) */
.asg-src { font-size: 12.5px; opacity: .75; padding: 8px 10px; margin-bottom: 4px;
  background: rgba(127,127,127,.1); border-radius: 8px; line-height: 1.45;
  max-height: 4.6em; overflow: hidden; }
.mg-body .asg-form select { width: 100%; padding: 9px 10px; border-radius: 8px;
  font: inherit; font-size: 16px; background: var(--bg, #fff); color: inherit;
  border: 1px solid rgba(127,127,127,.35); }
.mg-body .asg-form input, .mg-body .asg-form textarea { font-size: 16px; padding: 9px 10px;
  border: 1px solid rgba(127,127,127,.35); background: var(--bg, #fff); color: inherit; }
.mg-body .asg-form textarea { resize: vertical; line-height: 1.5; }
.asg-row { display: flex; gap: 8px; }
.asg-row > div { flex: 1; min-width: 0; }
.asg-foot { display: flex; gap: 8px; justify-content: flex-end; margin-top: 16px;
  padding-top: 12px; border-top: 1px solid rgba(127,127,127,.2); }
.asg-foot .btn { min-height: 44px; padding: 0 18px; }
/* 🔴 ชื่องาน = ช่องบังคับ (Boss สั่ง 2026-09-14 ให้ปล่อยว่างแล้วพิมพ์เอง)
   ⚠️ ช่องว่างเปล่าไม่มีอะไรบอกว่าบังคับ → ดาวแดง + กรอบแดงตอนกดส่งทั้งที่ว่าง */
.asg-req { color: #e5484d; font-weight: 700; }
.mg-body .asg-form input.asg-err { border-color: #e5484d; box-shadow: 0 0 0 2px rgba(229,72,77,.22); }
@media (max-width: 480px) {
  .asg-row { display: block; }        /* จอแคบ 2 ช่องเรียงกันแล้วบีบจนอ่านไม่ออก */
  .asg-foot .btn { flex: 1; }         /* ปุ่มเต็มความกว้าง แตะง่าย */
}

/* ยืนยันบัญชี TaskFlow โดยไม่ต้องใส่ PIN (Boss สั่ง 2026-09-01) — มือถือเป็นหลัก */
.tf-confirm-box { margin: 10px 0 14px; padding: 12px; border-radius: 10px;
  background: rgba(127,127,127,.10); border: 1px solid var(--border); }
.tf-confirm-box .tf-confirm-who { margin: 0 0 8px; font-size: 14px; line-height: 1.5; }
.tf-confirm-box .btn { width: 100%; min-height: 44px; }
.tf-confirm-box p.small-text { margin: 8px 0 0; }
@media (min-width: 640px) { .tf-confirm-box .btn { width: auto; min-width: 180px; } }

/* ── ใครกดรีแอ็ก (2026-09-02) ────────────────────────────────
   ไม่เพิ่มปุ่มบนการ์ด (Boss ขอ "ไม่รก"): คอม = hover ตัวเลขได้ tooltip
   มือถือ = แตะตรงตัวเลขโผล่รายชื่อ · แตะที่หน้าอีโมจิยังเป็นกดรีแอ็กเหมือนเดิม */
.react-chip { position: relative; }
/* ⚠️ เคยทำเป็นแผ่นทับ 34px ชิดขวา — วัดจริงชิปกว้างแค่ 56.7px แผ่นเลยกินทับหน้าอีโมจิ
   กลายเป็นกดรีแอ็กไม่ได้ · ตอนนี้ใช้ "ชี้ทั้งเม็ด" (คอม) + "กดค้าง" (มือถือ) แทน */
/* ทูลทิปดำแบบ Messenger — ตามรูปที่ Boss ส่งมา 2026-09-02 */
.react-tip {
  visibility: hidden; position: fixed; z-index: 10000; pointer-events: none;
  background: #1c1e21; color: #fff;
  padding: 7px 12px; border-radius: 999px;
  font-size: 12.5px; font-weight: 600; line-height: 1.45;
  max-width: 260px; text-align: center;
  box-shadow: 0 2px 10px rgba(0,0,0,.28);
}
/* มือถือกดค้าง — ใช้โทนดำชุดเดียวกับทูลทิปคอม จะได้หน้าตาเป็นระบบเดียวกัน */
.react-who {
  visibility: hidden; z-index: 10000;
  background: #1c1e21; color: #fff;
  border-radius: 14px;
  box-shadow: 0 6px 22px rgba(0,0,0,.35);
  padding: 9px 13px; max-width: 235px; font-size: 13px; line-height: 1.65;
}
.react-who .rw-head {
  display: flex; align-items: center; gap: 6px;
  font-weight: 700; margin-bottom: 5px;
  padding-bottom: 5px; border-bottom: 1px solid rgba(255,255,255,.18);
}
.react-who .rw-list { max-height: 190px; overflow-y: auto; }
.react-who .rw-more { color: rgba(255,255,255,.62); }

/* ── แถบ "มาจากเธรดไหน" แบบ Slack (2026-09-02) ──────────────
   ใบที่ติ๊ก "ส่งไปยัง #ห้อง ด้วย" จากในเธรด — ถ้าไม่มีแถบนี้
   คนในห้องหลักจะเห็นข้อความโผล่มาลอยๆ ไม่รู้ว่าคุยเรื่องอะไรอยู่ */
.msg-fromthr {
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  margin: 0 0 5px; padding: 4px 9px;
  background: var(--blue-light); border-left: 3px solid var(--blue);
  border-radius: 0 7px 7px 0;
  /* ไทยมีสระบน-ล่าง ต้องเผื่อ line-height ไม่งั้นสระชนขอบแถบ */
  font-size: 12px; color: var(--muted); cursor: pointer; line-height: 1.7;
}
.msg-fromthr:hover { filter: brightness(.97); }
/* ส่งต่อ — กดไม่ได้ (ไม่มีเธรดปลายทาง) ใช้สีกลางๆ แยกจากแถบเธรดที่กดได้ */
.msg-fromthr.is-fwd { cursor: default; border-left-color: var(--muted); }
.msg-fromthr.is-fwd:hover { filter: none; }
/* ส่งต่อที่ "กดไปหาต้นทางได้" — ใบเก่าก่อน 2026-09-02 ไม่มี id ต้นทาง เลยยังกดไม่ได้ */
.msg-fromthr.is-fwd.can-go { cursor: pointer; }
.msg-fromthr.is-fwd.can-go:hover { filter: brightness(.97); border-left-color: var(--blue); }
.msg-fromthr .mf-go { margin-left: auto; padding-left: 6px; font-weight: 700; opacity: .75; }
.msg-fromthr.is-fwd b { color: var(--text); }
/* 💬 ข้อความแนบตอนส่งต่อ — ต้องเห็นชัด ไม่จมใต้การ์ดรีวิว (pong 2026-10-01) */
.fwd-note {
  display: block; margin: 6px 0 12px; padding: 10px 14px 12px;
  background: #ffe9a3; border: 2px solid #e0a800; border-left: 8px solid #c78500;
  border-radius: 10px; color: #2b2000; line-height: 1.55;
  box-shadow: 0 2px 8px rgba(199,133,0,.35);
}
.fwd-note-lb { display: block; font-size: 12.5px; font-weight: 800; color: #7a5200; margin-bottom: 4px; letter-spacing: .2px; }
.fwd-note-tx { font-size: 18px; font-weight: 800; white-space: pre-wrap; word-break: break-word; }
html[data-theme="dark"] .fwd-note { background: #4d3d0a; border-color: #f2c94c; border-left-color: #f2c94c; color: #fff6d6; box-shadow: 0 2px 8px rgba(0,0,0,.5); }
html[data-theme="dark"] .fwd-note-lb { color: #ffd966; }
.msg-fromthr b { color: var(--blue); font-weight: 700; }
.msg-fromthr .mf-tx {
  color: var(--muted); opacity: .85;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
/* ── การ์ดอ้างอิงต้นเรื่อง (2026-09-23 · Non "ดูง่าย รู้ว่าส่งมาจากข้อความนี้ ใช้ย้ำ/ทวนงาน")
   ใบที่ติ๊ก "ส่งไปยัง #ห้อง" — เดิมแถบบรรทัดเดียว ต้นเรื่องโดนตัดจนอ่านไม่ออก
   ⚠️ ห้ามพื้นทึบ/ตัวขาว (--blue เปลี่ยนตามธีม 14 ชุด) ใช้ --blue-light + เส้นซ้ายเท่านั้น */
.msg-fromthr.thr-card {
  display: block; padding: 7px 10px 8px; margin: 0 0 7px;
  border-left-width: 4px; border-radius: 0 10px 10px 0; font-size: 12.5px; line-height: 1.6;
  max-width: 520px;
  /* ⚠️ พื้นโปร่งทับฟอง ไม่ใช้ --blue-light — ฟองของเรา/ธีมมือถือบางชุดพื้นสว่าง แต่ตัวอักษรสีอ่อน
     เคยได้ตัวหนังสือจางบนพื้นขาวอ่านไม่ออก → สีตัวอักษรตามฟอง (inherit) ใช้ได้ทุกธีม */
  background: rgba(77,155,224,.13);
  background: color-mix(in srgb, var(--blue) 14%, transparent);
  color: inherit;
}
.thr-card .tc-hd { display: flex; align-items: center; gap: 5px; min-width: 0; color: inherit; opacity: .8; }
.thr-card .tc-hd svg { flex: 0 0 auto; color: var(--blue); }
.thr-card .tc-lb { flex: 0 0 auto; }
.thr-card .tc-hd b { color: var(--blue); font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thr-card .tc-tm { flex: 0 0 auto; font-size: 11px; opacity: .8; }
.thr-card .tc-tm::before { content: '· '; }
.thr-card .tc-go {
  flex: 0 0 auto; margin-left: auto; padding: 0 8px; border-radius: 999px;
  border: 1px solid var(--blue); color: var(--blue); font-size: 11px; font-weight: 700; line-height: 1.8;
}
.thr-card .tc-body { display: flex; gap: 8px; align-items: flex-start; margin-top: 4px; }
.thr-card .tc-img { flex: 0 0 auto; width: 44px; height: 44px; object-fit: cover; border-radius: 6px; }
.thr-card .tc-tx {
  color: inherit; font-size: 13px; min-width: 0; word-break: break-word;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
@media (max-width: 480px) { .thr-card .tc-lb { display: none; } }
/* ติ๊ก "ส่งไปยัง #ห้อง ด้วย" ในช่องคอมเมนต์ (เดิมมีแค่ในแผงเธรด) */
.ir-also {
  display: flex; align-items: center; gap: 9px;
  margin: 2px 0 0 30px; font-size: 12.5px; color: var(--muted); cursor: pointer;
  /* (2026-09-07) เหมือน .thr-also — พื้นที่นิ้วต้องถึง 44px ไม่งั้นแตะไม่ติดบนมือถือ */
  min-height: 44px; padding: 0 8px; border-radius: 10px;
  -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none;
}
.ir-also:active { background: var(--blue-light); }
.ir-also input { cursor: pointer; width: 20px; height: 20px; flex: 0 0 auto; margin: 0; accent-color: var(--blue); }

/* ── เมนูคลิกขวาที่รูปโปรไฟล์/ชื่อคนในห้องแชท (2026-09-02) ──
   ⚠️ z-index ต้องสูงกว่าแผงเธรด(79)/หน้าต่าง DM(300) เหมือน .react-pick */
.uctx {
  visibility: hidden; position: fixed; z-index: 330;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 10px; padding: 4px; min-width: 168px;
  box-shadow: 0 8px 26px rgba(0,0,0,.24);
  display: flex; flex-direction: column; gap: 1px;
}
.uctx button {
  display: block; width: 100%; text-align: left;
  background: none; border: none; cursor: pointer;
  font-family: inherit; font-size: 13.5px; color: var(--text);
  padding: 9px 12px; border-radius: 7px; line-height: 1.5;
}
.uctx button:hover { background: var(--blue-light); }
.uctx button.danger { color: var(--red); }
.uctx button.danger:hover { background: color-mix(in srgb, var(--red) 12%, transparent); }
/* ปุ่มเอาออกในรายชื่อสมาชิก */
.list-row .mem-kick { flex: 0 0 auto; margin-left: 4px; }

/* ============================================================
 * 🔔 /แท็กฉัน — ตารางแยกห้อง + รูป + ลิงก์ไปโพสต์ (Boss 2026-09-02)
 * มือถือมาก่อน (360x780): ตารางเลื่อนข้างในกล่องตัวเอง (.mm-scroll)
 * ห้ามให้ทั้งหน้าเลื่อนข้าง — ใช้ตัวแปรธีมทั้งหมด ห้ามฮาร์ดโค้ดสี (ธีมสว่างจะขาวบนขาว)
 * ============================================================ */
/* ⚠️⚠️ #modal-generic **คือตัว .modal เอง** ไม่ใช่ลูก
   เขียน `#modal-generic .modal` (ลูกหลาน) จึงไม่แมตช์อะไรเลย → ค้าง 420px
   ตาราง 3 คอลัมน์ในกล่อง 420px = คอลัมน์เนื้อหาเหลือ ~130px อ่านไม่ได้
   (Boss แจ้ง 2026-09-02 "มันดูแคบไป") ต้องเขียนที่ตัวมันเอง
   มือถือไม่กระทบ: width:100% + max-width:100% ใน @media ชนะอยู่แล้ว */
#modal-generic.modal:has(.mm-room) { max-width: min(1000px, 94vw); }
.mm-head { display:flex; flex-wrap:wrap; gap:8px; align-items:center;
  justify-content:space-between; margin-bottom:10px; }
.mm-sum { font-size:13px; }
.mm-un { color:#e8564f; }
.mm-days { display:flex; gap:4px; }
.mm-day { font-size:12px; padding:4px 9px; border-radius:999px; cursor:pointer;
  border:1px solid var(--border); background:transparent; color:inherit; }
.mm-day.on { background:var(--accent,#4a7dff); color:#fff; border-color:transparent; }

.mm-room { margin:0 0 14px; }
.mm-rname { font-size:13px; font-weight:600; padding:6px 8px; border-radius:8px 8px 0 0;
  background:var(--border); display:flex; justify-content:space-between; gap:8px; }
.mm-cnt { font-weight:400; opacity:.75; font-size:12px; }
/* ตารางกว้างเลื่อนในกล่องตัวเอง — 78vw กันชนขอบโมดัลบนมือถือ */
.mm-scroll { overflow-x:auto; -webkit-overflow-scrolling:touch;
  border:1px solid var(--border); border-top:0; border-radius:0 0 8px 8px; }
.mm-tb { width:100%; border-collapse:collapse; font-size:13px; }
.mm-tb th { text-align:left; font-size:11px; font-weight:600; opacity:.6;
  padding:5px 8px; border-bottom:1px solid var(--border); white-space:nowrap; }
.mm-tb td { padding:7px 8px; border-bottom:1px solid var(--border); vertical-align:top; }
.mm-tb tr:last-child td { border-bottom:0; }
.mm-new { background:rgba(74,125,255,.07); }
.mm-by { white-space:nowrap; font-weight:500; min-width:88px; }
.mm-when { font-size:11px; opacity:.55; font-weight:400; margin-top:2px; }
.mm-dot { display:inline-block; width:6px; height:6px; border-radius:50%;
  background:#e8564f; margin-right:5px; vertical-align:middle; }
/* เนื้อหาคือพระเอก — ให้พื้นที่มากสุด และตัดคำยาว ๆ ไม่ให้ดันตารางบาน */
.mm-txt { line-height:1.5; word-break:break-word; min-width:180px; }
.mm-via { font-size:10px; padding:1px 5px; border-radius:4px; margin-left:5px;
  background:var(--border); opacity:.8; }
.mm-pics { display:flex; flex-wrap:wrap; gap:4px; margin-top:5px; }
.mm-pic { width:60px; height:60px; object-fit:cover; border-radius:6px; cursor:pointer;
  border:1px solid var(--border); }
/* 3 ปุ่ม (ไปโพสต์ · สั่งงาน Taskflow · สั่งงานช่าง) — เรียงตั้งบนคอลัมน์แคบ ๆ
   ปุ่มสูง 30px กว้าง 34px แตะได้บนมือถือโดยไม่ดันตารางบาน */
/* คอมมีที่ → เรียงปุ่มแนวนอน แถวไม่สูงเก้งก้าง · มือถือค่อยเรียงตั้ง (ดู @media ล่าง) */
/* ป้าย "ตอบหรือยัง" — ยังไม่ตอบต้องเด่นสุด เพราะเป็นของที่ต้องลงมือ */
.mm-rep { white-space:nowrap; }
.mm-nr { color:#e08c00; }
.mm-badge { font-size:11px; padding:2px 6px; border-radius:999px; display:inline-block;
  border:1px solid transparent; }
.mm-badge.ok    { background:rgba(46,160,67,.14); color:#2ea043; }
.mm-badge.maybe { background:var(--border); opacity:.85; cursor:help; }
.mm-badge.no    { background:rgba(224,140,0,.16); color:#e08c00; font-weight:600; }
/* แถวยังไม่ตอบ: ขีดเส้นซ้ายสีส้ม กวาดตาเจอเร็ว */
.mm-todo td:first-child { box-shadow: inset 3px 0 0 #e08c00; }
.mm-act { white-space:nowrap; }
.mm-act { display:flex; gap:3px; align-items:flex-start; justify-content:flex-end; }
.mm-goto { font-size:14px; line-height:1; cursor:pointer; padding:6px 8px; min-width:34px;
  border-radius:6px; border:1px solid var(--border); background:transparent; color:inherit; }
.mm-goto:hover { background:var(--border); }
.mm-tf:hover  { background:rgba(74,125,255,.18); }
.mm-phs:hover { background:rgba(255,165,0,.18); }
/* ป้ายใต้ชื่อ = ของสำรองสำหรับจอแคบ · จอกว้างใช้คอลัมน์ "ตอบหรือยัง" จริง */
.mm-by .mm-badge { display:none; }

/* จอเล็กจริง: ลดแพดดิ้ง+รูปเล็กลง ให้คอลัมน์เนื้อหาเหลือที่อ่าน */
@media (max-width:420px) {
  .mm-tb { font-size:12px; }
  .mm-tb td { padding:6px 5px; }
  .mm-by { min-width:70px; font-size:12px; }
  .mm-pic { width:48px; height:48px; }
  /* จอแคบ 3 ปุ่มเรียงนอนกินที่คอลัมน์เนื้อหา → เรียงตั้งแทน */
  .mm-act { flex-direction:column; align-items:center; }
  .mm-goto { padding:5px 6px; min-width:30px; font-size:13px; }
  /* ⚠️⚠️ 4 คอลัมน์บนจอ 360 = ป้าย "ตอบหรือยัง" ตกขอบขวา ต้องเลื่อนข้างจึงเห็น
     = เสียจุดประสงค์ (ต้องกวาดตาเห็นทันทีว่าอันไหนยังไม่ตอบ)
     → ยุบคอลัมน์นั้นทิ้ง ย้ายป้ายไปอยู่ใต้ชื่อคนแท็กแทน (Boss แจ้งขอเนื้อหานี้ 2026-09-02) */
  .mm-tb thead th:nth-child(3), .mm-rep { display:none; }
  .mm-by .mm-badge { display:inline-block !important; margin-top:3px; font-size:10px; }
}

/* ===== XL — ตารางแบบ Excel ในหน้า "แผนของเรา" (Boss สั่ง 2026-09-02) =====
   เลิกดึงจาก Google Sheet แล้ว เว็บเป็นต้นทางจริง → แก้ต้องครบเหมือน Excel
   ⚠️ ห้ามใส่ background ให้ .xl-sel — ช่องมีสีพื้นจากตาราง (inline style) ทับแล้วอ่านไม่ออก
      ใช้ "เงาโปร่งซ้อน" (box-shadow inset) แทน เห็นทั้งช่วงที่เลือกและสีเดิมของช่อง */
table.op-grid.xl-on { outline: none; user-select: none; -webkit-user-select: none; }
table.op-grid.xl-on td.op-cell { cursor: cell; }
.xl-sel { box-shadow: inset 0 0 0 999px rgba(37,99,235,.22); }
/* ช่องที่เล็งอยู่ (active cell) — กรอบหนาแบบ Excel ทับเงาช่วง
   ⚠️ ต้องเป็น outline ไม่ใช่ inset shadow: ช่องกว้าง ~28px กรอบ inset กินพื้นที่ในช่องจนสีเดิมหาย
      outline วาดทับขอบ ไม่เบียดเนื้อในช่อง และไม่ถูก overflow:hidden ของ td ตัด */
.xl-cur { position: relative; z-index: 6; outline: 2px solid #1a73e8; outline-offset: -1px; }
/* วันนี้มีกรอบแดง (inset shadow) อยู่แล้ว — ตอนเป็นช่องที่เล็งอยู่ต้องเห็นน้ำเงินชนะ */
table.op-grid td.op-today.xl-cur { box-shadow: none !important; }
/* ⚠️ กรอบแดง "วันนี้" ตีทุกแถวในคอลัมน์เดียวกัน (8 คน = 8 กรอบเรียงลงมา)
   ตอนมีการเลือกช่วงสีน้ำเงินด้วย มันอ่านเหมือนเลือกไว้ 2 ที่ สับสน
   → ตอนแก้ตาราง (.xl-on) เหลือเส้นแดงข้างซ้าย-ขวาบาง ๆ พอบอกว่าเป็นคอลัมน์วันนี้
     หัวตารางยังมีขีดแดงหนาใต้เลขวันที่อยู่ ไม่ต้องกลัวหาวันนี้ไม่เจอ */
table.op-grid.xl-on td.op-today { box-shadow: inset 1px 0 0 var(--red), inset -1px 0 0 var(--red); }
/* มุมเติมค่า — สี่เหลี่ยมเล็กมุมขวาล่างของช่วง ลากแล้วปูค่าซ้ำ */
.xl-handle { position: absolute; right: -3px; bottom: -3px; width: 7px; height: 7px;
  background: #1a73e8; border: 1px solid #fff; cursor: crosshair; z-index: 5; }
table.op-grid td { position: relative; }
/* ช่องกำลังพิมพ์: ต้องอ่านออกแม้ช่องเดิมกว้าง ~28px → ปล่อยให้ล้นทับช่องข้าง ๆ ชั่วคราว */
.xl-inline { position: absolute; inset: -1px auto -1px -1px; min-width: 88px; z-index: 20;
  background: #fff !important; color: #000 !important; font-size: 12px !important;
  border: 2px solid #1a73e8 !important; box-shadow: 0 2px 8px rgba(0,0,0,.28); }
table.op-grid td.op-editing-cell { overflow: visible; z-index: 20; }

/* แถบเครื่องมือ — มือถือไม่มีคีย์บอร์ด ปุ่มพวกนี้คือทางเดียวที่จะ undo/วาง/เติมค่าได้ */
.xl-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 8px;
  padding: 7px 9px; border: 1px solid var(--border); border-radius: 10px; background: var(--sunken); }
.xl-b { border: 1px solid var(--border); background: var(--card); color: var(--text);
  border-radius: 7px; padding: 6px 10px; font-size: 12px; cursor: pointer; line-height: 1.2; }
.xl-b:hover { border-color: var(--blue); color: var(--blue-dark); }
.xl-b:active { transform: translateY(1px); }
.xl-sep { width: 1px; height: 20px; background: var(--border); margin: 0 2px; }
.xl-hint { font-size: 11px; color: var(--muted); margin-left: auto; }

@media (max-width: 700px) {
  /* จอแคบ: ตารางเหลือ "แถบสี" (font-size:0) → ตัวหนังสือในช่องที่กำลังพิมพ์ต้องรอด
     .xl-inline ใส่ !important ไว้แล้ว แต่กฎ .op-cell .op-m ที่นี่กดทุกลูก จึงต้องยกเว้นให้ input */
  .op-cell input.xl-inline { font-size: 12px !important; color: #000 !important; }
  /* ⚠️ จอ 360x780: ปุ่ม 8 ตัวขึ้นบรรทัดใหม่กินความสูง ~140px ตารางเหลือที่ไม่พอ
     → แถวเดียวเลื่อนข้างแทน (nowrap + overflow-x) ปุ่มยังใหญ่พอกดโดนนิ้ว */
  .xl-bar { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch; scrollbar-width: none; padding: 6px 7px; }
  .xl-bar::-webkit-scrollbar { display: none; }
  .xl-b { padding: 7px 10px; font-size: 12px; min-height: 34px; flex: 0 0 auto; white-space: nowrap; }
  /* คำใบ้ยาว 1 บรรทัดกินที่ — ย้ายไปใต้แถบ ตัวเล็ก 2 บรรทัดพอ */
  .xl-hint { display: none; }
  /* มุมเติมค่าเล็กเกินไปสำหรับนิ้ว — ขยายพื้นที่กดด้วย ::after ที่โปร่งใส */
  .xl-handle { width: 9px; height: 9px; }
  .xl-handle::after { content: ''; position: absolute; inset: -9px; }
}

/* ============================================================
   ประวัติการเข้าชม ←/→/🕒 — Boss สั่ง 2026-09-03
   อยู่ "หัวแถบข้าง" (.sidebar-head) = เห็นทุกหน้า ไม่ใช่แค่ตอนเปิดห้อง
   (ย้ายมาจากท้ายรางเมื่อ 12:06 — Boss แจ้งว่าอยู่ล่างสุดแล้วหายาก)
   ⚠️ ซ่อนบนมือถือด้วยคลาส .only-desktop ที่มีอยู่แล้ว ไม่ต้องเขียน media query ซ้ำ
   ============================================================ */
.navh-bar { display: inline-flex; align-items: center; gap: 1px; margin-right: 6px; flex: 0 0 auto; }
/* ⚠️ ปุ่มแย่งที่จนแบรนด์ "X10 Chat" ตกบรรทัด — กันไว้ให้อยู่บรรทัดเดียวเสมอ */
.sidebar-head .brand { white-space: nowrap; }
.navh-btn {
  background: transparent; border: 0; cursor: pointer;
  color: var(--side-txt, var(--muted, #9aa0a6));
  width: 26px; height: 26px; border-radius: 6px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.navh-btn:hover:not(:disabled) {
  background: var(--side-hover, rgba(255,255,255,.12));
  color: var(--side-strong, #fff);
}
.navh-btn:disabled { opacity: .32; cursor: default; }
.navh-btn svg { width: 16px; height: 16px; display: block; }
.navh-wrap { position: relative; display: inline-flex; }

/* เมนูรายการ — กางลงล่างจากปุ่ม 🕒 */
.navh-menu {
  position: absolute; top: calc(100% + 6px); left: 0;
  min-width: 220px; max-width: 290px; max-height: 330px; overflow-y: auto;
  background: var(--card, #fff); color: var(--txt, #1d1c1d);
  border: 1px solid var(--border, rgba(0,0,0,.12));
  border-radius: 10px; box-shadow: 0 10px 28px rgba(0,0,0,.22);
  padding: 6px; z-index: 90;
}
.navh-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: transparent; border: 0; cursor: pointer; text-align: left;
  padding: 7px 9px; border-radius: 7px;
  font: inherit; font-size: 13.5px; color: inherit;
}
.navh-item:hover { background: var(--hover, rgba(0,0,0,.06)); }
.navh-item.on { font-weight: 700; background: var(--hover, rgba(0,0,0,.06)); }
.navh-dot {
  width: 6px; height: 6px; border-radius: 50%; flex: 0 0 6px;
  background: transparent; border: 1px solid var(--muted, #8a8a8a);
}
.navh-item.on .navh-dot { background: var(--accent, #611f69); border-color: var(--accent, #611f69); }
.navh-tx { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.navh-empty { padding: 10px 12px; font-size: 13px; color: var(--muted, #888); }

/* ============================================================
   หน้าแอดมิน แท็บผู้ใช้ — กลุ่มตามตำแหน่ง + กลุ่มบอท (Boss สั่ง 2026-09-03)
   178 คนกองเดียวหายาก → พับได้เป็นกลุ่ม กดหัวกลุ่มเพื่อกาง/หุบ
   ============================================================ */
.ug-bar { display: flex; gap: 8px; margin: 0 0 8px; }
.ug-empty { padding: 14px 4px; font-size: 13.5px; }
.ug { border-bottom: 1px solid var(--border); }
.ug:last-child { border-bottom: none; }
.ug[hidden] { display: none; }
/* หัวกลุ่ม — เป็นปุ่มเต็มความกว้าง กดที่ไหนก็ได้ (มือถือนิ้วโดนง่าย) */
.ug-head {
  display: flex; align-items: center; gap: 9px; width: 100%;
  min-height: 44px; padding: 10px 4px;
  background: none; border: none; cursor: pointer;
  color: var(--text); font: inherit; text-align: left;
}
.ug-head:hover { background: var(--sunken); }
.ug-caret { flex: 0 0 14px; font-size: 11px; color: var(--muted); }
.ug-ico { flex: 0 0 auto; font-size: 15px; }
.ug-name { flex: 1; min-width: 0; font-size: 14.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ตัวเลขจำนวนคน — เปลี่ยนตามผลค้นหา */
.ug-count {
  flex: 0 0 auto; min-width: 26px; padding: 2px 8px; border-radius: 11px;
  background: var(--sunken); border: 1px solid var(--border);
  color: var(--muted); font-size: 12px; text-align: center;
}
.ug-body { padding-left: 6px; }
.ug-body .cpu-row:last-child { border-bottom: none; }
@media (max-width: 480px) {
  .ug-head { padding: 10px 2px; }
  .ug-body { padding-left: 0; }
}

/* มือถือ: แถวรายชื่อในกลุ่มอยู่บรรทัดเดียว (เดิม .cpu-main flex 1 1 100% ดันชื่อลงบรรทัดใหม่
   ทำให้ป้ายสิทธิ์+ปุ่มจัดการไปลอยอยู่เหนือชื่อ ดูเหมือนของเสีย) — Boss สั่ง mobile first */
@media (max-width: 700px) {
  .ug-body .cpu-row { flex-wrap: nowrap; gap: 9px; }
  .ug-body .cpu-main { flex: 1 1 auto; order: 0; min-width: 0; }
  .ug-body .cpu-name { flex-wrap: nowrap; }
  .ug-body .cpu-name b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ug-body .cpu-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* ป้ายสิทธิ์ยาว ๆ บีบได้ ไม่ให้ดันปุ่มจัดการตกขอบ */
  .ug-body .cpu-rank { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 74px; }
  .ug-body .cpu-row .btn { flex: 0 0 auto; }
}

/* ============================================================
   psel — ช่องเลือกคนแบบค้นหาได้ (โมดัลสร้างงาน / ส่ง Note)
   Boss สั่ง 2026-09-03: รายชื่อ ~90 คน เลื่อนหาเองไม่ไหว ต้องพิมพ์ค้นได้
   mobile first: แผงกางเต็มความกว้าง แถวสูง 44px
   ============================================================ */
.psel-native { display: none !important; }   /* select เดิมยังอยู่ (createTask อ่าน .value) แค่ซ่อน */
.psel { position: relative; margin-bottom: 8px; }
.psel-btn {
  width: 100%; display: flex; align-items: center; gap: 8px; text-align: left;
  padding: 10px 12px; min-height: 44px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--card); color: var(--text); font-size: 15px; font-family: inherit; cursor: pointer;
}
.psel-btn:focus-visible { outline: 2px solid var(--blue); outline-offset: -1px; }
.psel-val { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.psel-val.psel-empty { color: var(--muted); }
.psel-caret { color: var(--muted); font-size: 12px; flex-shrink: 0; }
/* แผงกางแบบอยู่ในสายไหลของโมดัล (ดันโมดัลสูงขึ้น) ไม่ใช้ absolute
   เพราะ .modal มี overflow-y:auto — ถ้า absolute แผงจะถูกตัดที่ขอบล่างโมดัล
   เหลือเห็นแค่ 1-2 แถว (บั๊กเดียวกับ .composer overflow:hidden ที่เคยกินป๊อปอัป ＋) */
.psel-pop {
  margin-top: 4px; background: var(--sunken); border: 1px solid var(--border); border-radius: 10px;
  padding: 8px; display: flex; flex-direction: column; gap: 6px;
}
.psel-q { margin-bottom: 0; background: var(--card); }
.psel-list { max-height: 240px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.psel-item {
  padding: 11px 12px; min-height: 44px; display: flex; align-items: center;
  border-radius: 8px; cursor: pointer; font-size: 15px;
}
.psel-item.hi { background: var(--blue-light); }
.psel-item.sel { color: var(--blue); font-weight: 600; }
.psel-none { padding: 12px; color: var(--muted); font-size: 14px; text-align: center; }

/* เลือกได้หลายคน (งานติดตาม) — ชิปชื่อบนปุ่ม + ช่องติ๊กในรายการ
   mobile first 360px: ชื่อไทย 3 ชื่อไม่พอบรรทัดเดียว ปุ่มต้องยอมขึ้นบรรทัดใหม่ */
.psel-btn:has(.psel-chip) { align-items: flex-start; }
.psel-val:has(.psel-chip) { display: flex; flex-wrap: wrap; gap: 4px; white-space: normal; overflow: visible; }
.psel-chip {
  display: inline-block; max-width: 100%; padding: 2px 8px; border-radius: 999px;
  background: var(--blue-light); color: var(--blue); font-size: 13px; line-height: 18px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.psel-chip.more { background: var(--border); color: var(--muted); }
.psel-tick { display: inline-block; width: 20px; flex-shrink: 0; }
.psel-item { gap: 6px; }

/* ============================================================
   แท็กห้องด้วย # + ส่งต่อแบบจัดกลุ่ม (Boss สั่ง 2026-09-03)
   ============================================================ */
/* ชิป #ห้อง ในข้อความ — กดแล้วเด้งเข้าห้อง */
.mention.hashtag { cursor: pointer; }
.mention.hashtag:hover { text-decoration: underline; }
.hash-ic { display: inline-flex; width: 22px; justify-content: center; opacity: .7; font-weight: 700; }
/* ป๊อปอัพ @/# ในโมดัลส่งต่อ — โมดัลไม่มี composer ให้วัด เลยวางเหนือช่องพิมพ์ตรง ๆ */
.fw-note-wrap { position: relative; }
.fw-pop { position: absolute; left: 0; right: 0; bottom: 100%; margin-bottom: 6px; max-height: 200px; }
/* หัวข้อกลุ่มห้องในรายการส่งต่อ */
.fw-sec {
  display: flex; align-items: center; gap: 7px;
  padding: 9px 6px 5px; margin-top: 2px;
  font-size: 12px; font-weight: 700; color: var(--muted);
  text-transform: none; letter-spacing: .2px;
  position: sticky; top: 0; background: var(--card); z-index: 1;
}
.fw-sec-ic { opacity: .8; }
.fw-sec-n {
  margin-left: auto; padding: 1px 7px; border-radius: 9px;
  background: var(--sunken); border: 1px solid var(--border); font-weight: 600;
}

/* ============================================================
   หน้าแจ้งเตือน — หน้าตาแบบ Slack Activity (Boss สั่ง 2026-09-03 + ส่งรูป)
   แถวแบน ไม่ใช่การ์ดกรอบหนา · คั่นวันที่ · ตอบกลับได้ในหน้าเดียว
   ============================================================ */
/* เส้นคั่นวันที่ — ชื่อวันอยู่กลาง มีเส้นบางลากผ่าน (เหมือน Slack) */
.ntf-day {
  display: flex; align-items: center; gap: 10px;
  margin: 14px 2px 6px; color: var(--muted);
  font-size: var(--fs-xs); font-weight: 700;
}
.ntf-day::before, .ntf-day::after { content: ''; flex: 1; height: 1px; background: var(--border); }
.ntf-list { gap: 0; }
/* แถวแจ้งเตือน — แบน ๆ มีเส้นคั่นล่าง ไม่ใช่กล่องลอย */
.ntf-item {
  display: block; padding: 0; background: none; border: none;
  border-bottom: 1px solid var(--border); border-radius: 0; cursor: default;
}
.ntf-item:hover { border-color: var(--border); }
.ntf-item.read { opacity: 1; }                 /* อ่านแล้วไม่ต้องจางทั้งใบ ใช้สีตัวอักษรบอกพอ */
.ntf-item.read .ntf-head { color: var(--muted); font-weight: 400; }
.ntf-row {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 8px; cursor: pointer; border-radius: var(--radius);
  border-left: 3px solid transparent;
}
.ntf-row:hover { background: var(--sunken); }
/* ยังไม่อ่าน = แถบซ้ายน้ำเงิน + พื้นอ่อน (Slack ใช้จุดน้ำเงิน เราคงแถบเดิมที่คนคุ้นแล้ว) */
.ntf-item.unread .ntf-row { border-left-color: var(--blue); background: var(--blue-light); }
.ntf-item.unread .ntf-head { font-weight: 600; }
.ntf-ico { flex: 0 0 auto; width: 20px; text-align: center; color: var(--muted); padding-top: 3px; }
.ntf-main { flex: 1 1 auto; min-width: 0; }
/* หัวเรื่อง + เวลา อยู่บรรทัดเดียวกัน เวลาชิดขวาแบบ Slack */
.ntf-top { display: flex; align-items: baseline; gap: 10px; }
.ntf-head { flex: 1; min-width: 0; font-size: var(--fs-md); line-height: 1.4; }
.ntf-time { flex: 0 0 auto; font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }
/* บรรทัดบอกที่มา: "ตอบกลับใน #ห้อง" */
.ntf-where { margin-top: 2px; font-size: var(--fs-xs); color: var(--muted); }
.ntf-room, .ntf-dm {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 6px; border-radius: 5px;
  background: var(--sunken); border: 1px solid var(--border); color: var(--text);
}
.ntf-body { margin-top: 4px; color: var(--text); opacity: .85; }
.ntf-item.read .ntf-body { color: var(--muted); opacity: 1; }
/* ปุ่มลบ — ซ่อนไว้ก่อน โผล่ตอน hover (มือถือโชว์ตลอด นิ้วไม่มี hover) */
.ntf-x { opacity: 0; transition: opacity .12s; }
.ntf-row:hover .ntf-x { opacity: 1; }
/* แถวปุ่มจัดการ: ตอบกลับ / ไปที่ข้อความ */
.ntf-acts { display: flex; gap: 6px; padding: 0 8px 9px 62px; }
.ntf-act {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 11px; min-height: 30px;
  background: var(--card); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: var(--fs-xs); font-weight: 600; cursor: pointer;
}
.ntf-act:hover { background: var(--sunken); border-color: var(--blue); color: var(--blue); }
/* ---- ป้าย "รับรู้แล้ว / เสร็จแล้ว" (Boss สั่ง 2026-09-06) ----
   เป็นของส่วนตัวรายคน · คนละเรื่องกับ "อ่านแล้ว" ที่ระบบติ๊กเองตอนเปิดดู
   mobile-first: ปุ่มสูง 34px แตะง่ายบนจอ 360 · ปุ่มพวกนี้โชว์ทั้งมือถือและคอม */
.ntf-mark { white-space: nowrap; }
.ntf-mark.on-ack { background: var(--sunken); border-color: var(--muted); color: var(--muted); }
.ntf-mark.on-done { background: color-mix(in srgb, var(--green) 14%, transparent); border-color: var(--green); color: var(--green); }
.ntf-mark.on-done:hover { border-color: var(--green); color: var(--green); }
/* ป้ายบนหัวแถว — บอกสถานะโดยไม่ต้องมองปุ่ม */
.ntf-st {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 7px; border-radius: var(--radius-pill, 999px);
  font-size: var(--fs-xs); font-weight: 700; line-height: 1.7;
}
.ntf-st.ack { background: var(--sunken); color: var(--muted); }
.ntf-st.done { background: color-mix(in srgb, var(--green) 14%, transparent); color: var(--green); }
/* ใบที่ทำเสร็จแล้ว หรี่ลงให้สายตาไปโฟกัสงานที่ยังค้าง (แต่ยังอ่านออก) */
.ntf-item.st-done .ntf-main { opacity: .62; }
.ntf-item.st-done { border-left: 3px solid var(--green); }
.ntf-item.st-ack { border-left: 3px solid var(--border); }
/* กล่องตอบกลับในหน้าแจ้งเตือน */
.ntf-rbox { position: relative; display: flex; gap: 6px; align-items: flex-end; padding: 0 8px 10px 62px; }
.ntf-rbox.hidden { display: none; }
.ntf-rta {
  flex: 1; min-height: 38px; max-height: 120px; padding: 9px 11px;
  background: var(--sunken); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  font: inherit; font-size: var(--fs-sm); resize: none;
}
.ntf-rta:focus { outline: none; border-color: var(--blue); }
.ntf-rpop { position: absolute; left: 62px; right: 8px; bottom: 100%; margin-bottom: 6px; max-height: 190px; }

@media (max-width: 640px) {
  /* มือถือ: ปุ่มลบโชว์ตลอด (ไม่มี hover) · ปุ่มจัดการเลื่อนชิดซ้ายขึ้น ไม่งั้นตกขอบ */
  .ntf-x { opacity: .55; }
  .ntf-acts, .ntf-rbox { padding-left: 10px; }
  .ntf-rpop { left: 10px; }
  .ntf-row { padding: 9px 6px; gap: 8px; }
  .ntf-act { min-height: 34px; }
}

/* ============================================================
   หน้าแจ้งเตือน 2 ฝั่งแบบ Slack Activity (Boss สั่ง 2026-09-03)
   คอม: ซ้ายรายการ / ขวาเธรดเต็ม · มือถือ: ขวาสไลด์ทับเต็มจอ
   ============================================================ */
.ntf-split { display: flex; gap: 14px; align-items: flex-start; }
.ntf-split .ntf-list { flex: 1 1 0; min-width: 0; }
.ntf-detail {
  flex: 1.15 1 0; min-width: 0; position: sticky; top: 0;
  max-height: calc(100vh - 190px); display: flex; flex-direction: column;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden;
}
.ntf-dt-empty { padding: 40px 20px; text-align: center; color: var(--muted); font-size: var(--fs-sm); }
.ntf-dt-wrap { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.ntf-dt-wrap.hidden { display: none; }
.ntf-dt-head {
  display: flex; align-items: center; gap: 8px; flex: 0 0 auto;
  padding: 10px 12px; border-bottom: 1px solid var(--border); background: var(--sunken);
}
.ntf-dt-back { display: none; background: none; border: 0; color: var(--text); font-size: 22px; cursor: pointer; padding: 0 4px; }
.ntf-dt-ch { flex: 1; min-width: 0; color: var(--muted); font-size: var(--fs-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ปุ่ม "↗ ไปที่ข้อความ" ในหัวแผงเธรด — ติดป้ายแล้ว (เดิมเป็น ↗ เปล่าไม่มีใครรู้ว่าคืออะไร)
   ⚠️ .ntf-dt-ch มี flex:1 อยู่ข้างกัน ถ้าไม่กัน ปุ่มจะโดนบีบจนคำขึ้นบรรทัดใหม่บนจอแคบ */
.ntf-dt-open { flex: 0 0 auto; white-space: nowrap; }
.ntf-dt-x { background: none; border: 0; color: var(--muted); cursor: pointer; font-size: 15px; padding: 2px 5px; border-radius: var(--radius-sm); }
.ntf-dt-x:hover { background: var(--border); color: var(--red); }
.ntf-dt-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 10px 12px; }
.ntf-dt-load { padding: 26px 10px; text-align: center; color: var(--muted); font-size: var(--fs-sm); }
/* ข้อความในเธรด — ใช้ฟองข้อความชุดเดียวกับห้องแชท (Boss สั่ง 2026-09-06)
   .msg / .msg-bubble / .react-row / .msg-under มีสไตล์กลางอยู่แล้ว ที่นี่แค่ปรับให้เข้ากับแผงแคบ
   ⚠️ ยืมกฎชุดเดียวกับ .thr-body: ในแผงไม่ใช่ไทม์ไลน์ ข้อความตัวเองต้องชิดซ้ายเหมือนคนอื่น */
.ntf-dt-body .msg.mine { flex-direction: row; }
.ntf-dt-body .msg.nested { margin-left: 0; }
.ntf-dt-body .thr-bar { display: none; }
/* ใบที่ถูกแจ้งเตือนพูดถึง — แถบน้ำเงินซ้าย (แทน .ntf-dtm.hit เดิม) */
.ntf-dt-body .msg.ntf-hit > .msg-body > .msg-bubble { box-shadow: inset 3px 0 0 var(--blue); }
/* รูป/อัลบั้มในแผงแคบ ห้ามดันจนล้น */
.ntf-dt-body .msg-image, .ntf-dt-body .msg-video { max-height: 240px; }
/* เส้นคั่น "N คำตอบ" ใช้ .thr-sep ชุดเดียวกับแผงเธรด — แค่ลด padding ซ้ายขวาให้พอดีแผงแคบ */
.ntf-dt-body .thr-sep { padding-left: 4px; padding-right: 4px; }
/* ช่องตอบกลับท้ายฝั่งขวา */
/* ⚠️ เพิ่มแถบไฟล์แนบแล้ว (2026-09-06) → ต้องเรียงลง "แนวตั้ง" (ไฟล์อยู่บน แถวพิมพ์อยู่ล่าง)
   ของเดิมเป็น flex แนวนอน ถ้าคงไว้ แถบไฟล์จะไปเบียดอยู่ข้างช่องพิมพ์จนแคบใช้ไม่ได้ */
.ntf-dt-foot {
  position: relative; flex: 0 0 auto; display: flex; flex-direction: column; gap: 7px;
  padding: 9px 12px; border-top: 1px solid var(--border); background: var(--sunken);
}
/* แถวพิมพ์: 📎 + ช่องพิมพ์ + ปุ่มส่ง
   ⚠️ align-items:stretch ไม่ใช่ flex-end — ปุ่ม 📎/ส่ง ต้องสูงเท่าช่องพิมพ์
      (flex-end ทำให้ 📎 สูง 38 แต่ปุ่มส่ง 44 = ขอบล่างเหลื่อมกัน) */
.ntf-dt-inrow { display: flex; gap: 7px; align-items: stretch; }
.ntf-dt-attach {
  flex: 0 0 auto; width: 38px; min-height: 40px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--card); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  font-size: 17px; cursor: pointer; line-height: 1;
}
.ntf-dt-attach:hover { border-color: var(--blue); background: var(--sunken); }
/* แถบไฟล์ในช่องนี้ไม่ต้องมีเส้นคั่น/ระยะของช่องคอมเมนต์ */
.ntf-dt-foot .ir-files { margin: 0; padding: 0; border: 0; }
/* ⚠️ min-height 38px เตี้ยไปหลังมีปุ่ม 📎 มาแบ่งความกว้าง — ข้อความชี้นำ
   "พิมพ์ตอบกลับ… (@ แท็กคน · # ห้อง)" ตกไป 2 บรรทัดแล้วโดนตัดครึ่ง (วัดได้ 68px ในกล่อง 43px) */
.ntf-dt-foot textarea {
  flex: 1; min-height: 40px; max-height: 120px; padding: 9px 11px;
  background: var(--card); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  font: inherit; font-size: var(--fs-sm); resize: none;
}
.ntf-dt-foot textarea:focus { outline: none; border-color: var(--blue); }
.ntf-dt-pop { position: absolute; left: 12px; right: 12px; bottom: 100%; margin-bottom: 6px; max-height: 200px; }
/* ใบที่กำลังเปิดอยู่ฝั่งขวา */
.ntf-item.active .ntf-row { background: var(--blue-light); box-shadow: inset 0 0 0 1px var(--blue); }
/* แถบสถานะอ่าน/ยังไม่อ่าน (ชิปเล็ก) */
.ntf-subbar { display: flex; align-items: center; gap: 6px; margin: 8px 0 4px; }
.ntf-sub {
  padding: 4px 11px; border-radius: 999px; cursor: pointer;
  background: transparent; border: 1px solid var(--border);
  color: var(--muted); font-size: var(--fs-xs); font-weight: 600;
}
.ntf-sub.active { background: var(--blue-light); border-color: var(--blue); color: var(--blue); }
.ntf-sub-n { opacity: .85; }
.ntf-sub-sp { flex: 1; }
.ntf-tab-n.zero { opacity: .45; }

@media (max-width: 900px) {
  /* มือถือ/แท็บเล็ต: ฝั่งขวาสไลด์ทับเต็มจอ (Slack ก็ทำแบบนี้) */
  .ntf-split { display: block; }
  .ntf-detail {
    position: fixed; inset: 0; z-index: 60; max-height: none;
    border: none; border-radius: 0;
    transform: translateX(100%); transition: transform .18s ease;
  }
  .ntf-split.show-detail .ntf-detail { transform: none; }
  .ntf-split:not(.show-detail) .ntf-detail { pointer-events: none; }
  .ntf-dt-back { display: block; }
  .ntf-dt-x { display: none; }
  .ntf-dt-empty { display: none; }
  .ntf-dt-pop { left: 12px; right: 12px; }
}

/* มือถือ: เธรดฝั่งขวาเปิดเต็มจอ ต้องไม่ให้แถบแท็บล่างบังช่องตอบกลับ
   ⚠️ .x10m-tabbar เป็น fixed z-index 60 สูงเท่ากับแผงนี้พอดี → ต้องยกแผงขึ้นเหนือ
      และเว้นที่ท้ายให้พ้นแถบ + safe-area (ดู --x10m-tabbar-h ใน mobile.css) */
@media (max-width: 900px) {
  .ntf-detail { z-index: 62; }
  .ntf-dt-foot {
    padding-bottom: calc(9px + var(--x10m-tabbar-h, 0px) + var(--x10m-safe-b, 0px));
  }
}

/* ============================================================
   หน้าแจ้งเตือน — จัดระเบียบหัวหน้า (Boss สั่ง 2026-09-03 + ส่งรูป)
   เดิม 4 แถวซ้อนกันจนรายการจริงถูกดันลงเกือบสุดจอ → เหลือแท็บ + แถบเครื่องมือแถวเดียว
   ============================================================ */
/* แท็บหมวด — เตี้ยลง เส้นใต้บอกอันที่เลือก (แทนกล่องกรอบหนา) */
.ntf-tabs {
  display: flex; gap: 2px; margin: 0 0 2px;
  background: none; border: none; border-bottom: 1px solid var(--border); padding: 0;
}
.ntf-tab {
  flex: 1; min-width: 0; padding: 9px 6px 8px;
  background: none; border: none; border-bottom: 2px solid transparent;
  color: var(--muted); font-size: var(--fs-sm); font-weight: 600; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ntf-tab:hover { color: var(--text); }
.ntf-tab.active { color: var(--blue); border-bottom-color: var(--blue); background: none; }
.ntf-tab-n {
  padding: 1px 6px; border-radius: 9px; font-size: 11px; font-weight: 700;
  background: var(--sunken); border: 1px solid var(--border); color: var(--muted);
}
.ntf-tab.active .ntf-tab-n { background: var(--blue); border-color: var(--blue); color: #fff; }
.ntf-tab-n.zero { opacity: .4; }
/* แถบเครื่องมือแถวเดียว */
.ntf-bar { display: flex; align-items: center; gap: 7px; margin: 9px 0 6px; flex-wrap: wrap; }
.ntf-bar-sp { flex: 1; }
/* กลุ่มปุ่มสถานะติดกันเป็นชิ้นเดียว (segmented) ดูเป็นระเบียบกว่าชิปลอย 3 อัน */
.ntf-seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.ntf-seg .ntf-sub {
  border: none; border-radius: 0; background: var(--card);
  padding: 6px 13px; font-size: var(--fs-xs); font-weight: 600; color: var(--muted); cursor: pointer;
}
.ntf-seg .ntf-sub + .ntf-sub { border-left: 1px solid var(--border); }
.ntf-seg .ntf-sub:hover { background: var(--sunken); color: var(--text); }
.ntf-seg .ntf-sub.active { background: var(--blue); color: #fff; }
.ntf-sub-n { opacity: .9; font-weight: 700; }
/* ปุ่มเครื่องมือฝั่งขวา (ตัวกรอง / ตั้งค่าเสียง) */
.ntf-tool {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; min-height: 32px;
  background: var(--card); border: 1px solid var(--border); border-radius: 8px;
  color: var(--muted); font-size: var(--fs-xs); font-weight: 600; cursor: pointer;
}
.ntf-tool:hover { color: var(--text); border-color: var(--blue); }
.ntf-tool.on { background: var(--sunken); color: var(--text); border-color: var(--blue); }
/* กรองชนิดอยู่ = ปุ่มเปลี่ยนสี + บอกว่ากรองอะไรอยู่ (ไม่งั้นยุบชิปไว้แล้วงงว่าของหาย) */
.ntf-tool.filtering { background: var(--blue-light); border-color: var(--blue); color: var(--blue); }
.ntf-tool-n { padding: 1px 7px; border-radius: 8px; background: var(--blue); color: #fff; font-size: 11px; }
/* แผงที่ยุบไว้ */
.ntf-kinds.hidden, .ntfmgr-panel.hidden { display: none; }
.ntf-kinds {
  display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 8px;
  padding: 9px; background: var(--sunken); border: 1px solid var(--border); border-radius: 8px;
}
.ntfmgr-panel {
  margin: 0 0 8px; background: var(--sunken);
  border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
}
/* รายการเริ่มต้นชิดขึ้น ไม่ต้องเว้นเยอะ */
.ntf-list .ntf-day:first-child { margin-top: 4px; }

@media (max-width: 640px) {
  .ntf-tab { font-size: var(--fs-xs); padding: 9px 3px 8px; gap: 4px; }
  .ntf-tab-n { padding: 0 5px; font-size: 10px; }
  .ntf-bar { gap: 6px; }
  .ntf-seg .ntf-sub { padding: 6px 10px; }
  .ntf-tool { padding: 6px 10px; }
}

/* แผงตั้งค่าเสียงมี 60+ ห้อง — จำกัดความสูงให้เลื่อนในตัวเอง
   ไม่งั้นกางทีเดียวดันรายการแจ้งเตือนตกจอ (เจอตอนแคปเทส 2026-09-03) */
.ntfmgr-panel .ntfmgr-body { max-height: 260px; overflow-y: auto; padding: 10px; }
.ntfmgr-panel .ntfmgr-top { display: flex; gap: 6px; margin-bottom: 8px; position: sticky; top: 0; background: var(--sunken); z-index: 1; }
.ntfmgr-panel .ntf-q { flex: 1; min-width: 0; }

/* มือถือ: แท็บ 4 อันเบียดกันจนตัวหนังสือโดนตัด + แถบเครื่องมือตกบรรทัด
   → แท็บเลื่อนแนวนอนได้ (ไม่บีบให้พอดีจอ) · เครื่องมือแถวเดียวเลื่อนได้เหมือนกัน */
@media (max-width: 640px) {
  .ntf-tabs {
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none; gap: 0;
  }
  .ntf-tabs::-webkit-scrollbar { display: none; }
  .ntf-tab { flex: 0 0 auto; padding: 9px 12px 8px; }
  .ntf-bar {
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none; padding-bottom: 2px;
  }
  .ntf-bar::-webkit-scrollbar { display: none; }
  .ntf-bar > * { flex: 0 0 auto; }
  .ntf-bar-sp { display: none; }
}

/* ============================================================
   มือถือ: หัวหน้าเหลือแค่แท็บแถวเดียว (Boss สั่ง 2026-09-03 "มือถือใช้ยากไป")
   เดิมหัวหน้ากิน 253px จาก 780px = 1/3 จอ เห็นแจ้งเตือนแค่ 4 ใบ
   → เครื่องมือทั้งหมดยุบหลังปุ่ม ⚙ · การ์ดตัดปุ่มออก (แตะที่ใบเปิดเธรดอยู่แล้ว)
   ⚠️ เฉพาะมือถือ — คอมคงเดิมทุกอย่าง
   ============================================================ */
/* .ntf-acts เป็น block ใช้ .only-desktop (inline-flex) ตรง ๆ ไม่ได้ ต้องคุมเอง */
.ntf-acts.only-desktop { display: flex; }
/* แถวปุ่ม "ตัวกรอง / ตั้งค่า" — อยู่นอกแถบแท็บแล้ว จึงเป็นปุ่มมีกรอบมีคำกำกับ ไม่ใช่ไอคอนเปล่า
   โชว์ทั้งคอมและมือถือ (ปุ่มตั้งค่าอยู่ในนี้) · ปุ่มตัวกรองเองยังเป็น .only-mobile */
.ntf-gearrow { display: flex; gap: 7px; flex-wrap: wrap; align-items: center; margin: 8px 0 2px; }
.ntf-gear {
  display: inline-flex; align-items: center; gap: 6px; position: relative;
  min-height: 40px; padding: 6px 12px;
  background: var(--card); border: 1px solid var(--border); border-radius: 8px;
  color: var(--muted); font: inherit; font-size: var(--fs-xs); font-weight: 600; cursor: pointer;
}
.ntf-gear:active { background: var(--sunken); }
/* กำลังอยู่หน้าตั้งค่า = ปุ่มต้องบอกให้รู้ (ไม่มีแท็บ active ให้ดูแล้ว) */
.ntf-gear.on { background: var(--blue-light); border-color: var(--blue); color: var(--blue); }
.ntf-gear-dot {
  position: absolute; top: -3px; right: -3px;
  width: 9px; height: 9px; border-radius: 50%; background: var(--blue);
  border: 2px solid var(--bg, #fff);
}
@media (max-width: 860px) {
  .ntf-acts.only-desktop { display: none !important; }
  /* ปุ่ม "ไปที่ข้อความ" โผล่บนมือถือแล้ว (พี่ปองแจ้ง 2026-09-16 — เดิม .only-desktop
     ทำให้ไม่มีทางเข้าห้องไปอ่านบริบทก่อนหน้า) ⇒ ต้องได้ขนาดนิ้วกด 44px เหมือนปุ่มอื่นในหน้านี้
     และห้ามโดนบีบจนคำขึ้นบรรทัดใหม่เวลามีปุ่ม 👀/✅ อยู่ด้วยกันในแถวเดียว */
  .ntf-act.ntf-goto, .ntf-act.ntf-reply { min-height: 40px; white-space: nowrap; }
  /* 4 ปุ่มแล้ว (ตอบกลับ/ไปที่ข้อความ/👀/✅) ที่ 360px ต้องยอมตกบรรทัด ห้ามล้นแนวนอน */
  .ntf-acts { flex-wrap: wrap; }
  /* แถบเครื่องมือยุบไว้ กด ⚙ ถึงกาง */
  .ntf-bar { display: none; }
  .ntf-bar.open { display: flex; }
  /* นิ้วกดง่าย: ทุกปุ่มอย่างน้อย 44px (เดิม 30-38px กดพลาดบ่อย) */
  .ntf-tab { min-height: 44px; }
  .ntf-seg .ntf-sub { min-height: 40px; padding: 8px 13px; }
  .ntf-tool { min-height: 40px; }
  .ntf-x { min-width: 40px; min-height: 40px; }
  /* การ์ดเตี้ยลง เห็นได้มากขึ้น */
  .ntf-row { padding: 11px 8px; }
  .ntf-item { border-bottom-color: var(--border); }
}

/* เมนู ⋯ หัวหน้าแจ้งเตือน (มือถือเท่านั้น) */
.ntf-more-btn { font-size: 20px; line-height: 1; }
.ntf-hmenu {
  position: fixed; z-index: 90; min-width: 170px; padding: 5px;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 10px 28px rgba(0,0,0,.28);
  display: flex; flex-direction: column; gap: 2px;
}
.ntf-hmenu button {
  padding: 11px 13px; min-height: 44px; text-align: left;
  background: none; border: none; border-radius: 7px;
  color: var(--text); font: inherit; font-size: var(--fs-sm); cursor: pointer;
}
.ntf-hmenu button:hover { background: var(--sunken); }

/* มือถือ: เนื้อข้อความสำคัญกว่าหัวเรื่อง (Boss แจ้ง 2026-09-19)
   ⚠️⚠️ เดิมกลับกัน: .ntf-head 2 บรรทัด + .ntf-body **1 บรรทัด**
      → หัวเรื่อง "X แท็กคุณใน #ห้อง" กินพื้นที่หมด ส่วนข้อความที่เขาพิมพ์จริง
        เหลือบรรทัดเดียวโดนตัด … แทบทันที = "ไม่แสดงว่าคนที่แท็กเราพิมอะไรมาบ้าง"
      ⇒ สลับน้ำหนัก: หัวเรื่อง 1 บรรทัด (รู้ว่าใคร/เรื่องอะไรก็พอ) · เนื้อข้อความ 3 บรรทัด
   ⚠️ zip camshare 2026-09-19 เคยเอาค่าเดิม 2/1 กลับมาทับ — ใส่คืนแล้ว */
@media (max-width: 860px) {
  .ntf-head { display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
  .ntf-body { -webkit-line-clamp: 3; margin-top: 3px; }
  .ntf-where { margin-top: 1px; }
  .ntf-row { gap: 9px; }
  .ntf-ico { display: none; }        /* ไอคอนซ้ำกับอวาตาร์ — มือถือพื้นที่มีค่า ตัดทิ้ง */
}

/* กลับจากเธรดแล้วไฮไลต์ใบที่เพิ่งดูแวบนึง — ให้รู้ว่ากลับมาอยู่ตรงไหน */
.ntf-item.just-back .ntf-row { animation: ntfBack 1.4s ease-out; }
@keyframes ntfBack {
  0%, 45% { background: var(--blue-light); box-shadow: inset 3px 0 0 var(--blue); }
  100% { background: transparent; box-shadow: none; }
}

/* ================= แท็บที่ 5 "ตั้งค่า" หน้าการแจ้งเตือน (Boss สั่ง 2026-09-04) =================
   รวบตั้งค่าที่เคยกระจาย 4 ที่มาไว้ที่เดียว · 3 บล็อก: ทั่วไป / รายห้อง 3 ระดับ / รายหมวด
   ⚠️ ห้ามฮาร์ดโค้ดสี ใช้ตัวแปรธีมล้วน ไม่งั้นโหมดมืดพัง
   ⚠️ mobile first — ปุ่ม 3 ระดับต้องกว้างเต็มแถวที่ 360px ให้นิ้วแตะติด */
.ntf-set { display: flex; flex-direction: column; gap: var(--s3); padding-bottom: var(--s4); }
.ntf-set.hidden { display: none; }

/* แท็บที่ 5 ไม่มีตัวเลข ปล่อยให้แคบกว่าเพื่อนได้ ไม่ต้องกินพื้นที่เท่ากัน */

.ntfs-card {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--s3);
}
.ntfs-h { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2); margin-bottom: var(--s3); }
.ntfs-h b { font-size: var(--fs-lg); color: var(--text); }
.ntfs-h .muted { font-size: var(--fs-sm); }

.ntfs-row {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s2) 0; border-top: 1px solid var(--border);
}
.ntfs-row:first-of-type { border-top: 0; }
.ntfs-row.ntfs-col { flex-direction: column; align-items: stretch; }
.ntfs-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ntfs-tx b { font-size: var(--fs-md); color: var(--text); }
.ntfs-tx .muted { font-size: var(--fs-sm); }

/* คำอธิบาย 3 ระดับ — กันคนกดผิดว่า "ปิด" กับ "เฉพาะแท็ก" ต่างกันยังไง */
.ntfs-legend {
  display: flex; flex-direction: column; gap: 4px;
  background: var(--sunken); border-radius: var(--radius-sm);
  padding: var(--s2); margin-bottom: var(--s3);
  font-size: var(--fs-sm); color: var(--muted);
}
.ntfs-legend b { margin-right: 4px; }

.ntfs-top { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s2); }
.ntfs-top .ntf-q { flex: 1 1 140px; min-width: 0; }

.ntfs-rooms {
  max-height: 420px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.ntfs-room {
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s2) var(--s3); border-top: 1px solid var(--border);
}
.ntfs-room:first-child { border-top: 0; }
.ntfs-room-n {
  flex: 1; min-width: 0; font-size: var(--fs-md); color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ปุ่ม 3 ระดับเรียงติดกัน — แตะเลือกได้เลย ไม่ต้องเปิดเมนู */
.ntfs-seg {
  display: inline-flex; flex: 0 0 auto;
  background: var(--sunken); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 2px; gap: 2px;
}
.ntfs-lv {
  display: inline-flex; align-items: center; gap: 4px;
  min-height: 32px; padding: 4px 8px;
  border: 0; background: transparent; color: var(--muted);
  font: inherit; font-size: var(--fs-sm); cursor: pointer;
  border-radius: calc(var(--radius-sm) - 2px); white-space: nowrap;
}
.ntfs-lv i { font-style: normal; font-size: 14px; line-height: 1; }
/* คอม: โชว์เฉพาะไอคอน ประหยัดที่ (ชื่อระดับอยู่ใน title + แถบคำอธิบายด้านบน) */
.ntfs-lv em { display: none; font-style: normal; }
.ntfs-lv:hover { background: var(--card); color: var(--text); }
/* ⚠️ อีโมจิไม่รับ CSS color — ไฮไลต์ด้วย "พื้น+ขอบ+ความทึบ" แทนสีตัวอักษร
   ตัวที่ไม่ได้เลือกทำให้จางลง (opacity .45) ตัวที่เลือกทึบเต็ม + มีขอบสีน้ำเงิน
   ไม่งั้นทั้ง 3 ปุ่มดูเหมือนกันหมด แยกไม่ออกว่าอันไหนถูกเลือก */
.ntfs-lv i { opacity: .45; filter: grayscale(.6); transition: opacity .12s, filter .12s; }
.ntfs-lv.on {
  background: var(--card); color: var(--blue); font-weight: 600;
  box-shadow: 0 0 0 2px var(--blue) inset;
}
.ntfs-lv.on i { opacity: 1; filter: none; }

@media (max-width: 640px) {
  /* ⚠️⚠️ ประวัติ 2 รอบ — อ่านก่อนแก้:
     รอบ 1: ปล่อย 5 แท็บเลื่อนแนวนอน → แท็บ "ตั้งค่า" หลุดจอ ไม่มีอะไรบอกว่ามีอยู่
     รอบ 2: ตรึงแท็บตั้งค่าลอยขวาสุดเป็นไอคอน ⚙ → **ทับแท็บ "เธรด" 63px จนหายทั้งอัน**
             + ไปซ้ำกับปุ่ม ⚙ ตัวกรองที่อยู่ข้าง ๆ = ⚙ 2 อันคนละหน้าที่ ผู้ใช้แยกไม่ออก
             (Boss ส่งรูปมา 2026-09-04 "ดูบัคและเบียดแท็บ 4")
     รอบนี้: ไม่ตรึงอะไรลอยทับใครทั้งนั้น — แถบแท็บ "เลื่อนแนวนอนได้จริง" (overflow-x)
             + มีเงาขอบขวาบอกว่ายังมีต่อ · ปุ่ม ⚙ ตัวกรองย้ายออกจากแถบแท็บไปอยู่แถวเนื้อหา
     ⚠️ ห้ามเอา position:absolute กลับมาใส่ในแถบนี้อีก */
  .ntf-tabs {
    overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch;      /* iOS: เลื่อนลื่น ไม่งั้นฝืดมาก */
    scrollbar-width: none;
    /* เงาจาง ๆ ขอบขวา = สัญญาณว่ายังมีแท็บต่อ (แก้ปัญหารอบ 1 ที่ผู้ใช้ไม่รู้ว่ามีของซ่อน) */
    background:
      linear-gradient(to left, var(--bg, #fff), transparent) right / 18px 100% no-repeat;
  }
  .ntf-tabs::-webkit-scrollbar { display: none; }
  /* ทุกแท็บกว้างตามเนื้อหา ไม่บีบกัน — เลื่อนเอา */
  .ntf-tabs > .ntf-tab { flex: 0 0 auto; padding-left: 10px; padding-right: 10px; }

  /* มือถือ: ชื่อห้องขึ้นบรรทัดบน ปุ่ม 3 ระดับกว้างเต็มแถวข้างล่าง แตะง่าย */
  .ntfs-room { flex-wrap: wrap; }
  .ntfs-room-n { flex: 1 1 100%; }
  .ntfs-seg { flex: 1 1 100%; }
  .ntfs-lv { flex: 1; justify-content: center; min-height: 40px; }
  .ntfs-lv em { display: inline; }        /* มือถือมีที่พอ โชว์ชื่อระดับด้วย ชัดกว่าไอคอนเปล่า */
  .ntfs-rooms { max-height: none; }        /* มือถือให้ไหลไปกับหน้า ไม่ซ้อนสกรอลล์ */
}


/* ===== หน้า "เลือกห้อง" — Channel Browser แบบ Slack (Boss สั่ง 2026-09-04) =========
   มือถือเป็นหลัก (360x780): แถวเดียวจบ · ปุ่มสูง 34px กดถนัด · ชื่อยาวตัด ...
   ช่องค้นหา font-size 16px กัน iOS zoom ตอนโฟกัส */
.brw-wrap { display: flex; flex-direction: column; gap: 10px; min-height: 0; }
.brw-load, .brw-empty { padding: 18px 4px; text-align: center; opacity: .65; font-size: 13px; }
.brw-q { width: 100%; padding: 10px 12px; border-radius: 9px; font: inherit; font-size: 16px;
  background: var(--bg, #fff); color: inherit; border: 1px solid rgba(127,127,127,.35); }
.brw-list { display: flex; flex-direction: column; gap: 2px;
  max-height: min(58vh, 460px); overflow-y: auto; -webkit-overflow-scrolling: touch; }
.brw-row { display: flex; align-items: center; gap: 9px; padding: 9px 8px;
  border-radius: 9px; cursor: pointer; min-height: 44px; }
.brw-row:hover { background: rgba(127,127,127,.11); }
/* ไอคอนต้องตรงกับ "บรรทัดชื่อห้อง" ไม่ใช่กลางแถว — แถวที่มีหัวข้อสูงกว่า ถ้าจัดกลางจะเยื้องลง
   align-self:flex-start + line-height เท่าบรรทัดชื่อ (14px * 1.4 ≈ 20px) */
.brw-ic { flex: 0 0 auto; opacity: .6; display: flex; align-items: center;
  align-self: flex-start; height: 20px; }
/* ⚠️ min-width:0 จำเป็น ไม่งั้น flex item ไม่ยอมหด = ชื่อยาวดันปุ่มตกขอบบนมือถือ */
.brw-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.brw-name { font-weight: 600; font-size: 14px; line-height: 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.brw-topic { font-size: 12px; opacity: .6; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.brw-n { font-size: 11.5px; opacity: .5; }
.brw-join { flex: 0 0 auto; padding: 7px 13px; min-height: 34px; border-radius: 8px;
  border: 0; cursor: pointer; font: inherit; font-size: 13px; font-weight: 600;
  background: var(--accent, #2f6fed); color: #fff; }
.brw-join:active { filter: brightness(.9); }
.brw-in { flex: 0 0 auto; font-size: 12px; opacity: .55; white-space: nowrap; }

/* อัลบั้มรูปในแผงเธรดฝั่งขวา (หน้าแจ้งเตือน) — Boss แจ้ง 2026-09-04 "รูปไม่มา มีแค่ข้อความ"
   ใช้ albumHTML ตัวเดียวกับห้องหลัก แต่แผงนี้แคบกว่า จึงย่อกริดให้พอดีไม่ดันแผงบวม */
.ntf-dt-body .album-card { margin-top: 6px; }
.ntf-dt-body .album-grid { width: 100%; max-width: 260px; }
.ntf-dt-body .album-gridwrap { max-width: 260px; }
.ntf-dt-body .album-img { max-height: 150px; }
.ntf-dt-body .album-grid:has(.album-img:only-child) .album-img { max-height: 200px; }

/* ---- ทางแยกสร้างประชุม: ใหม่ / ใช้หัวข้อที่มีอยู่แล้ว (Boss 2026-09-04) ---- */
/* mobile-first: 360x780 เป็นหลัก ปุ่มเต็มความกว้าง แตะง่าย */
.prep-start { display: flex; flex-direction: column; gap: 10px; margin: 12px 0 4px; }
.prep-start-op { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 14px 14px; min-height: 64px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--card); color: inherit; cursor: pointer; }
.prep-start-op:hover, .prep-start-op:active { border-color: var(--blue); background: rgba(59,130,246,.08); }
.prep-start-ic { font-size: 24px; width: 34px; text-align: center; flex-shrink: 0; }
.prep-start-op .grow { display: flex; flex-direction: column; gap: 3px; min-width: 0; white-space: normal; }
.prep-srcbox { max-height: 60vh; overflow-y: auto; margin-top: 6px; }
.prep-tasks-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 8px 0; }
.prep-tasksbox { max-height: 52vh; overflow-y: auto; }
.prep-tpick { display: flex; align-items: flex-start; gap: 10px; padding: 10px 8px; min-height: 44px;
  border-bottom: 1px solid var(--border); cursor: pointer; font-size: 13px; }
.prep-tpick.on { background: rgba(59,130,246,.08); }
.prep-tpick input { width: 18px; height: 18px; flex-shrink: 0; margin-top: 1px; }
.prep-tpick .grow { white-space: normal; word-break: break-word; }

/* เวลาส่งข้อความ — ชี้เมาส์/กดค้าง แล้วบอกวันที่เต็ม (Boss ขอ 2026-09-04 แบบ Slack)
   เส้นใต้จางบอกว่า "ตรงนี้ชี้ดูได้" ไม่งั้นไม่มีใครรู้ว่ามีข้อมูลซ่อนอยู่ */
[data-tt] { cursor: help; }
@media (hover: hover) {
  .msg-time[data-tt]:hover, .msg-under-time[data-tt]:hover,
  .dmw-time[data-tt]:hover, .thr-last[data-tt]:hover {
    text-decoration: underline dotted currentColor;
    text-underline-offset: 2px;
  }
}

/* ================= หน้าประชุมเต็มจอแบบ Google Meet (Boss 2026-09-04) =================
   mobile-first 360x780 · คอมค่อยแยกซ้าย-ขวาด้วย media query ท้ายบล็อก */
.meet-stage { position: fixed; inset: 0; z-index: 900; background: #0A121C;
  display: flex; flex-direction: column; color: #fff; }
body.meet-open { overflow: hidden; }
.meet-main { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.meet-head { display: flex; align-items: center; gap: 8px; padding: 10px 14px;
  padding-top: max(10px, env(safe-area-inset-top)); font-size: 13px; color: #cbd5e1; }
.meet-head-title { font-weight: 600; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.meet-head-time { font-variant-numeric: tabular-nums; }
/* ตะแกรงหน้าคน — ยืดเต็มพื้นที่ที่เหลือจริง ไม่ fix อัตราส่วน
   ⚠️ เดิมบังคับ aspect-ratio 4/3 ทุกช่อง: วิดีโอจริงเป็น 16:9 (มือถือแนวตั้ง 9:16)
      + object-fit:cover → ภาพโดน crop หัวขาด และตอนแชร์หน้าจอ (จอกว้าง) เพี้ยนหนัก */
.meet-grid { flex: 1 1 auto; min-height: 0; overflow: hidden; padding: 0 8px 6px;
  display: grid; gap: 8px; align-content: center; justify-content: stretch;
  grid-template-columns: 1fr; grid-auto-rows: minmax(0, 1fr);
}
/* มือถือแนวตั้ง: 2 คนซ้อนบน-ล่าง · 3-4 คน 2 คอลัมน์ · เกินนั้นเลื่อนได้
   ⚠️ ช่องหลายคนบนจอแคบต้องคุมความสูงด้วย 16/9 ไม่งั้นกรอบสูงกว่ากว้าง 2 เท่า
      แล้วกล้องแนวนอนถูก crop เหลือแถบกลางหน้า (Boss แจ้ง "ยังไม่สมส่วน") */
.meet-grid:has(> :nth-child(2)):not(:has(> :nth-child(3))) { grid-auto-rows: auto; align-content: center; }
.meet-grid:has(> :nth-child(2)) .video-tile { max-height: min(44vh, 100%); }
.meet-grid:has(> :nth-child(3)) { grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: auto; align-content: center; }
.meet-grid:has(> :nth-child(3)) .video-tile { aspect-ratio: 4/3; width: 100%; }
.meet-grid:has(> :nth-child(5)) { overflow-y: auto; align-content: start; }

.meet-grid .video-tile { aspect-ratio: auto; min-height: 0; background: #1B2A3A; color: #fff;
  border: 2px solid transparent; transition: border-color .15s; border-radius: 12px; }
/* contain = เห็นภาพครบไม่โดนตัด (สำคัญมากตอนแชร์หน้าจอ ต้องอ่านตัวหนังสือออก) */
.meet-grid .video-tile video { width: 100%; height: 100%; object-fit: contain; background: #0d1620; }
/* กล้องคน crop ได้ ให้เต็มกรอบสวยกว่า — แต่แชร์หน้าจอห้าม crop */
.meet-grid .video-tile.cam video { object-fit: cover; }
.meet-grid .video-tile.speaking { border-color: #34d399; }   /* ไฮไลต์คนกำลังพูด */
.meet-grid .video-tile.cam-off video { opacity: .12; }

/* มีคนแชร์หน้าจอ = ภาพนั้นเป็นตัวหลัก คนอื่นย่อเป็นแถบเล็ก (แบบ Meet) */
.meet-grid.has-share { grid-template-columns: 1fr !important;
  grid-template-rows: 1fr auto !important; grid-auto-rows: auto !important;
  align-content: stretch !important; overflow: hidden; }
.meet-grid.has-share .video-tile { display: none; }              /* ซ่อนคนอื่นออกจากตะแกรงหลัก */
.meet-grid.has-share .video-tile.sharing { display: flex; align-items: center; grid-row: 1;
  aspect-ratio: auto !important; max-height: 100% !important; height: 100%;
  background: transparent; border-color: transparent; }
.meet-grid.has-share .video-tile.sharing video { background: #0d1620; border-radius: 10px;
  height: auto !important; max-height: 100%; width: 100%; object-fit: contain; }
/* กรอบสูงกว่าภาพ (ภาพหดตามสัดส่วน) — ป้ายต้องไม่ลอยไปติดขอบกรอบว่าง
   ทำกรอบเป็น flex column จัดกลาง แล้วป้ายอยู่ในสายไหลใต้ภาพพอดี */
.meet-grid.has-share .video-tile.sharing { flex-direction: column; justify-content: center; gap: 6px; }
.meet-grid.has-share .video-tile.sharing .vt-name { position: static; align-self: flex-start; }
.meet-strip { grid-row: 2; display: flex; gap: 6px; overflow-x: auto; padding-top: 2px; }
.meet-strip .video-tile { display: block !important; flex: 0 0 96px; height: 68px; }
.meet-strip .video-tile .vt-name { font-size: 10px; padding: 1px 5px; }
/* กล้องผู้จัด = ตัวรองหลัก: ใหญ่กว่าคนอื่น + ขอบเน้น (Boss 2026-09-06) */
.meet-strip .video-tile[data-host="1"] { flex: 0 0 150px; height: 100px; border: 2px solid #34d399; }
.meet-strip .video-tile[data-host="1"] .vt-name::after { content: ' · ผู้จัด'; opacity: .8; }
/* แถบปุ่มล่างทรงกลม */
/* ===== แถบปุ่มล่าง — 2 กลุ่ม: ปุ่มหลัก(กลาง) + ปุ่มออก(แยกขวา) (Boss 2026-09-07) =====
   เดิม 7 ปุ่มเรียงเดียวบีบกันจนเหลือ 40px บนจอ 360 และปุ่มแดงติดปุ่มข้างๆ
   → กดพลาด = หลุดออกจากประชุมกลางคัน แก้ด้วยการลดปุ่มเหลือ 3+1 และเว้นช่องกันชน */
.meet-bar { flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; padding-bottom: max(10px, env(safe-area-inset-bottom));
  background: rgba(0,0,0,.25); }
/* ปุ่มหลักอยู่กลางจอจริง (นิ้วโป้งเอื้อมถึงง่ายสุดบนมือถือ) */
.meet-bar-core { flex: 1 1 auto; display: flex; justify-content: center; align-items: flex-start; gap: 14px; }
/* ปุ่มออกดันไปขวาสุด + ช่องว่างกันชนก่อนถึงมัน */
.meet-bar-end { flex: 0 0 auto; display: flex; align-items: flex-start; padding-left: 6px; }
.meet-btn { display: flex; flex-direction: column; align-items: center; gap: 4px;
  min-width: 56px; padding: 4px 2px; background: none; border: 0; color: #e2e8f0;
  font-size: 10.5px; cursor: pointer; flex: 0 0 auto; -webkit-tap-highlight-color: transparent; }
.meet-btn .mb-ic { display: flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; border-radius: 50%; background: #263647; font-size: 22px;
  transition: background .15s, transform .1s; }
.meet-btn:active .mb-ic { transform: scale(.93); }
.meet-btn:hover .mb-ic { background: #32485e; }
.meet-btn.off .mb-ic { background: #dc2626; }        /* ปิดไมค์/กล้อง = แดง เห็นชัด */
.meet-btn.on  .mb-ic { background: #2563eb; }        /* กำลังแชร์/อัด */
.meet-btn.danger .mb-ic { background: #dc2626; width: 62px; border-radius: 26px; }
.meet-btn.danger:hover .mb-ic { background: #ef4444; }
/* จุดแดงบนปุ่ม ⋯ บอกว่ามีอะไรทำงานอยู่ข้างใน (แชร์จอ/อัดเสียง) จะได้ไม่ต้องเปิดดู */
.meet-btn.has-active .mb-ic::after { content: ''; position: absolute; width: 10px; height: 10px;
  border-radius: 50%; background: #f87171; transform: translate(20px, -18px);
  border: 2px solid #0A121C; }
#mb-more .mb-ic { position: relative; }

/* ===== ชิปแชท/คนเข้าร่วม มุมขวาบนของจอวิดีโอ (Discord-style) =====
   ย้ายออกจากแถบล่างเพื่อคืนพื้นที่ให้ปุ่มหลัก · ตัวเลขเด้งบอกจำนวน */
/* ⚠️ ชิปเคยทับแบนเนอร์ "ไมค์/กล้องปิดอยู่" (เห็นจากภาพเทส 2026-09-07)
   ใช้ตัวแปรคุมระยะบนที่เดียว แล้วให้แบนเนอร์เว้นขวาให้ชิปด้วย */
.meet-chips { position: absolute; top: max(52px, calc(env(safe-area-inset-top) + 44px));
  right: 10px; z-index: 3; display: flex; flex-direction: column; gap: 8px; }
/* แบนเนอร์ต้องไม่ไหลไปใต้ชิป — เว้นที่ขวาเท่าความกว้างชิปจริง
   ⚠️⚠️ เดิมเว้น 62px คงที่ (เผื่อชิป 1 คอลัมน์ 44 + ขอบ)
      แต่จอเตี้ยกฎ max-height:480px พลิกชิปเป็น flex-direction:row = **กว้าง 2 เท่า**
      → มือถือแนวนอน แบนเนอร์ไหลไปใต้ mb-chat ทับปุ่มไว้ (เทสจับได้ 2026-09-07)
      คุมด้วยตัวแปรที่เดียว แล้วให้กฎจอเตี้ยเพิ่มค่าเอง */
.meet-stage:has(.meet-chips) .meet-mute-banner { margin-right: var(--meet-chip-gutter, 62px); }
.meet-chip { position: relative; display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 50%; border: 0; cursor: pointer;
  background: rgba(15,23,36,.72); color: #e2e8f0; font-size: 18px;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  -webkit-tap-highlight-color: transparent; transition: background .15s, transform .1s; }
.meet-chip:active { transform: scale(.93); }
.meet-chip:hover { background: rgba(30,45,66,.85); }
.meet-chip.on { background: #2563eb; }
/* มือถือ: ชิปเป็นวงกลม ป้ายชื่อซ่อน (โชว์เฉพาะบนแถบล่างของคอม) */
.meet-chip .mb-lb { display: none; }
.meet-chip .mc-n { position: absolute; top: -3px; right: -3px; min-width: 18px; height: 18px;
  padding: 0 4px; border-radius: 9px; background: #2563eb; color: #fff;
  font-size: 10.5px; font-weight: 700; line-height: 18px; text-align: center;
  border: 2px solid #0A121C; box-sizing: content-box; }
.meet-chip #mb-chat-n { background: #dc2626; }

/* ===== แผ่น "เพิ่มเติม" เลื่อนขึ้นจากล่าง (Discord bottom sheet) ===== */
.meet-more { position: fixed; inset: 0; z-index: 950; background: rgba(0,0,0,.5);
  display: flex; align-items: flex-end; animation: mmFade .15s ease-out; }
@keyframes mmFade { from { opacity: 0 } to { opacity: 1 } }
.meet-more-sheet { width: 100%; background: #16212F; color: #e2e8f0;
  border-top-left-radius: 20px; border-top-right-radius: 20px;
  padding: 8px 16px max(18px, env(safe-area-inset-bottom));
  box-sizing: border-box; max-height: 85vh; overflow-y: auto;   /* จอเตี้ยต้องไม่ล้น */
  animation: mmUp .2s cubic-bezier(.2,.8,.3,1); }
@keyframes mmUp { from { transform: translateY(100%) } to { transform: translateY(0) } }
.mm-grab { width: 40px; height: 4px; border-radius: 2px; background: #47586c; margin: 0 auto 14px; }
/* ⚠️ ปุ่มในแผ่นเป็น 4 ตัวแล้ว (แชร์จอ/อัด/สลับกล้อง/มอบงาน)
   3 คอลัมน์ = แถว 2 เหลือปุ่มเดียวโดดๆ ดูไม่จบ → ใช้ 2 คอลัมน์ให้เป็น 2x2 พอดี
   ⚠️ คนที่ไม่ใช่ host ปุ่มอัดถูกซ่อน (display:none) เหลือ 3 ตัว grid จัดเองได้ ไม่ต้องแก้ */
.meet-more-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.meet-mbtn { display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 14px 6px; border: 0; border-radius: 14px; background: #22303F; color: #e2e8f0;
  font-size: 11.5px; cursor: pointer; min-height: 84px; justify-content: center;
  -webkit-tap-highlight-color: transparent; transition: background .15s, transform .1s; }
.meet-mbtn:active { transform: scale(.96); }
.meet-mbtn:hover { background: #2c3d4f; }
.meet-mbtn .mb-ic { font-size: 24px; line-height: 1; }
.meet-mbtn.on { background: #2563eb; }
.meet-mbtn.recording .mb-ic { animation: recPulse 1.2s infinite; }
/* แผงข้าง — มือถือกางทับเต็มจอ */
.meet-side { position: absolute; inset: 0; z-index: 2; background: var(--card); color: var(--text);
  display: flex; flex-direction: column; }
.meet-side-head { display: flex; align-items: center; gap: 8px; padding: 12px 14px;
  padding-top: max(12px, env(safe-area-inset-top)); border-bottom: 1px solid var(--border); }
.meet-side-body { flex: 1 1 auto; overflow-y: auto; padding: 10px 14px; }
.meet-side-foot { flex: 0 0 auto; display: flex; gap: 8px; padding: 10px 14px;
  padding-bottom: max(10px, env(safe-area-inset-bottom)); border-top: 1px solid var(--border); }
.meet-side-foot input { flex: 1 1 auto; min-width: 0; }
.meet-prow { display: flex; align-items: center; gap: 10px; padding: 10px 0; min-height: 44px;
  border-bottom: 1px solid var(--border); font-size: 14px; }
.meet-pav { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px;
  border-radius: 50%; background: var(--blue); color: #fff; font-weight: 600; flex-shrink: 0; }
.meet-crow { padding: 6px 0; font-size: 13px; word-break: break-word; }
/* ===== เฟส 2: แท็บ "งาน" ในแผงข้างประชุม (Boss สั่ง 2026-09-07) ===== */
.mt-taskform { display: flex; flex-direction: column; gap: 6px; padding-bottom: 10px;
  margin-bottom: 8px; border-bottom: 1px solid var(--border); }
.mt-taskform input, .mt-taskform select { width: 100%; box-sizing: border-box;
  min-height: 40px; padding: 6px 10px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--card); color: var(--text); font-size: 14px; }
/* ⚠️ มือถือ 320px: 3 ช่องเรียงนอนแล้วปุ่มหลุดขอบ → ปล่อยให้ตัดบรรทัดได้
   ปุ่มกว้างเต็มแถวเมื่อขึ้นบรรทัดใหม่ จะได้ยังกดง่าย (mobile first) */
.mt-taskrow { display: flex; flex-wrap: wrap; gap: 6px; }
.mt-taskrow select { flex: 1 1 120px; min-width: 0; }
.mt-taskrow input[type="date"] { flex: 1 1 130px; min-width: 0; }
.mt-taskrow .btn { flex: 1 1 auto; min-height: 40px; }
@media (min-width: 420px) { .mt-taskrow .btn { flex: 0 0 auto; } }
.meet-trow { display: flex; align-items: flex-start; gap: 10px; padding: 9px 0;
  min-height: 44px; border-bottom: 1px solid var(--border); font-size: 14px; }
.meet-trow input[type="checkbox"] { width: 20px; height: 20px; margin-top: 2px; flex: 0 0 auto; }
.meet-trow .mt-tt { word-break: break-word; }
.meet-trow.done .mt-tt { text-decoration: line-through; color: var(--muted); }
.meet-crow b { color: var(--blue); }
/* หน้ารายละเอียดประชุม — ตารางข้อมูลสรุป (Boss 2026-09-06) */
.md-facts { display: grid; grid-template-columns: 1fr; gap: 4px; font-size: 13px; margin-top: 6px; }
@media (min-width: 480px) { .md-facts { grid-template-columns: 1fr 1fr; } }
.md-facts .md-k { color: var(--muted); }
.md-sec { margin-top: 4px; }
.md-sec > b { font-size: 14px; }
/* ตัวกรองรายวันหน้าประชุม (Boss 2026-09-06) */
.mt-datefilter { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 6px 0 10px; }
.mt-datefilter input[type="date"] { min-height: 34px; padding: 4px 8px; border: 1px solid var(--border);
  border-radius: 8px; background: var(--card); color: var(--text); font-size: 13px; }
.meet-cimg { max-width: 180px; max-height: 180px; border-radius: 8px; display: block; margin-top: 4px; }
/* แบนเนอร์เตือน "เข้าประชุมแบบปิดไมค์/กล้อง" (ข้อ 4) */
.meet-mute-banner { flex: 0 0 auto; margin: 8px 16px 0; padding: 8px 12px; border-radius: 10px;
  background: rgba(220,38,38,.18); color: #fecaca; font-size: 13px; text-align: center; cursor: pointer;
  border: 1px solid rgba(220,38,38,.4); }
/* จุดแดงกะพริบตอนกำลังอัด (ข้อ 3) */
.meet-btn.recording .mb-ic { background: #dc2626; animation: recPulse 1.2s infinite; }
@keyframes recPulse { 0%,100% { box-shadow: 0 0 0 0 rgba(220,38,38,.6); } 50% { box-shadow: 0 0 0 6px rgba(220,38,38,0); } }
/* ป็อปอัพอิโมจิในแชทประชุม (ข้อ 5) */
.meet-side-foot { position: relative; flex-wrap: wrap; }
.meet-side-foot .icon-btn { flex: 0 0 auto; font-size: 18px; }
.meet-emoji-pop { position: absolute; bottom: 100%; left: 8px; right: 8px; margin-bottom: 6px;
  background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 8px;
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; box-shadow: 0 6px 24px rgba(0,0,0,.25); z-index: 5; }
.meet-emoji-pop .mep-b { border: 0; background: transparent; font-size: 20px; padding: 4px; cursor: pointer; border-radius: 8px; min-height: 36px; }
.meet-emoji-pop .mep-b:hover { background: var(--hover, rgba(0,0,0,.06)); }
/* มือถือ: แผงแชท/คน เลื่อนขึ้นแบบ bottom sheet ไม่ทับเต็มจอ 100%
   ⚠️⚠️ เกณฑ์ต้องเป็น "ไม่ใช่คอม" ตัวเดียวกับ meetIsWideUI() ใน app.js (760px × 500px)
      เดิมใช้ `max-width:600px` อย่างเดียว → **มือถือแนวนอน 780x360 หลุดกฎ**
      แผงเลยกาง inset:0 ทับเต็มจอรวมแถบปุ่มล่าง (เทสจับได้ 2026-09-07)
   ⚠️⚠️ และเดิม `height:72vh` วัดจากขอบล่างจอ = ยังคร่อมแถบปุ่มอยู่ดี
      → คนเปิดแชทแล้ว **กดปิดไมค์/ออกจากประชุมไม่ได้เลย** ต้องปิดแผงก่อน
      แก้ด้วยการอ้าง bottom = ความสูงแถบปุ่ม ให้แผงจบ "เหนือ" แถบเสมอ */
@media not all and (min-width: 760px) and (min-height: 500px) {
  .meet-side {
    top: auto; inset-inline: 0;
    bottom: var(--meet-bar-h, 84px);
    height: min(62vh, calc(100% - var(--meet-bar-h, 84px) - 56px));
    border-top-left-radius: 16px; border-top-right-radius: 16px;
    box-shadow: 0 -6px 24px rgba(0,0,0,.3);
  }
  /* แผงลอยเหนือแถบแล้ว ขอบล่างไม่ติดขอบจอ = ไม่ต้องเว้น safe-area ซ้ำ */
  .meet-side-foot { padding-bottom: 10px; }
  /* หัวแผงไม่ได้ชนขอบบนจออีกแล้ว (แผงเริ่มกลางจอ) */
  .meet-side-head { padding-top: 12px; }
}
/* จอเตี้ย (แนวนอน) แถบปุ่มบางกว่า → แผงลงมาต่ำกว่าได้ */
@media (max-height: 480px) {
  .meet-side { --meet-bar-h: 62px; height: min(72vh, calc(100% - 62px - 34px)); }
}

/* ⚠️ ต้องเช็ค min-height ด้วย! มือถือแนวนอน 780x360 กว้างพอผ่าน 760px
   แต่สูงแค่ 360 → ถ้าเหมาว่าเป็นคอมจะกางปุ่มครบ 7 ตัว + คลายแผ่น ⋯
   ทำให้จอวิดีโอเหลือ 24% ของจอ (เทสจับได้ 2026-09-07) */
@media (min-width: 760px) and (min-height: 500px) {
  .meet-stage { flex-direction: row; }
  .meet-main { flex: 1 1 auto; min-width: 0; }
  .meet-grid { padding: 0 16px 8px; grid-template-columns: repeat(2, 1fr); }
  .meet-grid:has(> :nth-child(5)) { grid-template-columns: repeat(3, 1fr); }
  .meet-grid:has(> :nth-child(7)) { grid-template-columns: repeat(4, 1fr); }
  /* จอกว้างมีที่พอ ปล่อยให้ยืดตามพื้นที่ ไม่ต้องล็อกสัดส่วน */
  .meet-grid:has(> :nth-child(2)) .video-tile,
  .meet-grid:has(> :nth-child(3)) .video-tile { aspect-ratio: auto; max-height: 100%; }
  /* คนเดียว = ไม่ยืดเต็มจอจนภาพบิด จำกัดความกว้างไว้กลางจอ */
  .meet-grid > .video-tile:only-child { max-width: min(100%, 1100px); margin: 0 auto; }
  .meet-strip .video-tile { flex: 0 0 132px; height: 92px; }
  .meet-side { position: relative; inset: auto; width: 330px; flex: 0 0 330px;
    border-left: 1px solid var(--border); }
  /* ---- คอม: มีที่พอ กางปุ่มครบเลย ไม่ต้องซ่อนในแผ่น ⋯ ----
     ⚠️⚠️ เคยพยายามใช้ `display:contents` ดึงปุ่มจาก #meet-more ขึ้นมา — **ใช้ไม่ได้**
        เพราะ #meet-more เป็น "พี่น้อง" กับ .meet-bar ไม่ใช่ลูก
        contents จึงโยนปุ่มเข้า .meet-main (flex column) = ปุ่มไปเรียงตั้งใต้แถบ หลุดจอ
        (Boss แจ้ง 2026-09-07 พร้อมรูป) → เปลี่ยนมาย้าย DOM จริงด้วย JS แทน (meetPlaceButtons)
     CSS ตรงนี้แค่จัดหน้าตาปุ่มที่ JS ย้ายเข้ามาไว้ใน .meet-bar-core แล้ว */
  .meet-btn { min-width: 62px; font-size: 11px; }
  .meet-btn .mb-ic { width: 48px; height: 48px; font-size: 20px; }
  .meet-btn.danger .mb-ic { width: 56px; }
  #mb-more { display: none; }                    /* คอมไม่ต้องมีปุ่ม ⋯ */
  .meet-chips { display: none; }                 /* แชท/คน ไปอยู่บนแถบล่างแทน */
  /* ปุ่มที่ย้ายมาจากแผ่น ⋯ ให้หน้าตาเหมือนปุ่มหลักทุกตัว */
  .meet-bar-core .meet-mbtn { flex-direction: column; align-items: center; gap: 4px;
    min-width: 62px; min-height: 0; padding: 4px 2px; background: none; border-radius: 0;
    color: #e2e8f0; font-size: 11px; cursor: pointer; border: 0; }
  .meet-bar-core .meet-mbtn:hover { background: none; }
  .meet-bar-core .meet-mbtn .mb-ic { display: flex; align-items: center; justify-content: center;
    width: 48px; height: 48px; border-radius: 50%; background: #263647; font-size: 20px; }
  .meet-bar-core .meet-mbtn:hover .mb-ic { background: #32485e; }
  .meet-bar-core .meet-mbtn.on { background: none; }
  .meet-bar-core .meet-mbtn.on .mb-ic { background: #2563eb; }
  .meet-bar-core .meet-mbtn.recording .mb-ic { background: #dc2626; }
  /* ชิปแชท/คนเข้าร่วมที่ย้ายลงมาบนแถบ — ข้างในเป็น .mc-ic/.mc-n (ไม่ใช่ .mb-ic/.mb-lb)
     ต้องแปลงหน้าตาให้เท่าปุ่มอื่น ไม่งั้นสูงแค่ 21-37px แตะยาก (เทสจับได้) */
  .meet-bar-core .meet-chip,
  .meet-bar-core #mb-chat, .meet-bar-core #mb-people {
    position: relative; width: auto; height: auto; min-width: 62px; border-radius: 0;
    background: none; backdrop-filter: none; -webkit-backdrop-filter: none;
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    padding: 4px 2px; color: #e2e8f0; font-size: 11px; }
  .meet-bar-core #mb-chat:hover, .meet-bar-core #mb-people:hover { background: none; }
  .meet-bar-core #mb-chat .mc-ic, .meet-bar-core #mb-people .mc-ic {
    display: flex; align-items: center; justify-content: center;
    width: 48px; height: 48px; border-radius: 50%; background: #263647; font-size: 20px; }
  .meet-bar-core #mb-chat:hover .mc-ic, .meet-bar-core #mb-people:hover .mc-ic { background: #32485e; }
  .meet-bar-core #mb-chat.on, .meet-bar-core #mb-people.on { background: none; }
  .meet-bar-core #mb-chat.on .mc-ic, .meet-bar-core #mb-people.on .mc-ic { background: #2563eb; }
  /* ตัวเลขบนแถบ = ป้ายเล็กมุมไอคอน (ไม่ใช่ตัวหนังสือใต้ปุ่ม) */
  .meet-bar-core #mb-chat .mc-n, .meet-bar-core #mb-people .mc-n {
    position: absolute; top: 0; right: 6px; }
  .meet-bar-core #mb-chat .mb-lb, .meet-bar-core #mb-people .mb-lb { display: block; }
}
/* จอเตี้ย (มือถือแนวนอน) — ปุ่มต้องไม่กินพื้นที่ภาพ */
@media (max-height: 480px) {
  .meet-head { padding: 4px 12px; font-size: 11px; }
  .meet-btn .mb-ic { width: 44px; height: 44px; font-size: 18px; }   /* คง HIG 44px */
  .meet-btn .mb-lb { display: none; }
  .meet-bar { padding: 5px 10px; padding-bottom: max(5px, env(safe-area-inset-bottom)); }
  /* แนวนอนไม่มีที่แนวตั้ง → ชิปเรียงแถว = กินความกว้าง 2 ชิป + ช่องไฟ
     ต้องบอกแบนเนอร์ให้เว้นขวาเพิ่มด้วย ไม่งั้นแบนเนอร์ไหลไปทับชิป */
  .meet-chips { top: 8px; flex-direction: row; }
  .meet-stage { --meet-chip-gutter: 114px; }                         /* 44*2 + gap 8 + ขอบ 10 + เผื่อ 8 */
  .meet-more-sheet { padding-top: 4px; }
  .meet-more .mm-grab { margin-bottom: 8px; }
  .meet-more .meet-mbtn { min-height: 66px; padding: 8px 6px; }
}

/* ---- แถบเริ่มประชุมแบบหน้าแรก Google Meet (Boss 2026-09-04) ---- */
.meet-start { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.meet-start-new { display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; font-size: 15px; }
.meet-start-join { display: flex; gap: 8px; }
.meet-start-join input { flex: 1 1 auto; min-width: 0; min-height: 44px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .5px; }
.meet-start-join .btn { min-height: 44px; flex: 0 0 auto; }
.meet-codebox { text-align: center; }
/* ช่องตั้งหัวข้อการประชุม (Boss สั่ง 2026-09-06)
   กล่องนี้ text-align:center ทั้งกล่อง (ไว้โชว์รหัสประชุมกลางจอ)
   ข้อความที่คนพิมพ์เองต้องชิดซ้าย ไม่งั้นหัวข้อยาวๆ อ่านยาก */
#ms-title { width: 100%; box-sizing: border-box; text-align: left; margin-top: .4rem; }
.meet-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 24px;
  font-weight: 700; letter-spacing: 1px; color: var(--blue); margin: 6px 0 4px; word-break: break-all; }
.meet-codelink { font-size: 12px; color: var(--muted); word-break: break-all; margin: 8px 0 4px; }
@media (min-width: 560px) { .meet-start { flex-direction: row; align-items: center; }
  .meet-start-new { flex: 0 0 auto; } .meet-start-join { flex: 1 1 auto; } }

/* แท็บหน้าผู้ดูแลระบบ — ย่อลง (Boss สั่ง 2026-09-04 "15 ตัวเลือกใหญ่ไป")
   จำกัดที่ #cp-tabs เท่านั้น ไม่แตะ .tab ทั่วแอป (แท็บอื่นยังขนาดเดิม)
   14px/6-14px → 12.5px/4-10px + gap แคบลง = 15 ปุ่มจบใน 1-2 บรรทัด ไม่กินครึ่งจอ */
#cp-tabs { gap: 4px; margin-bottom: 10px; }
#cp-tabs .tab {
  font-size: 12.5px;
  padding: 4px 10px;
  line-height: 1.5;
}
#cp-tabs .tab-badge {
  font-size: 9.5px; min-width: 14px; padding: 2px 3px; margin-left: 4px;
}
@media (max-width: 600px) {
  /* มือถือ: แถบแท็บเลื่อนแนวนอนแทนตัดบรรทัด จะได้ไม่ดันเนื้อหาลงไปไกล */
  #cp-tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
  #cp-tabs::-webkit-scrollbar { display: none; }
  /* ย่อจาก 42px (กฎเป้าแตะรวมที่บรรทัด ~2903) เหลือ 36px — ยังกดติดสบาย
     แถบนี้เลื่อนแนวนอนแล้ว ปุ่มไม่ต้องสูงเท่าเดิมเพื่อกันกดพลาดตอนตัดบรรทัด */
  #cp-tabs .tab { flex: 0 0 auto; min-height: 36px; }
}

/* ไทล์เมนู (DM / แจ้งเตือน / งาน / ประชุม …) — ย่อลง (Boss สั่ง 2026-09-04 ส่งรูปมา "ใหญ่ไป")
   เดิม padding 16px + gap 7px + ไอคอน 19px = การ์ดสูง ~86px เห็นได้ 3 แถวต่อจอมือถือ
   ย่อเป็น 10px/5px/17px → สูง ~66px เห็นครบทั้ง 11 ไทล์โดยไม่ต้องเลื่อนมาก */
.mn-tiles { gap: 6px; }
.mn-tile { padding: 10px 5px; gap: 5px; border-radius: 9px; }
.mn-tile-ic { font-size: 17px; }
.mn-tile-tx { font-size: 11.5px; }
.mn-tile-badge { top: 4px; right: 4px; font-size: 9.5px; min-width: 16px; height: 16px; border-radius: 8px; }

/* ============================================================
   แถบข้าง: แยก "หัวข้อหมวด" กับ "ห้องในหมวด" ให้ชัด
   (Boss สั่ง 2026-09-04 "ตอนนี้มันเป็นแนวเดียวกันหมด แยกไม่ออก")
   ปัญหาเดิม: หัวหมวด opacity .55 + 11px แต่ชื่อห้อง 14px เต็มสี
   → หัวข้อ "จางกว่า" ลูกตัวเอง เลยดูเป็นระนาบเดียวกันหมด
   แก้ 3 ชั้น: หัวข้อเด่นขึ้น · ห้องย่อหน้าเข้าไป+มีเส้นแกน · เว้นวรรคระหว่างหมวด
   ============================================================ */

/* 1) หัวหมวดเด่นขึ้น — สว่างกว่าห้อง ไม่ใช่จางกว่า */
.x10v3 .sidebar .chan-sec, .sidebar .chan-sec {
  opacity: 1;
  color: var(--side-text);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .06em;
  padding: 12px 12px 5px;
  margin-top: 10px;                     /* ระยะห่างระหว่างหมวด = เส้นแบ่งที่ไม่ต้องวาดเส้น */
  border-top: 1px solid rgba(255,255,255,.07);
}
/* หมวดแรกสุดไม่ต้องมีเส้น/ระยะบน */
.x10v3 .sidebar .chan-sec:first-child, .sidebar .chan-sec:first-child { margin-top: 0; border-top: none; }
/* จุดสีประจำหมวด ให้ใหญ่ขึ้นนิดเพื่อเป็นจุดยึดสายตา */
.x10v3 .sidebar .chan-sec-dot, .sidebar .chan-sec-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
/* ลูกศรพับ/กาง จางไว้ ไม่แย่งสายตาชื่อหมวด */
.x10v3 .sidebar .chan-sec-car, .sidebar .chan-sec-car { opacity: .45; font-size: 10px; }
.x10v3 .sidebar .chan-sec-n, .sidebar .chan-sec-n { opacity: .45; }

/* 2) ห้องในหมวด — ย่อหน้าเข้าไป + เส้นแกนตั้งบอกว่า "อยู่ใต้หมวดนี้" */
.sidebar .chan-body {
  position: relative;
  margin-left: 18px;                    /* ย่อหน้า = ลำดับชั้นที่ตาอ่านออกทันที */
  padding-left: 2px;
}
.x10v3 .sidebar .chan-body::before, .sidebar .chan-body::before {
  content: '';
  position: absolute; left: 0; top: 2px; bottom: 2px;
  width: 1px; background: rgba(255,255,255,.10);
}
/* ชื่อห้องเบากว่าหัวข้อ (กลับด้านจากของเดิม) */
.sidebar .chan-body .chan-item { font-size: 13px; padding: 6px 12px 6px 8px; }
.sidebar .chan-body .chan-item.active { font-weight: 700; }

/* 3) แถว "＋ สร้างห้องใน …" จางไว้ เป็นตัวช่วย ไม่ใช่รายการห้อง */
.x10v3 .sidebar .chan-add-row, .sidebar .chan-add-row { font-size: 11.5px; opacity: .5; padding-left: 8px; }
.sidebar .chan-add-row:hover { opacity: .85; }

@media (max-width: 860px) {
  /* มือถือ: คงเป้าแตะให้กดติด แต่ยังเห็นลำดับชั้น */
  .x10v3 .sidebar .chan-body, .sidebar .chan-body { margin-left: 14px; }
  .x10v3 .sidebar .chan-body .chan-item, .sidebar .chan-body .chan-item { font-size: 13.5px; min-height: 40px; }
}

/* แถบแท็บใต้หัวห้อง (ข้อความ / ไฟล์และลิงก์ / +) — ซ่อน (Boss สั่ง 2026-09-04 "รก เอาออก")
   เหตุผล: ซ้ำกับเมนู ⋯ อยู่แล้ว — "ไฟล์และลิงก์" เรียก openRoomMedia() ตัวเดียวกับ "คลังรูป" เป๊ะ
   ส่วนแท็บ "ข้อความ" เป็นหน้าที่เปิดอยู่แล้ว กดไปก็ไม่เกิดอะไร
   ตรวจแล้ว: ทั้งระบบไม่มีใครสร้างแท็บเองเลยสักอัน (channel_tabs = 0 แถว) ปุ่ม + จึงไม่มีคนใช้
   ⚠️ ซ่อนด้วย CSS ไม่ลบ markup — app.js ยังอ้าง #room-tabs / #rt-add / #rt-msg อยู่หลายจุด
      (loadRoomTabs, switchRoomTab, ws event 'channel.tabs') ลบแล้วจะพังเงียบๆ
   ถ้าอยากเอากลับ: ลบบล็อกนี้บล็อกเดียวจบ */
#room-tabs, #rt-menu { display: none !important; }

/* 📦 ปุ่ม "ของรอเซ็นรับ" ในหัวห้อง (Boss ชี้ตำแหน่ง 2026-09-16)
   อยู่แถวเดียวกับชื่อห้อง/ไอคอนโทร-วิดีโอ ไม่ใช่แถบแท็บข้างบน (ซึ่งซ่อนทั้งระบบ) */
.chat-head .icon-btn.pend-head { position: relative; font-size: 17px; line-height: 1; }
.chat-head .icon-btn.pend-head .rt-badge {
  position: absolute; top: 1px; right: 1px;
  min-width: 15px; height: 15px; padding: 0 3px;
  border-radius: 8px; background: #b91c1c; color: #fff;
  font-size: 10px; font-weight: 700; line-height: 15px; text-align: center;
}

/* ---- การ์ดเชิญประชุมใน DM + ประชุมที่กำลังดำเนินอยู่ (Boss 2026-09-04) ---- */
.meet-card { border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px;
  background: var(--card); max-width: 320px; }
.meet-card-head { font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.meet-card-title { font-weight: 600; font-size: 14px; word-break: break-word; }
.meet-card-sub { font-size: 12px; color: var(--muted); margin-top: 3px; word-break: break-all; }
.meet-card-sub code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.meet-card-foot { margin-top: 10px; }
.meet-card-foot .btn { width: 100%; min-height: 40px; }
.meet-live-foot { margin-top: 10px; }
.meet-live-foot .btn { width: 100%; min-height: 42px; }

/* ============================================================
   แถบอ้างอิง "ตอบกลับ" ใน DM — แบบ Discord (Boss สั่ง 2026-09-04)
   ทำเฉพาะ DM เท่านั้น! ห้องแชทคงกล่องเดิม เพราะเป็นระบบคอมเมนต์
   (คอมเมนต์อยู่ใต้โพสต์อยู่แล้ว รู้บริบทโดยไม่ต้องมีเส้น)
   DM คุยไหลเป็นเส้นเดียว ไม่มีคอมเมนต์ → ต้องมีเส้นโยงบอกว่าตอบอันไหน
   เส้นโค้ง └ วาดด้วย ::before (border ซ้าย+บน + มุมโค้ง) ไม่ใช้รูปภาพ
   ============================================================ */
.dmw-re {
  display: flex; align-items: center; gap: 6px;
  flex-direction: row;                   /* ⚠️ ทับกฎเก่าบรรทัด ~4286 ที่เป็น column (สไตล์ Messenger เดิม) */
  position: relative;
  margin: 0 0 3px 0;
  padding-left: 20px;                    /* เว้นที่ให้เส้นโค้ง */
  font-size: 12px;
  color: var(--muted);
  cursor: pointer;
  min-height: 17px;
  overflow: hidden;
}
.dmw-re::before {
  content: '';
  position: absolute;
  left: 5px; top: 50%; bottom: -3px;
  width: 10px;
  border-left: 2px solid var(--border, rgba(127,127,127,.35));
  border-top: 2px solid var(--border, rgba(127,127,127,.35));
  border-top-left-radius: 7px;
  pointer-events: none;
}
.dmw-re:hover { color: var(--text, inherit); }
.dmw-re:hover::before { border-color: var(--blue); }
.dmw-re .mr-av { flex: 0 0 auto; display: inline-flex; }
.dmw-re .mr-av .avatar, .dmw-re .mr-av img { width: 16px !important; height: 16px !important; font-size: 8px !important; }
.dmw-re .mr-name { flex: 0 0 auto; font-weight: 600; color: var(--blue); opacity: .95; }
.dmw-re .mr-tx {
  flex: 1 1 0; min-width: 0;            /* flex-basis 0 = ยอมหดได้เต็มที่ ไม่ดันชื่อตกบรรทัด */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  opacity: .85;
}
/* ⚠️ หน้าต่าง DM แคบ (~380px) — ชื่อยาวจะเบียดจนข้อความตกบรรทัด
   บังคับทั้งแถบไม่ให้ห่อบรรทัด + ชื่อยาวเกินก็ตัดท้ายเหมือนกัน */
.dmw-re { flex-wrap: nowrap; }
.dmw-re .mr-name { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ⚠️ .dmw-wrap เป็น flex column + align-items:flex-end (ฝั่งเรา)
   → แถบนี้ถูกบีบจนชื่อกับข้อความตกบรรทัด ต้องบังคับไม่ให้หด */
.dmw-re { align-self: stretch; flex-shrink: 0; width: 100%; }
.dmw-msg.me .dmw-re { justify-content: flex-end; align-items: center; padding-left: 0; padding-right: 20px; }
/* ฝั่งเรา: เส้นโค้งพลิกไปอยู่ขวา (โค้งเข้าหาบับเบิลตัวเอง) */
.dmw-msg.me .dmw-re::before {
  left: auto; right: 5px;
  border-left: none; border-right: 2px solid var(--border, rgba(127,127,127,.35));
  border-top-left-radius: 0; border-top-right-radius: 7px;
}
.dmw-msg.me .dmw-re:hover::before { border-right-color: var(--blue); }

/* แถบตอบกลับแบบ Discord ในห้อง DM เต็มจอ (.msg-reply.dc)
   ใช้คู่กับ .dmw-re (หน้าต่าง DM ลอย) — คนละ renderer แต่หน้าตาต้องเหมือนกัน
   ⚠️ ต้องทับกฎ .msg-reply เดิม (พื้นฟ้า + border-left) ที่ประกาศไว้ 2 ที่ (บรรทัด ~355 และ ~4237) */
.x10v3 .msg-reply.dc, .msg-reply.dc {
  display: flex; align-items: center; gap: 6px; flex-direction: row; flex-wrap: nowrap;
  position: relative;
  margin: 0 0 3px 0;
  padding: 0 0 0 20px;
  background: none; border: none; border-radius: 0;
  font-size: 12.5px; color: var(--muted);
  cursor: pointer; min-height: 17px; overflow: hidden;
}
.x10v3 .msg-reply.dc::before, .msg-reply.dc::before {
  content: '';
  position: absolute;
  left: 5px; top: 50%; bottom: -3px;
  width: 10px;
  border-left: 2px solid var(--border, rgba(127,127,127,.35));
  border-top: 2px solid var(--border, rgba(127,127,127,.35));
  border-top-left-radius: 7px;
  pointer-events: none;
}
.msg-reply.dc:hover { color: var(--text, inherit); }
.msg-reply.dc:hover::before { border-color: var(--blue); }
.msg-reply.dc .mr-av { flex: 0 0 auto; display: inline-flex; }
.msg-reply.dc .mr-av .avatar, .msg-reply.dc .mr-av img { width: 16px !important; height: 16px !important; font-size: 8px !important; }
/* ชื่อ: ให้พื้นที่ก่อน ค่อยหดถ้าจำเป็น (เดิม max-width 40% ตัดชื่อทิ้งทั้งที่ยังมีที่ว่าง) */
.msg-reply.dc .mr-name { flex: 0 1 auto; font-weight: 600; color: var(--blue); opacity: .95; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-reply.dc .mr-tx { flex: 1 1 0; min-width: 40px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: .85; }
/* ข้อความตัวอย่างในแถบ "กำลังตอบกลับ" — จางกว่าชื่อ ให้ชื่อเด่นก่อน */
.reply-bar .rb-pv { opacity: .7; font-weight: 400; }

/* ===== ตั้งค่าการแจ้งเตือนรายชนิด (2026-09-04) =====
   ⚠️ ต้องมี .x10v3 นำหน้าทุกตัว ไม่งั้น x10-ui.css ทับเงียบๆ (โหลดทีหลังชนะ)
   ⚠️ ห้าม position:absolute ในแถบแท็บ — ต้นเหตุบั๊กล้นจอที่ล้ม 2 รอบ */
.x10v3 .ntfs-preset { display:flex; gap:8px; padding:10px 12px; }
.x10v3 .ntfs-pbtn { flex:1 1 0; min-width:0; display:flex; flex-direction:column;
  align-items:center; gap:4px; padding:10px 6px; border:1px solid var(--line,#d8dee6);
  border-radius:10px; background:var(--card,#fff); cursor:pointer; font-size:12px; }
.x10v3 .ntfs-pbtn b { font-size:12px; text-align:center; line-height:1.25; }
.x10v3 .ntfs-pico { font-size:19px; line-height:1; }
.x10v3 .ntfs-pbtn.on { border-color:var(--accent,#0F4C81); border-width:2px;
  background:color-mix(in srgb, var(--accent,#0F4C81) 8%, transparent); }
.x10v3 .ntfs-note { padding:0 12px 8px; font-size:11px; line-height:1.4; }
.x10v3 .ntfs-more { width:100%; padding:10px 12px; border:0; border-top:1px solid var(--line,#e6e9ef);
  background:transparent; color:var(--accent,#0F4C81); font-size:13px; text-align:left; cursor:pointer; }

/* แถบแท็บในการ์ด — เลื่อนแนวนอนได้ ไม่ลอยทับอะไร */
.x10v3 .ntfs-tabs { display:flex; gap:4px; padding:8px 12px 0;
  overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none; }
.x10v3 .ntfs-tabs::-webkit-scrollbar { display:none; }
.x10v3 .ntfs-tab { flex:0 0 auto; padding:7px 12px; border:0; border-radius:8px 8px 0 0;
  background:transparent; font-size:13px; cursor:pointer; color:var(--muted,#6b7280);
  border-bottom:2px solid transparent; white-space:nowrap; }
.x10v3 .ntfs-tab.on { color:var(--accent,#0F4C81); font-weight:600;
  border-bottom-color:var(--accent,#0F4C81); }

/* ตารางชนิด — มือถือเป็นแถวเดียวไม่ใช่ <table> กว้าง */
.x10v3 .ntfs-kinds { padding:4px 0 8px; }
.x10v3 .ntfs-khead, .x10v3 .ntfs-krow {
  display:grid; grid-template-columns:1fr 52px 52px; align-items:center; gap:6px; padding:9px 12px; }
.x10v3 .ntfs-khead { font-size:11px; color:var(--muted,#6b7280); padding-bottom:4px; }
.x10v3 .ntfs-khead span:not(:first-child), .x10v3 .ntfs-krow .ntfs-kbox { text-align:center; }
.x10v3 .ntfs-krow { border-top:1px solid var(--line,#eef1f5); }
.x10v3 .ntfs-kname { font-size:13px; min-width:0; }
.x10v3 .ntfs-kbox input { width:20px; height:20px; }
.x10v3 .ntfs-khint { grid-column:1 / -1; font-size:11px; color:var(--muted,#6b7280); padding-top:2px; }
.x10v3 .ntfs-qtime { display:flex; gap:12px; flex-wrap:wrap; }
.x10v3 .ntfs-qtime label { display:flex; align-items:center; gap:6px; font-size:13px; }
.x10v3 .ntfs-qtime input[type=time] { padding:6px 8px; border:1px solid var(--line,#d8dee6);
  border-radius:8px; font-size:14px; }

@media (max-width:420px) {
  .x10v3 .ntfs-pbtn b { font-size:11px; }
  .x10v3 .ntfs-khead, .x10v3 .ntfs-krow { grid-template-columns:1fr 44px 44px; padding:9px 10px; }
}

/* แถบ "เมนู" ในแถบข้าง กว้างไม่เท่าของข้างล่าง (Boss แจ้ง 2026-09-04 "มันเบี้ยว")
   .mn-wrap เดิม padding: 0 → กล่องเมนูชนขอบซ้าย-ขวาของแถบข้าง
   แต่ช่องค้นหา (.side-search-row) และแถวอื่นใต้ลงมาเป็น margin ซ้าย-ขวา 12px
   → กล่องเมนูยื่นออกข้างละ 12px เห็นเป็นแถวไม่ตรงแนวกัน
   แก้: ใส่ padding ข้างให้ .mn-wrap เท่ากับ margin ของแถวอื่น */
.mn-wrap { padding-left: 12px; padding-right: 12px; }

/* ===== ไฟล์ที่วางไว้ในกล่องแก้ไขข้อความ (Boss 2026-09-05) ===== */
.ed-att { display: flex; flex-wrap: wrap; gap: 6px; }
.ed-att-item {
  display: flex; align-items: center; gap: 6px;
  max-width: 100%; padding: 4px 6px 4px 4px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--bg);
}
.ed-att-item img { width: 40px; height: 40px; object-fit: cover; border-radius: 5px; flex: 0 0 auto; }
.ed-att-ic { width: 40px; height: 40px; display: grid; place-items: center; font-size: 20px; flex: 0 0 auto; }
.ed-att-name {
  font-size: 12px; color: var(--muted);
  max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ed-att-x {
  border: 0; background: transparent; color: var(--muted);
  cursor: pointer; font-size: 13px; line-height: 1;
  min-width: 28px; min-height: 28px;      /* มือถือ: นิ้วกดโดน */
}
.ed-att-x:hover { color: var(--red, #e5484d); }
@media (max-width: 860px) {
  .ed-att-name { max-width: 96px; }
}

/* ===== 🔑 Google Drive — อนุมัติคำขอสิทธิ์ (Boss สั่ง 2026-09-05) =====================
   ⚠️ มือถือเป็นหลัก (360px): การ์ดเรียงลงล่าง ไม่มีตารางกว้าง ไม่มีสกรอลล์แนวนอน
   ⚠️ ปุ่มสูง 44px ตามมาตรฐานแตะของแอป */
/* 🔄 2026-09-23 รื้อใหม่ ("UI ดูยากมาก") + รอบ 2 "สีไม่เข้ากับธีม"
   ⚠️ สีต้องมาจากธีมเท่านั้น — สีหลัก = var(--blue) (สลับตาม data-accent เช่น ทอง/เขียว/ม่วง)
      พื้นผิว = ชุด --v3-* ของ x10-ui.css (สำรองเป็น --card/--border ของ style.css)
   ⚠️ ห้ามฮาร์ดโค้ดเขียว/แดง/ส้มเป็นพื้นปุ่ม (รอบแรกทำแล้วโดนท้วง) · แดงใช้แค่ตัวหนังสือ error / hover ปฏิเสธ
   (รุ่นแรกสุดใช้ --panel/--line/--bg2 ที่ไม่มี → พื้นขาว + ตัวหนังสืออ่อนในธีมมืด = มองไม่เห็น) */
.gd-wrap { --gd-card: var(--v3-card, var(--card)); --gd-bd: var(--v3-bd, var(--border)); --gd-sub: var(--v3-sub, var(--sunken));
  --gd-mut: var(--v3-mut, var(--muted)); --gd-acc: var(--blue);
  padding: 16px; max-width: 760px; margin: 0 auto; color: var(--text); }
.gd-sec { background: var(--gd-card); border: 1px solid var(--gd-bd); border-radius: 12px; padding: 14px 16px; margin-bottom: 14px; }
.gd-sec-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.gd-sec-head h3 { margin: 0; font-size: 14.5px; font-weight: 700; color: var(--text); }
.gd-count { font-size: 12px; font-weight: 700; min-width: 22px; height: 22px; padding: 0 7px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center; background: var(--gd-sub); color: var(--gd-mut); }
.gd-count.on { background: var(--gd-acc); color: var(--on-brand, #fff); }
.gd-add { margin-left: auto; }
.gd-hint { color: var(--gd-mut); font-size: 14px; padding: 6px 0; line-height: 1.6; }
.gd-empty { color: var(--gd-mut); font-size: 14px; padding: 18px 0; text-align: center; }
.gd-ok { color: var(--v3-up, var(--green)); font-weight: 600; }
.gd-bad { color: var(--v3-down, var(--red)); font-weight: 600; }

/* บัญชี Gmail */
.gd-acct { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-top: 1px solid var(--gd-bd); flex-wrap: wrap; }
.gd-sec-head + .gd-acct { border-top: 0; padding-top: 2px; }
.gd-acct-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--v3-up, var(--green)); flex: none; }
.gd-acct.is-bad .gd-acct-dot { background: var(--v3-down, var(--red)); }
.gd-acct-main { flex: 1 1 200px; min-width: 0; }
.gd-acct-mail { font-weight: 600; color: var(--text); word-break: break-all; }
.gd-acct-sub { font-size: 12.5px; color: var(--gd-mut); margin-top: 2px; }
.gd-unlink { color: var(--gd-mut); }
.gd-unlink:hover { color: var(--v3-down, var(--red)); }

/* การ์ดคำขอ — แถบซ้ายสีหลักของธีม */
.gd-req { border: 1px solid var(--gd-bd); border-left: 3px solid var(--gd-acc); border-radius: 10px;
  padding: 14px; margin-bottom: 12px; background: var(--gd-sub); }
.gd-req:last-child { margin-bottom: 0; }
.gd-req-top { display: flex; gap: 12px; align-items: flex-start; }
.gd-req-ic { font-size: 24px; line-height: 1; flex: none; }
.gd-req-main { min-width: 0; flex: 1; }
.gd-req-file { font-weight: 700; font-size: 15px; color: var(--text); line-height: 1.4; word-break: break-word; }
.gd-req-who { font-size: 14px; color: var(--text); margin-top: 4px; word-break: break-word; }
.gd-req-mail { color: var(--gd-mut); font-size: 13px; word-break: break-all; }
.gd-req-meta { font-size: 12px; color: var(--gd-mut); margin-top: 3px; }
.gd-err { margin-top: 10px; font-size: 13px; color: var(--v3-down, var(--red)); word-break: break-word; }
.gd-req-role { display: flex; align-items: center; gap: 10px; margin: 14px 0 12px; flex-wrap: wrap; }
.gd-lb { font-size: 13px; color: var(--gd-mut); }
.gd-seg { display: inline-flex; background: var(--gd-card); border: 1px solid var(--gd-bd); border-radius: 9px; padding: 3px; gap: 2px; flex-wrap: wrap; }
.gd-seg-opt { position: relative; cursor: pointer; }
.gd-seg-opt input { position: absolute; opacity: 0; pointer-events: none; }
.gd-seg-opt span { display: inline-block; padding: 6px 12px; border-radius: 7px; font-size: 13px; color: var(--gd-mut); font-weight: 600; }
.gd-seg-opt:hover span { color: var(--text); }
.gd-seg-opt input:checked + span { background: var(--gd-acc); color: var(--on-brand, #fff); }
.gd-seg-opt input:focus-visible + span { outline: 2px solid var(--gd-acc); outline-offset: 1px; }
.gd-req-act { display: flex; gap: 8px; flex-wrap: wrap; }
/* ปุ่ม: อนุมัติ = .btn.primary ของแอป (สีหลักธีม) · ปฏิเสธ/เปิดไฟล์ = .btn ธรรมดา */
.gd-btn { min-height: 40px; flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none; font-weight: 600; white-space: nowrap; }
.gd-yes { flex-grow: 2; }
.gd-no:hover { color: var(--v3-down, var(--red)); border-color: var(--v3-down, var(--red)); }

/* ประวัติ */
.gd-hist { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-top: 1px solid var(--gd-bd); }
.gd-sec-head + .gd-hist { border-top: 0; }
.gd-hist-st { width: 20px; height: 20px; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 800; background: var(--gd-sub); }
.gd-hist-st.ok { color: var(--v3-up, var(--green)); }
.gd-hist-st.no { color: var(--v3-down, var(--red)); }
.gd-hist-main { flex: 1; min-width: 0; }
.gd-hist-file { font-weight: 600; font-size: 13.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gd-hist-sub { font-size: 12px; color: var(--gd-mut); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gd-hist-when { color: var(--gd-mut); font-size: 12px; white-space: nowrap; }
@media (max-width: 480px) {
  .gd-wrap { padding: 10px; }
  .gd-sec { padding: 12px; }
  .gd-req-act .gd-yes { flex-basis: 100%; }
  .gd-sec-head { flex-wrap: wrap; }
  .gd-add { flex: 1 1 100%; margin: 4px 0 0; min-height: 40px; }
  .gd-req-mail { display: block; }
  .gd-acct-mail { font-size: 14px; }
  .gd-seg { display: flex; width: 100%; }
  .gd-seg-opt { flex: 1; }
  .gd-seg-opt span { display: block; text-align: center; padding: 8px 4px; }
}

/* ===== ไฟล์แนบเดิมในกล่องแก้ไข — เอาออก/เปลี่ยนได้ (Boss สั่ง 2026-09-05) =====
   ปุ่ม ✕ ต้องเห็นตลอด ห้ามซ่อนรอ hover (มือถือไม่มี hover) */
.ed-old { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.ed-old.hidden { display: none; }
.ed-old-item {
  position: relative; width: 84px; height: 84px; border-radius: 8px; overflow: hidden;
  background: var(--panel2, rgba(127,127,127,.12)); flex: 0 0 auto;
}
.ed-old-item img, .ed-old-item video { width: 100%; height: 100%; object-fit: cover; display: block; }
.ed-old-ic { width: 100%; height: 100%; display: grid; place-items: center; font-size: 26px; }
.ed-old-x {
  position: absolute; top: 2px; right: 2px; width: 26px; height: 26px; border: 0;
  border-radius: 50%; background: rgba(0,0,0,.62); color: #fff; font-size: 15px; line-height: 1;
  cursor: pointer; display: grid; place-items: center; padding: 0;
}
.ed-old-x:hover { background: var(--red, #e5484d); }
@media (max-width: 600px) {
  .ed-old-item { width: 76px; height: 76px; }
  .ed-old-x { width: 28px; height: 28px; }   /* นิ้วกดง่าย */
}

/* 🔄 เปลี่ยนรูปช่องนี้ (2026-09-23) — แถบล่างของรูปย่อ เห็นตลอด ไม่รอ hover */
.ed-old-rp {
  position: absolute; left: 0; right: 0; bottom: 0; border: 0; padding: 3px 0;
  background: rgba(0,0,0,.62); color: #fff; font-size: 11.5px; font-weight: 700; cursor: pointer;
}
.ed-old-rp:hover, .ed-old-rp:active { background: var(--blue); }
@media (max-width: 600px) {
  .ed-old-item { width: 88px; height: 88px; }
  .ed-old-x { width: 32px; height: 32px; }
  .ed-old-rp { padding: 6px 0; font-size: 12.5px; }
}
/* ===== หน้าแก้ไขใหม่ (2026-09-23 · Non "ปรับ UI หน้าแก้ไข") =====
   รูปเดิม/รูปใหม่/ช่องเพิ่ม = แถวเดียว (ed-old/ed-att ใช้ display:contents ให้ลูกไหลรวมกัน)
   ใบข้อความล้วน: ช่องพิมพ์ขึ้นก่อน แถวรูปอยู่ล่าง · ใบรูป: แถวรูปก่อน */
.edit-wrap { display: flex; flex-direction: column; gap: 12px; }
.edit-wrap.is-txt .ed-sec-media { order: 2; }
.edit-wrap.is-txt .ed-sec-text { order: 1; }
.edit-wrap > .ed-also, .edit-wrap > .ed-also-hint, .edit-wrap > .edit-hint, .edit-wrap > .modal-actions { order: 5; }
.ed-sec { display: flex; flex-direction: column; gap: 6px; position: relative; }
.ed-sec-lb { font-size: 12px; font-weight: 700; color: var(--muted); letter-spacing: .2px; }
.ed-media { display: flex; flex-wrap: wrap; gap: 8px; }
.ed-media > .ed-old, .ed-media > .ed-att { display: contents; }
.ed-media > .ed-old.hidden, .ed-media > .ed-att.hidden { display: none; }
.ed-media .ed-old-item { margin: 0; }
.ed-media .ed-att-item.is-new { padding: 0; border: 2px solid var(--green, #16a34a); background: var(--panel2, rgba(127,127,127,.12)); display: block; }
.ed-new-badge {
  position: absolute; left: 4px; top: 4px; padding: 1px 7px; border-radius: 999px;
  background: var(--green, #16a34a); color: #fff; font-size: 11px; font-weight: 700; line-height: 1.6;
}
.ed-media .is-new .ed-att-name {
  position: absolute; left: 0; right: 0; bottom: 0; max-width: none; padding: 2px 4px;
  font-size: 10.5px; color: #fff; background: rgba(0,0,0,.55); text-align: center;
}
.ed-tile-add {
  width: 84px; height: 84px; flex: 0 0 auto; border-radius: 8px; cursor: pointer;
  border: 2px dashed var(--border); background: transparent; color: var(--muted);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  font: inherit; font-size: 11.5px; line-height: 1.3; padding: 4px; text-align: center;
}
.ed-tile-add b { font-size: 22px; line-height: 1; color: var(--blue); }
.ed-tile-add:hover, .ed-tile-add:active { border-color: var(--blue); color: var(--blue); }
.ed-tile-add.hidden { display: none; }
.edit-wrap .edit-input { min-height: 0; }
.edit-wrap .edit-hint { margin-top: -4px; }
body.x10m .edit-wrap .edit-hint { display: none; }          /* Ctrl+Enter ไม่มีบนมือถือ */
/* ปุ่มล่าง: ยกเลิก | บันทึก คู่กัน · "ส่งเป็นใบใหม่" เป็นปุ่มรอง เต็มแถวด้านบน (โผล่เฉพาะมีรูปใหม่) */
.edit-wrap .modal-actions { flex-wrap: wrap; }
.edit-wrap .modal-actions #ed-send.hidden { display: none; }
body.x10m .edit-wrap .modal-actions { flex-direction: row; }
body.x10m .edit-wrap .modal-actions .btn { width: auto; flex: 1 1 0; }
body.x10m .edit-wrap .modal-actions #ed-send { order: -1; flex: 1 1 100%; }
body.x10m .edit-wrap .modal-actions #ed-save { flex-grow: 1.6; }
/* ปุ่ม "ปิด" ของโมดัลกลางซ้ำกับ "ยกเลิก" ของหน้าแก้ไข → ซ่อน (เบราว์เซอร์เก่าไม่รู้จัก :has ก็แค่เห็นปุ่มเดิม) */
#modal-generic:has(.edit-wrap) > .modal-actions { display: none; }
@media (max-width: 600px) { .ed-tile-add { width: 88px; height: 88px; } }
.ed-att-hint { margin-top: 2px; line-height: 1.5; }
.ed-att-hint.hidden { display: none; }

/* ปุ่มเพิ่มรูป/ถ่ายรูปในกล่องแก้ไข (Boss แจ้ง 2026-09-05 "แล้วมือถือล่ะจะเพิ่มไง")
   มือถือวาง Ctrl+V / ลากไฟล์ไม่ได้ ต้องมีปุ่มกดจริง */
.ed-addrow { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 6px; }
.ed-addbtn { flex: 1 1 auto; min-height: 44px; font-size: 14px; }   /* 44px = นิ้วกดถนัด */
.ed-addbtn.hidden { display: none; }

/* คำแนะนำ Ctrl+V / ลากไฟล์ ใช้ไม่ได้บนมือถือ ซ่อนไป ให้ใช้ปุ่มแทน */
body.x10m .ed-hint-desk { display: none; }
@media (max-width: 600px) { .ed-hint-desk { display: none; } }

/* ============================================================
   พรีวิวลิงก์แบบ Facebook / LINE (Boss สั่ง 2026-09-05)
   มือถือมาก่อน: การ์ดเป็นแนวตั้ง รูปเต็มความกว้าง · จอกว้างขึ้นค่อยเป็นแนวนอน
   ============================================================ */
.lnk-card {
  display: block; margin-top: 6px; max-width: 420px;
  border: 1px solid var(--line, rgba(127,127,127,.28)); border-radius: 10px;
  overflow: hidden; text-decoration: none; color: inherit;
  background: var(--panel2, rgba(127,127,127,.06));
}
.lnk-card:hover { border-color: var(--accent, #1264a3); }
/* ⚠️⚠️ ที่ว่างรอโหลด: ห้าม display:none — IntersectionObserver ไม่เคยเห็น element ที่ไม่มีพื้นที่
   เลยไม่ยิงโหลดเลย (เจอมาแล้ว การ์ดค้าง waiting ทุกใบ) ใช้สลิว 1px โปร่งใสแทน */
.lnk-wait {
  display: block; height: 1px; margin: 0; border: 0; background: none;
  max-width: none; overflow: hidden;
}
.lnk-img { position: relative; line-height: 0; background: rgba(127,127,127,.12); }
.lnk-img img { width: 100%; max-height: 220px; object-fit: cover; display: block; }
.lnk-play {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 34px; color: #fff; text-shadow: 0 2px 10px rgba(0,0,0,.6); pointer-events: none;
}
.lnk-body { padding: 8px 10px; }
.lnk-host { font-size: 11.5px; color: var(--muted, #888); text-transform: uppercase; letter-spacing: .02em; }
.lnk-title {
  font-weight: 700; font-size: 14px; margin-top: 2px; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  /* ⚠️ line-clamp เดี่ยว ๆ ไม่พอ ต้องล็อกความสูงด้วย ไม่งั้นบรรทัดที่ 2 ล้นขอบการ์ด */
  max-height: calc(14px * 1.35 * 2);
}
.lnk-desc {
  font-size: 12.5px; color: var(--muted, #888); margin-top: 3px; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  max-height: calc(12.5px * 1.4 * 2);
}
/* ลิงก์ที่เป็นรูปตรง ๆ — โชว์รูปใหญ่ ไม่ต้องมีกล่องข้อความ (เหมือน LINE) */
.lnk-card.lnk-photo { position: relative; border: 0; background: none; max-width: 320px; }
.lnk-card.lnk-photo img {
  width: 100%; border-radius: 10px; display: block; cursor: zoom-in;
  border: 1px solid var(--line, rgba(127,127,127,.28));
}
.lnk-card.lnk-photo .lnk-host {
  position: absolute; left: 8px; bottom: 6px; color: #fff;
  background: rgba(0,0,0,.55); padding: 1px 6px; border-radius: 6px; font-size: 10.5px;
}
@media (min-width: 620px) {
  /* จอกว้าง: รูปอยู่ซ้าย ข้อความอยู่ขวา แบบการ์ด Slack */
  .lnk-card:not(.lnk-photo) { display: flex; align-items: stretch; }
  .lnk-card:not(.lnk-photo) .lnk-img { flex: 0 0 120px; }
  .lnk-card:not(.lnk-photo) .lnk-img img { height: 100%; max-height: 120px; }
  .lnk-card:not(.lnk-photo) .lnk-body { flex: 1 1 auto; min-width: 0; }
}

/* ---------- call UI: mobile tap targets (Boss 2026-09-05) ----------
   ตรวจที่ 360x780 จริง เจอ 2 ปัญหา:
   1) ปุ่มคุมสาย + ปุ่มรับสาย/ปฏิเสธ สูงแค่ 42px < 44px ที่นิ้วกดถนัด
      ต้นเหตุ: x10-ui.css โหลด "ทีหลัง" style.css → .x10v3 .btn.small{padding:5px 12px}
      ทับ .btn{padding:11px 18px} ในสื่อมือถือของ style.css ที่ตั้งใจขยายปุ่มไว้
      (เคสเดียวกับ x10chat_head_btn_oversize_mobile แต่กลับด้าน = เล็กเกินแทนบวม)
      ⚠️ ต้องใส่ .x10v3 นำหน้า ไม่งั้นแพ้ x10-ui.css เหมือนเดิม
   2) ปุ่มรับสาย/ปฏิเสธ กว้าง 72px ลอยมุมขวาล่างของ bottom sheet
      สายเรียกเข้าต้องกดเร็ว+มักกดมือเดียว → ทำเต็มแถวแบบแอปโทรทั่วไป
   ⚠️ จำกัดขอบเขตแค่ call UI เท่านั้น ห้ามไปโดนปุ่มโมดัลอื่นทั้งแอป */
@media (max-width: 768px) {
  /* 1) แถวคุมสาย — ปุ่มสูงพอกดถนัด และไม่ล้นแถว */
  .call-controls .btn,
  .x10v3 .call-controls .btn.small {
    min-height: 44px; padding: 8px 4px; font-size: 12px; line-height: 1.15;
    /* ⚠️ ห้ามใช้ flex:1 1 auto — จอ 320px ปุ่มตก 2 บรรทัดแล้ว "วางสาย" ยืด 300px เต็มแถว
       ใช้ 1 1 0 + basis 0 ให้ 4 ปุ่มกว้างเท่ากันเป๊ะ และบีบลงได้ไม่ตกบรรทัด */
    flex: 1 1 0; min-width: 0;
    /* ⚠️⚠️ ห้าม white-space:nowrap — ป้ายภาษาพม่า/ไทใหญ่/เขมร ยาวกว่าไทยมาก
       เทสแล้วโดนตัดหัวท้าย 4/5 ภาษา (เช่น '📹 ကင်မရာပိတ်' ต้องการ 92px แต่ปุ่มกว้าง 79px)
       ปล่อยให้ตัดบรรทัดในปุ่มแทน — ปุ่มสูงขึ้นได้ แต่ต้องอ่านออกครบทุกภาษา */
    white-space: normal; overflow-wrap: anywhere; word-break: break-word;
    display: flex; align-items: center; justify-content: center; text-align: center;
  }
  /* กันแถวแตกเด็ดขาด — 4 ปุ่มต้องอยู่บรรทัดเดียวเสมอ ถึงจอจะแคบแค่ไหน */
  .call-controls { flex-wrap: nowrap; gap: 6px; }

  /* 2) สายเรียกเข้า — ปุ่มรับ/ปฏิเสธ เต็มแถว กดง่ายด้วยมือเดียว
        เรียง "รับสาย" ไว้ล่างสุด = นิ้วโป้งถึงก่อน และห่างจากปุ่มปฏิเสธ */
  #modal-incoming-call .modal-actions {
    flex-direction: column-reverse; gap: 10px; justify-content: stretch;
  }
  #modal-incoming-call .modal-actions .btn {
    width: 100%; min-height: 52px; font-size: 16px; font-weight: 700;
    justify-content: center;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   [เฟส 3] แท็บห้อง + แบ่งช่อง 2-3 ช่อง — ย้ายจาก demo-chat (2026-09-05)
   ที่มา: /opt/x10-chat-demo/public/style.css บรรทัด 6750-6811
   เฉพาะจอ >=1100px (ฝั่งคอม) · @media(max-width:1099px) ปิดทุกอย่าง
   → มือถือ/จอแคบได้พฤติกรรมเดิมเป๊ะ
   ⚠️ .panes ต้องรับ flex:1 แทน .chat-room เพราะไปคั่นระหว่าง .page(column)
      กับ .chat-room — .panes { flex:1; display:flex } จัดการให้แล้ว
   ══════════════════════════════════════════════════════════════════════ */
.rtabs { display: flex; align-items: stretch; gap: 6px; padding: 4px 8px; min-height: 34px;
  background: var(--card, #fff); border-bottom: 1px solid var(--border, #E2E8F0); }
.rtabs-list { display: flex; gap: 4px; flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: thin; }
/* 🔖 แท็บห้องด้านบน — Boss: "แท็บด้านบนที่ผมชี้ก็ทำให้แบบหน้าแรก"
   เดิมแท็บที่ไม่ได้เลือกเป็นกล่องสีพื้นติดกันหมด แยกไม่ออกว่ากี่แท็บ
   → ใส่เส้นขอบทุกแท็บ + ตัวที่เลือกยกขึ้นเป็นสีการ์ดพร้อมขีดน้ำเงินหนา (เหมือนแท็บห้องหลัก) */
.rtab { display: flex; align-items: center; gap: 5px; max-width: 190px; flex: 0 0 auto;
  padding: 5px 8px 5px 11px; border-radius: 8px 8px 0 0; cursor: pointer; font-size: 13px;
  background: var(--bg, #F4F6F9); color: var(--muted, #64748b);
  border: 1px solid var(--border, #E2E8F0); border-bottom: none; }
.rtab:hover { background: var(--card, #fff); color: var(--text, #0f172a); }
.rtab.on { background: var(--card, #fff); border-color: var(--pane-split, #CBD5E1);
  color: var(--text, #0f172a); font-weight: 700;
  box-shadow: inset 0 3px 0 var(--blue, #0F4C81); }
/* แท็บที่กำลังวางอยู่ในช่องเสริม = เห็นอยู่แล้ว ทำให้จางลงกันสับสน */
.rtab.inpane { opacity: .62; }
.rtab-nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rtab-x { border: none; background: none; color: inherit; cursor: pointer; opacity: .5;
  font-size: 11px; padding: 1px 3px; line-height: 1; font-family: inherit; }
.rtab-x:hover { opacity: 1; }
/* ⭐ Boss สั่ง 2026-09-05: "ย้ายไปบนขวา" — ปุ่มแบ่งจอ ▊ ▊▊ ▊▊▊ (ตัวที่เปิดหน้าซ้อน 3 ช่อง)
   เดิมอยู่ในแถวเดียวกับแท็บแต่กินเต็มความกว้าง (วัดได้ 1140px @y=26) ดูเหมือนลอยกลาง
   ย้ายไปเกาะมุมบนขวาของแถบ ให้อยู่แนวเดียวกับปุ่ม 🔔📞📹⋯ ของหัวห้อง
   ⚠️ .rtabs ต้อง position:relative รองรับ (ตั้งไว้ด้านล่าง)
   ⚠️ .rtabs-list เว้นที่ขวาไว้ ไม่งั้นแท็บตัวท้ายลอดไปใต้ปุ่ม */
.rtabs { position: relative; }
.rtabs-list { padding-right: 108px; }
.rtabs-tools {
  position: absolute; top: 4px; right: 8px; z-index: 2;
  display: flex; gap: 3px; align-items: center; flex: 0 0 auto;
  background: var(--card, #fff); padding-left: 6px;
}
.rtb-split { border: 1px solid var(--border, #E2E8F0); background: var(--bg, #F4F6F9);
  color: var(--muted, #64748b); border-radius: 6px; cursor: pointer; font-size: 10px;
  padding: 3px 6px; letter-spacing: -1px; font-family: inherit; }
.rtb-split.on { background: var(--blue, #0F4C81); color: var(--on-brand, #fff); border-color: transparent; }
.rtb-split:disabled { opacity: .35; cursor: not-allowed; }

/* กริดช่อง — ช่องแรกคือ #chat-room ตัวเดิม (ไม่ได้โคลน) */
.panes { flex: 1; display: flex; min-height: 0; min-width: 0; }
.panes > .chat-room { flex: 1; min-width: 0; }
/* 🔻 เส้นแบ่งระหว่างบาน — Boss: "เส้นตัดระหว่างหน้าซ้อนให้ชัด"
   ของเดิม 1px สีจาง มองไม่ออกว่าคนละห้อง → 3px ทึบ + เงาช่วยให้เห็นเป็นคนละแผ่น
   ⚠️ ใส่ที่ .panes > * + * ด้วย เผื่อช่องแรก (#chat-room) ไม่ใช่ .pane2 */
.panes > * + * { border-left: 3px solid var(--pane-split, #CBD5E1); }
.pane2 { flex: 1; min-width: 0; display: flex; flex-direction: column;
  background: var(--bg, #F4F6F9); box-shadow: inset 6px 0 10px -10px rgba(0,0,0,.35); }
/* หัวบาน — หน้าตาเดียวกับหัวห้องหลัก (.chat-head) ไม่ใช่แถบน้ำเงินทึบแบบเดิม */
.pane-head { display: flex; align-items: center; gap: 8px; padding: 8px 12px; min-height: 46px;
  background: var(--card, #fff); color: var(--text, #1B2A3A);
  border-bottom: 1px solid var(--border, #E2E8F0); }
.pane-nm { flex: 1; min-width: 0; font-size: 15px; font-weight: 650; letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ปุ่มบนหัวบานต้องเห็นบนพื้นขาว (เดิมเป็นสีขาวบนแถบน้ำเงิน = จมหายไปเลย) */
.pane-head .dmw-btn { color: var(--muted, #64748b); background: none; border: none;
  cursor: pointer; font-size: 15px; padding: 2px 6px; border-radius: 6px; }
.pane-head .dmw-btn:hover { background: var(--side-hover, #EEF2F7); color: var(--text, #1B2A3A); }
/* เมนู ⋯ บนหัวบานแยก (พี่ปอง 2026-09-14) — ปุ่มลัดชุดเดียวกับห้องหลัก
   ⚠️ หัวบาน overflow ไม่ได้ซ่อน แต่ .pane-body ข้างล่างเป็น overflow-y:auto
      ถ้าวางเมนูใน flow ปกติมันจะโดนตัด → ต้อง absolute เกาะ .pane-more-wrap
   ⚠️ ชิดขวา (right:0) กันเมนูล้นขอบขวาของบาน ซึ่งแคบกว่าห้องหลักมาก */
.pane-more-wrap { position: relative; flex: 0 0 auto; }
.pane-pop { position: absolute; top: 100%; right: 0; z-index: 60; min-width: 172px; }
.pane-body { flex: 1; min-height: 0; overflow-y: auto; padding: 10px;
  display: flex; flex-direction: column; gap: 8px; }
/* ท้ายบาน — วางเป็นแถว: ช่องพิมพ์บรรทัดบน แถบปุ่มบรรทัดล่าง (เหมือนช่องหลัก) */
.pane-foot { display: flex; flex-direction: column; gap: 4px; padding: 7px;
  border-top: 1px solid var(--border, #E2E8F0); background: var(--card, #fff); }
.pane-act { display: flex; align-items: center; gap: 2px; }
.pane-act .dmw-send { margin-left: auto; font-size: 19px; }
.pane-act .pfmt-tg.on { background: var(--blue-light, #E3EDF7); border-radius: 6px; opacity: 1; }
/* แถบจัดข้อความของบาน — เลื่อนแนวนอนได้ บานแคบกว่าห้องหลักมาก */
.pane-fmt { display: flex; gap: 2px; overflow-x: auto; scrollbar-width: thin;
  padding: 3px 0 1px; border-top: 1px dashed var(--border, #E2E8F0); }
.pane-fmt .cp-fbtn { flex: 0 0 auto; }
.pane-empty, .pane-head.drop, .pane-empty.drop { }
.pane-empty { flex: 1; display: flex; align-items: center; justify-content: center;
  text-align: center; padding: 16px; color: var(--muted, #64748b); font-size: 12.5px;
  border: 2px dashed var(--border, #E2E8F0); margin: 10px; border-radius: 10px; }
.pane-empty.drop, .pane-head.drop { outline: 2px dashed var(--blue, #0F4C81); outline-offset: -3px; }

/* จอแคบ/มือถือ: ปิดฟีเจอร์ทั้งหมด — กลับไปเป็นห้องเดียวเหมือนเดิมทุกประการ */
@media (max-width: 1099px) {
  .rtabs { display: none !important; }
  .panes { display: flex; }
  .pane2 { display: none !important; }
}

/* แท็บ = พื้นที่ทำงาน (แก้รอบ 2 · พี่ปอง 11:34) — 1 แท็บถือชุดช่องของตัวเอง */
.rtab-cnt { font-size: 10px; padding: 0 4px; border-radius: 6px; font-weight: 700;
  background: var(--border, #E2E8F0); color: var(--muted, #64748b); }
.rtab.on .rtab-cnt { background: var(--blue, #0F4C81); color: var(--on-brand, #fff); }
.rtab-add { flex: 0 0 auto; border: 1px dashed var(--border, #E2E8F0); background: none;
  color: var(--muted, #64748b); border-radius: 7px; cursor: pointer; font-size: 13px;
  padding: 2px 9px; font-family: inherit; align-self: center; }
.rtab-add:hover { color: var(--blue, #0F4C81); border-color: var(--blue, #0F4C81); }
/* ปล่อยห้องลงบนแท็บได้ด้วย (ย้ายเข้าช่องแรกของแท็บนั้น) */
.rtab.drop { outline: 2px dashed var(--blue, #0F4C81); outline-offset: -2px; }
/* ลากสลับลำดับแท็บแบบ Chrome (Boss 2026-09-08)
   ⚠️ ต้อง position:relative รับเส้นแทรก ::before/::after
   ⚠️ ห้ามใช้ margin/border ขยับเส้น — แท็บจะกระตุกตอนลากผ่าน */
.rtab { position: relative; user-select: none; }
.rtab.dragging { opacity: .4; }
.rtab.ins-l::before, .rtab.ins-r::after {
  content: ''; position: absolute; top: 2px; bottom: 2px; width: 3px;
  background: var(--blue, #0F4C81); border-radius: 2px; pointer-events: none;
}
.rtab.ins-l::before { left: -3px; }
.rtab.ins-r::after { right: -3px; }

/* ============================================================
   จอโทรแบบโทรศัพท์ (Boss 2026-09-06)
   ดัดจากดีไซน์ที่ Boss ส่งมา แต่:
   - ไม่ดึงรูปพื้นหลังจากเน็ตนอก (unsplash) — พนักงานเน็ตช้า/บล็อกโดเมนนอกได้
     ใช้ไล่สีเข้มแทน โหลดทันทีเสมอ
   - ไม่ล็อกขนาด 390x844 — เต็มจอจริงทุกเครื่อง (mobile first 360x780)
   ⚠️ z-index ต้องสูงกว่า meet-stage เพราะสายเรียกเข้าต้องเด้งทับทุกอย่าง
   ============================================================ */
.call-screen {
  position: fixed; inset: 0; z-index: 3000;
  display: flex; justify-content: center; align-items: stretch;
  color: #fff;
  /* 🎨 เข้าธีมแอป: สีแบรนด์ #0F4C81 (navy) แทนโทนเขียวอมฟ้าเดิมที่ไม่เข้ากับที่อื่น */
  background:
    radial-gradient(130% 85% at 50% -5%, #1B5E96 0%, rgba(27,94,150,0) 62%),
    linear-gradient(to bottom, #0F4C81 0%, #0B3A63 48%, #071E33 100%);
}
.call-screen.hidden { display: none; }
.cs-inner {
  width: 100%; max-width: 480px;
  display: flex; flex-direction: column; align-items: center;
  /* กันรอยบาก/แถบล่างบน iPhone — แอปนี้ใช้ env(safe-area-*) อยู่แล้วทั้งแอป */
  padding: calc(env(safe-area-inset-top, 0px) + 46px) 22px calc(env(safe-area-inset-bottom, 0px) + 28px);
}
.cs-status { font-size: 15px; opacity: .75; min-height: 20px; }
.cs-avatar {
  width: 104px; height: 104px; border-radius: 50%; margin-top: 22px;
  background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.25);
  display: flex; justify-content: center; align-items: center;
  font-size: 40px; font-weight: 600; overflow: hidden;
}
.cs-avatar img { width: 100%; height: 100%; object-fit: cover; }
.cs-name { margin-top: 22px; font-size: 30px; font-weight: 600; text-align: center; line-height: 1.25; }
.cs-where { margin-top: 8px; opacity: .72; font-size: 14px; text-align: center; }
.cs-wave { margin-top: 28px; display: flex; gap: 6px; align-items: center; height: 46px; }
.cs-wave span {
  width: 4px; height: 14px; border-radius: 10px; background: rgba(255,255,255,.8);
  animation: cs-wave 1s infinite ease-in-out;
}
.cs-wave span:nth-child(2) { animation-delay: .1s; }
.cs-wave span:nth-child(3) { animation-delay: .2s; }
.cs-wave span:nth-child(4) { animation-delay: .3s; }
.cs-wave span:nth-child(5) { animation-delay: .4s; }
.cs-wave span:nth-child(6) { animation-delay: .5s; }
.cs-wave span:nth-child(7) { animation-delay: .6s; }
@keyframes cs-wave {
  0%, 100% { height: 12px; opacity: .4; }
  50%      { height: 42px; opacity: 1; }
}
/* เคารพคนที่ตั้งเครื่องว่า "ลดการเคลื่อนไหว" (คนเมารถ/ไมเกรน) */
@media (prefers-reduced-motion: reduce) {
  .cs-wave span { animation: none; height: 22px; opacity: .7; }
}
/* แนวตั้ง: กล่อง "โทรหาใคร" ไม่ยืด ปล่อยให้ .cs-bottom ดันตัวเองลงล่างด้วย margin-top:auto
   (แนวนอนจะ override ให้ยืดเป็นคอลัมน์ซ้ายแทน) */
.cs-head-wrap { display: contents; }
.cs-bottom { margin-top: auto; width: 100%; padding-top: 30px; }

.cs-incoming { display: flex; justify-content: space-around; }
.cs-btnwrap { display: flex; flex-direction: column; align-items: center; }
.cs-round {
  width: 70px; height: 70px; border-radius: 50%; border: none; color: #fff;
  cursor: pointer; transition: transform .15s;
  display: flex; align-items: center; justify-content: center;
}
.cs-round:active { transform: scale(.9); }
.cs-round.decline { background: #ff453a; }
.cs-round.answer  { background: #32d74b; }
/* ปุ่มวางสาย/ปฏิเสธ หมุนหูโทรศัพท์ให้เป็นท่า "วาง" แบบโทรศัพท์จริง */
.cs-round.decline .cs-ic, .cs-end .cs-ic { transform: rotate(135deg); }
.cs-lb { margin-top: 9px; font-size: 13px; opacity: .9; }
.cs-ic { display: inline-flex; }
.cs-ic svg { width: 28px; height: 28px; display: block; }

/* 🎨 2026-09-09 Boss: "ปรับ UI ให้ดูโปร เข้าธีมแอป"
   เดิมกริด 3 คอลัมน์ตายตัว → ปุ่มซ่อน/โชว์ตามสถานะ (สลับกล้องโชว์เฉพาะตอนเปิดกล้อง)
   ทำให้แถวเบี้ยว ปุ่มวางสายเลื่อนตำแหน่ง = กดพลาด
   ใหม่: แถวควบคุมเป็น flex ยืดตามจำนวนปุ่มจริง + ปุ่มวางสายแยกกลุ่มกลางล่าง */
.cs-active { display: flex; flex-direction: column; gap: 18px; width: 100%; }
.cs-row {
  display: flex; justify-content: center; align-items: flex-start;
  gap: 10px; flex-wrap: wrap;
}
/* ⚠️ ปุ่มควบคุมมีได้ 3-5 ปุ่ม (สลับกล้องโชว์เฉพาะตอนเปิดกล้อง)
   ต้องอยู่ "แถวเดียว" ให้ได้บนจอ 360 → ยอมให้ย่อความกว้างลงตามจำนวนปุ่ม */
.cs-row .cs-ctl { flex: 1 1 0; min-width: 0; max-width: 84px; }
.cs-endrow { display: flex; justify-content: center; }
/* ปุ่มวางสายเด่นกว่าเพื่อน (เป็นปุ่มที่ต้องหาเจอเร็วที่สุด) */
.cs-endrow .cs-ctl-ic { width: 68px; height: 68px; }
.cs-endrow .cs-ctl-ic svg { width: 28px; height: 28px; }
/* ปุ่มที่ซ่อน (เช่น สลับกล้อง ตอนยังไม่เปิดกล้อง) ต้องไม่กินที่ในแถว flex
   ⚠️ ของเดิมใช้ visibility:hidden = ยังกินที่ ทำให้แถวมีรูโหว่ */
.cs-row .cs-ctl.cs-hide { display: none; }
.cs-ctl { text-align: center; cursor: pointer; user-select: none; }
.cs-ctl-ic {
  width: 60px; height: 60px; margin: auto; border-radius: 50%;
  background: rgba(255,255,255,.16);
  border: 1px solid rgba(255,255,255,.08);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  display: flex; justify-content: center; align-items: center;
  transition: background .15s, transform .15s;
}
/* ต้นแบบย่อปุ่มตอนกด (transform: scale(.9)) ให้รู้สึกว่ากดติด */
.cs-ctl:active .cs-ctl-ic { transform: scale(.9); }
.cs-ctl:active .cs-ctl-ic { background: rgba(255,255,255,.3); }
/* ปุ่มที่ "เปิดอยู่" ต้องต่างจากปิดชัดๆ — เดิมดีไซน์ต้นแบบไม่มีสถานะเลย
   กดปิดไมค์แล้วหน้าตาเหมือนเดิม = ไม่รู้ว่าปิดสำเร็จไหม */
.cs-ctl.on .cs-ctl-ic { background: #fff; color: #0d2233; }
.cs-ctl.on .cs-ctl-ic svg { stroke: #0d2233; }
.cs-ctl-ic.cs-end { background: #ff453a; }
.cs-ctl-ic.cs-end svg { stroke: #fff; }
.cs-ctl p { margin-top: 9px; font-size: 12px; opacity: .9; }
.cs-ctl.cs-hide { visibility: hidden; pointer-events: none; }
.cs-ctl-ic svg { width: 24px; height: 24px; }

/* จอเล็กมาก (360x640 เครื่องพนักงานรุ่นเก่า) — บีบให้ครบจอไม่ต้องเลื่อน */
@media (max-height: 700px) {
  .cs-inner { padding-top: calc(env(safe-area-inset-top, 0px) + 24px); }
  .cs-avatar { width: 84px; height: 84px; font-size: 32px; margin-top: 14px; }
  .cs-name { font-size: 25px; margin-top: 16px; }
  .cs-wave { margin-top: 16px; height: 34px; }
  @keyframes cs-wave { 0%,100% { height: 10px; opacity:.4 } 50% { height: 30px; opacity:1 } }
  .cs-active { gap: 14px; }
}
/* จอแคบ (360px) — บีบปุ่มให้ครบแถวเดียว ไม่ตกบรรทัด */
@media (max-width: 400px) {
  .cs-row { gap: 4px; }
  .cs-ctl-ic { width: 54px; height: 54px; }
  .cs-ctl p { font-size: 11px; margin-top: 6px; }
}
/* 🔴 2026-09-08 มือถือ "แนวนอน" (780x360) — เจอตอนกวาดทุกขนาดจอ
   กฎคอมใช้ `min-width:900px` จึงไม่ครอบจอนี้ แต่ความสูงมีแค่ 360px
   → เลย์เอาต์แนวตั้งเดิมต้องการ 374px = **ปุ่มวางสายตกขอบล่าง กดไม่ได้**
     (วัดได้: .cs-hangup bottom=374 > viewport 360 · .cs-avatar ถูกบีบเหลือสูง 2px)
   ⚠️ ห้ามใช้ min-width อย่างเดียวตัดสินว่า "คอมหรือมือถือ" — ต้องดูความสูงด้วย
      (บทเรียนเดียวกับหน้าประชุม ดู memory x10chat_meet_ui_rebuild) */
@media (max-height: 480px) and (orientation: landscape) {
  .cs-inner {
    max-width: 100%;
    padding: calc(env(safe-area-inset-top, 0px) + 8px) 18px
             calc(env(safe-area-inset-bottom, 0px) + 8px);
    justify-content: center;
  }
  /* ย่อส่วนหัวลงให้พอดีความสูง — ยังเห็นครบว่าโทรหาใคร */
  .cs-avatar { width: 52px; height: 52px; font-size: 20px; margin-top: 0; flex: 0 0 auto; }
  .cs-name { font-size: 18px; margin-top: 6px; }
  .cs-where { font-size: 12px; margin-top: 2px; }
  .cs-status { font-size: 12px; }
  .cs-wave { display: none; }          /* คลื่นเสียงเป็นของประดับ ตัดได้ก่อนเพื่อน */
  /* 🎨 2026-09-09 แนวนอนเดิม: ปุ่มกระจายกว้างสุดจอ + ป้ายชื่อปุ่มโดนขอบล่างตัด
     ใหม่: แบ่ง 2 คอลัมน์ — ซ้าย=โทรหาใคร · ขวา=ปุ่ม (ใช้ความกว้างที่มีเหลือเฟือ) */
  .cs-inner { flex-direction: row; align-items: center; gap: 20px; }
  .cs-head-wrap { flex: 1 1 auto; display: flex; flex-direction: column;
                  align-items: center; justify-content: center; min-width: 0; }
  .cs-bottom { margin-top: 0; padding-top: 0; flex: 0 0 auto; width: auto; }
  .cs-active { gap: 10px; }
  .cs-row { gap: 8px; max-width: 340px; }
  .cs-row .cs-ctl { width: 62px; }
  .cs-ctl-ic { width: 44px; height: 44px; }
  .cs-endrow .cs-ctl-ic { width: 50px; height: 50px; }
  .cs-endrow .cs-ctl-ic svg { width: 22px; height: 22px; }
  .cs-ctl p, .cs-lb { font-size: 10px; margin-top: 5px; }
  .cs-round { width: 52px; height: 52px; }
}

/* คอม: ไม่ต้องกินเต็มจอ 27 นิ้ว — จัดเป็นการ์ดกลางจอ */
@media (min-width: 900px) {
  .call-screen { align-items: center; }
  .cs-inner {
    max-width: 400px; height: min(780px, 92vh);
    border-radius: 22px; box-shadow: 0 24px 70px rgba(0,0,0,.5);
    background: linear-gradient(to bottom, #0F4C81 0%, #0B3A63 45%, #071E33 100%);
    border: 1px solid rgba(255,255,255,.08);
  }
}

/* ระหว่างเปิดจอโทร ห้ามมีอะไรลอยทับปุ่มรับสาย/วางสาย
   ⚠️ #ntf-perm-bar ต่อกับ body ตรงๆ (ไม่ได้อยู่ใน .app) จึงลอยทับจอโทรได้
   เจอตอนเทสสายจริง: แถบ "เบราว์เซอร์ปิดสิทธิ์แจ้งเตือน" บังป้ายปุ่มไมค์/ลำโพง
   ซ่อนชั่วคราวระหว่างโทรเท่านั้น วางสายแล้วกลับมาเหมือนเดิม */
body.cs-open #ntf-perm-bar,
body.cs-open #meeting-bar { display: none !important; }
/* toast ยังต้องเห็น (บอกว่าเปิดไมค์ไม่ได้ ฯลฯ) แต่ต้องอยู่เหนือจอโทร */
/* ต้นแบบวาง toast ที่ bottom:160px เพื่อไม่ให้ทับแถวปุ่ม (ของแอปอยู่ที่ 80px = ทับพอดี) */
body.cs-open #toast {
  z-index: 3100;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 200px);
}

/* ---------- กล้องบนจอโทร (Boss 2026-09-06 · ตามดีไซน์ที่ Boss ส่งมา) ----------
   ยึดตามต้นแบบ: อวตาร/คลื่นเสียงใช้ opacity ไม่ใช่ display:none
   (ต้นแบบตั้งใจให้ "จางหาย" แต่ยังกินที่เท่าเดิม ชื่อจึงไม่ขยับขึ้นลงตอนเปิด/ปิดกล้อง)
   ปุ่มยังเป็นแก้วฝ้าโปร่ง rgba(255,255,255,.16) + blur ตามต้นแบบ ไม่ทึบดำ */
.cs-cam {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: none; z-index: 0;
  transform: scaleX(-1);          /* กล้องหน้า = กระจกเงา ให้เหมือนส่องกระจก */
}
.cs-cam.cs-rear { transform: scaleX(1); }   /* กล้องหลัง ห้ามกลับด้าน ตัวหนังสือจะกลับ */
/* ไล่เฉดตามต้นแบบ .15 → .05 → .65 (บนใส กลางโปร่ง ล่างเข้มรับปุ่ม) */
.cs-cam-veil {
  position: absolute; inset: 0; display: none; z-index: 1; pointer-events: none;
  background: linear-gradient(to bottom, rgba(0,0,0,.15), rgba(0,0,0,.05), rgba(0,0,0,.65));
}
.call-screen.cam-on .cs-cam,
.call-screen.cam-on .cs-cam-veil { display: block; }

/* 🔴 2026-09-08 Boss: "ในคอมดูเอา การโทรมันต้องปรับรูปแบบไปตามอุปกรณ์สิ"
   (ส่งรูป: การ์ดโทรแคบ ๆ ตรงกลาง แต่ **ภาพกล้องเต็มจอ 27 นิ้วอยู่ข้างหลัง**)
   ต้นเหตุ: `.cs-cam`/`.cs-cam-veil` เป็น `absolute; inset:0` และเป็น **พี่น้องของ
   `.cs-inner`** (ไม่ใช่ลูก) จึงอิงกรอบ `.call-screen` = เต็มจอเสมอ
   มือถือการ์ด = เต็มจออยู่แล้วเลยไม่เห็นปัญหา พอขึ้นคอมถึงหลุดกรอบ
   วัดจริง 1280x800: การ์ด 400x736 แต่กล้อง **1280x800**
   ⚠️ `.cs-inner{position:relative}` ไม่ช่วย — containing block ใช้กับ "ลูก" เท่านั้น
   ⚠️⚠️ **บล็อกนี้ต้องอยู่ "ใต้" กฎฐาน `.cs-cam` เสมอ** — specificity เท่ากัน
      ถ้าไปวางไว้ในบล็อก @media ข้างบน (ก่อนกฎฐาน) กฎฐานจะทับทิ้งทั้งหมด
      (เสียเวลาไปหนึ่งรอบเพราะเรื่องนี้ — วัดได้ว่ากล้องยัง 1280x800 เหมือนเดิม) */
/* ⚠️⚠️ ต้องคุมทุกความกว้าง ไม่ใช่เฉพาะคอม — `.cs-inner` มี `max-width:480px`
   อยู่แล้วตั้งแต่ฐาน แปลว่า **แท็บเล็ต (768x1024) การ์ดก็แคบกว่าจอ** เหมือนกัน
   (วัดได้: การ์ด 480px แต่กล้อง 768px = ล้นออกนอกการ์ดเหมือนบนคอม)
   เดิมผมเขียนไว้แค่ min-width:900px แล้วแท็บเล็ตหลุด — เจอตอนกวาดครบทุกขนาด
   → ยึดกล้องให้กว้างเท่าการ์ดเสมอด้วยสูตรเดียวกับ .cs-inner */
.cs-cam, .cs-cam-veil {
  inset: auto; top: 50%; left: 50%;
  width: 100%; max-width: 480px; height: 100%;
}
.cs-cam { transform: translate(-50%, -50%) scaleX(-1); }
.cs-cam.cs-rear { transform: translate(-50%, -50%) scaleX(1); }
.cs-cam-veil { transform: translate(-50%, -50%); }

@media (min-width: 900px) {
  /* คอม: การ์ดถูกย่อเป็น 400px + สูงจำกัด + มุมโค้ง → กล้องต้องตามเป๊ะ */
  .cs-cam, .cs-cam-veil {
    max-width: 400px; height: min(780px, 92vh);
    border-radius: 22px;
  }
}

/* มือถือแนวนอน: การ์ดกางเต็มกว้าง (max-width:100%) → กล้องต้องกางตามให้เท่ากัน
   ไม่งั้นกล้องค้างที่ 480px = มีแถบดำสองข้าง
   ⚠️ ต้องอยู่ "ใต้" กฎฐาน .cs-cam เหมือนกัน (specificity เท่ากัน ตัวหลังชนะ)
      เขียนไว้ในบล็อก @media แนวนอนข้างบนแล้วไม่มีผล — พลาดซ้ำรอบสอง */
@media (max-height: 480px) and (orientation: landscape) {
  .cs-cam, .cs-cam-veil { max-width: 100%; }
}

/* ═══════════════════════════════════════════════════════════════════
   🆕 2026-09-10 ภาพ "คู่สาย" บนจอโทร (Boss: คอมเปิดกล้องแล้วไม่มีอะไรเกิดขึ้น)
   🔴 ต้นเหตุเดิม: จอโทรมีแต่ `#cs-cam` (ภาพตัวเอง) ไม่มีที่แสดงภาพปลายทาง
      pc.ontrack จึงส่งภาพไป addVideoTile() ของหน้าประชุมที่ซ่อนอยู่
      วัดจริงฝั่งคู่สาย: สตรีมมาถึง (videoWidth 320) แต่ <video> กว้าง 0px = จอว่าง
   กติกาการวางกฎ (บทเรียนจากบล็อกข้างบน): ต้องอยู่ "ใต้" กฎฐานเสมอ
   ═══════════════════════════════════════════════════════════════════ */
.cs-remote {
  position: absolute; display: none; z-index: 0;   /* ใต้ .cs-inner (z-index:2) */
  inset: auto; top: 50%; left: 50%;
  width: 100%; max-width: 480px; height: 100%;
  transform: translate(-50%, -50%);
  object-fit: cover; background: #071E33;
}
/* มีภาพคู่สายจริงเท่านั้นถึงแสดง — สายเสียงล้วนหน้าตาเดิมทุกอย่าง */
.call-screen.remote-on .cs-remote { display: block; }
/* ⚠️ ภาพคู่สายมาแล้ว = ภาพตัวเองต้องหลบไปเป็นกรอบเล็กมุมบนขวา (แบบแอปโทรทั่วไป)
   ไม่งั้นภาพเราเต็มจอทับภาพคู่สายที่เพิ่งแก้ให้ขึ้นมาได้ */
.call-screen.remote-on.cam-on .cs-cam {
  inset: auto; top: calc(env(safe-area-inset-top, 0px) + 14px); left: auto; right: 14px;
  width: 108px; height: 148px; max-width: none;
  border-radius: 12px; object-fit: cover; z-index: 3;
  border: 2px solid rgba(255,255,255,.5); box-shadow: 0 6px 20px rgba(0,0,0,.5);
  transform: scaleX(-1);
}
.call-screen.remote-on.cam-on .cs-cam.cs-rear { transform: scaleX(1); }
/* ภาพคู่สายเต็มพื้นหลังแล้ว ไม่ต้องมีม่านของกล้องตัวเอง แต่ยังต้องมีเงาให้อ่านตัวหนังสือออก */
.call-screen.remote-on .cs-cam-veil { display: block; max-width: none; width: 100%; }
.call-screen.remote-on .cs-avatar,
.call-screen.remote-on .cs-wave { opacity: 0; }
.call-screen.remote-on .cs-status,
.call-screen.remote-on .cs-name,
.call-screen.remote-on .cs-where,
.call-screen.remote-on .cs-ctl p { text-shadow: 0 1px 6px rgba(0,0,0,.9); }

/* ═══ 🖥️ คอม: จอโทร "ต้องต่างจากมือถือ" (Boss 2026-09-10 ส่งรูปมายืนยัน) ═══
   เดิม @media(min-width:900px) บีบทุกอย่างเหลือการ์ด 400px ทรงมือถือกลางจอ
   วัดจริง 1280x800: .cs-inner = 400x736 ที่ left 440 → คอมได้ UI เดียวกับมือถือเป๊ะ
   ตอนนี้: **มีภาพคู่สายเมื่อไหร่ = กางเป็นหน้าต่างวิดีโอกว้างแบบ Meet**
   ไม่มีภาพ (สายเสียงล้วน) = คงการ์ดแคบไว้เหมือนเดิม เพราะไม่มีอะไรให้ดู
   ⚠️ ต้องอยู่ใต้บล็อก min-width:900px เดิม ไม่งั้นโดนทับ (specificity เท่ากัน) */
@media (min-width: 900px) {
  .call-screen.remote-on .cs-inner {
    max-width: min(1180px, 94vw); width: min(1180px, 94vw);
    height: min(860px, 94vh);
  }
  .call-screen.remote-on .cs-remote {
    max-width: min(1180px, 94vw); height: min(860px, 94vh);
    border-radius: 22px;
  }
  .call-screen.remote-on .cs-cam-veil {
    max-width: min(1180px, 94vw); height: min(860px, 94vh);
    inset: auto; top: 50%; left: 50%; transform: translate(-50%, -50%);
    border-radius: 22px;
  }
  /* จอกว้าง = ภาพตัวเองใหญ่ขึ้นได้ ไม่ต้องจิ๋วเท่ามือถือ */
  .call-screen.remote-on.cam-on .cs-cam { width: 208px; height: 150px; }
}
.cs-inner { position: relative; z-index: 2; }
/* ⚠️ ต้นแบบใช้ opacity ไม่ใช่ display:none — คงพื้นที่ไว้ เลย์เอาต์ไม่กระตุกตอนสลับ */
.call-screen.cam-on .cs-avatar,
.call-screen.cam-on .cs-wave { opacity: 0; }
.cs-avatar, .cs-wave { transition: opacity .25s; }
.call-screen.cam-on .cs-where { color: rgba(255,255,255,.8); }
/* ปุ่มสลับกล้องโผล่เฉพาะตอนกล้องเปิด และเฉพาะเครื่องที่มีมากกว่า 1 ตัว */
#cs-flip { display: none; }
/* ⚠️ ต้องเป็น flex item เหมือนปุ่มอื่นในแถว (เดิม display:block ทำให้ไม่รับ flex:1 = กว้างไม่เท่าเพื่อน) */
.call-screen.cam-on #cs-flip.cs-can-flip { display: block; flex: 1 1 0; }
/* ฉากหลังเป็นภาพจริง = ตัวหนังสือต้องมีเงาช่วย (ต้นแบบพื้นหลังคุมโทนได้ ของจริงคุมไม่ได้) */
.call-screen.cam-on .cs-status,
.call-screen.cam-on .cs-name,
.call-screen.cam-on .cs-where,
.call-screen.cam-on .cs-ctl p { text-shadow: 0 1px 6px rgba(0,0,0,.9); }

/* ============================================================
   บีบแผงเธรดให้กะทัดรัดบนมือถือ (Boss สั่ง 2026-09-06 · เลือกแบบ B)
   ------------------------------------------------------------
   ปัญหา: หัวแผง+ช่องพิมพ์กินคงที่ 176px ทุกเครื่อง จอ iPhone เตี้ยกว่า
   Android เลยโดนกินสัดส่วนหนักกว่ามาก — วัดจริง (WebKit):
     iPhone SE 667px → เหลืออ่านเธรดแค่ 278px | Android Pixel 915px → 447px
   แก้: ลดขนาดหัว 73→62px และช่องพิมพ์ 103→91px  (SE ได้คืน 278→301px)
   ⚠️ จงใจ "ไม่" ยืดความสูงแผง (68vh) เพราะจะเหลือเห็นห้องหลักแค่ 100px
      ขัดกับที่ Boss สั่งไว้ 2026-08-29 ว่าต้องเลื่อนห้องหลักได้ระหว่างเปิดแผง
   ⚠️ ไม่แตะ .thr-x (40x40) — เป็นขนาดขั้นต่ำที่นิ้วกดติด ห้ามลด
   ============================================================ */
@media (max-width: 860px) {
  .thr-head { padding: 8px 12px; padding-top: max(8px, env(safe-area-inset-top)); }
  .thr-head h3 { font-size: 15px; }
  .thr-composer { padding: 7px 12px; padding-bottom: max(22px, env(safe-area-inset-bottom)); }
  /* (2026-09-07) เดิมย่อเป็น 11.5px/margin 5px ทำให้พื้นที่นิ้วยิ่งเล็ก
     คงขนาดนิ้ว 44px ไว้ ลดแค่ระยะห่างบน */
  .thr-also { margin-top: 2px; font-size: 12.5px; min-height: 44px; }
  /* ════════════════════════════════════════════════════════════
     (2026-09-11) "ติ๊กไม่ได้สักกลุ่ม" — Boss แจ้งพร้อมภาพ 11:11
     ------------------------------------------------------------
     อาการจริง: ต้องพิมพ์ข้อความก่อนถึงจะติ๊ก → ตอนนั้น "แป้นพิมพ์เปิดอยู่"
     แผงใช้ height:68dvh + bottom:0 แต่ dvh **ไม่หดตอนแป้นพิมพ์เปิดบน iOS**
     (แป้นทับหน้า layout viewport เท่าเดิม · visualViewport เท่านั้นที่หด)
     → ขอบล่างแผงยังปักอยู่ใต้แป้นพิมพ์ ป้าย "ส่งไปยัง" ที่เป็นลูกตัวท้ายสุด
       เลยไปจมอยู่ใต้แป้น: วัดจริง 390x430 ป้ายอยู่ 391→435px บนจอสูง 430px
       elementFromPoint() คืน null = นิ้วแตะไม่ถึงเลย ไม่ใช่แค่กดยาก
     แก้: ตอน kb-open ผูกความสูงแผงกับ --x10m-vv (ความสูงจริงจาก
          visualViewport ที่ mobile.js วัดให้อยู่แล้ว) แผงจะหดขึ้นมาเหนือแป้น
     ⚠️ --x10m-vv มีค่าเฉพาะเมื่อมี visualViewport (iOS13+/Chrome61+)
        ใส่ fallback 68dvh ไว้ เครื่องเก่าได้พฤติกรรมเดิม ไม่พังกว่าเดิม
     ⚠️ ห้ามกลับไปพึ่ง dvh/vh เพียว ๆ ตรงนี้ — เป็นต้นเหตุของบั๊กนี้ทั้งอัน
     ════════════════════════════════════════════════════════════ */
  body.kb-open .thrpanel {
    /* ⚠️⚠️ ลดความสูงอย่างเดียว "ไม่พอ" — แผงเป็น bottom:0 หดความสูงแล้ว
       ขอบล่างยังปักที่ก้นจอ (ใต้แป้นพิมพ์) ป้ายติ๊กตัวท้ายก็ยังจมอยู่ที่เดิม
       ต้อง "ยกก้นแผงขึ้น" มาเหนือแป้นพิมพ์ด้วย = ตัวแปรสำคัญคือ bottom ไม่ใช่ height
       --x10m-kb = ความสูงแป้นพิมพ์ที่ mobile.js วัดให้ (0 เมื่อแป้นปิด) */
    /* ⚠️⚠️ (2026-09-14) iPhone "แผงลอยยกขึ้น" — Boss แจ้ง
       position:fixed ผูกกับ **layout viewport** ไม่ใช่ visual viewport
       iOS ตอนแป้นเปิดจะเลื่อน layout viewport ขึ้น = vv.offsetTop
       ⇒ ฐาน bottom:0 ขยับตามไปด้วย ต้อง "บวก" --x10m-vvtop กลับเข้าไป
         แผงถึงจะกลับมานั่งบนขอบแป้นพอดี (พิสูจน์ด้วยเทส: ไม่บวก = ลอยขึ้น 120px)
       ⚠️ เครื่องหมายต้องเป็น + ไม่ใช่ - (ลบแล้วเพี้ยนหนักกว่าเดิม 240px)
       ⚠️ Android/ไม่มี visualViewport ได้ 0px = พฤติกรรมเดิมเป๊ะ ไม่กระทบ */
    /* ⚠️ 2026-09-18 แผงเป็นเต็มจอแล้ว (top:0;bottom:0) ตอนแป้นพิมพ์เปิดต้อง
       "ปล่อย top" ให้ความสูงคุมด้วย --x10m-vv อย่างเดียว ไม่งั้น top:0 กับ bottom
       ที่ยกขึ้นตีกัน → แผงถูกยืดกลับไปใต้แป้นเหมือนเดิม */
    /* 🔴🔴 2026-09-19 Boss แจ้งจาก iPhone (ภาพที่ 3):
       "เวลาพิมพ์เซิร์ชหรือพิมพ์ตอบกลับ มันดันขึ้นไปอยู่เลยจอขึ้นไปข้างบนเลย"
       ------------------------------------------------------------
       ยึด bottom แล้วบวก --x10m-vvtop **ผิดทางสำหรับแผงเต็มความสูง**:
         kb    = innerH - vvH - offsetTop   (หัก offsetTop ออกไปแล้ว)
         bottom= kb + offsetTop = innerH - vvH  → คงที่ ไม่ขยับตาม offsetTop
       ⇒ แผงนั่งนิ่งใน **layout viewport** แต่ iOS เลื่อน layout viewport ขึ้น
         เท่ากับ offsetTop เพื่อไล่ตาม caret ⇒ ผู้ใช้เห็นแผง **เลยขอบบนจอ** ไป
         เท่ากับ offsetTop พอดี (คำนวณจริง 16 Pro Max แป้น 336:
         offsetTop 0/150/336 → topOnScreen 0/-150/-336 = ตรงกับภาพที่ Boss ส่ง)
       แก้: ยึด **top** กับ offsetTop ตรง ๆ แล้วปล่อย bottom
         top = offsetTop, height = vvH ⇒ topOnScreen = 0 ทุกค่า offsetTop (เทสแล้ว 5/5)
       ⚠️ ห้ามกลับไปใช้ bottom+vvtop กับแผงที่สูงเท่า vv — เป็นต้นเหตุของบั๊กนี้ทั้งอัน
       ⚠️ ไม่มี visualViewport (Android เก่า) = vvtop 0 + fallback 100dvh = พฤติกรรมเดิม */
    top: var(--x10m-vvtop, 0px);
    bottom: auto;
    height: var(--x10m-vv, 100dvh);
    max-height: var(--x10m-vv, 100dvh);
  }
  /* ป้ายติ๊กต้องไม่ถูกบีบหาย เมื่อที่ว่างเหลือน้อย ให้เนื้อเธรดหดแทน */
  .thr-composer { flex: 0 0 auto; }
  .thr-also { flex: 0 0 auto; }
  /* รอบ 2 (Boss: "ลดอันไหนที่ไม่จำเป็น") — เก็บที่ว่างเปล่าที่ไม่ได้ทำหน้าที่อะไร
     ⚠️ ห้ามลด .thr-input font-size ต่ำกว่า 16px → iOS ซูมจอตอนโฟกัส
     ⚠️ ห้ามลด .thr-x (40x40) → นิ้วกดไม่ติด */
  .thr-body { padding: 4px 0 6px; }            /* 8/12 → กันชนบน-ล่างที่ไม่มีเนื้อหา */
  .thr-sep { padding: 5px 14px 3px; margin-bottom: 2px; }  /* ป้าย "n คำตอบ" ล้วนๆ */
  .thr-parent { padding-bottom: 4px; }
  .thr-input { min-height: 36px; padding: 8px 12px; }       /* พิมพ์ 1 บรรทัดพอดี ยังยืดได้ */
  .thr-cbox .ir-files { margin-top: 6px; }
}

/* 🔴 Boss แจ้ง 2026-09-06 (ภาพวงแดง markup_1788665650137):
   "หัวข้อมันโดนกดจนเล็กๆ มากครับ" — หัวแผงแจ้งเตือน + แถวชิปตัวกรอง
   วัดจริงบน iPhone 390px: ชิป **ตัวอักษร 11.5px สูง 28px** · "110 รายการใหม่" 11.5px
   = เล็กกว่ามาตรฐานอ่านสบาย (13px+) และต่ำกว่าพื้นที่แตะ (40px+) มาก
   ค่าพวกนี้ hardcode px ไว้ทั้งหมด จึงไม่ได้ยืดตามจอเหมือนที่เหลือของแอป
   → ขยายเฉพาะมือถือ ให้อ่านออกและกดถนัด (เดสก์ท็อปคงเดิม) */
@media (max-width: 860px) {
  .bell-head { padding: 13px 14px 9px; font-size: 15.5px; }
  .bell-head b { font-size: 16px; }
  .bell-new { font-size: 12.5px; opacity: .8; }
  .bell-all { font-size: 13.5px; padding: 6px 4px; }   /* ปุ่ม "อ่านทั้งหมด" แตะติดขึ้น */
  .bell-chips { padding: 0 12px 10px; gap: 7px; }
  .bell-chip {
    font-size: 13px; padding: 8px 14px;                /* 11.5px/4px → อ่านออก กดถนัด */
    min-height: 36px; display: inline-flex; align-items: center;
  }
  /* พื้นแผงโปร่ง 72% (Boss ขอไว้ 2026-08-23) บนจอมือถือที่ข้อความหนาแน่น
     ทำให้ตัวหนังสือด้านหลังทะลุขึ้นมาซ้อนจนอ่านไม่ออก (เห็นชัดในภาพวงแดง)
     → ทึบขึ้นเฉพาะมือถือ · เดสก์ท็อปยังโปร่งเหมือนเดิมตามที่ Boss สั่ง
     ⚠️ ต้องเผื่อเบราว์เซอร์ที่ไม่รองรับ backdrop-filter ด้วย (พื้นจะโปร่งจริง) */
  .bell-pop {
    background: color-mix(in srgb, var(--card, #fff) 94%, transparent);
  }
  /* 🔴 Boss แจ้ง 2026-09-06 รอบ 2 (ภาพวง markup_1788666122038):
     "หัวข้อตรงนั้นมันต้องลอยสิ ไม่ใช่โดนทับแล้วมองยากแบบนั้น"
     วัดจริง: รายการที่เลื่อนขึ้นไปอยู่ที่ top -154px (พ้นขอบแผงแล้ว)
     แต่ `.bell-chips` เป็น position:static / z-index:auto = **ไม่มีชั้นของตัวเอง**
     → บน WebKit รายการเลยวาดทับแถวชิปจนอ่านไม่ออก
     แก้: ยกหัวแผง+แถวชิปขึ้นเป็นชั้นบนสุดของแผง แล้วตรึงไว้ไม่ให้เลื่อนหนี
     ⚠️ ต้องมี background ทึบคู่กันเสมอ ไม่งั้นตรึงแล้วก็ยังเห็นทะลุอยู่ดี */
  .bell-head, .bell-chips {
    background: var(--card, #fff);
    position: relative; z-index: 2; flex: 0 0 auto;
  }
  /* เส้นคั่นบางๆ ใต้ชิป ให้เห็นขอบเขตชัดว่าส่วนบนคือตัวกรอง ส่วนล่างคือรายการ */
  .bell-chips { box-shadow: 0 1px 0 var(--border, #E2E8F0); }
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .bell-pop { background: var(--card, #fff); }
}

/* ===== การ์ด "ขอทำ OT" (timescan → ห้อง 359) — Boss สั่ง 2026-09-06 =====
   โครงเดียวกับการ์ด Requirement แต่สีส้ม (งานเงิน/เวลา ไม่ใช่งานซ่อม)
   ปุ่มสูง 38px นิ้วโป้งกดติดบนมือถือ 360px · ปุ่มยาวเต็มแถวเมื่อจอแคบ */
.ot-card {
  margin-top: 6px; max-width: min(420px, 100%);
  border: 1px solid var(--border); border-left: 3px solid #EA580C; border-radius: 10px;
  background: var(--card); overflow: hidden;
}
.ot-card .ot-head {
  display: flex; align-items: center; gap: 7px;
  padding: 8px 11px; font-weight: 700; line-height: 1.45;
  background: rgba(234, 88, 12, .10); color: var(--text);
  border-bottom: 1px solid var(--border); word-break: break-word;
}
.ot-card .ot-badge {
  flex: none; background: #EA580C; color: #fff;
  font-size: 10px; font-weight: 800; letter-spacing: .3px;
  padding: 2px 6px; border-radius: 4px; line-height: 1.5;
}
.ot-card .ot-body { padding: 9px 11px 7px; }
.ot-card .ot-row {
  padding: 2px 0; line-height: 1.55;
  word-break: break-word; overflow-wrap: anywhere;
}
.ot-card .ot-foot {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 11px; border-top: 1px solid var(--border); background: var(--bg);
}
.ot-card .ot-btn {
  flex: 1 1 120px; border: none; border-radius: 7px;
  padding: 8px 14px; min-height: 38px;
  font-family: inherit; font-size: 13.5px; font-weight: 700;
  color: #fff; cursor: pointer;
}
.ot-card .ot-btn.ok { background: #16A34A; }
.ot-card .ot-btn.ok:hover { background: #15803D; }
.ot-card .ot-btn.no { background: #6B7280; }
.ot-card .ot-btn.no:hover { background: #4B5563; }
.ot-card .ot-btn:disabled { opacity: .55; cursor: default; }
.ot-card .ot-pending { font-size: 13px; font-weight: 600; color: var(--muted); }
.ot-card .ot-done { font-size: 13px; font-weight: 700; }
.ot-card .ot-done.ok { color: #15803D; }
.ot-card .ot-done.no { color: #B91C1C; }
.ot-card .ot-note {
  flex: 1 1 100%; font-size: 12.5px; color: var(--muted);
  word-break: break-word; overflow-wrap: anywhere;
}

/* ============================================================
   DM/ห้องแชทบนคอม — 2 บั๊กที่ Boss แจ้ง 2026-09-06 (ภาพ 1788681592200)
   ============================================================ */

/* (1) "ข้อความฝั่งผมหายมองไม่เห็น"
   ปุ่ม "วันนี้" (.datejump) ลอย absolute ที่ right:18px โดยไม่มีใครกันที่ให้
   ข้อความของเราเอง (.mine) ชิดขวาสุด → ชื่อ/เวลา/แถวปุ่ม 🙂↩⧉🔖⋯ ของแถวบนสุด
   มุดใต้ปุ่มจนอ่านไม่ออก (วัดจริง 1280px: ชื่อจบ x=1226 ปุ่มกิน 1198–1262 ทับ 28px)
   แก้ที่ "กันที่ด้านบนของลิสต์" ไม่ใช่ขยับปุ่ม — ขยับปุ่มก็แค่ย้ายจุดชนไปที่อื่น
   ⚠️ ปุ่มเกาะ #chat-room (รวมหัวห้อง) ไม่ได้เกาะ .messages
      → ระยะที่มันกินเข้ามาในลิสต์ = (--rt-dj-top + สูงปุ่ม 34) − สูงหัวห้อง
      ใช้ตัวแปรตัวเดียวกับที่ JS วัดไว้ (syncRoomTabsOffset) จะได้ไม่หลุดกันคนละทาง
      วัดจริง 1280px: ปุ่มจบที่ y=138 ลิสต์เริ่ม y=54 = ต้องกัน 84px ไม่ใช่ 34px
   ⚠️⚠️ กฎนี้ต้องอยู่ใน x10-ui.css ไม่ใช่ที่นี่ — `.x10v3 .messages` ที่นั่นใช้ padding
      แบบย่อ (shorthand) + specificity สูงกว่า + โหลดทีหลัง จะล้าง padding-top ทิ้งหมด
      (เสียเวลาไปรอบนึงเพราะวางผิดไฟล์) → ดูกฎจริงท้าย x10-ui.css */

/* (2) "ปัญหาเรื่องการจัดข้อความ"
   เพดาน 760px (บรรทัด ~5367) = ~130 ตัวอักษร/บรรทัดที่ font 14.5px
   ยาวเกินกว่าตาจะกวาดกลับต้นบรรทัดได้ อ่านยาก (ที่สบายคือ 60–80)
   การ์ดสรุปประชุมยาวๆ เลยลากเต็มแผงอย่างในภาพ → หุบเหลือ 62ch */
@media (min-width: 1101px) {
  .msg:not(.nested):not(.system) .msg-body { max-width: min(62ch, calc(100% - 44px)); }
}
/* ช่วง 861–1100px ไม่เคยมีเพดานเลย (กฎ 900px ของแถวโดนปลดที่ ≥1101 เท่านั้น
   แต่ช่วงนี้ .msg-body = calc(100% - 44px) ล้วน) → ใส่ให้ครบ ไม่งั้นย่อจอแล้วยาวกว่าเดิม */
@media (min-width: 861px) and (max-width: 1100px) {
  .msg:not(.nested):not(.system) .msg-body { max-width: min(62ch, calc(100% - 44px)); }
}

/* ปุ่ม "เข้าร่วม" บนแถวแจ้งเตือนคำเชิญประชุม (Boss แจ้ง 2026-09-06)
   เดิมต้องกดเข้า DM ไปหาการ์ดก่อนถึงจะเข้าร่วมได้ — เน้นให้เห็นว่ากดได้เลย */
.ntf-act.ntf-join {
  background: var(--blue); border-color: var(--blue); color: #fff; font-weight: 650;
}
.ntf-act.ntf-join:hover { filter: brightness(1.08); background: var(--blue); color: #fff; }

/* ---- จอ "รอผู้นำประชุมกลับเข้ามา" (Boss 2026-09-07) — mobile first ---- */
.meet-hostwait{position:absolute;inset:0;z-index:40;display:flex;align-items:center;justify-content:center;
  background:rgba(12,14,18,.82);backdrop-filter:blur(6px);padding:20px;text-align:center;
  padding-top:max(20px,env(safe-area-inset-top));padding-bottom:max(20px,env(safe-area-inset-bottom))}
.meet-hostwait.hidden{display:none}
.meet-hostwait .mhw-box{max-width:340px;width:100%;color:#fff}
.meet-hostwait .mhw-spin{width:44px;height:44px;margin:0 auto 16px;border-radius:50%;
  border:3px solid rgba(255,255,255,.18);border-top-color:#4c8dff;animation:mhwspin 1s linear infinite}
@keyframes mhwspin{to{transform:rotate(360deg)}}
.meet-hostwait .mhw-t{font-size:17px;font-weight:700;margin-bottom:6px;line-height:1.4}
.meet-hostwait .mhw-s{font-size:13.5px;opacity:.72;line-height:1.5}
.meet-hostwait .mhw-c{margin-top:14px;font-size:26px;font-weight:700;font-variant-numeric:tabular-nums;color:#ffd479}
@media (min-width:768px){.meet-hostwait .mhw-t{font-size:19px}.meet-hostwait .mhw-c{font-size:30px}}

/* ---- จอแคบ: ไม่ต้องบีบปุ่มอีกแล้ว (Boss 2026-09-07 รอบ 2) ----
   ประวัติ: เดิม 7 ปุ่ม × 52px = 391-406px > จอ 360/375/390 → ปุ่มวางสายหลุดนอกจอ
   รอบแรกแก้ด้วยการ "บีบ" ทุกปุ่มลงเหลือ 40-44px ซึ่งยังเบียดและปุ่มแดงติดปุ่มข้างๆ
   รอบนี้แก้ที่ต้นเหตุ: เหลือ 3 ปุ่มหลัก + ปุ่มออก = 4 × 56px + gap ≈ 258px พอดีจอ 360 สบาย
   ที่เหลือย้ายไปแผ่น ⋯ และชิปมุมขวาบน → ไม่ต้องย่อไอคอนต่ำกว่า HIG 44px อีก */
@media (max-width: 400px) {
  .meet-bar { gap: 4px; padding-left: 8px; padding-right: 8px; }
  .meet-bar-core { gap: 8px; }
  .meet-btn { min-width: 52px; }
  .meet-btn .mb-ic { width: 52px; height: 52px; font-size: 21px; }   /* ยังเกิน HIG 44px */
  .meet-btn.danger .mb-ic { width: 58px; }
  .meet-btn .mb-lb { font-size: 9.5px; max-width: 100%; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; }
}
/* จอแคบมาก (≤340) — ซ่อนเฉพาะป้ายชื่อ ไอคอนคงขนาดกดง่ายไว้ */
@media (max-width: 340px) {
  .meet-btn .mb-lb { display: none; }
  .meet-btn .mb-ic { width: 50px; height: 50px; }
}

/* แตะรูปแนบ (ยังไม่ส่ง) เพื่อดูใหญ่ — Boss/พี่ปอง 2026-09-07
   ⚠️ ห้ามใช้ hover อย่างเดียวบอกว่ากดได้ มือถือไม่มี hover (ผู้ใช้มือถือเยอะกว่าคอม)
   จึงใส่แว่นขยายค้างไว้มุมล่างซ้ายของรูป ให้เห็นตลอดว่ากดดูใหญ่ได้ */
img.pq-zoom { cursor: zoom-in; }
.pq-item, .ir-file, .atsheet-thumb { position: relative; }
.pq-item:has(img.pq-zoom)::after,
.ir-file:has(img.pq-zoom)::after,
.atsheet-thumb:has(img.pq-zoom)::after {
  content: '🔍';
  position: absolute; left: 2px; bottom: 2px;
  font-size: 9px; line-height: 1;
  padding: 2px; border-radius: 4px;
  background: rgba(0, 0, 0, .55);
  pointer-events: none;            /* ป้ายห้ามกินคลิก ต้องทะลุไปโดน <img> */
}
img.pq-zoom:active { filter: brightness(.85); }

/* ═══ การ์ด "ฟองแชทนอกแอป" ในหน้าโปรไฟล์ (Boss 2026-09-10) ═══
   mobile-first 360px — แถวต้องอ่านออกและปุ่มกดถึงบนจอแคบ */
.pf-bb-note { margin: 0 0 10px; font-size: 13.5px; line-height: 1.5; }
.pf-bb-note.ok { color: var(--green, #16a34a); }
.pf-bb-note.bad { color: var(--danger, #E5484D); }
.pf-bb-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 0; border-top: 1px solid var(--border, #E2E8F0);
}
.pf-bb-row:first-of-type { border-top: none; }
.pf-bb-ic { flex: 0 0 auto; font-size: 17px; line-height: 1; }
.pf-bb-tx { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pf-bb-tx b { font-size: 14px; font-weight: 600; }
.pf-bb-hint { font-size: 12px; color: var(--muted, #64748b); line-height: 1.45; }
/* ปุ่มต้องแตะได้จริงบนมือถือ (≥44px ตามกฎเดิมของโปรเจค)
   ⚠️ `.btn.small` มี min-height:38px อยู่แล้ว — specificity เท่ากัน ตัวหลังชนะ
      แต่ถ้าไฟล์นี้ถูกโหลดก่อนจะแพ้ จึงใส่ !important ให้แน่ (วัดได้ 38px ตอนไม่ใส่) */
.pf-bb-row .btn.small {
  flex: 0 0 auto; min-height: 44px !important; padding: 10px 16px; white-space: nowrap;
}
.pf-bb-ver { margin: 10px 0 0; font-size: 12px; color: var(--muted, #64748b); }
/* 🩺 บรรทัดวินิจฉัยฟองแชท — ตัวเล็ก อ่านได้บนมือถือ 360px ไม่ดันขอบ
   ⚠️ ต้อง break-all: ข้อความเป็นค่าติดกันยาว (svc=on·ฟอง=0/0·...) ไม่มีช่องให้ตัดบรรทัด */
/* 🎨 2026-09-10 บล็อก action "ย่อเป็นฟองแชท" — mobile first 360px
   ปุ่มเต็มความกว้าง กดด้วยนิ้วโป้งได้ · คำอธิบายอยู่ใต้ปุ่ม ไม่แย่งสายตา */
.pf-bb-act { margin: 12px 0 0; padding: 12px 0 0; border-top: 1px solid var(--line, #e2e8f0);
  display: flex; flex-direction: column; gap: 6px; }
.pf-bb-go { width: 100%; min-height: 44px; font-size: 15px; font-weight: 600; }
.pf-bb-achint { font-size: 12px; line-height: 1.5; color: var(--muted, #64748b); }

.pf-bb-dbg { margin: 8px 0 0; font-size: 10px; opacity: .75; line-height: 1.5; color: var(--muted, #64748b);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  overflow-wrap: anywhere; word-break: break-all; }
/* จอแคบมาก — ปุ่มลงบรรทัดใหม่เต็มความกว้าง ดีกว่าบีบข้อความจนอ่านไม่ออก */
@media (max-width: 380px) {
  .pf-bb-row { flex-wrap: wrap; }
  .pf-bb-row .btn.small { width: 100%; margin-left: 27px; }
}

/* ===== รวมใบเตรียมประชุม + ห้องประชุมสด (Boss 2026-09-10) ===== */
/* แถบบนเหลือแค่ช่องกรอกรหัส (ปุ่ม "ประชุมใหม่" ย้ายไปหัวหน้าแล้ว) */
.meet-start-joinonly { margin-bottom: 14px; }

/* ปุ่มเริ่ม/เข้าห้องประชุมในใบเตรียม — mobile first แตะได้ถนัด ไม่เบียดปุ่มลบ */
.prep-head { flex-wrap: wrap; }
.prep-meetbtn { min-height: 40px; }
.prep-meetbtn.live { animation: prepLivePulse 2s ease-in-out infinite; }
@keyframes prepLivePulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, .45); }
  50%      { box-shadow: 0 0 0 6px rgba(34, 197, 94, 0); }
}
@media (prefers-reduced-motion: reduce) { .prep-meetbtn.live { animation: none; } }

/* แผงเช็กลิสต์ในห้องประชุมสด — การ์ดต้องแบนลง ไม่งั้นกินพื้นที่แผงข้างที่แคบอยู่แล้ว */
.meet-prep .card { margin: 0 0 8px; padding: 8px; }
.meet-prep .prep-bars { margin-bottom: 10px; }
.meet-prep .prep-item { padding: 6px 0; }
.meet-prep .prep-who { max-width: 100%; }

/* ── แจ้งผลการลงโทษเข้าห้องแชท: เลือกได้หลายห้อง (Boss สั่ง 2026-09-12) ──
   "เวลาลงโทษ ให้เลือกหลายๆ กลุ่มได้ ว่าลงโทษแล้ว ให้ไปแจ้งผลการลงโทษที่กลุ่มไหน"
   ⚠️ มือถือ 360px: แถวสูง 44px กดติดนิ้ว · เพดาน 30vh กันดันปุ่มบันทึกตกนอกจอ */
.pn-hint { font-weight: 400; font-size: 11.5px; color: var(--muted); margin-left: 6px; }
.pn-rooms {
  max-height: 30vh; overflow-y: auto; display: flex; flex-direction: column; gap: 4px;
  border: 1px solid var(--border); border-radius: 8px; padding: 6px; background: var(--bg);
}
.pn-room {
  display: flex; align-items: center; gap: 9px; width: 100%; min-height: 44px;
  border: 1px solid transparent; background: transparent; padding: 6px 10px;
  cursor: pointer; border-radius: 8px; font-family: inherit; font-size: 14.5px;
  color: var(--text); text-align: left;
}
.pn-room:hover { background: var(--blue-light); }
.pn-room.on { background: var(--blue-light); border-color: var(--blue); font-weight: 600; }
.pn-room .pn-room-ck { flex: 0 0 18px; text-align: center; color: var(--muted); font-size: 15px; }
.pn-room.on .pn-room-ck { color: var(--blue); }
.pn-room .fw-nm { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-picked { margin-top: 6px; font-size: 12.5px; color: var(--blue); line-height: 1.5; word-break: break-word; }
.pn-picked.none { color: var(--muted); }
/* ⚠️⚠️ ฟอร์มลงโทษมีกล่องเลือกแบบเลื่อน **3 กล่อง** แล้ว (แผนก/คน/ห้อง — พี่ปอง 2026-09-16)
   ถ้าปล่อยให้สูง 30vh เท่ากันหมด = กิน 90% ของจอ ช่องที่เหลือกับปุ่มส่งตกจอ
   ⇒ 2 กล่องบนเตี้ยกว่า เพราะมีช่องค้นหาคุมอยู่แล้ว ไม่ต้องกวาดตาทั้งลิสต์
   ⚠️⚠️ ค่านี้เป็นแค่ "ค่าตั้งต้น" — กฎจอคอม/มือถือข้างล่างมาทีหลังจะชนะเสมอ
      ต้องตั้งซ้ำในทั้ง 2 บล็อก ไม่งั้นโดน .pn-rooms ของบล็อกนั้นทับ (เคยพลาดมาแล้ว) */
#pn-dept-list, #pn-staff-list { max-height: 21vh; }

/* ── ช่องที่ "กดเลือกจากรายการได้" (datalist) — Boss แจ้ง 2026-09-12 ──
   ⚠️⚠️ <datalist> ไม่มีหน้าตาของตัวเองเลย คนเลยนึกว่าเป็นช่องพิมพ์เปล่า
        ("มันไม่ดึงมานิหรอ" ทั้งที่ดึงมาแล้ว) → ต้องมีลูกศร ▾ ให้เห็น */
.pn-pick { position: relative; display: block; }
.pn-pick > input { width: 100%; box-sizing: border-box; padding-right: 30px; }
.pn-pick-car {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  color: var(--muted); font-size: 12px; pointer-events: none; opacity: 0;
  transition: opacity .15s;
}
/* โชว์ลูกศรเฉพาะตอนโหลดรายการมาแล้วจริง — ไม่มีของก็ไม่ต้องหลอกว่ากดได้ */
.pn-pick > input.ready ~ .pn-pick-car { opacity: 1; }
.pn-pick > input.ready { cursor: pointer; }
/* ซ่อนปุ่มลูกศรของเบราว์เซอร์เอง (Chrome วาดทับลูกศรเรา) */
.pn-pick > input::-webkit-calendar-picker-indicator { opacity: 0; }

/* ลากไฟล์มาวางในบานแยก (ใช้กรอบเดียวกับหน้าต่าง DM ลอย) */
.pane-body.dz { outline: 2px dashed var(--blue, #0F4C81); outline-offset: -3px; opacity: .75; }

/* ── แจ้งเตือน "มีคนแท็กถึงคุณ" มุมขวาล่าง + กดเพื่อเด้งไปหา ──
   Boss สั่ง 2026-09-12: "ทำไมขึ้นล่างกลาง ทำไมไม่ขึ้นล่างขวา และคลิกเพื่อเด้งไปที่คนแท็ก"
   ⚠️ แยกจาก .toast ปกติ (ตัวนั้นใช้ 424 ที่ทั่วแอป ห้ามย้าย) */
.mtoast {
  position: fixed; right: 16px; bottom: 80px; z-index: 260;
  display: flex; align-items: stretch; gap: 0;
  background: var(--toast-bg); color: var(--toast-text);
  border-radius: 14px; box-shadow: 0 8px 28px rgba(0,0,0,.38);
  max-width: min(380px, calc(100vw - 32px)); overflow: hidden;
  animation: mtIn .18s ease-out;
}
@keyframes mtIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.mtoast .mt-go {
  flex: 1 1 auto; display: flex; align-items: center; gap: 9px;
  background: transparent; border: 0; cursor: pointer; text-align: left;
  color: inherit; font-family: inherit; font-size: 14px;
  padding: 12px 6px 12px 14px; min-height: 48px;
}
.mtoast .mt-go:hover { background: rgba(255,255,255,.08); }
.mtoast .mt-ic { flex: 0 0 auto; font-size: 15px; }
/* 2 บรรทัด: ใครแท็ก / เขาพิมพ์ว่าอะไร (Boss สั่ง 2026-09-12) */
.mtoast .mt-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.mtoast .mt-who {
  font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mtoast .mt-tx {
  opacity: .82; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* ป้าย "ดูข้อความ" — บอกให้รู้ว่ากดได้ ไม่ใช่ข้อความเฉย ๆ */
.mtoast .mt-cta {
  flex: 0 0 auto; font-size: 12px; font-weight: 600; opacity: .95;
  border: 1px solid currentColor; border-radius: 999px; padding: 2px 9px;
}
.mtoast .mt-x {
  flex: 0 0 auto; background: transparent; border: 0; cursor: pointer;
  color: inherit; opacity: .6; font-size: 14px; padding: 0 12px; min-width: 40px;
}
.mtoast .mt-x:hover { opacity: 1; background: rgba(255,255,255,.08); }
/* มือถือ: กินเต็มความกว้าง เหนือแท็บล่าง · ชื่อยาวตัดได้ 2 บรรทัด */
/* ── คอม: จอกว้าง โชว์ข้อความได้ยาวขึ้น บรรทัดเดียวพอ (กวาดตาเร็ว) ── */
@media (min-width: 769px) {
  .mtoast { max-width: min(420px, calc(100vw - 32px)); }
  .mtoast .mt-tx { -webkit-line-clamp: 1; }
}
/* ── มือถือ: กว้างจำกัด ยอมให้ข้อความตก 2 บรรทัด จะได้อ่านได้จริง ── */
@media (max-width: 768px) {
  .mtoast { left: 12px; right: 12px; bottom: 84px; max-width: none; }
  .mtoast .mt-go { padding: 11px 6px 11px 12px; }
  .mtoast .mt-tx {
    white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    font-size: 12.5px; line-height: 1.35;
  }
  /* ปุ่ม "ดูข้อความ" ไม่ให้ถูกข้อความยาวบีบจนหาย */
  .mtoast .mt-cta { align-self: center; }
}

/* ══ ฟอร์มลงโทษ: แยกกฎ "คอม" กับ "มือถือ" ออกจากกัน ══
   Boss สั่ง 2026-09-12: "มือถือกับคอมมันต้องแยกอยู่แล้ว เรื่องการปรับขนาดหรือตำแหน่ง
   จะเอาเหมารวมไม่ได้"
   ⚠️ ของเดิมผมเขียนกฎชุดเดียวใช้ทั้ง 2 จอ → วัดแล้วขนาดเท่ากันเป๊ะทุกช่อง
      (คอม 1280 กับมือถือ 360 ได้ช่องสูง 45px เท่ากัน · กล่องห้อง 30vh เท่ากัน)
      มือถือเลยต้องเลื่อน 2.3 จอกว่าจะถึงปุ่มบันทึก */

/* ── คอม: จอกว้าง ใช้พื้นที่แนวนอนได้ กล่องห้องสูงได้ เห็นหลายห้องพร้อมกัน ── */
@media (min-width: 769px) {
  .pn-rooms { max-height: 26vh; }   /* เดิม 34vh — ลดเพราะมี 3 กล่อง (2026-09-16) */
  .pn-room { min-height: 38px; font-size: 14px; }    /* ใช้เมาส์ ไม่ต้องเผื่อนิ้ว */
  .pn-picked { font-size: 12.5px; }
  /* 🔴 มี 3 กล่องแล้ว (พี่ปอง 2026-09-16) — 34vh ×3 = 102vh ดันฟอร์มที่เหลือตกจอ
     วัดจริงบน 1280×800 ได้ 608px = 76% ของจอ ก่อนจะลดลงมา
     กล่องแผนก/คน มีช่องค้นหาคุมอยู่แล้ว เตี้ยกว่าได้ ยกพื้นที่ให้กล่องห้องซึ่งไม่มีตัวกรองหมวด */
  #pn-dept-list, #pn-staff-list { max-height: 19vh; }
}

/* ── มือถือ: จอสูงมีจำกัด ต้องลดของที่ไม่จำเป็นให้ถึงปุ่มบันทึกเร็วขึ้น ── */
@media (max-width: 768px) {
  /* กล่องเลือกห้องเตี้ยลง — เลื่อนในกล่องได้อยู่แล้ว ไม่ต้องกินจอ 30% */
  .pn-rooms { max-height: 22vh; padding: 4px; gap: 2px; }
  /* 🔴 มือถือมี 3 กล่อง ยิ่งต้องเตี้ย — 3×22vh = 66vh ยังดันปุ่มส่งตกจอ
     เอาแค่พอเห็น ~3 แถว รู้ว่าเลื่อนได้ ที่เหลือใช้ช่องค้นหา */
  #pn-dept-list, #pn-staff-list { max-height: 16vh; }
  /* แถวห้องยังต้อง 44px (นิ้วแตะ) แต่บีบ padding แนวนอนให้ชื่อห้องยาวขึ้น */
  .pn-room { min-height: 44px; padding: 6px 8px; font-size: 14.5px; }
  .pn-room .pn-room-ck { flex-basis: 16px; }
  /* ป้ายกำกับชิดขึ้น ประหยัดแนวตั้ง (มี 8 ป้ายในฟอร์มเดียว = ประหยัดได้จริง) */
  .mg-body .asg-form .sec-lb { margin: 7px 0 3px; }
  /* คำใบ้ตกบรรทัดเองได้ ไม่ดันป้ายให้ล้น */
  .pn-hint { display: block; margin: 1px 0 0; font-size: 11px; }
  /* สรุปห้องที่เลือก จำกัด 2 บรรทัด ไม่ให้ดันปุ่มบันทึกตกจอเวลาเลือกหลายห้อง */
  .pn-picked {
    margin-top: 4px; font-size: 12px; max-height: 2.8em; overflow: hidden;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  }
  /* ช่องพิมพ์ยาว ๆ เตี้ยลงหน่อย (ขยายเองได้ด้วยการลาก) */
  .mg-body .asg-form textarea { line-height: 1.45; }
}

/* "ค่าปรับ" + "วันที่" เป็นช่องสั้น — มือถือวางคู่กันได้ ไม่ต้องซ้อนกันเหมือนช่องชื่อ/บ้าน
   (กฎเดิม .asg-row ที่ <=480px สั่ง display:block เหมาหมด = 2 ช่องสั้นกินแนวตั้ง 158px)
   ⚠️ ต้องอยู่หลังกฎ @media 480px เดิม ไม่งั้นโดนทับ */
@media (max-width: 480px) {
  .asg-row.asg-row-keep { display: flex; gap: 8px; }
  .asg-row.asg-row-keep > div { flex: 1; min-width: 0; }
}

/* ── ปุ่ม "ส่งเข้าแชท" ในแถบวาดรูป (Boss สั่ง 2026-09-12 — เหมือน LINE) ──
   เป็นปุ่มที่คนจะกดบ่อยสุดหลังวาดเสร็จ → ทำให้เด่นกว่าปุ่มเซฟ/คัดลอก
   ⚠️ .lb-btn เดิมเป็น transparent ทั้งแถบ ต้องระบุพื้นหลังเอง */
.lb-btn.lb-btn-primary {
  background: var(--blue, #0F4C81); color: #fff; font-weight: 700;
}
.lb-btn.lb-btn-primary:hover { background: #1565A8;   /* ⚠️ ไม่มี --blue-hover ในระบบ ใช้ค่าตรง */ }
.lb-btn.lb-btn-primary:disabled { opacity: .55; cursor: default; }
/* ── คอม: อยู่ในแถวเดียวกับปุ่มอื่น กว้างพอให้อ่านออก ── */
@media (min-width: 861px) {
  .lb-btn.lb-btn-primary { padding: 0 16px; }
}
/* ── มือถือ: ดันขึ้นเป็นปุ่มแรกของแถว (นิ้วเล็งง่าย) ──
   ⚠️⚠️ เดิมแถวนี้มี 3 ปุ่มพอดีจอ 360 (23..345) พอเพิ่มปุ่มที่ 4 ปุ่มท้ายล้นออกไป 399
        (วัดแล้ว) → ต้องให้ตกบรรทัดได้ ไม่ใช่ปล่อยล้นขอบจอ */
@media (max-width: 860px) {
  .lb-grp-end { flex-wrap: wrap; row-gap: 6px; }
  .lb-grp-end .lb-btn.lb-btn-primary { order: -1; }
  /* 4 ปุ่ม = 2 แถว แถวละ 2 ปุ่ม · กว้างเท่ากันดูเป็นระเบียบ */
  .lb-grp-end .lb-btn-wide { flex: 1 1 calc(50% - 4px); max-width: none; }
}

/* ============================================================
   แผงเลือกรีแอ็กชัน 3 แถว (มาตรฐาน / พลูโต / สี)
   🔴 บั๊ก 2026-09-13 (พี่ปองแจ้ง: แผงอีโมจิว่าง/เบี้ยว):
   app.js ห่อปุ่มไว้ใน .rp-row มาตั้งแต่ 2026-08-27 แต่ CSS ของ .rp-row
   ถูกเขียนไว้ใน x10-ui.css **ใต้ .x10v3 เท่านั้น** → ธีมอื่นไม่มีกฎเลย
   .react-pick เป็น display:flex ⇒ 3 แถวไปเรียง "ข้างกัน" แถวละคอลัมน์
   ⚠️ ห้ามลบ — ต้องเป็นกฎไม่ผูกธีม (x10-ui.css ที่ผูก .x10v3 ยังทับซ้อนได้ตามปกติ)
   ============================================================ */
.react-pick { flex-direction: column; align-items: stretch; gap: 4px; }
.react-pick .rp-row { display: flex; flex-wrap: wrap; gap: 1px; align-items: center; }
.react-pick .rp-pluto,
.react-pick .rp-color { border-top: 1px solid var(--border); padding-top: 4px; }
/* แถวมาตรฐาน 15 ตัว: จอ 360 วางได้ 8 ตัว/แถว ไม่ล้นขอบ */
.react-pick { max-width: min(320px, calc(100vw - 24px)); border-radius: 14px; }
/* ⚠️ กฎเก่าบังคับ nowrap ให้แถบเครื่องมือ — ทับได้แล้วเพราะตอนนี้ห่อเป็นแถว */
.msg-tools .react-pick { flex-wrap: wrap; }
@media (max-width: 480px) {
  .react-pick { gap: 3px; padding: 5px 6px; }
  .react-pick .rp-row { gap: 0; }
}

/* ถังขยะห้อง + ปุ่มลบห้อง (พี่ปองสั่ง 2026-09-13) — mobile first 360px
   ⚠️ ปุ่ม "กู้คืน" เดิมบีบจนตัวหนังสือตก 2 บรรทัด: ตรึงไม่ให้ตารางบีบคอลัมน์ปุ่ม */
.ra-table td:last-child { white-space: nowrap; width: 1%; }
.ra-table .btn-mini { white-space: nowrap; }
/* แถวปุ่มลบ/ถังขยะ: จอแคบให้ตกบรรทัดแทนล้นขอบ */
.ra-danger-row { display: flex; flex-wrap: wrap; gap: 8px; }
.ra-danger-row .btn { flex: 1 1 auto; min-height: 40px; }

/* ═══ "ใครอ่านแล้ว" ใน DM — รูปโปรไฟล์กลมเล็ก (Boss สั่ง 2026-09-13) ═══════════
   รอบแรกเป็นติ๊ก ✓✓ · Boss สั่งแก้เป็น "รูปโปรไฟล์กลม ๆ เล็ก ๆ ของคนที่อ่าน"
   ไม่มีรูป = ยังไม่มีใครอ่าน (ไม่ต้องมีคำว่า "ส่งแล้ว" ให้รก)
   ⚠️ มือถือเป็นหลัก (360px) — 14px พอให้เห็นว่าเป็นใคร แต่ไม่ดันแถวเวลาให้ล้น */
/* 🆕 2026-09-16 Boss: "อยากให้มันขึ้นอัปเดตอ่านล่าสุดแบบนั้นจริง ๆ ทำเหมือน Messenger เลยก็ได้"
   Messenger วางรูปคนอ่าน **บรรทัดของตัวเอง ชิดขวาใต้ฟองล่าสุดที่เขาอ่านถึง**
   ไม่ใช่แทรกกลางแถวเวลา (ของเดิมเบียดกับ 🙂 ↩ ⋯ จนแทบมองไม่เห็นบนจอ 360px)
   ⚠️ ใช้ order ดันไปท้ายแถว + width:100% ให้ตกบรรทัดเอง — ไม่ต้องแก้โครง HTML
      (เคยพลาดมาแล้วเรื่อง slice ตัดบล็อก HTML ย้ายเอง) */
.dm-seen {
  display: flex; justify-content: flex-end; align-items: center;
  /* ⚠️⚠️ `width:100%` อย่างเดียวไม่พอ: ตัวนี้เป็น flex item ใน .msg-under
     ถ้า parent เป็น nowrap มันจะถูกบีบ (flex-shrink:1) เหลือเท่าที่ว่าง
     วัดจริงได้ 230px ไม่ใช่เต็มแถว ⇒ ต้องล็อก flex-basis 100% + ห้ามหด */
  flex: 0 0 100%; width: 100%; order: 99; margin: 2px 2px 0 0; line-height: 0;
}
/* ⚠️⚠️ ต้องมี `.msg` / `.dmw-msg` นำหน้าให้ specificity ชนะ
   `@media (max-width:700px) .msg-under{display:flex}` ที่บรรทัด ~4139
   (วัดจริงแล้ว: เขียนแค่ `.msg-under{flex-wrap:wrap}` ได้ computed = nowrap = ไม่ตกบรรทัด) */
.msg .msg-under, .dmw-msg .dmw-under,
.msg-under, .dmw-under { flex-wrap: wrap !important; }
.dm-seen .avatar {
  width: 14px; height: 14px; border-radius: 50%;
  font-size: 8px; line-height: 14px; text-align: center;
  border: 1px solid var(--card, #fff);      /* ขอบบาง ๆ ให้ลอยจากพื้นหลังฟองแชท */
  box-shadow: 0 0 0 1px var(--border, #E2E8F0);
}

/* ===== ติ๊ก "ส่งไปยัง #ห้อง ด้วย" ในกล่องแก้ไข (Boss สั่ง 2026-09-13) =====
   คนลืมติ๊กตอนส่งคอมเมนต์ ต้องมาติ๊กย้อนหลังตรงนี้แล้วกดบันทึก
   ยึดหน้าตาเดียวกับ .thr-also ของแผงเธรด จะได้จำได้ว่าเป็นปุ่มเดียวกัน
   มือถือมาก่อน: min-height 44px ให้นิ้วกดติด (360x780) */
.ed-also {
  display: flex; align-items: center; gap: 10px;
  font-size: 13px; color: var(--muted); cursor: pointer;
  min-height: 44px; padding: 0 10px; margin-top: 6px;
  border: 1px solid var(--border); border-radius: 10px;
  -webkit-tap-highlight-color: transparent;
  user-select: none; -webkit-user-select: none;
}
.ed-also:active { background: var(--blue-light); }
.ed-also input {
  width: 20px; height: 20px; flex: 0 0 auto;
  accent-color: var(--blue); cursor: pointer; margin: 0;
}
.ed-also-hint { margin: 4px 2px 0; line-height: 1.4; }

/* ---- หมวดงาน (Physical): ชิปเลือกได้หลายหมวด — Boss สั่ง 2026-09-13 ----
   ช่อง input ด้านบนยังพิมพ์เองได้ ชิปเป็นทางลัด · ค่าเก็บเป็น "ก, ข" ในช่องเดิม
   ⚠️ มือถือ 360: ชิปสูง 32px + wrap ไม่ล้นขอบโมดัล (ช่องหมวดกว้างครึ่งเดียวของแถว) */
.asg-cats { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.asg-cat {
  border: 1px solid var(--border); background: var(--bg); color: var(--text);
  border-radius: 999px; padding: 5px 10px; min-height: 32px; cursor: pointer;
  font-family: inherit; font-size: 12.5px; line-height: 1.2; white-space: nowrap;
}
.asg-cat:hover { background: var(--blue-light); }
.asg-cat.on { background: var(--blue-light); border-color: var(--blue); color: var(--blue); font-weight: 600; }

/* ============================================================
   หน้า "งาน & Note" — ยกเครื่อง UX 2026-09-13 (pong สั่ง "ปรับ UX/UI ดูโปร ใช้ง่าย")
   มือถือกับคอมจัดคนละแบบได้ (pong อนุญาต) — ขอแค่ใช้ง่าย
   ⭐ เขียนแบบ mobile-first: ค่าตั้งต้น = มือถือ แล้วค่อย @media (min-width) ขยายเป็นคอม
   ⚠️ ใช้ตัวแปรสีเดิมของแอปทั้งหมด (--blue/--red/--amber) ไม่ตั้งจานสีใหม่
      หน้านี้ต้องกลืนกับแอป ไม่ใช่หน้าโชว์
   ============================================================ */
.wk-body { display: flex; flex-direction: column; gap: var(--s3); }

/* ---- แถบสรุปบนสุด: 3 ช่องกดได้ = ตัวกรอง ---- */
.wk-sum { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s2); }
.wk-s {
  /* มือถือ: เตี้ยลง ตัวเลขกับป้ายอยู่บรรทัดเดียวกัน — จอ 780px ต้องเห็น "งานใบแรก"
     โดยไม่ต้องเลื่อน แถบสรุปเป็นตัวบอกสถานะ ไม่ใช่พระเอกของหน้า */
  display: flex; flex-direction: row; align-items: baseline; gap: 5px;
  flex-wrap: wrap; padding: var(--s2); min-height: 0;
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); cursor: pointer; text-align: left;
  font: inherit; color: inherit;
  /* เส้นบอกสถานะอยู่ "ข้างซ้าย" ไม่ระบายทั้งใบ — อ่านเร็วโดยจอไม่ลายพร้อย */
  border-left: 3px solid var(--border);
}
.wk-s:hover { background: var(--sunken); }
.wk-s:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.wk-s .n { font-size: var(--fs-lg); font-weight: 600; line-height: 1.2; }
.wk-s .l { font-size: var(--fs-xs); color: var(--muted); }
@media (min-width: 900px) {
  /* คอมมีที่เหลือเฟือ — วางเป็นบล็อกตัวเลขใหญ่ให้อ่านข้ามจอได้ */
  .wk-s { flex-direction: column; align-items: flex-start; gap: 2px;
          padding: var(--s2) var(--s3); min-height: 58px; }
  .wk-s .n { font-size: var(--fs-xl); line-height: 1.1; }
}
.wk-s.on { background: var(--blue-light); border-color: var(--blue); }
.wk-s.red { border-left-color: var(--red); }
.wk-s.red .n { color: var(--red); }
.wk-s.blue { border-left-color: var(--blue); }
.wk-s.zero .n { color: var(--muted); font-weight: 400; }

/* ---- แท็บ ---- */
.wk-sub { margin: 0 0 var(--s2); }
.wk-mtabs { margin: 0; }

/* ---- กล่องงาน/Note ---- */
.wk-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s3); }
.wk-card { min-width: 0; }
.wk-list { display: flex; flex-direction: column; }

/* ---- แถวรายการ: เส้นซ้ายบอกความด่วน ---- */
.wk-row {
  display: flex; align-items: flex-start; gap: var(--s2);
  padding: var(--s2) var(--s2) var(--s2) var(--s3);
  border-left: 3px solid transparent;
  border-bottom: 1px solid var(--border);
}
.wk-row:last-child { border-bottom: 0; }
.wk-row.over { border-left-color: var(--red); background: rgba(185,28,28,.035); }
.wk-row.soon { border-left-color: var(--amber); }
.wk-row.fin { opacity: .55; }
.wk-row > input[type=checkbox] { margin-top: 3px; width: 18px; height: 18px; flex: none; }
.wk-row .gr { flex: 1 1 auto; min-width: 0; }
.wk-ttl { font-size: var(--fs-md); line-height: 1.45; overflow-wrap: anywhere; }
.wk-row.fin .wk-ttl { text-decoration: line-through; color: var(--muted); }
.wk-meta {
  display: flex; flex-wrap: wrap; gap: 4px 10px;
  font-size: var(--fs-xs); color: var(--muted); margin-top: 3px;
}
.wk-meta .d-over { color: var(--red); font-weight: 500; }
.wk-meta .d-soon { color: var(--amber); font-weight: 500; }

/* ป้ายห้องต้นทางที่กดเข้าไปดูข้อความได้ (พี่ปองขอ 2026-09-15)
   ⚠️ มือถือมาก่อน: ป้ายนี้อยู่ปนกับ meta ตัวเล็ก ถ้าไม่บังคับพื้นที่กด
      นิ้วจะโดนยาก → min-height 32px + ระยะกดขยายด้วย padding ไม่ใช่ font ใหญ่ */
.wk-src {
  display: inline-flex; align-items: center; gap: 3px;
  min-height: 32px; padding: 3px 9px; margin: -3px 0;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font: inherit; font-size: var(--fs-xs); line-height: 1.2;
  color: var(--accent); background: var(--chip, rgba(127,127,127,.10));
  border: 1px solid var(--border); border-radius: 999px;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.wk-src:hover { background: var(--hover, rgba(127,127,127,.18)); }
.wk-src:active { transform: scale(.97); }
.wk-src:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.wk-src-go { opacity: .7; font-size: .9em; }
.wk-row.fin .wk-src { opacity: .8; }
/* หมายเหตุ: เคยลองขยายพื้นที่แตะเป็น 44px ด้วย ::after (ท่าเดียวกับ body.x10m .chip)
   แต่ **ใช้ไม่ได้ผลตรงนี้** — ป้ายอยู่ใต้ .wk-ttl ที่เป็นข้อความหลายบรรทัด
   พื้นที่ที่ขยายขึ้นไปจึงถูก .wk-ttl ทับ (elementFromPoint เหนือกล่อง 6px ได้ DIV.wk-ttl)
   = ไม่ได้อะไรเพิ่ม แถมเสี่ยงไปแย่งพื้นที่กดของข้อความ → ใช้กล่องจริง 32px ตามเดิม
   ซึ่งกดติดสบายอยู่แล้ว (ยืนยันด้วย tap จริงบน Android emulation) */

/* ---- ว่าง: บอกทางต่อ ไม่ใช่แค่ "ไม่มีข้อมูล" ---- */
.wk-empty { padding: var(--s5) var(--s3); text-align: center; }
.wk-empty b { display: block; font-weight: 500; font-size: var(--fs-md); }
.wk-empty span { display: block; font-size: var(--fs-sm); color: var(--muted); margin-top: 2px; }

/* ---- ของรอง: พับไว้ ไม่กินที่ตอนว่าง ---- */
.wk-minor { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s2); }
.wk-fold {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
}
.wk-fold > summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  padding: var(--s3); cursor: pointer; font-size: var(--fs-md); min-height: 44px;
  list-style: none;
}
.wk-fold > summary::-webkit-details-marker { display: none; }
.wk-fold > summary::after {
  content: '⌄'; color: var(--muted); font-size: 16px; line-height: 1;
  transition: transform .15s ease;
}
.wk-fold[open] > summary::after { transform: rotate(180deg); }
.wk-fold > summary:hover { background: var(--sunken); }
.wk-cnt { margin-left: auto; margin-right: var(--s2); font-size: var(--fs-sm); color: var(--muted); }
.wk-fold .wk-list { padding: 0 var(--s3) var(--s3); }

/* ---- คอม (>=900px): 2 คอลัมน์ · แท็บอยู่ในกล่อง ไม่ต้องมีแท็บรวม ---- */
@media (min-width: 900px) {
  .wk-mtabs { display: none; }
  .wk-grid { grid-template-columns: 1fr 1fr; align-items: start; }
  .wk-minor { grid-template-columns: 1fr 1fr; }
  .wk-sum { grid-template-columns: repeat(3, minmax(0, 180px)); }
}
/* ---- มือถือ: แท็บรวมคุมทั้งหน้า แท็บย่อยในกล่องซ่อน ----
   🔴 ต้องเขียน `body.x10m .wk-sub` ด้วย เพราะ mobile.css มี `body.x10m .tab-bar { display:flex }`
      ซึ่ง specificity สูงกว่า `.wk-sub` เฉย ๆ และโหลดทีหลัง → แท็บย่อยไม่ยอมซ่อน โผล่ซ้ำ 2 ชุด */
@media (max-width: 899px) {
  .wk-sub, body.x10m .wk-sub { display: none !important; }
}
@media (prefers-reduced-motion: reduce) {
  .wk-fold > summary::after { transition: none; }
}

/* ── ส่งต่อ: เลือกได้หลายห้อง (Boss สั่ง 2026-09-13 "ข้อความเดียวส่งหลายกลุ่ม") ──
   ยกหน้าตาจาก .pn-room ของฟอร์มลงโทษ ให้ทั้งแอปเลือกหลายอย่างเหมือนกันหมด
   ⚠️ มือถือ 360px: แถวสูง 44px กดติดนิ้ว · รายการเตี้ยลงเพราะมีแถบปุ่มส่งเพิ่มมาท้ายโมดัล */
.fw-room { min-height: 44px; }
.fw-room.on { background: var(--blue-light); border-color: var(--blue); font-weight: 600; }
.fw-room .fw-ck { flex: 0 0 18px; text-align: center; color: var(--muted); font-size: 15px; }
.fw-room.on .fw-ck { color: var(--blue); }
/* ปุ่ม "ทั้งหมด / ล้าง" ท้ายหัวข้อหมวด — เลือกยกกลุ่มได้ในกดเดียว */
.fw-sec-all {
  flex: 0 0 auto; margin-left: 8px; padding: 3px 10px; min-height: 26px;
  font-family: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer;
  color: var(--blue); background: var(--card);
  border: 1px solid var(--border); border-radius: 999px;
}
.fw-sec-all:hover { background: var(--blue-light); border-color: var(--blue); }
.fw-sec-all.on { color: var(--muted); }
/* ⚠️ .fw-sec-n เดิมเป็น margin-left:auto ดันตัวเองไปชิดขวา — พอมีปุ่มต่อท้ายต้องไม่ให้ปุ่มโดนดันตก */
.fw-sec-n { margin-left: auto; }
/* แถบท้าย: สรุปห้องที่เลือก + ปุ่มส่ง */
.fw-foot {
  margin-top: 8px; border-top: 1px solid var(--border); padding-top: 8px;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.fw-picked { flex: 1 1 160px; font-size: 12.5px; color: var(--blue); line-height: 1.5; word-break: break-word; }
.fw-picked.none { color: var(--muted); }
.fw-send { flex: 0 0 auto; align-self: center; min-height: 40px; padding: 9px 18px; line-height: 1.2; }
.fw-send:disabled { opacity: .5; cursor: not-allowed; }
/* จอเตี้ย/มือถือ: รายการห้องต้องเตี้ยลงอีก ไม่งั้นปุ่มส่งตกนอกจอ (โมดัลเพดาน 90vh) */
@media (max-height: 720px), (max-width: 480px) {
  .fw-list { max-height: 34vh; }
  .fw-send { width: 100%; }
}

/* ⭐ กล่องยืนยันของแอปเอง (askConfirm) — แทน confirm() ที่แอป/WebView มือถือบล็อก
   Boss แจ้ง 2026-09-13 "มือถือน่ะ" · ออกแบบมือถือก่อน (360x780) */
.x10cf-bd {
  position: fixed; inset: 0; z-index: 100000;
  background: rgba(0, 0, 0, .5);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  /* ⚠️ ต้องกันพื้นที่ขอบจอ iPhone ไม่งั้นปุ่มไปจมใต้แถบล่าง */
  padding-bottom: max(20px, env(safe-area-inset-bottom));
}
.x10cf {
  background: var(--card, #fff); color: var(--fg, #111);
  border-radius: 14px; padding: 18px 16px 14px;
  width: 100%; max-width: 340px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .3);
}
.x10cf-msg { font-size: 15px; line-height: 1.5; white-space: pre-line; margin-bottom: 16px; }
.x10cf-acts { display: flex; gap: 8px; }
/* ⚠️ ปุ่มต้องสูงพอให้นิ้วกดติด (44px ตามมาตรฐาน iOS) */
.x10cf-acts .btn { flex: 1; min-height: 44px; font-size: 15px; }
/* ⚠️ ย้ำสีปุ่มยืนยันเอง — กล่องนี้ถูกแปะท้าย <body> ไม่ได้อยู่ในขอบเขตที่ .btn.danger
   ตัวอื่นครอบไว้ ปล่อยตามลำดับ cascade แล้วออกมาเป็นปุ่มขาวจาง ดูไม่ออกว่าอันไหนคือปุ่มลบ */
.x10cf-acts .x10cf-yes.btn.danger {
  background: var(--red, #e5484d);
  border-color: var(--red, #e5484d);
  color: #fff; font-weight: 600;
}

/* ============================================================
   แผงอัดเสียงแบบ Messenger (Boss สั่ง 2026-09-14)
   "กดครั้งเดียวและจะขึ้นช่องอัดเสียงขึ้นมา แล้วเราจะเป็นคนกดส่งเอง ไม่ต้องกดค้าง"
   mobile-first 360px — ผู้ใช้มือถือเยอะกว่าคอม
   ⚠️⚠️ z-index ต้องสูงกว่าแผงเธรด(79) · หน้าต่าง DM ลอย(300) · react-pick(320)
      เพราะกดไมค์จากในนั้นได้ทุกที่ ถ้าต่ำกว่าแผงจะไปโผล่ "ใต้" จนกดส่งไม่ได้
   ============================================================ */
.vrec {
  position: fixed; z-index: 340;
  left: 50%; transform: translateX(-50%);
  bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  width: min(calc(100vw - 24px), 420px);
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  background: var(--card); color: var(--text);
  border: 1px solid var(--border); border-radius: 999px;
  box-shadow: 0 6px 28px rgba(0,0,0,.28);
}
.vrec.hidden { display: none; }

/* จุดแดงกะพริบ = "กำลังอัดอยู่จริง" (หยุดแล้วต้องหยุดกะพริบด้วย ไม่งั้นอ่านผิด) */
.vr-dot {
  flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%;
  background: #e8453c; animation: pulse 1s infinite;
}
.vrec.paused .vr-dot { background: var(--muted); animation: none; }

/* เวลาใช้ตัวเลขความกว้างเท่ากัน ไม่งั้นเลขขยับแล้วคลื่นกระตุกตาม */
.vr-time {
  flex: 0 0 auto; min-width: 42px; text-align: center;
  font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.vr-wave { flex: 1 1 auto; min-width: 0; height: 28px; display: block; }

.vr-btn {
  flex: 0 0 auto; width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid var(--border); background: transparent; color: var(--text);
  font-size: 15px; line-height: 1; cursor: pointer; font-family: inherit;
  display: flex; align-items: center; justify-content: center;
}
.vr-btn:hover { background: var(--bg); }
.vr-del:hover { border-color: #e8453c; color: #e8453c; }
.vr-send {
  background: var(--blue, #0F4C81); border-color: var(--blue, #0F4C81);
  color: #fff; font-size: 16px;
}
.vr-send:hover { filter: brightness(1.1); background: var(--blue, #0F4C81); }

/* ════════════════════════════════════════════════════════════
   กดค้างอัดเสียงแบบ Messenger — สถานะ "ลากซ้ายจะยกเลิก"
   (Boss สั่ง 2026-09-18) ป้ายทับคลื่น + ขอบแดง ให้รู้ทันทีว่าปล่อยแล้วทิ้ง
   ⚠️ ป้ายซ่อนไว้เสมอ โผล่เฉพาะ .vr-cancelling ไม่งั้นโหมดแตะจะเห็นป้ายค้าง
   ════════════════════════════════════════════════════════════ */
.vr-cancel-hint { display: none; }
.vrec.vr-cancelling { border-color: #e8453c; box-shadow: 0 6px 28px rgba(232,69,60,.34); }
.vrec.vr-cancelling .vr-wave { display: none; }
.vrec.vr-cancelling .vr-cancel-hint {
  display: block; flex: 1 1 auto; min-width: 0;
  color: #e8453c; font-size: 13px; font-weight: 700;
  text-align: center; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.vrec.vr-cancelling .vr-dot { background: #e8453c; }

/* จอแคบมาก (360px) — ซ่อนคลื่นก่อน ปุ่มกับเวลาสำคัญกว่า ห้ามให้ปุ่มส่งหลุดขอบ */
@media (max-width: 380px) {
  .vr-wave { display: none; }
  .vrec { gap: 6px; padding: 7px 8px; }
  .vr-btn { width: 34px; height: 34px; }
}
/* คีย์บอร์ดมือถือเด้งขึ้น — ยกแผงตามเหมือนช่องพิมพ์ ไม่งั้นโดนบัง */
body.kb-open .vrec { bottom: calc(6px + env(safe-area-inset-bottom, 0px)); }

/* ปุ่มไมค์ตอนกำลังอัด — ให้รู้ว่ากดไปแล้ว (ปุ่มมี 4 ที่ คลาสชุดเดียวกันหมด) */
.dmw-att.recording, .chs-tb.recording { color: #e8453c; animation: pulse 1s infinite; }

/* ============================================================
   ข้อความเสียง — เครื่องเล่นของเราเอง (Boss สั่ง 2026-09-14)
   "ทำออกสี่เหลี่ยมและทำเป็นรูปแบบดูโปร ๆ หน่อย"

   เดิมใช้ <audio controls> ของเบราว์เซอร์ = แคปซูลมนสีเทา
   หน้าตาคนละภาษากับแอป + แต่ละเครื่องไม่เหมือนกัน คุมดีไซน์ไม่ได้เลย

   ตอนนี้:  [▶]  ▮▮▁▮▁▮▮▁▮▮  0:04
   · สี่เหลี่ยมมุมโค้ง 10px = ชุดเดียวกับ .msg-file (การ์ดไฟล์แนบ) อยู่ในภาษาแอป
   · แถบคลื่นทำหน้าที่เป็นตัวเลื่อนด้วย กดตรงไหนกระโดดไปตรงนั้น
   · ส่วนที่ฟังผ่านแล้วทึบ ส่วนที่ยังไม่ฟังจาง — รู้ทันทีว่าฟังถึงไหน
   ⚠️ ตัว <audio> ยังอยู่ (ซ่อนไว้) ไม่ได้เขียน WebAudio เอง
   mobile-first 360px
   ============================================================ */
.vmsg {
  display: inline-flex; align-items: center; gap: 10px;
  max-width: 100%; box-sizing: border-box;
  padding: 9px 12px 9px 10px;
  background: var(--bubble, var(--sunken));
  border: 1px solid var(--border);
  border-radius: 10px;              /* สี่เหลี่ยมมุมโค้ง ตามที่ Boss สั่ง */
  min-width: 0;
}
.vmsg audio { display: none; }      /* ใช้ความสามารถ แต่ไม่เอาหน้าตา */

/* ปุ่มเล่น — วงเดียวที่ยอมให้กลม เพราะเป็น "จุดเดียวที่ต้องกด" ต้องเด่นและนิ้วโดนง่าย */
.vmsg-play {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
  border: none; cursor: pointer; padding: 0;
  background: var(--blue); color: var(--on-brand, #fff);
  display: flex; align-items: center; justify-content: center;
  font-family: inherit;
}
.vmsg-play:hover { filter: brightness(1.08); }
.vmsg-play:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/* ไอคอน ▶ / ⏸ วาดด้วย CSS — ไม่พึ่งฟอนต์อีโมจิ (แต่ละเครื่องขนาดไม่เท่ากัน เบี้ยวง่าย) */
.vmsg-ic {
  width: 0; height: 0; margin-left: 2px;
  border-left: 10px solid currentColor;
  border-top: 6.5px solid transparent;
  border-bottom: 6.5px solid transparent;
}
.vmsg.playing .vmsg-ic {
  width: 10px; height: 12px; margin-left: 0;
  border: none;
  border-left: 3.5px solid currentColor;
  border-right: 3.5px solid currentColor;
  background: transparent;
}

/* แถบคลื่น = ตัวเลื่อนในตัว */
.vmsg-wave {
  position: relative; flex: 1 1 auto; min-width: 54px; height: 26px;
  cursor: pointer; overflow: hidden;
}
.vmsg-bars {
  position: absolute; inset: 0;
  display: flex; align-items: center; gap: 2px;
  pointer-events: none;
}
/* ⚠️ ส่วนที่ยังไม่ฟังต้องจางพอที่จะเห็น "เส้นแบ่ง" ตอนเล่น
   .42 ยังเข้มไป — วัดจากภาพจริงแล้วแยกไม่ออกว่าฟังถึงไหน */
.vmsg-bars > i {
  flex: 1 1 0; min-width: 2px; border-radius: 1px;
  background: currentColor; color: var(--muted); opacity: .3;
}
/* ส่วนที่ฟังผ่านแล้ว — ทับด้วยชั้นทึบสีหลัก แล้วรูดความกว้างตามเวลา */
/* 🔴🔴 ชั้น "ฟังผ่านแล้ว" รูดด้วย width — แท่งข้างในต้องกว้างคงที่เท่าแถบเต็มเสมอ
   วัดจริงตอนแรก: แท่งเต็ม 4.9px แต่แท่งในชั้นที่รูด 40% เหลือ 2px = คลื่นบิดตัวขณะเล่น
   (flex:1 บีบลูกตามความกว้างพ่อที่ถูกรูด) — เจอจากการวัด DOM ไม่ใช่จากอ่านโค้ด
   → แยกเป็น 2 ชั้น: .vmsg-done = หน้าต่างที่รูด (overflow:hidden)
     ข้างในมี .vmsg-fill ที่ล็อกความกว้าง = .vmsg-wave ตลอด จึงไม่ถูกบีบ */
/* 🔴🔴 หน้าต่างที่รูด: ต้อง absolute เทียบ .vmsg-wave และสูงเต็มแถบ
   เดิมใส่ position:static ทำให้กล่องสูง 0 และ .vmsg-fill (absolute) ไปเทียบ .vmsg-wave แทน
   ⇒ **ไม่ถูกตัดเลย** แท่งสีน้ำเงินทับเต็มทั้งแถบ = มองไม่ออกว่าฟังถึงไหน (เห็นจากภาพซูม) */
.vmsg-done {
  position: absolute; left: 0; top: 0; bottom: 0;
  overflow: hidden; width: 0; display: block;
}
/* ⭐ กุญแจ: ล็อกความกว้างชั้นในไว้ที่ "ความกว้างของ .vmsg-wave" ตรง ๆ
   ใช้ absolute + right:0 เทียบ .vmsg-wave (ไม่ใช่ .vmsg-done ที่ถูกรูด)
   ⚠️ .vmsg-done ต้อง position:static ไม่งั้นมันกลายเป็น containing block แล้วชั้นในหดตาม */
/* ชั้นในต้องกว้าง = .vmsg-wave เสมอ ไม่ใช่กว้างตามหน้าต่างที่ถูกรูด
   ⚠️ ใช้ width จากตัวแปร --vw ที่ JS ตั้งให้ (อ่านความกว้างจริงของแถบ)
      เพราะ right:0 จะไปเทียบ .vmsg-done ที่ถูกรูด = แท่งโดนบีบอีก */
.vmsg-fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: var(--vw, 100%);
  display: flex; align-items: center; gap: 2px;
}
.vmsg-fill > i { flex: 1 1 0; min-width: 2px; border-radius: 1px; background: var(--blue); opacity: 1; }

.vmsg-dur {
  flex: 0 0 auto;
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--muted); white-space: nowrap; min-width: 30px; text-align: right;
}
.vmsg-dur.vmsg-wait { opacity: .45; }

/* ขนาดกะทัดรัดใน DM ลอย / Chat Head / บานแยก (พื้นที่แคบกว่าห้องหลักมาก)
   ⚠️ วัดจริงแล้วฟองหุบเหลือ 136px คลื่นเหลือเป็นตอ ๆ อ่านไม่ออกว่าเป็นเสียง
      → ตั้งความกว้างขั้นต่ำให้คลื่นมีที่พอ แต่ยังไม่ล้นกล่อง DM ที่แคบสุด (~280px) */
.vmsg-sm { padding: 7px 10px 7px 8px; gap: 8px; width: 210px; max-width: 100%; }
.vmsg-sm .vmsg-play { width: 30px; height: 30px; }
.vmsg-sm .vmsg-wave { height: 22px; min-width: 40px; }

/* ห้องหลักจอกว้าง: กันยืดจนยาวเกินอ่าน */
.msg .vmsg { width: 300px; max-width: 100%; }

/* ข้อความเสียงของเราเอง — ใช้สีฟองของเรา ให้ดูเป็นชุดเดียวกับข้อความอื่นที่เราส่ง */
.msg.mine .vmsg { background: var(--blue-light); border-color: transparent; }

/* จอแคบ: หุบให้พอดี ปุ่มยังแตะง่าย */
@media (max-width: 420px) {
  .msg .vmsg { width: 232px; }
  .vmsg { gap: 8px; padding: 8px 10px 8px 8px; }
  .vmsg-wave { min-width: 40px; }
}

/* ============================================================
   แถบปุ่มของช่องตอบกลับ — หน้าแจ้งเตือน (#ntf-*) และบันทึกไว้ (#lt-*)
   Boss สั่ง 2026-09-14 (ส่งรูปเทียบ): "ปรับให้เหมือนช่องแชทปกติ ฟีเจอร์ครบๆ"
   เดิมมีแค่ 📎 + ช่องพิมพ์ + ปุ่มส่ง · ตอนนี้ได้ @ / 😀 / 🎤 / ☰ จัดข้อความ ครบเหมือนห้องจริง
   ⚠️ ตัวปุ่มยืมสไตล์ .cp-act/.cp-fmt/.cp-fbtn จาก x10-ui.css (scoped .x10v3) ไม่เขียนซ้ำ
      ที่นี่เติมเฉพาะ "ตำแหน่ง" ในแผงตอบกลับ ซึ่งเป็นคนละโครงกับ footer.composer
   ============================================================ */
.ntf-dt-act { padding: 0 !important; }
.ntf-dt-act .cp-act-l { flex-wrap: wrap; }
/* แผงอีโมจิของช่องตอบ: ลอยขึ้นเหนือแถบพิมพ์ ไม่ดันความสูงแผง
   ⚠️ ต้อง position:absolute เทียบ .ntf-dt-foot (relative อยู่แล้ว) ไม่งั้นไปเกาะ .page แล้วหลุดจอ */
.ntf-dt-foot .emoji-pop {
  position: absolute; left: 12px; right: 12px; bottom: 100%; margin-bottom: 6px; z-index: 5;
}
/* มือถือ: แผงตอบกลับเปิดเต็มจอ แถบปุ่มต้องเลื่อนแนวนอนได้ ไม่ตกบรรทัดจนกินที่เนื้อเธรด */
@media (max-width: 900px) {
  .ntf-dt-act .cp-act-l { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; min-width: 0; }
  .ntf-dt-act .cp-act-l::-webkit-scrollbar { display: none; }
}

/* ════════════════════════════════════════════════════════════════
   🔴 (2026-09-14) iPhone: ของที่ปักขอบล่างลอยตอนแป้นพิมพ์เปิด (ต่อจาก mobile.css)
   position:fixed ผูกกับ layout viewport ที่ iOS เลื่อนขึ้น = --x10m-vvtop
   ⚠️⚠️ .toast / .vrec มี translateX(-50%) จัดกึ่งกลางอยู่แล้ว
        **ต้องเขียน translate ทั้งคู่** ไม่งั้นเขียนทับแล้วเด้งไปชิดซ้าย
   ⚠️ แป้นปิด = 0px → ไม่กระทบสภาพปกติ
   ════════════════════════════════════════════════════════════════ */
body.x10m.plat-ios.kb-open .dm-dock,
body.x10m.plat-ios.kb-open .thr-dock,
body.x10m.plat-ios.kb-open .mtoast,
body.x10m.plat-ios.kb-open .pushbar,
body.x10m.plat-ios.kb-open .notif-wrap {
  transform: translateY(var(--x10m-vvtop, 0px));
}
/* คู่ที่จัดกึ่งกลางด้วย translateX อยู่แล้ว — ต้องคงแกน X ไว้ */
body.x10m.plat-ios.kb-open .toast,
body.x10m.plat-ios.kb-open .vrec {
  transform: translateX(-50%) translateY(var(--x10m-vvtop, 0px));
}

/* ═══ สถานะการส่งคอมเมนต์ในเธรด (Boss สั่ง 2026-09-16) ═══════════════
   ใบชั่วคราวต้องดู "ยังไม่เสร็จ" ชัดเจน แต่ไม่จางจนอ่านไม่ออก
   ⚠️ opacity ต่ำกว่า .6 บนจอมือถือกลางแดด = อ่านไม่ออกเลย (ทดสอบแล้ว) */
.msg-pending { opacity: .72; }
.msg-pending.msg-failed { opacity: 1; }
.send-state {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-top: 3px; font-size: 11px; color: var(--muted, #888); line-height: 1.4;
}
.send-state.st-sent { color: var(--green, #2e7d32); }
.send-state.st-failed { color: var(--red, #c62828); font-weight: 600; }
.send-retry {
  border: 1px solid currentColor; background: transparent; color: inherit;
  border-radius: 999px; padding: 1px 9px; font-size: 11px; cursor: pointer;
  font-family: inherit; line-height: 1.6;
}
.send-retry:hover { background: rgba(198,40,40,.08); }
.pend-file { margin-left: 6px; opacity: .8; font-size: 12px; }
/* 📱 มือถือ: ปุ่มต้องกดโดนนิ้ว (บทเรียน feedback_hover_only_affordance_mobile) */
@media (max-width: 860px) {
  .send-retry { padding: 4px 12px; font-size: 12px; min-height: 30px; }
  .send-state { font-size: 12px; gap: 8px; }
}

/* ═══ ⑥ เส้นแดง "ข้อความใหม่" (Boss สั่ง 2026-09-16) ═══════════════════
   เปิดห้องแล้วรู้ทันทีว่าอ่านค้างไว้ตรงไหน ไม่ต้องเลื่อนหาเอง
   ⚠️ ต้องเห็นชัดทั้งธีมสว่าง/มืด แต่ไม่แย่งสายตาจากตัวข้อความ */
.unread-line {
  display: flex; align-items: center; gap: 10px;
  margin: 10px 0 6px; padding: 0 2px;
  font-size: 11.5px; font-weight: 700; color: #e53935;
  /* ⚠️ ไม่ใช้ position:sticky — กล่องข้อความมี overflow-anchor อยู่ ถ้า sticky
     จะทำให้เบราว์เซอร์คิดความสูงผิดตอนโหลดข้อความเก่าเพิ่ม (จอกระตุก) */
}
.unread-line::before, .unread-line::after {
  content: ''; flex: 1; height: 1px; background: #e53935; opacity: .55;
}
.unread-line span { flex: 0 0 auto; white-space: nowrap; letter-spacing: .2px; }
/* จอมืด: แดงสดเกินไปจะแสบตา → ลดความอิ่มสีลงเล็กน้อย */
@media (prefers-color-scheme: dark) {
  .unread-line { color: #ff6b68; }
  .unread-line::before, .unread-line::after { background: #ff6b68; opacity: .45; }
}
body.dark .unread-line { color: #ff6b68; }
body.dark .unread-line::before, body.dark .unread-line::after { background: #ff6b68; opacity: .45; }

/* ===== แถบจัดข้อความของแผงเธรด (2026-09-17) =====
   พี่ปอง: "ใน ตอบกลับ ปุ่มยังมาไม่ครบ" — เธรดเคยมีแค่ 📎 @ 😀 🧸
   เพิ่ม 🎤 + ☰ (B I S </> 🔗 📋 ❝ ⌗) ให้เท่าช่องพิมพ์ห้องหลัก
   ⚠️ แถบนี้อยู่ใน .thr-cbox ซึ่ง overflow:hidden — ต้องเป็นลูกในสายปกติ
      ห้ามทำ position:absolute ไม่งั้นโดนตัดหายเหมือนรายชื่อแท็ก */
.thr-fmt {
  display: flex; gap: 2px; overflow-x: auto; scrollbar-width: thin;
  padding: 4px 7px 5px; border-top: 1px dashed var(--border);
}
.thr-fmt.hidden { display: none; }
.thr-fmt::-webkit-scrollbar { height: 0; }
.thr-fmt .cp-fbtn { flex: 0 0 auto; }
.thr-tool.thrfmt-tg.on { background: var(--card); color: var(--text); }

/* มือถือ 360px: 6 ปุ่มเบียดกัน — บีบระยะแทนการซ่อน
   (ช่องพิมพ์ห้องหลักซ่อน ☰ ได้เพราะมีเมนู ＋ สำรอง แต่เธรดไม่มี ＋ จะกดไม่ได้เลย) */
@media (max-width: 480px) {
  .thr-tool { min-width: 34px; padding: 7px 6px; }
  .thr-tool-l { gap: 1px; }
}

/* แถบจัดข้อความของแผ่นหัวห้อง (chat head) — (2026-09-17) */
.chs-fmt {
  display: flex; gap: 2px; overflow-x: auto; scrollbar-width: thin;
  padding: 3px 7px 4px; border-bottom: 1px dashed var(--border);
}
.chs-fmt.hidden { display: none; }
.chs-fmt::-webkit-scrollbar { height: 0; }
.chs-fmt .cp-fbtn { flex: 0 0 auto; }
.chs-tb.chsfmt-tg.on { background: var(--card); color: var(--text); }

/* ⚖️ แถบเลือก "ใบลงโทษ" ในฟอร์มแก้ไข (pong สั่ง 2026-09-17)
   ข้อความแจ้ง 1 ใบผูกได้หลายใบ (คนละแผนก/ยอด/เจ้าของ) ต้องเห็นชัดว่ากำลังแก้ใบไหน
   ⚠️ มือถือเป็นหลัก: สูง 44px แตะง่าย · ล้นแล้วขึ้นบรรทัดใหม่ ไม่ตัดข้อความ */
.pn-chip {
  display: inline-flex; align-items: center; min-height: 44px;
  margin: 0 6px 6px 0; padding: 0 12px;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--card); color: var(--text);
  font: inherit; font-size: 13.5px; cursor: pointer;
}
.pn-chip:hover { background: var(--blue-light); }
.pn-chip.on { background: var(--blue-light); border-color: var(--blue); font-weight: 600; }

/* ===== ⚖️ การ์ด "แจ้งผลการลงโทษ" — pong สั่ง 2026-09-17 =====
   "ตัวลิงก์นี้ทำเป็นปุ่มแทนได้ไหม ตอนยิงมาในแอพแชท"
   ทรงเดียวกับการ์ด SOS/Requirement ที่มีอยู่แล้ว · ขอบซ้ายสีส้ม = เรื่องลงโทษ
   ⚠️ มือถือเป็นหลัก: ปุ่มสูง 40px+ แตะง่าย · ค่ายาว ๆ ตัดคำได้ ไม่ดันการ์ดล้นจอ */
/* 📋 การ์ดนับของในบ้าน (Amenity) — Boss 2026-09-17 · ทรงเดียวกับ .pn-card
   ขอบซ้ายเขียว (งานของแม่บ้าน) แยกจากใบลงโทษที่เป็นเหลือง */
.am-card {
  margin-top: 6px; max-width: min(420px, 100%);
  border: 1px solid var(--border); border-left: 3px solid var(--green, #16A34A); border-radius: 10px;
  background: var(--card); overflow: hidden;
}
.am-card .am-head {
  padding: 8px 11px; font-weight: 700; font-size: 14px;
  background: var(--sunken); border-bottom: 1px solid var(--border);
}
.am-card .am-body { padding: 7px 11px 8px; }
.am-card .am-sub { color: var(--muted); font-size: 12.5px; padding: 1px 0 4px; }
.am-card .am-blk-h {
  color: var(--muted); font-size: 12px; font-weight: 700;
  margin: 6px 0 3px; padding-top: 5px; border-top: 1px solid var(--border);
}
.am-card .am-item { padding: 2px 0; line-height: 1.5; word-break: break-word; overflow-wrap: anywhere; }
.am-card .am-row { padding: 3px 0; line-height: 1.5; word-break: break-word; }
.am-card .am-note { margin-top: 5px; color: var(--muted); font-size: 12.5px; line-height: 1.5; }
.am-card .am-foot {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 11px; border-top: 1px solid var(--border); background: var(--sunken);
}
.am-card .am-btn {
  display: inline-flex; align-items: center; min-height: 40px; padding: 0 14px;
  border: 0; border-radius: 8px; background: var(--blue); color: #fff;
  font: inherit; font-size: 13px; font-weight: 700; text-decoration: none; cursor: pointer;
}
.am-card .am-btn:hover { background: var(--blue-dark); }

.pn-card {
  margin-top: 6px; max-width: min(420px, 100%);
  border: 1px solid var(--border); border-left: 3px solid var(--amber); border-radius: 10px;
  background: var(--card); overflow: hidden;
}
.pn-card .pn-head {
  padding: 8px 11px; font-weight: 700; font-size: 14px;
  background: var(--sunken); border-bottom: 1px solid var(--border);
}
.pn-card .pn-body { padding: 7px 11px 3px; }
.pn-card .pn-kv { display: flex; gap: 8px; padding: 3px 0; line-height: 1.5; }
.pn-card .pn-k { flex: none; min-width: 72px; color: var(--muted); font-size: 12.5px; }
.pn-card .pn-v { flex: 1; font-weight: 600; word-break: break-word; overflow-wrap: anywhere; }
.pn-card .pn-row { padding: 3px 0; line-height: 1.5; word-break: break-word; }
.pn-card .pn-blk { padding: 5px 0 2px; }
.pn-card .pn-blk-h { color: var(--muted); font-size: 12.5px; margin-bottom: 2px; }
.pn-card .pn-blk-v { line-height: 1.55; word-break: break-word; overflow-wrap: anywhere; }
.pn-card .pn-note { margin-top: 4px; color: var(--muted); font-size: 12.5px; }
.pn-card .pn-void { margin: 2px 0 4px; font-weight: 700; color: var(--red); }
.pn-card .pn-foot {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 11px; border-top: 1px solid var(--border); background: var(--sunken);
}
.pn-card .pn-btn {
  min-height: 40px; padding: 0 14px; border: 0; border-radius: 8px;
  background: var(--blue); color: #fff; font: inherit; font-size: 13px; font-weight: 700;
  cursor: pointer;
}
.pn-card .pn-btn:hover { background: var(--blue-dark); }
.pn-card .pn-link {
  margin-left: auto; font-size: 12.5px; font-weight: 600;
  color: var(--blue); text-decoration: none;
}

/* ⚡ ปุ่มประชุมด่วน (Boss 2026-09-18 "มันแอบทำงานยากนะครับ")
   เส้นทางเดิมต้องผ่าน 5 หน้าจอกว่าจะเริ่มประชุมได้ → ปุ่มนี้กดเดียวเข้าเลย
   ⚠️ min-height 48px — ปุ่มหลักที่ใช้บ่อยต้องแตะง่ายบนมือถือ (เกณฑ์นิ้ว ≥44px) */
.meet-quick-btn { min-height: 48px; font-size: 15px; font-weight: 600;
  flex: 0 0 auto; white-space: nowrap; }
/* ตัวคั่น "หรือ" ระหว่างปุ่มด่วนกับช่องกรอกรหัส */
.meet-start-or { text-align: center; font-size: 12px; color: var(--muted, #6b7280);
  flex: 0 0 auto; }
@media (min-width: 560px) { .meet-start-or { padding: 0 2px; } }

/* ═══ 🎨 หน้าประชุม จัดใหม่ 2026-09-18 (Boss: "มันดู งงๆ") ═══ */

/* ① กล่องเริ่มประชุม — ทางเข้าหลัก ต้องเด่นที่สุดในหน้า */
.meet-hero { background: var(--card, #fff); border: 1px solid var(--line, #e5e7eb);
  border-radius: 14px; padding: 16px; margin-bottom: 16px; text-align: center; }
.meet-hero .meet-quick-btn { width: 100%; max-width: 320px; min-height: 52px;
  font-size: 16px; font-weight: 700; }
.meet-hero-hint { margin: 8px 0 0; }
/* ตัวคั่น "หรือ" แบบมีเส้นสองข้าง — บอกว่าเป็นทางเลือกที่สอง ไม่ใช่ขั้นตอนถัดไป */
.meet-hero-div { display: flex; align-items: center; gap: 10px;
  margin: 14px 0 10px; font-size: 12px; color: var(--muted, #6b7280); }
.meet-hero-div::before, .meet-hero-div::after { content: ''; flex: 1 1 auto;
  height: 1px; background: var(--line, #e5e7eb); }
.meet-hero .meet-start-join { max-width: 420px; margin: 0 auto; }

/* ② แท็บ — แยก "ประชุม" กับ "ใบเตรียมงาน" ให้ชัด */
.mt-tabs { display: flex; gap: 6px; margin-bottom: 14px;
  border-bottom: 2px solid var(--line, #e5e7eb); }
.mt-tab { flex: 1 1 0; min-height: 44px; padding: 10px 8px; border: 0;
  background: transparent; color: var(--muted, #6b7280);
  font-size: 14px; font-weight: 600; cursor: pointer;
  border-bottom: 3px solid transparent; margin-bottom: -2px; }
/* ⚠️ แท็บที่เลือกต้องต่างชัดด้วย "สี + เส้นใต้" ไม่ใช่สีอย่างเดียว
   (คนตาบอดสีแยกจากสีอย่างเดียวไม่ออก) */
.mt-tab.on { color: var(--accent, #0F4C81); border-bottom-color: var(--accent, #0F4C81); }

/* ③ หัวแท็บใบเตรียม — คำอธิบายซ้าย ปุ่มสร้างขวา */
.mt-pane-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.mt-pane-head p { flex: 1 1 auto; margin: 0; }
.mt-pane-head .btn { flex: 0 0 auto; }

@media (max-width: 480px) {
  .meet-hero { padding: 14px 12px; }
  .mt-pane-head { flex-direction: column; align-items: stretch; }
  .mt-pane-head .btn { width: 100%; min-height: 44px; }
}

/* 🎥 แถบสถานะในห้องประชุม "กำลังเชื่อมต่อ…" (Boss 2026-09-18 "กดเข้าร่วมแล้วช้า")
   เข้าห้องทันทีแล้วบอกสถานะ ดีกว่าจอค้างเงียบ ๆ จนคิดว่ากดไม่ติด */
.meet-status { position: absolute; left: 50%; top: 16px; transform: translateX(-50%);
  background: rgba(0,0,0,.72); color: #fff; padding: 8px 16px; border-radius: 999px;
  font-size: 13px; z-index: 30; pointer-events: none; }

/* ══════════════════════════════════════════════════════════════════════
   🎨 2026-09-18 — หน้า /#/meetings รอบ 2
   Boss: "ประชุมที่ผ่านมาอยากให้ UI แยกชัดเจน"
        "ให้ตรงนี้มี 2 ปุ่ม เป็น สร้างประชุม กับ สร้างประชุมด่วน"
   ⚠️ ต่อท้ายไฟล์เพราะทับกฎ .meet-hero .meet-quick-btn ที่ประกาศไว้ก่อนหน้า
      (specificity เท่ากัน ตัวล่างชนะ) — ย้ายบล็อกนี้ขึ้นไปข้างบน = พัง
   ══════════════════════════════════════════════════════════════════════ */

/* ── ① ปุ่มสองทางเข้าในกล่องเริ่มประชุม ─────────────────────────────
   ตะแกรง 2 ช่อง: แถวบน = ปุ่ม · แถวล่าง = คำอธิบายใต้ปุ่มของตัวเอง
   ⚠️ จอ 360: ช่องละ ~160px · ป้ายยาวขึ้นบรรทัดสองได้ ปุ่มสูงขึ้นตาม
      แต่ยังสูง ≥52px ตามเกณฑ์นิ้ว */
.meet-hero-acts {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px 10px;
  max-width: 480px; margin: 0 auto; align-items: stretch;
}
.meet-hero-acts .btn { width: 100%; min-height: 52px; font-size: 15px; font-weight: 700;
  padding-left: 8px; padding-right: 8px; }
/* ทับกฎเดิมที่บังคับปุ่มด่วนเป็น max-width 320px กลางจอ — ตอนนี้อยู่ในตะแกรงแล้ว */
.meet-hero .meet-hero-acts .meet-quick-btn { max-width: none; white-space: normal; }
/* ⚠️ น้ำหนักต่างกันโดยตั้งใจ: ด่วน=ทึบ (ใช้บ่อย) · สร้างประชุม=โปร่ง (ใช้นาน ๆ ครั้ง)
   ไม่ใช่ปุ่มเด่นเท่ากันสองอัน ไม่งั้นคนไม่รู้จะกดอันไหน */
.meet-hero-acts .meet-new-btn { border: 1px solid var(--line, #e5e7eb); }
.meet-hero-acts .meet-hero-hint { margin: 0; text-align: center; line-height: 1.35; }

/* ⚠️ **ห้ามซ้อนเป็นแถวเดียวที่จอมือถือ** — Boss สั่งว่า "ให้ตรงนี้มี 2 ปุ่ม"
   มือถือ Android ที่ใช้จริงกว้าง 360-412px ถ้าตั้ง breakpoint ที่ 380 จะซ้อนเกือบทุกเครื่อง
   ที่ 360px: ช่องละ (360 − 24 ขอบ − 12 ช่องไฟ − 20 padding) / 2 ≈ 152px
   ป้ายยาวสุด "⚡ สร้างประชุมด่วน" ตกบรรทัดสองได้ ปุ่มสูงขึ้นแต่ยัง ≥52px */
@media (max-width: 400px) {
  .meet-hero-acts { gap: 6px 8px; }
  .meet-hero-acts .btn { font-size: 14px; line-height: 1.25; }
  .meet-hero-acts .meet-hero-hint { font-size: 11.5px; }
}

/* ── ② ตัวกรองวัน — ปุ่มที่เลือกต้องเห็นว่าเลือกอยู่ ────────────────
   🔴 บั๊กเดิม: mtSetDay() ลบ .primary ออกจากทุกปุ่มแล้วไม่ใส่คืน = ไม่มีตัวไหนสว่าง
   ⚠️ ต่างด้วย "สี + เส้นใต้" ไม่ใช่สีอย่างเดียว (คนตาบอดสี) — กฎเดียวกับ .mt-tab.on */
.mt-datefilter .btn.on {
  position: relative; font-weight: 700;
  box-shadow: inset 0 -3px 0 0 var(--accent, #0F4C81);
}
/* ช่องเลือกวันเคยยืดเต็มแถวของตัวเอง (ตัวอักษร 16px + ป้าย mm/dd/yyyy = ~359px บนจอ 375)
   เลยเด่นกว่าปุ่ม "ทั้งหมด/วันนี้/เมื่อวาน" ที่เป็นตัวกรองหลัก — หดให้อยู่แถวเดียวกัน
   ⚠️ ห้ามลด font-size ต่ำกว่า 16px: iOS จะซูมหน้าจอเองตอนโฟกัส (กฎใน mobile.css)
      และ selector นี้มี id = ชนะกฎ plat-ios ของ mobile.css ถ้าเผลอใส่ค่าอื่นจะพังที่ iPhone */
#meeting-datefilter input[type="date"] { flex: 1 1 130px; min-width: 0; max-width: 180px; }

/* ── ③ ประชุมที่ผ่านมา: คั่นเป็นกลุ่มวัน ───────────────────────────── */
.mt-daygroup + .mt-daygroup { margin-top: 18px; }
.mt-dayhead {
  position: sticky; top: 0; z-index: 2;
  margin: 0 0 8px; padding: 6px 2px;
  background: var(--bg, #f4f6f8);
  font-size: 12px; font-weight: 700; letter-spacing: .03em;
  color: var(--muted, #6b7280);
}

/* ── ④ การ์ดประชุม — แยกเป็นชั้น ไม่ใช่บรรทัดเทาก้อนเดียว ──────────
   ชั้น 1 ชื่อเรื่อง · ชั้น 2 ตัวเลข · ชั้น 3 ห้อง/คนเริ่ม · ชั้น 4 ชิป */
.meeting-item { display: grid; gap: 4px; }
.mt-it-title { margin: 0; font-size: 15px; font-weight: 700; line-height: 1.35;
  overflow-wrap: anywhere; }
/* ตัวเลขใช้ฟอนต์ความกว้างเท่ากัน — เวลา/นาที/คน เรียงตรงกันทุกใบ อ่านไล่ลงมาได้ */
.mt-it-facts { display: flex; flex-wrap: wrap; gap: 4px 12px;
  font-size: 13px; font-variant-numeric: tabular-nums; }
.mt-it-meta { margin: 0; overflow-wrap: anywhere; }
.mt-it-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
/* ⚠️ ชิปแยกกันด้วย "ไอคอน + ข้อความ" ไม่ได้ใช้สีแยก — ทุกใบสีเดียวกันหมด */
.mt-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 9px; border-radius: 999px;
  background: var(--sunken, #eef1f4); color: var(--muted, #6b7280);
  font-size: 12px; font-weight: 600; white-space: nowrap;
}

/* ══════════════════════════════════════════════════════════════════════
   🎨 2026-09-19 — ไทล์คนที่ปิดกล้อง (Boss: "ทำ UI/UX ไว้สำหรับมือถือด้วย และคอม")
   เดิมปิดกล้อง = สี่เหลี่ยมมืด ๆ เปล่า ๆ (.cam-off video { opacity:.12 })
   บนมือถือกรอบเล็กอยู่แล้ว → แยกไม่ออกว่าใครเป็นใคร หรือสายหลุดไปแล้ว
   → โชว์วงกลมรูป/ตัวอักษรย่อ แบบเดียวกับ Google Meet
   ⚠️ ต่อท้ายไฟล์ เพราะต้องชนะกฎ .video-tile / .meet-grid .video-tile ที่มาก่อนหน้า
   ══════════════════════════════════════════════════════════════════════ */

/* วงกลมซ้อนกลางไทล์ — ซ่อนไว้ก่อน โผล่เฉพาะตอนกล้องปิด */
.vt-avatar {
  position: absolute; inset: 0; display: none;
  align-items: center; justify-content: center;
  pointer-events: none;                 /* ⚠️ ห้ามบังการกดไทล์ */
}
.vt-avatar .avatar {
  border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-weight: 700; color: #fff; box-shadow: 0 2px 10px rgba(0,0,0,.35);
}
.video-tile.cam-off .vt-avatar,
.video-tile.audio-only .vt-avatar { display: flex; }
/* ไทล์เสียงล้วนเคยโชว์อิโมจิ 🎙️ เป็น textContent — วงกลมสวยกว่าและบอกได้ว่าเป็นใคร */
.video-tile.audio-only { font-size: 0; }
.video-tile.audio-only .vt-name { font-size: 12px; }

/* กล้องปิด = พื้นหลังทึบขึ้น ให้วงกลมเด่น (เดิมเหลือภาพจาง ๆ 12% ดูเหมือนสัญญาณเสีย) */
.meet-grid .video-tile.cam-off { background: #16222f; }
.meet-grid .video-tile.cam-off video { opacity: 0; }

/* 📱 มือถือ: กรอบเล็ก วงกลมต้องเล็กตาม ไม่งั้นล้นกรอบ
   ใช้ min() เทียบกับด้านสั้นของไทล์ แทนการ fix px ต่อ breakpoint */
.vt-avatar .avatar { width: min(72px, 34%); height: min(72px, 34%); font-size: min(28px, 14%); }
@media (max-width: 480px) {
  .vt-avatar .avatar { width: min(56px, 38%); height: min(56px, 38%); }
}
/* จอแชร์ไม่ต้องมีวงกลม — เป็นภาพหน้าจอ ไม่ใช่หน้าคน */
.video-tile.sharing .vt-avatar { display: none !important; }


/* 🏢 ชิปเลือกแผนกในฟอร์มสร้างประชุม (Boss 2026-09-19)
   เดิมมีแต่รายชื่อ 198 คนเรียงยาว ต้องติ๊กทีละคน → ให้กดทั้งแผนกรวดเดียว
   ⚠️ ปุ่มสูง ≥ 36px แตะง่ายบนมือถือ · ห่อบรรทัดได้ ไม่ดันจอกว้าง */
.prep-deptchips { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 10px; }
.prep-dchip {
  display: inline-flex; align-items: center; gap: 5px;
  min-height: 36px; padding: 6px 11px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--sunken); color: var(--text);
  font: inherit; font-size: var(--fs-sm); cursor: pointer; white-space: nowrap;
}
.prep-dchip:hover { border-color: var(--blue); }
.prep-dchip.on { background: rgba(59,130,246,.16); border-color: var(--blue); font-weight: 600; }
.prep-dchip .muted { opacity: .65; font-size: 11px; }

/* ══════════════════════════════════════════════════════════════════════
   ฟอร์มสร้างประชุมตามแบบ Boss 2026-09-19 (ส่งรูป 2 ใบ)
   · หัวฟอร์มมีคำอธิบายซ้าย + ปุ่ม "ย้อนกลับ" ขวา
   · แถวป้ายมีตัวเลขสรุปมุมขวา ("ยังไม่ได้เลือก" / "เลือกแล้ว N คน")
   ⚠️ มือถือ: หัวฟอร์มต้องพับลง ไม่งั้นปุ่มย้อนกลับเบียดคำอธิบายจนอ่านไม่ออก
   ══════════════════════════════════════════════════════════════════════ */
.pn-head { display: flex; align-items: flex-start; gap: 10px; margin: -2px 0 12px; }
.pn-head .pn-sub { flex: 1; min-width: 0; margin: 0; }
.pn-head .pn-back { flex-shrink: 0; }
.pn-lbl-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin: 12px 0 6px; font-size: var(--fs-sm); color: var(--muted);
}
.pn-count { font-size: 12px; color: var(--muted); }
.pn-count.on { color: var(--blue); font-weight: 600; }
@media (max-width: 560px) {
  .pn-head { flex-direction: column; gap: 6px; }
  .pn-head .pn-back { align-self: flex-start; }
}

/* 🏠 ชิปเลือกบ้านที่เข้าพัก แบ่งตามโซน (Boss 2026-09-19)
   ⚠️ 53 หลัง — ถ้าเรียงรวดเดียวจะหาไม่เจอ ต้องคั่นหัวโซนพร้อมแถบสีของโซนนั้น */
.prep-housechips { margin: 4px 0 8px; }
.ph-zone { margin-bottom: 10px; }
.ph-zname {
  font-size: 11px; color: var(--muted); margin-bottom: 5px;
  padding-left: 8px; border-left: 3px solid var(--zc); line-height: 1.3;
}
.ph-row { display: flex; flex-wrap: wrap; gap: 6px; }
.prep-hchip {
  min-height: 34px; padding: 5px 10px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--sunken); color: var(--text);
  font: inherit; font-size: var(--fs-sm); cursor: pointer; white-space: nowrap;
}
.prep-hchip:hover { border-color: var(--blue); }
.prep-hchip.on { background: rgba(59,130,246,.16); border-color: var(--blue); font-weight: 600; }
.pn-houses-txt { width: 100%; }

/* ============================================================
   🎬 วิดีโอ: สตรีมเล่นทันที + ปุ่มบันทึกมุมขวาบน (Boss 2026-09-20)
   ⚠️ ปุ่มต้องไม่บังปุ่มเล่น/แถบเวลาของ <video> (controls อยู่ "ล่าง")
      จึงวางไว้ "บนขวา" · แตะได้ 32px ตามขนาดนิ้ว
   ⚠️ .vdo-wrap เป็น inline-block ไม่ใช่ block — ไม่งั้นบับเบิลยืดเต็มความกว้าง
   ============================================================ */
/* 🔴 2026-09-20 Boss: "ส่งคลิปแล้วเปิดดูมืดเลยไม่เห็นอะไร"
   ต้นเหตุ: กฎขนาดสื่อเดิมใช้ selector **ลูกตรง** `.msg-bubble > video.msg-video`
     (style.css:4161) การที่ผมครอบ <div class="vdo-wrap"> ทำให้ video
     ไม่ใช่ "ลูกตรง" ของบับเบิลอีกต่อไป → กฎ max-width/margin-left หลุดหมด
   ซ้ำร้าย mobile.css:1226 ทา `background: var(--x10m-ground)` (สีเข้ม)
     พอ wrapper สูง 0 (line-height:0) + video ไม่ได้ขนาด = เห็นแต่พื้นเข้ม = "จอมืด"
   แก้: ให้ wrapper "โปร่งใสต่อ layout" — สืบทอดขนาดจาก video ข้างใน
     และ **ต้องมีกฎลูกตรงคู่ขนาน** สำหรับ .vdo-wrap ด้วย
   ⚠️ ห้ามใส่ line-height:0 (ทำให้กล่องยุบ) · ห้ามใส่ background (ทับเป็นจอมืด) */
.vdo-wrap { position: relative; display: block; width: fit-content; max-width: 100%; }
.vdo-wrap > video { display: block; max-width: 100%; height: auto; }
/* คู่ขนานกับกฎลูกตรงเดิม — คืนขนาด/การชิดขวาที่หลุดไปเพราะมี wrapper คั่น */
.msg:not(.nested):not(.system) .msg-bubble > .vdo-wrap { max-width: min(320px, 100%); }
.msg:not(.nested):not(.system).mine .msg-bubble > .vdo-wrap { margin-left: auto; }
.vdo-dl {
  position: absolute; top: 6px; right: 6px;
  width: 32px; height: 32px; padding: 0;
  border: 0; border-radius: 50%;
  background: rgba(0,0,0,.55); color: #fff;
  font-size: 15px; line-height: 32px; text-align: center;
  cursor: pointer; opacity: .75; transition: opacity .15s, background .15s;
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
.vdo-dl:hover, .vdo-dl:focus-visible { opacity: 1; background: rgba(0,0,0,.75); }
/* ⚠️ มือถือไม่มี hover — ต้องเห็นปุ่มตลอด ห้ามซ่อนรอ hover
   (บทเรียนเดิม: feedback_hover_only_affordance_mobile) */
@media (hover: none) { .vdo-dl { opacity: .85; } }

/* ---------- ระดับแจ้งเตือนของห้องในแถบข้าง (2026-09-20) ----------
   ห้องที่ตั้ง "เฉพาะตอนแท็กฉัน" (ระดับ 2) เดิมหน้าตาเหมือนห้องปกติเป๊ะ
   ⇒ คนจำไม่ได้ว่าปิดห้องไหนไว้ แล้วเผลอกดปุ่ม 🔔 ทับค่าที่ตั้งไว้
   คลาส .chan-muted ถูกใส่ใน markup มานานแล้วแต่ **ไม่เคยมีกฎ CSS** = มองไม่ออกทั้ง 2 ระดับ */
.chan-item.chan-muted > .grow { opacity: .62; }
.chan-mute-ic {
  flex: 0 0 auto; font-size: 11px; line-height: 1; opacity: .75;
  margin-left: 2px; pointer-events: none;   /* เป็นป้ายบอกสถานะ ไม่ใช่ปุ่ม — ปล่อยคลิกทะลุไปเปิดห้อง */
}

/* ===== สถานะบน "ตัวข้อความ" (พี่ปองขอ 2026-09-20 ห้อง IT-แจ้งBug) =====
   "เวลาเราไปดูหน้าข้อความจะต้องแสดงสถานะด้วย" — ป้ายอยู่ในฟองข้อความ ทุกคนในห้องเห็นเหมือนกัน
   ⚠️ ใช้ตัวแปรสีตามธีม (--green/--red/--amber/--blue) ไม่ฮาร์ดโค้ดสี
      แอปนี้มีหลายธีม + โหมดสว่าง/มืด ฮาร์ดโค้ดแล้วจะอ่านไม่ออกในบางธีม */
.msg-sts { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.msg-st {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 8px; border-radius: var(--radius-pill, 999px);
  font-size: var(--fs-xs); font-weight: 700; line-height: 1.7;
  background: var(--sunken); color: var(--muted);
  border: 1px solid transparent; cursor: pointer;
}
.msg-st:hover { border-color: var(--muted); }
/* อันที่ "เรา" เป็นคนกด — ขอบทึบให้รู้ว่าเราอยู่ในสถานะนี้ (กดซ้ำ = ถอนออก) */
.msg-st.is-mine { border-color: currentColor; }
.msg-st.st-done    { background: color-mix(in srgb, var(--green) 14%, transparent);  color: var(--green); }
.msg-st.st-correct { background: color-mix(in srgb, var(--green) 14%, transparent);  color: var(--green); }
.msg-st.st-ack     { background: color-mix(in srgb, var(--blue) 14%, transparent);   color: var(--blue); }
.msg-st.st-wip     { background: color-mix(in srgb, var(--amber) 16%, transparent);  color: var(--amber); }
.msg-st.st-urgent  { background: color-mix(in srgb, var(--red) 14%, transparent);    color: var(--red); }
.msg-st.st-cancel  { background: var(--sunken); color: var(--muted); text-decoration: line-through; }
/* มือถือ: ป้ายสถานะต้องกดโดนด้วยนิ้ว (จอ 360px ป้ายสูงแค่ ~22px = เล็กไป)
   ⚠️ ขยายด้วย padding แนวตั้ง ไม่ใช่ font-size — ตัวหนังสือโตแล้ว 6 ป้ายจะล้นบรรทัด */
@media (max-width: 640px) {
  .msg-st { padding: 5px 10px; }
  .msg-sts { gap: 6px; }
}
/* ===== แถวสถานะ 6 แบบ "ในแผงอีโมจิเดิม" (พี่ปองขอ 2026-09-21) =====
   อยู่เป็นแถวที่ 4 ของ .react-pick ต่อจาก อีโมจิ/พลูโต/สีวงกลม
   🔴 โดนท้วง "ใหญ่ไป" 2 รอบ — ต้นเหตุคือ **ใส่ตัวหนังสือในปุ่ม** (เม็ดกว้าง ~90px vs อีโมจิ 33px
      แถวสถานะเลยเป็นแถวที่สูงที่สุดในแผง 59px = 27% ของแผง)
   ⇒ ตอนนี้ **ไอคอนล้วน ชื่ออยู่ใน title/aria-label** เหมือนแถวสีวงกลม (COLOR_REACTS)
      พี่ปองขอ "เป็นในเชิงสัญลักษณ์ก็ได้" ⇒ ตรงโจทย์อยู่แล้ว
   ⚠️ ห้ามเอาตัวหนังสือกลับเข้าปุ่ม — จะใหญ่ซ้ำรอยเดิมทันที */
.rp-row.rp-status {
  display: flex; gap: 2px; align-items: center;
  border-top: 1px solid var(--border, var(--sunken));
  margin-top: 3px; padding-top: 4px;
}
/* geometry ต้องเท่า `.react-pick button` เป๊ะ (19px / padding 2px 4px) ไม่งั้นแถวนี้โดดออกมา */
.rp-st {
  border: none; background: none; cursor: pointer; font-size: 19px;
  padding: 2px 4px; border-radius: 50%; line-height: 1;
  position: relative; filter: grayscale(.55) opacity(.8);
}
.rp-st:hover { transform: scale(1.25); background: var(--sunken); filter: none; }
/* อันที่ "เรา" กดอยู่ — สีเต็ม + วงพื้นจาง ⇒ รู้ว่ากำลังอยู่สถานะไหน (กดซ้ำ = ถอน)
   ใช้ box-shadow เป็นวงแทน border เพื่อไม่ให้ปุ่มขยับ (border กิน layout) */
.rp-st.is-mine { filter: none; }
.rp-st.is-mine.st-done,
.rp-st.is-mine.st-correct { background: color-mix(in srgb, var(--green) 20%, transparent); box-shadow: 0 0 0 2px var(--green); }
.rp-st.is-mine.st-ack     { background: color-mix(in srgb, var(--blue) 20%, transparent);  box-shadow: 0 0 0 2px var(--blue); }
.rp-st.is-mine.st-wip     { background: color-mix(in srgb, var(--amber) 22%, transparent); box-shadow: 0 0 0 2px var(--amber); }
.rp-st.is-mine.st-urgent  { background: color-mix(in srgb, var(--red) 20%, transparent);   box-shadow: 0 0 0 2px var(--red); }
.rp-st.is-mine.st-cancel  { background: var(--sunken); box-shadow: 0 0 0 2px var(--muted); }
/* แผงที่เปิดจากหน้าแจ้งเตือน = มีแถวสถานะแถวเดียว ไม่ต้องมีเส้นคั่นบน */
.react-pick.rp-only-status .rp-row.rp-status { border-top: 0; margin-top: 0; padding-top: 0; }
/* ปุ่มเปิดแผงในแถวแจ้งเตือน — โชว์สถานะปัจจุบันเป็นสัญลักษณ์เลย */
.ntf-act.ntf-mst-open { white-space: nowrap; }
.nmf { display: inline-flex; align-items: center; gap: 3px; }
.nmf.on { font-weight: 800; }
.nmf.st-done, .nmf.st-correct { color: var(--green); }
.nmf.st-ack { color: var(--blue); }
.nmf.st-wip { color: var(--amber); }
.nmf.st-urgent { color: var(--red); }
.nmf.st-cancel { color: var(--muted); text-decoration: line-through; }
/* มือถือ: ไอคอนล้วนแล้วเล็กลงมาก — ขยายระยะกดเล็กน้อยให้เท่าปุ่มอีโมจิที่มือถือ
   ⚠️ ขยายด้วย padding เท่านั้น อย่าใส่ min-height/ตัวหนังสือกลับมา (บทเรียน "ใหญ่ไป") */
@media (max-width: 640px) {
  .rp-row.rp-status { gap: 3px; }
  .rp-st { padding: 4px 6px; }
}

/* ===== การ์ดตามของ/อาหาร (marketing → ห้องครัว) — Boss สั่ง 2026-09-23 รอบ 2 "rework UI หมด" =====
   หัวการ์ดสีตามกะ (เช้า=อำพัน · เย็น=คราม) · หัวข้อตัวใหญ่ · ไทม์ไลน์ 3 จุด แจ้ง→รับเรื่อง→ส่งแล้ว
   · ปุ่มขั้นถัดไปเด่นเต็มแถว · ใช้ตัวแปรที่มีจริงเท่านั้น (--card/--text/--muted/--border/--bg) */
.fl-card {
  --fl-a: #D97706; --fl-a2: rgba(217, 119, 6, .12);
  margin-top: 6px; width: min(520px, 100%);
  border: 1px solid var(--border); border-radius: 14px; background: var(--card);
  overflow: hidden; box-shadow: 0 1px 3px rgba(0, 0, 0, .08);
}
.fl-card.fl-pm { --fl-a: #4F46E5; --fl-a2: rgba(79, 70, 229, .12); }
.fl-card.fl-etc { --fl-a: #64748B; --fl-a2: rgba(100, 116, 139, .12); }
/* เคสคืนเงินลูกค้า (ห้อง 84) — ม่วง/บานเย็น ตัดกับส้มของใบเบิกทั่วไป (ห้อง 282) ชัดกว่าฟ้า
   (Boss 25 ก.ย. "สีเดียวกันจะหลง" — ต้องต่างจนมองแวบเดียวแยกออก ไม่ใช่แค่เฉดใกล้เคียงกัน)
   คู่กับป้ายหัวการ์ดที่เปลี่ยนคำเป็น "คืนเงินลูกค้า" ด้วย ไม่พึ่งสีอย่างเดียว */
.fl-card.fl-refund { --fl-a: #A21CAF; --fl-a2: rgba(162, 28, 175, .14); }
/* ใบเบิกโอนธนาคาร (ห้อง 151) เขียว · ใบเบิกสินค้าออนไลน์ (ห้อง 152) ช็อกโกแลต — Boss เลือก 25 ก.ย.
   ทั้ง 4 ห้องต้องแยกสีคนละชุดจนมองแวบเดียวออก: 282=ส้ม 84=ม่วง 151=เขียว 152=ช็อกโกแลต */
.fl-card.fl-greenroom { --fl-a: #15803D; --fl-a2: rgba(21, 128, 61, .13); }
.fl-card.fl-choc { --fl-a: #78350F; --fl-a2: rgba(120, 53, 15, .14); }
/* ห้อง 155 HR-FE-ACC-ประกันสังคม-เบิกค่าจ้าง — เขียวน้ำเงิน (teal) แยกจากเขียว 151 (Boss 1 ต.ค.) */
.fl-card.fl-socsec { --fl-a: #0E7490; --fl-a2: rgba(14, 116, 144, .13); }
/* ห้อง 149 be-new-vender-item (Boss 25 ก.ย. "ui แบบห้องเงินโอน เปลี่ยนสี") — โทนน้ำเงิน แยกสีต่อชนิดงาน
   ไม่ชนกับ 282=ส้ม 84=ม่วง 151=เขียว 152=ช็อกโกแลต · ด่วน=แดง ต้องเด่นสุดในห้อง */
.fl-card.fl-ni-item     { --fl-a: #1D4ED8; --fl-a2: rgba(29, 78, 216, .11); }
.fl-card.fl-ni-vendor   { --fl-a: #0E7490; --fl-a2: rgba(14, 116, 144, .12); }
.fl-card.fl-ni-recipe   { --fl-a: #BE185D; --fl-a2: rgba(190, 24, 93, .11); }
.fl-card.fl-ni-urgent   { --fl-a: #DC2626; --fl-a2: rgba(220, 38, 38, .11); }
.fl-card.fl-ni-pr       { --fl-a: #475569; --fl-a2: rgba(71, 85, 105, .12); }
.fl-card.fl-ni-transfer { --fl-a: #4338CA; --fl-a2: rgba(67, 56, 202, .11); }
.fl-card.fl-ni-vehout   { --fl-a: #B45309; --fl-a2: rgba(180, 83, 9, .12); }   /* 🚗 ขอใช้รถ (ห้อง 253) */
.fl-card.fl-ni-vehin    { --fl-a: #047857; --fl-a2: rgba(4, 120, 87, .12); }   /* 🔑 ส่งคืนรถ */
.fl-card .fl-ni-list { white-space: normal; padding: 6px 10px; margin-top: 10px; }
.fl-card .fl-ni-row { display: flex; gap: 8px; align-items: flex-start; padding: 4px 0; font-size: 14.5px; line-height: 1.45; }
.fl-card .fl-ni-row + .fl-ni-row { border-top: 1px dashed var(--border); }
.fl-card .fl-ni-n {
  flex: 0 0 auto; min-width: 20px; height: 20px; border-radius: 999px; background: var(--fl-a); color: #fff;
  font-size: 11.5px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; margin-top: 1px;
}
.fl-card .fl-ni-t { word-break: break-word; overflow-wrap: anywhere; }
/* ปุ่มเปิดในแอป = สีเดียวกับหัวการ์ด (ปุ่มเขียวค่าเริ่มต้นชนกับสีการ์ด) */
.fl-card.fl-ni .fl-btn.fl-go { background: var(--fl-a); border-color: var(--fl-a); color: #fff; }
.fl-card .fl-top {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 12px; background: var(--fl-a); color: #fff; font-size: 13px; font-weight: 700;
}
.fl-card .fl-pill {
  background: rgba(255, 255, 255, .95); color: #1F2937; border-radius: 999px;
  padding: 2px 10px; font-size: 12px; font-weight: 800; white-space: nowrap;
}
.fl-card.fl-delivered .fl-pill { background: #DCFCE7; color: #166534; }
.fl-card.fl-rejected .fl-pill { background: #FEE2E2; color: #991B1B; }
.fl-card.fl-accepted .fl-pill { background: #DBEAFE; color: #1E40AF; }
.fl-card .fl-main { padding: 12px 14px 10px; }
.fl-card .fl-kind { font-size: 11.5px; font-weight: 700; color: var(--fl-a); letter-spacing: .2px; margin-bottom: 2px; }
.fl-card .fl-title { font-size: 17px; font-weight: 800; line-height: 1.4; color: var(--text); word-break: break-word; overflow-wrap: anywhere; }
.fl-card .fl-detail {
  margin-top: 6px; padding: 9px 11px; border-radius: 10px; background: var(--fl-a2);
  font-size: 15px; line-height: 1.55; color: var(--text); white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere;
}
.fl-card .fl-detail.fl-big { font-size: 16.5px; font-weight: 700; }
.fl-card .fl-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 9px; }
.fl-card .fl-chip-i {
  font-size: 12.5px; color: var(--muted); border: 1px solid var(--border); border-radius: 999px;
  padding: 2px 9px; line-height: 1.6; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fl-card .fl-chip-i b { color: var(--text); font-weight: 700; margin-right: 2px; }

/* บล็อกบัญชีต้นทาง/ปลายทาง — แยกเด่นชัด ไม่ปนกับ chip อื่น (Boss สั่ง "ต้องแสดง") */
.fl-card .fl-acc {
  margin-top: 10px; border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
  background: color-mix(in srgb, var(--fl-a2) 55%, transparent);
}
.fl-card .fl-acc-row {
  display: flex; align-items: flex-start; gap: 8px; padding: 8px 11px;
  font-size: 14px; line-height: 1.45; color: var(--text);
}
.fl-card .fl-acc-row + .fl-acc-row { border-top: 1px dashed var(--border); }
.fl-card .fl-acc-k { flex: 0 0 auto; font-weight: 700; color: var(--fl-a); font-size: 12.5px; white-space: nowrap; padding-top: 1px; }
.fl-card .fl-acc-v { font-weight: 700; word-break: break-word; overflow-wrap: anywhere; }

/* ไทม์ไลน์ 3 จุด — จุดที่ผ่านแล้วสีเขียว · จุดปัจจุบันมีวงแหวน */
.fl-card .fl-steps { display: flex; padding: 10px 10px 12px; border-top: 1px dashed var(--border); }
.fl-card .fl-step { flex: 1 1 0; position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; min-width: 0; }
.fl-card .fl-step::before {
  content: ''; position: absolute; top: 7px; right: 50%; width: 100%; height: 2px; background: var(--border);
}
.fl-card .fl-step:first-child::before { display: none; }
.fl-card .fl-step.on::before { background: #16A34A; }
.fl-card .fl-dot {
  position: relative; z-index: 1; width: 16px; height: 16px; border-radius: 50%;
  background: var(--card); border: 2px solid var(--border); box-sizing: border-box;
}
.fl-card .fl-step.on .fl-dot { background: #16A34A; border-color: #16A34A; }
.fl-card .fl-step.cur .fl-dot { box-shadow: 0 0 0 4px rgba(22, 163, 74, .22); }
.fl-card .fl-step.cur:not(.on) .fl-dot, .fl-card.fl-pending .fl-step.cur .fl-dot { box-shadow: 0 0 0 4px rgba(217, 119, 6, .25); }
.fl-card .fl-sl { margin-top: 5px; font-size: 12.5px; font-weight: 700; color: var(--muted); }
.fl-card .fl-step.on .fl-sl { color: var(--text); }
.fl-card .fl-sw { font-size: 11.5px; color: var(--muted); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 2px; }
/* การ์ดใบเบิก: แถบ 4 ขั้นแบบมีเลขในวง (บัญชีขอ 3 ต.ค.) */
.fl-card .fl-steps.fl-num .fl-step::before { top: 11px; }
.fl-card .fl-steps.fl-num .fl-dot {
  width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;
  font-size: 12.5px; font-weight: 800; line-height: 1; color: var(--muted);
}
.fl-card .fl-steps.fl-num .fl-step.on .fl-dot { color: #fff; }
.fl-card .fl-steps.fl-num .fl-step.cur .fl-dot { border-color: #D97706; color: #D97706; box-shadow: 0 0 0 4px rgba(217, 119, 6, .22); }
.fl-card .fl-steps.fl-num .fl-step.cur .fl-sl { color: #D97706; }
.fl-card .fl-steps.fl-num .fl-step.rej .fl-dot { border-color: #DC2626; color: #DC2626; }

.fl-card .fl-rej { margin: 0 12px 12px; padding: 9px 11px; border-radius: 10px; background: rgba(220, 38, 38, .10); border: 1px solid rgba(220, 38, 38, .35); }
.fl-card .fl-rej-h { font-weight: 800; color: #DC2626; font-size: 13.5px; }
.fl-card .fl-rej-r { margin-top: 3px; font-size: 14px; color: var(--text); word-break: break-word; }
.fl-card .fl-photos { display: grid; gap: 4px; padding: 0 12px 10px; grid-template-columns: repeat(3, 1fr); }
.fl-card .fl-photos.n1 { grid-template-columns: 1fr; }
.fl-card .fl-photos.n2 { grid-template-columns: 1fr 1fr; }
.fl-card .fl-photo { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 10px; cursor: zoom-in; display: block; background: var(--bg); }
.fl-card .fl-photos.n1 .fl-photo { aspect-ratio: 16 / 10; }
.fl-card .fl-note { padding: 0 14px 12px; font-size: 13.5px; color: var(--text); word-break: break-word; }
.fl-sheet .fl-hint { font-size: 12px; color: var(--text-dim, #888); padding: 2px 2px 0; }
/* ไฟล์แนบที่ไม่ใช่รูป (PDF/Word/ฯลฯ) — ลิงก์ดาวน์โหลดในการ์ด disburse (25 ก.ย. พี่ออยขอ) */
.fl-card .fl-docs { display: flex; flex-direction: column; gap: 6px; padding: 0 12px 10px; }
.fl-card .fl-doc {
  display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 10px;
  background: var(--bg); border: 1px solid var(--border); text-decoration: none; color: var(--text);
  font-size: 13.5px; font-weight: 600; overflow: hidden;
}
.fl-card .fl-doc-ext {
  flex: 0 0 auto; background: var(--fl-a); color: #fff; font-size: 10.5px; font-weight: 800;
  border-radius: 6px; padding: 3px 6px; letter-spacing: .3px;
}
.fl-card .fl-doc-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fl-card .fl-foot { display: flex; gap: 8px; flex-wrap: wrap; padding: 10px 12px 12px; border-top: 1px solid var(--border); background: var(--bg); }
.fl-btn {
  border: none; border-radius: 10px; padding: 8px 12px; min-height: 40px;
  font-family: inherit; font-size: 13.5px; font-weight: 700; cursor: pointer; white-space: nowrap;
  display: flex; align-items: center; justify-content: center; text-align: center; text-decoration: none;
}
.fl-btn:disabled { opacity: .6; cursor: default; }
.fl-btn.fl-go { background: #16A34A; color: #fff; }
.fl-btn.fl-go:hover { background: #15803D; }
.fl-btn.fl-alt { background: var(--card); color: var(--text); border: 1px solid var(--border); }
.fl-btn.fl-no { background: var(--card); color: #DC2626; border: 1px solid rgba(220, 38, 38, .5); }
/* ปุ่มหลัก (ขั้นถัดไป) เต็มแถวบน สูงแตะง่าย · ปุ่มรองแบ่งครึ่งแถวล่าง */
.fl-card .fl-foot .fl-btn { flex: 1 1 0; }
.fl-card .fl-foot .fl-btn:first-child { flex-basis: 100%; min-height: 46px; font-size: 15px; }

/* แผ่นกรอกส่งอาหาร/ทำไม่ได้ — ลอยทับทั้งจอ มือถือเป็นแผ่นล่าง */
.fl-sheet-bg {
  position: fixed; inset: 0; z-index: 9000; background: rgba(0, 0, 0, .45);
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
.fl-sheet {
  width: min(420px, 100%); max-height: calc(100dvh - 32px); overflow: auto;
  background: var(--card); color: var(--text); border-radius: 14px; padding: 16px;
  display: flex; flex-direction: column; gap: 10px; box-shadow: 0 10px 40px rgba(0, 0, 0, .3);
}
@media (max-width: 520px) {
  .fl-sheet-bg { align-items: flex-end; padding: 0; }
  .fl-sheet { width: 100%; border-radius: 14px 14px 0 0; padding-bottom: calc(16px + env(safe-area-inset-bottom)); }
}
.fl-sheet .fl-sh-title { font-weight: 800; font-size: 16px; }
.fl-sheet textarea {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 15px; padding: 9px 10px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--bg); color: var(--text); resize: vertical;
}
.fl-sheet .fl-add {
  display: flex; align-items: center; justify-content: center; min-height: 48px;
  border: 2px dashed var(--border); border-radius: 10px; cursor: pointer; font-weight: 700; color: var(--text);
}
.fl-sheet .fl-pics { display: flex; gap: 8px; flex-wrap: wrap; }
.fl-sheet .fl-pics:empty { display: none; }
.fl-sheet .fl-pic { position: relative; }
.fl-sheet .fl-pic img { width: 76px; height: 76px; object-fit: cover; border-radius: 8px; display: block; }
.fl-sheet .fl-pic button {
  position: absolute; top: -6px; right: -6px; width: 24px; height: 24px; border-radius: 50%;
  border: none; background: #DC2626; color: #fff; font-size: 12px; cursor: pointer; line-height: 24px; padding: 0;
}
.fl-sheet .fl-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.fl-sheet .fl-chip {
  border: 1px solid var(--border); background: var(--bg); color: var(--text); border-radius: 999px;
  padding: 6px 12px; font: inherit; font-size: 13px; cursor: pointer; min-height: 34px;
}
/* เลือกผู้รับเรื่องซ่อม (เลือกได้หลายคน) — ต้องเห็นชัดว่ากดติดหรือยัง — Boss 2026-09-26 */
.fl-sheet .fl-chip.fl-chip-on {
  border-color: #16A34A; background: #16A34A; color: #fff; font-weight: 600;
}
.fl-sheet .fl-sh-foot { display: flex; gap: 8px; justify-content: flex-end; }
.fl-sheet .fl-sh-foot .fl-btn { min-height: 42px; padding: 8px 18px; }
/* 📷 ถ่ายรูป / 🖼️ เลือกรูป — 2 ปุ่มคู่กัน ถ่ายรูปเด่นกว่า (ครัวส่วนใหญ่ถ่ายสด) */
.fl-sheet .fl-add-row { display: flex; gap: 8px; }
.fl-sheet .fl-add-row .fl-add { flex: 1 1 0; font-family: inherit; font-size: 14px; background: var(--card); }
.fl-sheet .fl-add.fl-cam { border-style: solid; border-color: #16A34A; color: #16A34A; background: rgba(22, 163, 74, .08); }

/* ===== ปุ่มสถานะ 6 แบบในแถวเครื่องมือใต้ข้อความ (พี่ปองขอ 2026-09-23) =====
   กดได้เลยไม่ต้องเปิด 🙂 / ⋯ · ขนาดเท่า .msg-tool (21px) · จางเหมือนแถวเครื่องมือ ชัดตอนชี้
   อันที่เรากด = สีเต็ม + วงแหวน box-shadow (ห้าม border ปุ่มจะขยับ) */
.mst-tools { display: inline-flex; align-items: center; gap: 1px; opacity: .45; transition: opacity .15s;
  padding-left: 5px; margin-left: 1px; border-left: 1px solid var(--border, var(--sunken)); }
.msg:hover .mst-tools, .msg.show-actions .mst-tools { opacity: 1; }
.mst-tools { flex-wrap: wrap; row-gap: 3px; gap: 3px; }
.mst-tool {
  border: none; background: none; cursor: pointer; font-size: 12px; line-height: 1;
  padding: 3px 7px 3px 5px; border-radius: 999px; min-height: 21px; white-space: nowrap;
  display: inline-flex; align-items: center; justify-content: center; gap: 3px;
  color: var(--muted); filter: grayscale(.6) opacity(.85);
}
.mst-lbl { font-size: 11px; font-weight: 600; }
.mst-tool.is-mine { color: var(--text); }
.mst-tool:hover { background: var(--sunken); filter: none; transform: scale(1.15); }
.mst-tool.is-mine { filter: none; }
.mst-tool.is-mine.st-done,
.mst-tool.is-mine.st-correct { background: color-mix(in srgb, var(--green) 20%, transparent); box-shadow: 0 0 0 2px var(--green); }
.mst-tool.is-mine.st-ack     { background: color-mix(in srgb, var(--blue) 20%, transparent);  box-shadow: 0 0 0 2px var(--blue); }
.mst-tool.is-mine.st-wip     { background: color-mix(in srgb, var(--amber) 22%, transparent); box-shadow: 0 0 0 2px var(--amber); }
.mst-tool.is-mine.st-urgent  { background: color-mix(in srgb, var(--red) 20%, transparent);   box-shadow: 0 0 0 2px var(--red); }
.mst-tool.is-mine.st-cancel  { background: var(--sunken); box-shadow: 0 0 0 2px var(--muted); }
.msg-under:has(.mst-tool.is-mine) .mst-tools { opacity: 1; }
@media (hover: none) {
  .mst-tools { opacity: 1; }
  .mst-tool { padding: 5px 8px 5px 6px; font-size: 13px; min-height: 27px; }
}
/* มือถือ: ปุ่มสถานะตกบรรทัดใหม่ใต้ 🙂↩🔖⋯ — เส้นคั่นซ้ายไม่มีความหมายแล้ว เอาออก */
@media (max-width: 700px) {
  .mst-tools { border-left: 0; padding-left: 0; margin-left: 0; }
}

/* 🔄 แถวสถานะในแผงอีโมจิ "แสดงคำด้วย" (พี่ปองสั่ง 2026-09-23) — ไอคอน + ชื่อ ตัวเล็ก
   เม็ดเตี้ย ~24px วาง 3 อันต่อแถว (แผงกว้างสุด 320px) · ⚠️ ห้าม min-height สูง/grid ยืด (บทเรียน "ใหญ่ไป") */
.react-pick .rp-row.rp-status { display: grid; grid-template-columns: repeat(3, auto); gap: 4px; justify-content: start; align-items: center; }
.react-pick .rp-st {
  display: inline-flex; align-items: center; gap: 3px; white-space: nowrap;
  font-size: 14px; padding: 3px 8px 3px 6px; border-radius: 999px; color: var(--muted);
  background: var(--sunken);
}
.react-pick .rp-st:hover { transform: none; filter: none; color: var(--text); }
.react-pick .rp-st.is-mine { color: var(--text); }
.rp-st-lbl { font-size: 11.5px; font-weight: 600; }
@media (max-width: 640px) {
  .react-pick .rp-st { padding: 4px 8px 4px 6px; }
}

/* สถานะที่มีคนตั้งแล้ว (ของใครก็ได้) = สีเต็มตามชนิด — แทนป้าย .msg-sts เดิมที่เลิกวาด (กันขึ้นซ้ำ 2026-09-23) */
.mst-tool.has { filter: none; font-weight: 700; }
.mst-tool.has.st-done, .mst-tool.has.st-correct { color: var(--green); background: color-mix(in srgb, var(--green) 14%, transparent); }
.mst-tool.has.st-ack     { color: var(--blue);  background: color-mix(in srgb, var(--blue) 14%, transparent); }
.mst-tool.has.st-wip     { color: var(--amber); background: color-mix(in srgb, var(--amber) 16%, transparent); }
.mst-tool.has.st-urgent  { color: var(--red);   background: color-mix(in srgb, var(--red) 14%, transparent); }
.mst-tool.has.st-cancel  { color: var(--muted); background: var(--sunken); }
.mst-tools:has(.mst-tool.has) { opacity: 1; }
.mst-n { font-size: 10.5px; font-weight: 800; margin-left: 1px; }

/* 🧹 แถวสถานะ 6 ปุ่มใต้ "ทุก" ข้อความ = ตาลาย (Boss 2026-09-23 14:41 แนบรูปกรอบแดง 3 แถวติดกัน)
   ⇒ ปกติโชว์ "เฉพาะสถานะที่มีคนตั้งแล้ว" (.has) + ของเรา (.is-mine) · ปุ่มที่เหลือซ่อน
     คอม: ชี้เมาส์ที่ข้อความ → โผล่ครบ 6 · มือถือ: แตะฟอง (.show-actions ตัวเดิมของแถวเครื่องมือ) → โผล่ครบ 6
   ⚠️ ต้อง "> .msg-body > .msg-under" — ไม่งั้นชี้คอมเมนต์ลูกแล้วแถวของโพสต์แม่โผล่ตาม (hover ติดบรรพบุรุษ)
   ⚠️ ซ่อนด้วย display ไม่ใช่ opacity — opacity 0 ยังกินที่ = ช่องว่างใต้ข้อความเท่าเดิม ไม่หายตาลาย */
.mst-tool:not(.has):not(.is-mine) { display: none; }
.msg:hover > .msg-body > .msg-under .mst-tool,
.msg.show-actions > .msg-body > .msg-under .mst-tool,
.mst-tools:focus-within .mst-tool { display: inline-flex; }
.mst-tools:not(:has(.mst-tool.has, .mst-tool.is-mine)) { border-left: 0; padding-left: 0; }
.msg:hover > .msg-body > .msg-under .mst-tools,
.msg.show-actions > .msg-body > .msg-under .mst-tools { border-left: 1px solid var(--border, var(--sunken)); padding-left: 5px; }
@media (max-width: 700px) {
  .msg:hover > .msg-body > .msg-under .mst-tools,
  .msg.show-actions > .msg-body > .msg-under .mst-tools { border-left: 0; padding-left: 0; }
}

/* #/gdrive: ปุ่มหลักใช้สีธีม (--v3-acc = สีเดียวกับหัวข้อหน้า/แถบข้าง) — .x10v3 .btn.primary ของ x10-ui.css ล็อกน้ำเงิน #0F4C81
   เจาะจงเฉพาะหน้านี้ ไม่แตะปุ่มทั้งแอป · ตัวหนังสือใช้ --on-brand (ธีมมืดสีหลักอ่อน → ตัวหนังสือเข้ม อ่านออก) */
.x10v3 .gd-wrap .btn.primary, .gd-wrap .btn.primary {
  background: var(--v3-acc, var(--blue)); border-color: var(--v3-acc, var(--blue)); color: var(--on-brand, #fff); }
.x10v3 .gd-wrap .btn.primary:hover, .gd-wrap .btn.primary:hover {
  background: var(--blue-dark, var(--v3-acc)); border-color: var(--blue-dark, var(--v3-acc)); color: var(--on-brand, #fff); }
.gd-wrap .gd-seg-opt input:checked + span, .gd-wrap .gd-count.on { background: var(--v3-acc, var(--blue)); }
.gd-wrap .gd-req { border-left-color: var(--v3-acc, var(--blue)); }

/* การ์ดคำขอที่เพิ่งเข้ามาแบบสด — วงสีธีมกระพริบ 3 ครั้งแล้วหยุด (ไม่ค้างรกตา) */
@keyframes gdNewPulse { 0%,100% { box-shadow: 0 0 0 0 transparent; } 50% { box-shadow: 0 0 0 3px var(--v3-acc, var(--blue)); } }
.gd-req.gd-new { animation: gdNewPulse 1s ease-in-out 3; }
@media (prefers-reduced-motion: reduce) { .gd-req.gd-new { animation: none; box-shadow: 0 0 0 2px var(--v3-acc, var(--blue)); } }

/* ↩️ อ้างอิงข้อความ (meta.quote) + 🔔 การ์ดตามซ้ำ (Boss 2026-09-23) */
.msg-reply.msg-quote { cursor: pointer; border-left: 3px solid var(--accent, #2563EB); }
.fl-card.fl-chase .fl-top { background: #DC2626; }
.fl-card.fl-chase.fl-etc .fl-top { background: #64748B; }
.fl-card .fl-quote {
  margin-top: 8px; padding: 8px 10px; border-radius: 10px; cursor: pointer;
  border-left: 4px solid var(--fl-a); background: var(--fl-a2);
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.fl-card .fl-quote:hover { filter: brightness(.97); }
.fl-card .fl-q-k { font-size: 11.5px; font-weight: 800; color: var(--fl-a); }
.fl-card .fl-q-t { font-size: 14.5px; font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fl-card.fl-chase .fl-foot .fl-btn:first-child { min-height: 44px; font-size: 14.5px; }

/* 💬 คำตอบใหม่ในรายการที่บันทึกไว้ (Boss สั่ง 2026-09-24) */
.rail-newdot { position: absolute; bottom: -3px; left: 100%; margin-left: -9px; width: 11px; height: 11px;
  border-radius: 50%; background: #2eb67d; border: 2px solid var(--rail-bg, #3f0e40); }
.later-row.lt-new { background: #eefbf4; box-shadow: inset 3px 0 0 #2eb67d; }
[data-theme="dark"] .later-row.lt-new { background: #173427; }
.lt-newrep { display: inline-flex; align-items: center; gap: 4px; margin-top: 5px; padding: 3px 9px;
  border-radius: 10px; background: #2eb67d; color: #fff; font-size: 12px; font-weight: 700; }
#lt-tabs .ntf-tab.lt-has-new { position: relative; }
#lt-tabs .ntf-tab.lt-has-new::after { content: ''; position: absolute; top: 4px; right: 4px; width: 8px; height: 8px;
  border-radius: 50%; background: #2eb67d; }

/* 📅 กรองแจ้งเตือนตามวันที่ (Boss สั่ง 2026-09-24) */
.ntf-date { display: inline-flex; align-items: center; gap: 4px; padding: 2px 6px; border: 1px solid var(--border, #ddd);
  border-radius: 8px; font-size: 13px; cursor: pointer; white-space: nowrap; }
.ntf-date input { border: 0; background: transparent; color: inherit; font: inherit; padding: 2px 0; max-width: 130px; }
.ntf-date.filtering { border-color: #1264a3; box-shadow: 0 0 0 1px #1264a3 inset; }
.ntf-date-clr { border: 0; background: none; color: inherit; cursor: pointer; padding: 0 2px; font-size: 13px; }
.ntf-date-clr[hidden] { display: none; }
/* ช่วงวันที่ (2026-10-03): ตั้งแต่ – ถึง */
.ntf-date-sep { opacity: .55; }
.ntf-date input#ntf-date-to:invalid, .ntf-date input#ntf-date-to:placeholder-shown { opacity: .75; }
@media (max-width: 860px) { .ntf-date input { max-width: 118px; } }
/* มือถือ: แถบตัวกรองไม่ตัดบรรทัด → กล่องวันที่หลุดขอบขวา (เทส 390px: ขอบกล่องไปถึง 486px)
   ⇒ ให้แถบตัดบรรทัดได้ + กล่องวันที่ลงบรรทัดใหม่เต็มความกว้าง */
@media (max-width: 860px) {
  #ntf-bar { flex-wrap: wrap; row-gap: 6px; }
  #ntf-bar .ntf-date { flex: 1 1 100%; order: 20; }
  #ntf-bar .ntf-date input { max-width: none; flex: 1 1 0; min-width: 0; }
}

/* 🍽️ การ์ดอาหารพร้อมบ้าน (meta.card='meal' · guest-service/meals · 2026-09-27)
   สีตามชนิดผ่าน --mc: ใบใหม่เขียว / แก้ไขน้ำเงิน / ยกเลิก-ไม่รับแดง / ย้ายบ้านส้ม */
.meal-card {
  margin-top: 6px; max-width: min(400px, 100%);
  border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
  background: var(--card); box-shadow: 0 1px 2px rgba(0,0,0,.05);
}
.meal-card .mc-head {
  display: flex; align-items: center; gap: 8px; padding: 9px 12px;
  background: color-mix(in srgb, var(--mc, #2563EB) 11%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--mc, #2563EB) 22%, var(--border));
}
.meal-card .mc-badge {
  flex: none; background: var(--mc, #2563EB); color: #fff; font-size: 11.5px; font-weight: 800;
  padding: 3px 8px; border-radius: 999px; white-space: nowrap; line-height: 1.4;
}
.meal-card .mc-meal { flex: 1; min-width: 0; font-weight: 700; font-size: 13.5px; color: var(--text); line-height: 1.3; }
.meal-card .mc-meal small { display: block; font-weight: 500; font-size: 12px; color: var(--muted); }
.meal-card .mc-house {
  flex: none; text-align: center; min-width: 46px; padding: 3px 9px; border-radius: 8px;
  background: var(--card); border: 1.5px solid var(--mc, #2563EB); color: var(--mc, #2563EB);
  font-size: 17px; font-weight: 800; line-height: 1.1;
}
.meal-card .mc-house small { display: block; font-size: 9.5px; font-weight: 600; opacity: .8; }
.meal-card .mc-alert {
  margin: 10px 12px 0; padding: 8px 10px; border-radius: 8px; font-size: 13.5px; line-height: 1.5;
  background: color-mix(in srgb, var(--mc, #DC2626) 10%, transparent); color: var(--text);
  border-left: 3px solid var(--mc, #DC2626);
}
.meal-card .mc-alert.mc-warn { --mc: #EA580C; }
.meal-card .mc-items { padding: 8px 12px 2px; }
.meal-card .mc-it {
  display: flex; justify-content: space-between; gap: 10px; align-items: baseline;
  padding: 5px 0; border-bottom: 1px dashed var(--border); font-size: 14px; line-height: 1.4;
}
.meal-card .mc-it:last-child { border-bottom: 0; }
.meal-card .mc-it span { min-width: 0; overflow-wrap: anywhere; color: var(--text); }
.meal-card .mc-it b { flex: none; color: var(--mc, #2563EB); font-size: 15px; }
.meal-card .mc-ab { color: var(--muted); font-size: 11px; font-style: normal; margin-left: 3px; }
.meal-card .mc-empty { padding: 10px 12px 2px; color: var(--muted); font-size: 13px; font-style: italic; }
.meal-card .mc-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 12px 0; }
.meal-card .mc-chips span {
  font-size: 12.5px; padding: 3px 9px; border-radius: 999px; line-height: 1.5;
  background: color-mix(in srgb, var(--muted) 12%, transparent); color: var(--text);
}
.meal-card .mc-note {
  margin: 8px 12px 0; padding: 7px 10px; border-radius: 8px; font-size: 13px; line-height: 1.5;
  background: color-mix(in srgb, #CA8A04 10%, transparent); color: var(--text); overflow-wrap: anywhere;
}
.meal-card .mc-foot { padding: 8px 12px 9px; color: var(--muted); font-size: 11.5px; text-align: right; }
/* เมนูเกิน 3 อย่าง (มื้อเช้าส่วนใหญ่ 5-7 อย่าง) → 2 คอลัมน์ การ์ดไม่ยาวเกินจอมือถือ */
.meal-card .mc-items.mc-2col { display: grid; grid-template-columns: 1fr 1fr; column-gap: 16px; }
.meal-card .mc-items.mc-2col .mc-it:nth-last-child(-n+2) { border-bottom: 0; }
/* 📊 การ์ดสรุปอาหารรายวัน (meta.card='meal_summary') — เช้าสีอำพัน / เย็นสีม่วง */
.meal-card.meal-sum { max-width: min(460px, 100%); }
.meal-card .ms-stats { display: flex; gap: 8px; padding: 10px 12px 0; }
.meal-card .ms-stat {
  flex: 1; text-align: center; padding: 7px 4px; border-radius: 10px;
  background: color-mix(in srgb, var(--mc) 9%, transparent);
}
.meal-card .ms-stat b { display: block; font-size: 22px; line-height: 1.1; color: var(--mc); }
.meal-card .ms-stat span { font-size: 11.5px; color: var(--muted); }
.meal-card .ms-tot b { color: var(--mc); margin-left: 2px; }
.meal-card .ms-img { padding: 10px 12px 0; }
.meal-card .ms-img .msg-image { display: block; width: 100%; max-width: 100%; max-height: none; height: auto; object-fit: contain; margin: 0; border-radius: 8px; border: 1px solid var(--border); }
.meal-card .ms-text { padding: 8px 12px 0; font-size: 13px; line-height: 1.55; white-space: pre-wrap; }
.meal-card .ms-foot { text-align: left; }
/* 🔤 ตัวย่อครัวบนการ์ดสรุปอาหารเช้า (1 ต.ค.) */
.meal-card .ms-sec { padding: 12px 12px 6px; font-size: 12.5px; font-weight: 800; color: var(--mc); }
.meal-card .ms-abs { display: grid; grid-template-columns: repeat(auto-fill, minmax(58px, 1fr)); gap: 6px; padding: 0 12px; }
.meal-card .ms-ab {
  text-align: center; padding: 6px 3px 5px; border-radius: 9px; min-width: 0;
  background: var(--card); border: 1px solid var(--border); border-top: 3px solid var(--mc);
}
.meal-card .ms-ab b { display: block; font-size: 17px; line-height: 1.15; color: var(--mc); font-weight: 900; }
.meal-card .ms-ab.ms-ab-long b { font-size: 13px; line-height: 1.5; }
.meal-card .ms-ab i { display: block; font-style: normal; font-size: 19px; font-weight: 800; color: var(--text); line-height: 1.15; }
.meal-card .ms-ab small { display: block; font-size: 9.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.meal-card .ms-ab.ms-ab-dr { border-top-color: #0891B2; }
.meal-card .ms-ab.ms-ab-dr b { color: #0891B2; }
.meal-card .ms-tbl-wrap { padding: 0 12px; }
.meal-card .ms-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.meal-card .ms-tbl th {
  text-align: left; font-size: 11px; font-weight: 700; color: var(--muted); padding: 5px 6px;
  background: color-mix(in srgb, var(--mc) 9%, transparent);
}
.meal-card .ms-tbl th:first-child { border-radius: 6px 0 0 6px; } .meal-card .ms-tbl th:last-child { border-radius: 0 6px 6px 0; }
.meal-card .ms-tbl td { padding: 5px 6px; border-bottom: 1px solid var(--border); color: var(--text); white-space: nowrap; }
.meal-card .ms-tbl td:nth-child(2), .meal-card .ms-tbl td:nth-child(3) { color: var(--muted); font-size: 12px; }
.meal-card .ms-tbl td.ms-h { font-weight: 800; }
.meal-card .ms-tbl td.ms-l { white-space: normal; font-weight: 800; color: var(--mc); letter-spacing: .2px; width: 100%; }
.meal-card .ms-tbl tr.ms-brk td { border-top: 2px solid color-mix(in srgb, var(--mc) 35%, var(--border)); }
/* ✅ ติ๊กเสิร์ฟบนการ์ดสรุป (2026-10-03) — แตะเมนู = ขีดฆ่า · ครบบ้าน = ขีดทั้งแถว */
.meal-card .ms-prog { padding: 10px 12px 0; }
.meal-card .ms-prog-t { display: flex; align-items: baseline; gap: 6px; font-size: 12.5px; color: var(--text); }
.meal-card .ms-prog-t b { color: #16A34A; font-size: 15px; }
.meal-card .ms-prog-t span { margin-left: auto; color: var(--muted); font-size: 11.5px; }
.meal-card .ms-prog-bar { height: 6px; margin-top: 5px; border-radius: 99px; background: color-mix(in srgb, var(--border) 70%, transparent); overflow: hidden; }
.meal-card .ms-prog-bar i { display: block; height: 100%; background: #16A34A; border-radius: 99px; transition: width .25s; }
.meal-card .ms-allok { margin: 10px 12px 0; padding: 9px 12px; border-radius: 10px; font-weight: 800; font-size: 14px;
  color: #15803D; background: color-mix(in srgb, #16A34A 13%, var(--card)); border: 1px solid color-mix(in srgb, #16A34A 40%, var(--border)); }
.meal-card .ms-allok small { display: block; font-weight: 500; font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.meal-card .ms-hint { font-weight: 500; color: var(--muted); font-size: 11px; margin-left: 4px; }
.meal-card .ms-tick td { vertical-align: top; padding-top: 7px; padding-bottom: 7px; }
.meal-card .ms-tick td.ms-hbtn { cursor: pointer; user-select: none; color: var(--mc); text-decoration: underline dotted; text-underline-offset: 3px; }
.meal-card .ms-cks { display: flex; flex-wrap: wrap; gap: 4px; }
.meal-card .ms-ck {
  font: inherit; font-size: 13px; font-weight: 800; line-height: 1; letter-spacing: .2px;
  min-height: 30px; min-width: 34px; padding: 6px 8px; border-radius: 8px; cursor: pointer;
  color: var(--mc); background: color-mix(in srgb, var(--mc) 9%, var(--card));
  border: 1px solid color-mix(in srgb, var(--mc) 35%, var(--border));
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.meal-card .ms-ck.ms-ro { cursor: default; display: inline-flex; align-items: center; }
.meal-card .ms-ck.on {
  color: var(--muted); background: transparent; border-style: dashed; border-color: var(--border);
  text-decoration: line-through; text-decoration-thickness: 2px; text-decoration-color: #16A34A;
}
.meal-card .ms-ck.on::before { content: '✓ '; color: #16A34A; text-decoration: none; display: inline-block; margin-right: 2px; }
.meal-card .ms-rn { margin-top: 4px; font-size: 11.5px; font-weight: 500; color: var(--muted); letter-spacing: 0; white-space: normal; }
.meal-card .ms-who { margin-top: 3px; font-size: 11px; font-weight: 600; color: #16A34A; letter-spacing: 0; }
.meal-card .ms-tick tr.ms-done td { background: color-mix(in srgb, #16A34A 7%, transparent); }
.meal-card .ms-tick tr.ms-done td:not(.ms-l), .meal-card .ms-tick tr.ms-done .ms-rn {
  text-decoration: line-through; text-decoration-thickness: 2px; text-decoration-color: #16A34A; color: var(--muted);
}
.meal-card .ms-tick tr.ms-done td.ms-hbtn { color: #16A34A; }

/* 🧾 ปุ่มบนการ์ดบิล KDS (27 ก.ย.) */
.kds-card .kds-acts { display: flex; gap: 6px; padding: 0 11px 10px; flex-wrap: wrap; }
.kds-card .kds-act { flex: 1 1 140px; min-height: 44px; border: 0; border-radius: 10px; font-weight: 800; font-size: 15px; color: #fff; cursor: pointer; }
.kds-card .kds-act-pick { background: #0284C7; }
.kds-card .kds-act-serve { background: #16A34A; }
.kds-card .kds-act:disabled { opacity: .55; cursor: default; }
/* ⏰ เตือนอัตโนมัติ + ป้ายบนการ์ดเดิม (20260927-alertjump) */
.fl-card .fl-alertbar { margin-top: 8px; padding: 6px 10px; border-radius: 8px; background: #FEF2F2; color: #B91C1C; font-size: 13px; font-weight: 700; border: 1px solid #FECACA; }
.fl-card.fl-auto .fl-top { background: #EA580C; }
.fl-card .fl-al-row { display: flex; flex-direction: row; align-items: center; gap: 8px; cursor: pointer; margin-top: 6px; }
.fl-card .fl-al-row .fl-q-t { flex: 1; min-width: 0; }
.fl-card .fl-al-row .fl-q-k { white-space: nowrap; font-weight: 700; color: #C2410C; }
@media (prefers-color-scheme: dark) { .fl-card .fl-alertbar { background: #3B1515; color: #FCA5A5; border-color: #7F1D1D; } }

/* แผนของเรา: ปุ่ม ✕ ข้างชื่อ (โหมดแก้ไขเท่านั้น) — มือถือกดได้ ไม่ใช้ hover */
table.op-grid .op-rowh .op-rowdel { margin-left: 4px; border: 0; background: #fecaca; color: #b91c1c; border-radius: 4px;
  font-size: 10px; line-height: 1; padding: 2px 4px; cursor: pointer; vertical-align: middle; }
table.op-grid .op-rowh .op-rowdel:hover { background: #ef4444; color: #fff; }

/* 🚨 การ์ดรหัสลูกค้า (customer-status → ห้อง 98) — สีหัวการ์ดตามรหัส · แถบรหัส 4 ช่อง (28 ก.ย.) */
.fl-card.fl-cc-green  { --fl-a: #16A34A; --fl-a2: rgba(22, 163, 74, .11); }
.fl-card.fl-cc-blue   { --fl-a: #2563EB; --fl-a2: rgba(37, 99, 235, .11); }
.fl-card.fl-cc-orange { --fl-a: #EA580C; --fl-a2: rgba(234, 88, 12, .12); }
.fl-card.fl-cc-red    { --fl-a: #DC2626; --fl-a2: rgba(220, 38, 38, .11); }
.fl-card.fl-cc .fl-btn.fl-go { background: var(--fl-a); border-color: var(--fl-a); color: #fff; }
.fl-card.fl-cc .fl-foot .fl-btn { text-align: center; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; }
.fl-card .cc-scale { display: flex; gap: 4px; margin-bottom: 8px; }
.fl-card .cc-seg {
  flex: 1 1 0; min-width: 0; text-align: center; font-size: 11.5px; font-weight: 700; padding: 4px 2px; border-radius: 8px;
  color: var(--muted); background: var(--bg); border: 1px solid var(--border); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: .55;
}
.fl-card .cc-seg.was { opacity: .9; border-style: dashed; border-width: 1.5px; }
.fl-card .cc-seg.on { opacity: 1; color: #fff; border-color: transparent; font-weight: 800; box-shadow: 0 1px 4px rgba(0,0,0,.18); }
.fl-card .cc-s-green.on { background: #16A34A; } .fl-card .cc-s-blue.on { background: #2563EB; }
.fl-card .cc-s-orange.on { background: #EA580C; } .fl-card .cc-s-red.on { background: #DC2626; }
.fl-card .cc-move { font-size: 12.5px; }
.fl-card .cc-room { display: inline-block; margin-left: 4px; padding: 0 8px; border-radius: 999px; background: var(--fl-a2); color: var(--fl-a); font-size: 14px; font-weight: 800; vertical-align: 2px; }
.fl-card .cc-sec { margin-top: 10px; font-size: 12px; font-weight: 800; color: var(--fl-a); }
.fl-card .cc-sec + .fl-detail { margin-top: 3px; }
.fl-card .cc-act { background: var(--bg); border: 1px solid var(--border); }
.fl-card .cc-sub { margin-top: 5px; font-size: 13.5px; }
.fl-card .cc-comp { margin-top: 10px; padding: 8px 11px; border-radius: 10px; border: 1px dashed #A21CAF; background: rgba(162, 28, 175, .07); font-size: 14px; line-height: 1.5; word-break: break-word; }
.fl-card .cc-amt { font-weight: 800; color: #A21CAF; }
.fl-card .cc-wait { font-size: 11.5px; color: var(--muted); }
.fl-card .fl-chip-i.cc-warn { color: #B91C1C; border-color: rgba(220, 38, 38, .45); font-weight: 700; }
/* 🗂 ปุ่มเลื่อนขั้นเคสบนการ์ดรหัสลูกค้า (ผูกต้นฉบับ customer-status) */
.fl-card .cc-upd { margin: 0 12px 10px; padding: 8px 11px; border-radius: 10px; background: var(--fl-a2); font-size: 13px; line-height: 1.5; }
.fl-card .cc-upd-h b { color: var(--fl-a); }
.fl-card .cc-upd-n { margin-top: 3px; white-space: pre-wrap; word-break: break-word; }
.fl-card .cc-log { margin-top: 6px; font-size: 12.5px; }
.fl-card .cc-log summary { cursor: pointer; color: var(--muted); font-weight: 700; }
.fl-card .cc-log-r { padding: 5px 0; border-top: 1px dashed var(--border); display: flex; flex-wrap: wrap; gap: 2px 8px; }
.fl-card .cc-log-r > span:first-child { font-weight: 800; }
.fl-card .cc-log-w { color: var(--muted); }
.fl-card .cc-log-n { flex-basis: 100%; white-space: pre-wrap; word-break: break-word; }
.fl-card .cc-links { display: flex; gap: 8px; padding: 0 12px 12px; background: var(--bg); }
.fl-card .cc-foot + .cc-links { margin-top: -4px; }
.fl-card .cc-link { flex: 1 1 0; text-align: center; font-size: 13.5px; font-weight: 700; color: var(--fl-a); text-decoration: none; padding: 8px 6px; border-radius: 10px; border: 1px solid var(--border); background: var(--card); }
.fl-sheet .cc-pick { display: flex; flex-direction: column; gap: 6px; }
.fl-sheet .cc-opt { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 10px; border: 1.5px solid var(--border); background: var(--card); color: var(--text); font-size: 15px; font-weight: 700; text-align: left; cursor: pointer; }
.fl-sheet .cc-opt small { margin-left: auto; font-size: 11.5px; color: var(--muted); font-weight: 600; }
.fl-sheet .cc-opt-n { width: 24px; height: 24px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; background: var(--bg); border: 1px solid var(--border); font-size: 12.5px; }
.fl-sheet .cc-opt.on { border-color: #DC2626; background: rgba(220, 38, 38, .08); }
.fl-sheet .cc-opt.on .cc-opt-n { background: #DC2626; color: #fff; border-color: #DC2626; }
/* ✋ คนรับเคส + การ์ดย้ำเตือน (28 ก.ย.) */
.fl-card .cc-own { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 12px 10px; padding: 8px 10px; border-radius: 10px; border: 1px dashed var(--border); }
.fl-card .cc-own-k { font-size: 12px; font-weight: 800; color: var(--fl-a); }
.fl-card .cc-own-n { font-size: 13px; font-weight: 700; padding: 1px 9px; border-radius: 999px; background: var(--fl-a2); }
.fl-card .cc-own-none { font-size: 13px; color: var(--muted); }
.fl-card .cc-claim { margin-left: auto; padding: 5px 12px; border-radius: 999px; border: 1.5px solid var(--fl-a); background: var(--card); color: var(--fl-a); font-weight: 800; font-size: 13px; cursor: pointer; }
.fl-card .cc-rm-ask { margin-top: 8px; font-size: 14px; line-height: 1.5; }
.fl-card .cc-rm-ask b { color: var(--fl-a); }
.fl-card .cc-rm-none { color: #B45309; font-weight: 700; }
.fl-sheet textarea.cc-req { border-color: #DC2626; }
.fl-sheet .cc-req-hint { color: #B91C1C; font-weight: 700; }
.fl-sheet .cc-actor-l { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; font-weight: 700; color: var(--muted); }
.fl-sheet .cc-actor-l input { font-size: 15px; padding: 9px 11px; border-radius: 10px; border: 1px solid var(--border); background: var(--card); color: var(--text); }
/* 🎨 การ์ดช่าง: สีทั้งใบตามสถานะ + 🚨 เร่งด่วนพิเศษ (28 ก.ย.) */
.fl-card.rp-st-new              { --fl-a: #D97706; --fl-a2: rgba(217, 119, 6, .12); }
.fl-card.rp-st-in_progress      { --fl-a: #2563EB; --fl-a2: rgba(37, 99, 235, .11); }
.fl-card.rp-st-done             { --fl-a: #16A34A; --fl-a2: rgba(22, 163, 74, .11); }
.fl-card.rp-st-pending_approval { --fl-a: #7C3AED; --fl-a2: rgba(124, 58, 237, .11); }
.fl-card.rp-st-cancel           { --fl-a: #64748B; --fl-a2: rgba(100, 116, 139, .12); }   /* 🚫 งาน TaskFlow ยกเลิก */
.fl-card.tf-st-card .tf-st-title { font-size: 14px; font-weight: 600; line-height: 1.5; max-height: 12em; overflow: auto; }
.fl-card.rp-crit { --fl-a: #DC2626; --fl-a2: rgba(220, 38, 38, .12); border: 2px solid #DC2626; animation: rp-crit-pulse 1.6s ease-in-out infinite; }
.fl-card.rp-card .fl-btn.fl-go { background: var(--fl-a); border-color: var(--fl-a); color: #fff; }
.fl-card .rp-crit-bar { padding: 8px 12px; background: #FEE2E2; color: #991B1B; font-weight: 800; font-size: 14.5px; line-height: 1.4; border-bottom: 1px solid rgba(220, 38, 38, .35); }
.fl-card .rp-crit-bar small { display: block; font-size: 12px; font-weight: 700; opacity: .85; }
:root[data-theme="dark"] .fl-card .rp-crit-bar { background: rgba(220, 38, 38, .22); color: #FCA5A5; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .fl-card .rp-crit-bar { background: rgba(220, 38, 38, .22); color: #FCA5A5; } }
@keyframes rp-crit-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, .45); } 50% { box-shadow: 0 0 0 6px rgba(220, 38, 38, 0); } }
@media (prefers-reduced-motion: reduce) { .fl-card.rp-crit { animation: none; } }

/* ---- อนุมัติทีละหลายใบ (Boss 2026-09-30) ----
   ช่องติ๊กอยู่คอลัมน์ 38px เดียวกับอวาตาร์ · เป้าแตะ ≥40px บนมือถือ */
.ap-ck { grid-column: 1; display: flex; align-items: center; justify-content: center; min-height: 40px; cursor: pointer; }
.ap-ck input, .ap-bulk-all input { width: 20px; height: 20px; cursor: pointer; accent-color: var(--blue, #1264a3); }
.ap-row-ck > .ap-main { grid-column: 2; }
.ap-row.ap-picked { background: rgba(18,100,163,.07); }
.ap-row.ap-done { opacity: .45; }
.ap-bulk {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  padding: 8px 14px; border-bottom: 1px solid var(--v3-bd, #e3e8ee);
  position: sticky; top: 0; z-index: 2; background: var(--card, #fff);
}
.ap-bulk-all { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; cursor: pointer; min-height: 40px; }
@media (max-width: 560px) {
  .ap-row-ck > .ap-main { grid-column: 2 / -1; }
  .ap-row-ck > .ap-act { grid-column: 2 / -1; }
}

/* ✏️ การ์ดอัปเดตใบเบิก (disburse_edit) — เดิม ขีดฆ่าจาง · ใหม่ ตัวหนาสีห้อง */
.fl-card.ds-edit .ds-edit-old { color: var(--muted, #888); font-weight: 400; }
.fl-card.ds-edit .ds-edit-arrow { color: var(--fl-a); font-weight: 700; margin: 0 2px; }
.fl-card.ds-edit .ds-edit-new { color: var(--fl-a); font-weight: 800; }
.fl-card.ds-edit .fl-acc-k { min-width: 84px; }

/* แผนของเรา · แท็บ 3 กำลังพลแม่บ้าน (2026-10-01) — ดูอย่างเดียว */
table.op-hk td.op-cell { vertical-align: top; min-width: 150px; cursor: default; }
.op-hk-slot { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; margin: 2px 0; }
.op-hk-time { font-size: 11px; font-weight: 600; color: var(--muted, #64748b); margin-right: 4px; min-width: 34px; }
table.op-hk .op-chip { cursor: pointer; }
.op-hk-nocode { outline: 1px dashed var(--red); }
table.op-hk td.op-hk-offcell { min-width: 110px; opacity: .85; }
/* 📊 การ์ดสรุปตามของ/อาหารรายกะ (meta.card='follow_summary' + กราฟตอบใต้โพสต์ follow_summary_chart · 1 ต.ค.)
   ใช้โครง .meal-card · กะเช้าสีเขียวอมฟ้า / กะเย็นสีคราม */
.meal-card.fs-card { --mc: #0D9488; }
.meal-card.fs-card.fs-pm { --mc: #4F46E5; }
.meal-card .fs-total { padding: 10px 12px 0; font-size: 13px; color: var(--muted); display: flex; align-items: baseline; gap: 6px; }
.meal-card .fs-total b { font-size: 24px; line-height: 1; color: var(--text); }
.meal-card .fs-pct { margin-left: auto; font-weight: 700; color: #16A34A; font-size: 12.5px; }
.meal-card .fs-bar { display: flex; gap: 2px; height: 8px; margin: 8px 12px 0; border-radius: 99px; overflow: hidden; background: color-mix(in srgb, var(--muted) 15%, transparent); }
.meal-card .fs-bar i { display: block; min-width: 6px; }
.meal-card .fs-stats { gap: 6px; }
.meal-card .fs-stats .ms-stat { padding: 6px 2px; }
.meal-card .fs-stats .ms-stat b { font-size: 20px; }
.meal-card .fs-stats .ms-stat span { font-size: 11px; white-space: nowrap; }
.meal-card .fs-stats .fs-zero { opacity: .45; }
.meal-card .fs-list { padding: 0 12px; }
.meal-card .fs-row {
  display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px; margin-bottom: 6px; border-radius: 9px;
  background: color-mix(in srgb, var(--mc) 7%, transparent); border-left: 3px solid var(--mc);
}
.meal-card .fs-row[onclick] { cursor: pointer; }
.meal-card .fs-row[onclick]:hover { background: color-mix(in srgb, var(--mc) 13%, transparent); }
.meal-card .fs-dot { flex: none; font-size: 13px; line-height: 1.5; }
.meal-card .fs-mid { flex: 1; min-width: 0; }
.meal-card .fs-t { font-weight: 700; font-size: 14px; line-height: 1.4; color: var(--text); overflow-wrap: anywhere; }
.meal-card .fs-t i { font-style: normal; color: var(--muted); font-weight: 600; }
.meal-card .fs-sub { font-size: 12px; color: var(--muted); line-height: 1.45; margin-top: 1px; overflow-wrap: anywhere; }
.meal-card .fs-st { color: var(--mc); font-weight: 700; }
.meal-card .fs-why { font-size: 12.5px; margin-top: 3px; color: var(--text); }
.meal-card .fs-min { flex: none; text-align: right; font-weight: 800; font-size: 15px; color: var(--mc); line-height: 1.2; white-space: nowrap; }
.meal-card .fs-min small { display: block; font-size: 10px; font-weight: 600; color: var(--muted); }
.meal-card .fs-alldone { padding: 10px 12px 0; font-size: 13.5px; color: #16A34A; font-weight: 700; }
.meal-card .fs-avg { padding: 10px 12px 0; font-size: 13px; color: var(--muted); }
.meal-card .fs-avg b { font-size: 18px; color: var(--mc); }

/* ---- รายการอุปกรณ์พับได้ในการ์ดอนุมัติ (พี่ปอง 2026-10-02) ---- */
.ap-lines { margin-top: 6px; border: 1px solid var(--line, rgba(0,0,0,.1)); border-radius: 8px; font-size: 12.5px; }
.ap-lines > summary { cursor: pointer; padding: 6px 9px; font-weight: 600; list-style: none; user-select: none; }
.ap-lines > summary::-webkit-details-marker { display: none; }
.ap-lines > summary::after { content: '▾'; float: right; color: var(--muted); }
.ap-lines[open] > summary::after { content: '▴'; }
.ap-ln { display: grid; grid-template-columns: 1fr auto auto; gap: 8px; padding: 5px 9px; border-top: 1px solid var(--line, rgba(0,0,0,.08)); }
.ap-ln-n { overflow-wrap: anywhere; } .ap-ln-n small { color: var(--muted); }
.ap-ln-q, .ap-ln-t { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ap-ln-t { min-width: 56px; }

/* ===== ปุ่มจัดการบนการ์ดแจ้งบัค (ห้อง 50) — pong สั่ง 2026-10-02: เปลี่ยนสถานะ/แก้ไข/มอบงาน/ตามงาน ทรงเดียวกับป้ายใต้การ์ดรีวิว ===== */
.bug-act { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 2px; }
.bug-btn { border: 1px solid var(--border); background: var(--card); color: var(--text); border-radius: 999px;
  font: inherit; font-size: 12px; font-weight: 600; padding: 5px 12px; min-height: 30px; cursor: pointer; white-space: nowrap; }
.bug-btn:hover { background: var(--sunken); }
.bug-btn:active { transform: scale(.97); }
@media (max-width: 700px) { .bug-btn { font-size: 13px; min-height: 36px; padding: 6px 13px; } }
.fl-sheet .bug-stlist { display: flex; flex-direction: column; gap: 8px; }
.fl-sheet .bug-stlist .fl-btn { min-height: 44px; text-align: left; }

/* ลากห้องมาวางบนห้องที่เปิดอยู่ = เปิดเป็นช่องข้าง ๆ (2026-10-03) — ดู paneOpenBeside() ใน app.js */
.pane2 { position: relative; }
.chat-room.room-drop::after, .pane2.room-drop::after {
  content: attr(data-drop-msg);
  position: absolute; inset: 6px; z-index: 50; pointer-events: none;
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 16px; font-size: 16px; font-weight: 600; color: var(--blue, #0F4C81);
  border: 3px dashed var(--blue, #0F4C81); border-radius: 12px;
  background: color-mix(in srgb, var(--blue, #0F4C81) 10%, transparent);
}

/* ลากสลับตำแหน่งช่องแชทแบบแท็บเบราว์เซอร์ (2026-10-03) — ดู paneMove() ใน app.js */
#panes .pane-head[draggable="true"], #chat-room > .chat-head[draggable="true"] { cursor: grab; }
#panes .pane-head[draggable="true"]:active, #chat-room > .chat-head[draggable="true"]:active { cursor: grabbing; }
.chat-room.pane-dragging, .pane2.pane-dragging { opacity: .55; }
.chat-room.pane-ins-l::before, .pane2.pane-ins-l::before,
.chat-room.pane-ins-r::before, .pane2.pane-ins-r::before {
  content: ''; position: absolute; top: 0; bottom: 0; width: 4px; z-index: 51; pointer-events: none;
  background: var(--blue, #0F4C81); border-radius: 2px;
}
.chat-room.pane-ins-l::before, .pane2.pane-ins-l::before { left: 0; }
.chat-room.pane-ins-r::before, .pane2.pane-ins-r::before { right: 0; }

/* 🧪 ทดลอง (?fx=1): ลากช่องไปวางบนอีกช่อง = สลับที่ — ไฮไลต์ทั้งช่องปลายทาง */
.chat-room.pane-swap::before, .pane2.pane-swap::before {
  content: ''; position: absolute; inset: 4px; z-index: 51; pointer-events: none;
  border: 3px dashed var(--blue, #0F4C81); border-radius: 10px;
  background: color-mix(in srgb, var(--blue, #0F4C81) 8%, transparent);
}
/* 🔗 ปุ่มไปหน้าต้นฉบับบนการ์ดสรุปอาหาร (2026-10-03) */
.meal-card .ms-links { display: flex; gap: 6px; padding: 10px 12px 0; flex-wrap: wrap; }
.meal-card .ms-link {
  flex: 1 1 140px; text-align: center; padding: 8px 10px; border-radius: 9px; font-size: 13px; font-weight: 700;
  text-decoration: none; color: var(--mc); background: color-mix(in srgb, var(--mc) 9%, var(--card));
  border: 1px solid color-mix(in srgb, var(--mc) 35%, var(--border));
}
.meal-card .ms-link:hover { background: color-mix(in srgb, var(--mc) 16%, var(--card)); }
