/* กฎที่ v3 ไม่มี แต่แอปจริงต้องใช้ — โหลดหลัง v3.css เท่านั้น
   ห้ามแก้ v3.css (ต้องเท่าต้นฉบับไบต์ต่อไบต์เสมอ) */

/* ── ธีม "auto" ──────────────────────────────────────────────────────────────
   v3.css รู้จักแค่ค่าเริ่มต้น (มืด) กับ `[data-theme="light"]` — ไม่มี
   `prefers-color-scheme` อยู่ในไฟล์เลย (เกรปแล้ว: เจอ `data-theme` บรรทัดเดียว
   คือบรรทัด 49). แต่ index.html ตั้ง `data-theme="auto"` เป็นค่าตั้งต้น และ
   main.js เขียนค่า "auto" ลง localStorage ได้ ⇒ ผู้ใช้ที่เครื่องเป็นโหมดสว่าง
   และไม่เคยกดสลับเอง จะโดนโหมดมืดตลอด. บล็อกนี้ทำให้ "auto" แปลว่า auto จริง
   โดยสำเนาค่าโทเคนชุดสว่างจาก v3.css บรรทัด 49–65 มาตรง ๆ (ห้ามแก้ที่นั่น) —
   ค่าใดเปลี่ยนที่ต้นฉบับ ต้องตามมาแก้ที่นี่ด้วย. */
@media (prefers-color-scheme: light) {
  [data-theme="auto"] {
    color-scheme: light;
    --bg-app: #FFFFFF;
    --bg-card: #FFFFFF;
    --bg-card-hover: #F8FAFC;
    --bg-input: #F8FAFC;
    --bg-input-focus: #F1F5F9;
    --bg-rail: #FFFFFF;
    --bg-header: rgba(255, 255, 255, 0.96);
    --border: rgba(0, 0, 0, 0.08);
    --border-strong: rgba(0, 0, 0, 0.14);
    --text-main: #0F172A;
    --text-muted: #475569;
    --text-dim: #64748B;
    --card-shadow: 0 4px 20px -2px rgba(0, 0, 0, 0.06), 0 0 1px rgba(0, 0, 0, 0.1);
    --modal-shadow: 0 20px 60px -10px rgba(0, 0, 0, 0.25);
  }
  /* v3's scrollbar thumb is white-on-dark; invisible on a white page. */
  [data-theme="auto"] ::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.18); }
  [data-theme="auto"] ::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.32); }
}
[data-theme="light"] ::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.18); }
[data-theme="light"] ::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.32); }

/* ── โครงหน้า ───────────────────────────────────────────────────────────────
   v3 วาง `.app-shell` เป็นลูกของ <body> ตรง ๆ ส่วนที่นี่มี `#root` คั่นอยู่.
   `#root` ไม่ใช่ต้นเหตุของตะแกรงพัง — `.app-shell` เป็น `display:grid` ในตัวเอง
   จึงสร้างคอนเทกซ์ของมันเองไม่ว่าพ่อจะเป็นอะไร และ `max-width` + `margin:0 auto`
   ทำงานในบล็อกธรรมดาอยู่แล้ว. บรรทัดนี้มีไว้กันเรื่องเดียว: `#root` สูงไม่เต็มจอ
   เมื่อเนื้อหาสั้น. ห้ามใช้ `display: contents` ที่นี่ — `#root` มี `hidden` อยู่
   ตอนบูต และ `display` ของผู้เขียนชนะ `[hidden]` ของเบราว์เซอร์ ⇒ จะเห็นเชลล์
   โผล่ก่อนเวลา. */
#root { min-height: 100%; }

/* ── หน้าบูต / toast / dialog ───────────────────────────────────────────────
   ทั้งสามอย่างเคยอยู่ใน app.css ที่ถูกตัดทิ้ง และ v3.css ไม่มีคลาสพวกนี้เลย
   (ไม่มีแม้แต่ `.btn`) ⇒ ถ้าไม่เขียนที่นี่ หน้าจอบูตจะเป็นข้อความลอย ๆ มุมซ้ายบน
   และกล่องยืนยัน "ออกจากระบบ" จะไหลไปต่อท้ายหน้าแทนที่จะทับหน้าจอ. */
.boot { min-height: 100dvh; display: grid; place-items: center; align-content: center; gap: 20px; }
.boot-mark { width: 54px; height: 54px; border-radius: 14px;
  background: url("/logo.png") center / cover no-repeat, var(--brand-gradient);
  box-shadow: var(--brand-glow); animation: koratBootPulse 1.4s ease-in-out infinite; }
.boot-text { color: var(--text-dim); font-size: 14px; margin: 0; }
@keyframes koratBootPulse { 0%, 100% { opacity: .45; transform: scale(.94); } 50% { opacity: 1; transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .boot-mark { animation: none; } }

.toast-host {
  position: fixed; inset-inline: 0; bottom: calc(80px + env(safe-area-inset-bottom, 0px));
  z-index: 9998; display: flex; flex-direction: column; align-items: center; gap: 6px;
  pointer-events: none; padding: 0 16px;
}
.toast {
  max-width: 420px; padding: 10px 16px; border-radius: var(--radius-md); font-size: 14px;
  background: var(--bg-card-hover); color: var(--text-main); border: 1px solid var(--border-strong);
  box-shadow: var(--modal-shadow); word-break: break-word; backdrop-filter: blur(16px);
}
/* สีสถานะเป็นค่าคงที่ ไม่ผูกกับ accent */
.toast.bad { border-color: #EF4444; }
.toast.good { border-color: #22C55E; }
.toast.warn { border-color: #F59E0B; }

/* ==========================================================================
   Korat Frosted Glass & Translucent Modals (Glassmorphism Next-Gen)
   ========================================================================== */

/* ── 1. Backdrop / Scrim Overlays ── */
.scrim,
.sheet-scrim,
.compose-scrim,
.sheetwrap,
.mobile-drawer-overlay,
.call-modal-scrim,
[data-console="business"] .scrim,
.bz-backdrop {
  position: fixed; inset: 0; z-index: 9990; display: grid; place-items: center; padding: 24px;
  background: rgba(4, 5, 12, 0.58) !important;
  backdrop-filter: blur(16px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(16px) saturate(140%) !important;
}
[data-theme="light"] .scrim,
[data-theme="light"] .sheet-scrim,
[data-theme="light"] .compose-scrim,
[data-theme="light"] .sheetwrap,
[data-theme="light"] .mobile-drawer-overlay,
.theme-light .scrim,
.theme-light .sheet-scrim,
.theme-light .compose-scrim,
.theme-light .sheetwrap,
.theme-light .mobile-drawer-overlay {
  background: rgba(15, 23, 42, 0.28) !important;
  backdrop-filter: blur(20px) saturate(150%) !important;
  -webkit-backdrop-filter: blur(20px) saturate(150%) !important;
}
@media (prefers-color-scheme: light) {
  [data-theme="auto"] .scrim,
  [data-theme="auto"] .sheet-scrim,
  [data-theme="auto"] .compose-scrim,
  [data-theme="auto"] .sheetwrap,
  [data-theme="auto"] .mobile-drawer-overlay {
    background: rgba(15, 23, 42, 0.28) !important;
    backdrop-filter: blur(20px) saturate(150%) !important;
    -webkit-backdrop-filter: blur(20px) saturate(150%) !important;
  }
}

.lightbox-modal,
.story-modal {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(4, 5, 12, 0.72) !important;
  backdrop-filter: blur(24px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(24px) saturate(140%) !important;
  display: none; place-items: center; padding: 16px;
}
.lightbox-modal.open,
.story-modal.open {
  display: grid !important;
}

/* ── 2. Modal Surfaces & Cards (Frosted Glass Translucency) ── */
.dialog,
.sheet-modal,
.sheet,
.compose-modal-content,
.story-dialog,
.story-studio-modal,
.story-viewers-sheet,
.quick-chat-popup,
.mobile-drawer,
.lightbox-shell,
.lightbox-side,
.plan-sheet .sheet-modal,
.receipt-sheet .sheet-modal,
.compose-scrim .sheet-modal,
[data-console="business"] .dialog,
[data-console="business"] .sheet {
  background: rgba(13, 14, 28, 0.78) !important;
  backdrop-filter: blur(28px) saturate(190%) !important;
  -webkit-backdrop-filter: blur(28px) saturate(190%) !important;
  border: 1px solid rgba(255, 255, 255, 0.12) !important;
  box-shadow: 0 24px 64px -8px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(255, 255, 255, 0.06) !important;
  color: var(--text-main);
}

[data-theme="light"] .dialog,
[data-theme="light"] .sheet-modal,
[data-theme="light"] .sheet,
[data-theme="light"] .compose-modal-content,
[data-theme="light"] .story-dialog,
[data-theme="light"] .story-studio-modal,
[data-theme="light"] .story-viewers-sheet,
[data-theme="light"] .quick-chat-popup,
[data-theme="light"] .mobile-drawer,
[data-theme="light"] .lightbox-shell,
[data-theme="light"] .lightbox-side,
[data-theme="light"] .plan-sheet .sheet-modal,
[data-theme="light"] .receipt-sheet .sheet-modal,
[data-theme="light"] .compose-scrim .sheet-modal,
.theme-light .dialog,
.theme-light .sheet-modal,
.theme-light .sheet,
.theme-light .compose-modal-content,
.theme-light .story-dialog,
.theme-light .story-studio-modal,
.theme-light .story-viewers-sheet,
.theme-light .quick-chat-popup,
.theme-light .mobile-drawer,
.theme-light .lightbox-shell,
.theme-light .lightbox-side,
.theme-light .plan-sheet .sheet-modal,
.theme-light .receipt-sheet .sheet-modal,
.theme-light .compose-scrim .sheet-modal,
[data-theme="light"] [data-console="business"] .dialog,
[data-theme="light"] [data-console="business"] .sheet {
  background: rgba(255, 255, 255, 0.72) !important;
  backdrop-filter: blur(32px) saturate(190%) !important;
  -webkit-backdrop-filter: blur(32px) saturate(190%) !important;
  border: 1px solid rgba(255, 255, 255, 0.85) !important;
  box-shadow: 0 24px 64px -12px rgba(15, 23, 42, 0.18), 0 0 0 1px rgba(0, 0, 0, 0.05), inset 0 1px 1.5px rgba(255, 255, 255, 0.95), inset 0 -1px 0 rgba(0, 0, 0, 0.04) !important;
  color: var(--text-main, #0F172A) !important;
}

@media (prefers-color-scheme: light) {
  [data-theme="auto"] .dialog,
  [data-theme="auto"] .sheet-modal,
  [data-theme="auto"] .sheet,
  [data-theme="auto"] .compose-modal-content,
  [data-theme="auto"] .story-dialog,
  [data-theme="auto"] .story-studio-modal,
  [data-theme="auto"] .story-viewers-sheet,
  [data-theme="auto"] .quick-chat-popup,
  [data-theme="auto"] .mobile-drawer,
  [data-theme="auto"] .lightbox-shell,
  [data-theme="auto"] .lightbox-side,
  [data-theme="auto"] .plan-sheet .sheet-modal,
  [data-theme="auto"] .receipt-sheet .sheet-modal,
  [data-theme="auto"] .compose-scrim .sheet-modal,
  [data-theme="auto"] [data-console="business"] .dialog,
  [data-theme="auto"] [data-console="business"] .sheet {
    background: rgba(255, 255, 255, 0.72) !important;
    backdrop-filter: blur(32px) saturate(190%) !important;
    -webkit-backdrop-filter: blur(32px) saturate(190%) !important;
    border: 1px solid rgba(255, 255, 255, 0.85) !important;
    box-shadow: 0 24px 64px -12px rgba(15, 23, 42, 0.18), 0 0 0 1px rgba(0, 0, 0, 0.05), inset 0 1px 1.5px rgba(255, 255, 255, 0.95), inset 0 -1px 0 rgba(0, 0, 0, 0.04) !important;
    color: var(--text-main, #0F172A) !important;
  }
}

/* Modal inner container transparency (prevents opaque solid boxes from covering the glass) */
.sheet-modal > .sheet-body,
.sheet-modal > .sheet-header,
.compose-scrim .composer-card.in-modal,
.compose-scrim .composer-card,
.sheet-modal .plan-detail-view,
.sheet-modal .plan-detail-scroll,
.sheet-modal .repost-sheet-content,
.sheet-modal .k3-body,
.sheet-modal .composer-top,
.sheet-modal .composer-bottom,
.dialog form,
.dialog .row,
.dialog .actions {
  background: transparent !important;
}

[data-theme="light"] .sheet-modal .sheet-header {
  border-bottom: 1px solid rgba(0, 0, 0, 0.06) !important;
}
[data-theme="light"] .sheet-modal .sheet-close {
  background: rgba(0, 0, 0, 0.04) !important;
  color: var(--text-muted, #64748B) !important;
  border-radius: 50% !important;
}
[data-theme="light"] .sheet-modal .sheet-close:hover {
  background: rgba(0, 0, 0, 0.08) !important;
  color: var(--text-main, #0F172A) !important;
}

.dialog {
  width: 100%; max-width: 380px; border-radius: var(--radius-lg); padding: 20px;
  max-height: 86vh; overflow-y: auto;
}
.dialog h3 { margin: 0 0 8px; font-size: 17px; font-weight: 700; text-align: start; }
.dialog p { margin: 0 0 10px; font-size: 14px; color: var(--text-muted); text-align: start; }
.dialog .keeps { font-size: 13px; color: var(--text-dim); margin-bottom: 16px; }
.dialog .row, .dialog .actions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }

/* ── 3. Floating Popovers & Menus (Glassmorphism) ── */
.menu,
.picker-menu,
.msg-more-menu,
.lang-menu,
.toast {
  background: rgba(14, 16, 32, 0.82) !important;
  backdrop-filter: blur(24px) saturate(190%) !important;
  -webkit-backdrop-filter: blur(24px) saturate(190%) !important;
  border: 1px solid rgba(255, 255, 255, 0.12) !important;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55) !important;
}
[data-theme="light"] .menu,
[data-theme="light"] .picker-menu,
[data-theme="light"] .msg-more-menu,
[data-theme="light"] .lang-menu,
[data-theme="light"] .toast,
.theme-light .menu,
.theme-light .picker-menu,
.theme-light .msg-more-menu,
.theme-light .lang-menu,
.theme-light .toast {
  background: rgba(255, 255, 255, 0.78) !important;
  backdrop-filter: blur(28px) saturate(190%) !important;
  -webkit-backdrop-filter: blur(28px) saturate(190%) !important;
  border: 1px solid rgba(255, 255, 255, 0.85) !important;
  box-shadow: 0 16px 40px -8px rgba(15, 23, 42, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.05), inset 0 1px 1px rgba(255, 255, 255, 0.9) !important;
  color: var(--text-main) !important;
}

@media (prefers-color-scheme: light) {
  [data-theme="auto"] .menu,
  [data-theme="auto"] .picker-menu,
  [data-theme="auto"] .msg-more-menu,
  [data-theme="auto"] .lang-menu,
  [data-theme="auto"] .toast {
    background: rgba(255, 255, 255, 0.78) !important;
    backdrop-filter: blur(28px) saturate(190%) !important;
    -webkit-backdrop-filter: blur(28px) saturate(190%) !important;
    border: 1px solid rgba(255, 255, 255, 0.85) !important;
    box-shadow: 0 16px 40px -8px rgba(15, 23, 42, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.05), inset 0 1px 1px rgba(255, 255, 255, 0.9) !important;
    color: var(--text-main) !important;
  }
}

.btn {
  padding: 9px 16px; border-radius: var(--radius-pill); font-size: 14px; font-weight: 600;
  background: var(--bg-input); color: var(--text-main); border: 1px solid var(--border);
}
.btn:hover { background: var(--bg-input-focus); }
.btn.primary { background: var(--brand-gradient); color: #FFF; border-color: transparent; }
.btn.danger { background: #EF4444; color: #FFF; border-color: transparent; }
.btn[disabled] { opacity: .5; cursor: default; }

/* ── Avatar Initial Fallback (เมื่อไม่มีรูปโปรไฟล์) ── */
.av {
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, rgba(139, 61, 255, 0.12), rgba(255, 59, 136, 0.12));
  color: var(--accent-purple);
  border: 1px solid var(--border);
  font-weight: 700;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  overflow: hidden;
}
.av img { width: 100%; height: 100%; object-fit: cover; }
.composer-top > .av { width: 36px; height: 36px; }
.comment-item > .av, .comment-input-row > .av { width: 34px; height: 34px; font-size: 13px; }

/* ── Character Count Helper ── */
.charcount { font-size: 11px; color: var(--text-dim); text-align: right; padding: 2px 6px; }
.charcount[hidden] { display: none !important; }
.chat-lenwarn { font-size: 11px; color: var(--text-dim); margin: 2px 14px; text-align: right; }
.chat-lenwarn.bad { color: #EF4444; font-weight: 700; }

/* ── ซ่อน Floating Quick-Chat เมื่ออยู่ในหน้าแชทหลัก ── */
.app-shell[data-route="chat"] ~ [data-dock],
.app-shell[data-route="mchat"] ~ [data-dock],
.app-shell[data-route="chat"] .quick-chat-popup,
.app-shell[data-route="mchat"] .quick-chat-popup,
[data-route="chat"] .dock, [data-route="mchat"] .dock {
  display: none !important;
}

/* ── Call cards inside chat bubbles ── */
.att-card {
  display: flex; align-items: center; gap: 8px; padding: 8px 12px; margin-top: 6px;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--bg-input); color: inherit; text-decoration: none; white-space: normal;
}
.att-card small { display: block; font-size: 11px; color: var(--text-dim); }
.att-card .grow { min-width: 0; overflow-wrap: anywhere; }
.att-card.call.missed { color: #EF4444; }
.msg-bubble.outgoing .att-card {
  background: rgba(255, 255, 255, 0.22);
  border-color: rgba(255, 255, 255, 0.35);
  color: #FFFFFF;
  backdrop-filter: blur(8px);
}
.msg-bubble.outgoing .att-card small { color: rgba(255, 255, 255, 0.85); }
.msg-bubble.outgoing .att-card.call.missed {
  background: rgba(239, 68, 68, 0.35);
  border-color: rgba(255, 255, 255, 0.4);
  color: #FFFFFF;
}

@media (max-width: 640px) { .mobile-nav { display: flex !important; } }

.badge-num[hidden], .badge-dot[hidden], .icon-btn-ghost[hidden] { display: none !important; }
.left-rail { overflow-y: auto; }
.top-header .search-box { flex: 1 1 240px; max-width: 420px; }
.app-shell[data-route="chat"] .fabcompose,
.app-shell[data-route="mchat"] .fabcompose,
.app-shell[data-route="post"] .fabcompose { display: none; }

/* ── ฟีด/การ์ดโพสต์/คอมเมนต์: กฎที่ v3.css ไม่มี ── */
.post-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.post-actions { display:flex; gap:8px; align-items:center; }
.post-header .openarea { flex:1; align-self:stretch; min-width:16px; cursor:pointer; }
.gallery-4 { grid-template-columns:1fr 1fr; grid-template-rows:1fr 1fr; height:320px; }
.media-gallery { position:relative; }
.media-gallery .shots-more { position:absolute; inset-inline-end:8px; bottom:8px; padding:2px 8px;
  border-radius:999px; background:rgba(0,0,0,.6); color:#fff; font-size:11px; font-weight:700; }
/* คลิปในโพสต์ — ปกคลิป + ปุ่มเล่นทับกลาง (feed.js: `mediaSlidesOf`/`openVideoModal`) */
.media-item-video { position:relative; cursor:pointer; background:#000; }
.media-item-video img { opacity:.85; }
.media-item-video .video-play-badge {
  position:absolute; inset:0; margin:auto; width:48px; height:48px; display:flex;
  align-items:center; justify-content:center; border-radius:999px;
  background:rgba(0,0,0,.55); color:#fff; pointer-events:none;
}
.media-item-video .video-play-badge svg { width:22px; height:22px; fill:#fff; margin-inline-start:2px; }
.video-stage { display:flex; align-items:center; justify-content:center; }
.lightbox-video { max-width:100%; max-height:100vh; background:#000; }
.action-bookmark.on svg { fill: var(--accent-purple); }
.action-like .reaction { font-size:16px; line-height:1; }
.comment-item.reply { margin-inline-start:40px; }
.reply-link { background:none; border:none; cursor:pointer; display:inline-flex; align-items:center; gap:4px; }
.reply-link svg { width:12px; height:12px; }
.reply-link.on { color:var(--accent-pink); } .reply-link.danger { color:#EF4444; } .reply-link.warn { color:#F59E0B; }
/* คอมเมนต์ในโมดัลดูรูป (lightbox panel) และหน้าโพสต์เดี่ยว (#/post/<id>) ใช้ตัวเรนเดอร์
   คอมเมนต์เดียวกัน (mountPostComments) — ต่างกันแค่ opts.iconOnly: โมดัลส่ง true
   (ไอคอนล้วน, ใช้ .icon-only ด้านล่าง), หน้าโพสต์เดี่ยวไม่ส่ง ⇒ ปริยาย = มีข้อความ
   (.reply-link ฐาน ด้านบน). ปรับความหนาแน่นที่ mountPostComments จุดเดียว
   คงข้อความไว้เป็น aria-label/title เสมอ (เข้าถึงได้), พื้นที่กดขั้นต่ำ 40x40px เฉพาะโหมดไอคอนล้วน */
.reply-link.icon-only {
  justify-content: center;
  min-width: 40px;
  min-height: 40px;
  padding: 8px;
  border-radius: 8px;
}
.reply-link.icon-only svg { width: 16px; height: 16px; flex-shrink: 0; }
.reply-link.icon-only .cnt { font-size: 11px; font-weight: 600; }
.reply-link.icon-only:active { background: var(--bg-card-hover); }
.comment-input { resize:none; max-height:120px; font-family:inherit; line-height:1.4; padding:6px 0; }
a.k3-row { text-decoration:none; color:inherit; }
.shopx { margin-top:10px; } .shopx > .k3-card + .k3-card { margin-top:8px; }
.post-card.text-only .post-text { font-size:17px; }
.post-card.text-only.brief .post-text { font-size:20px; line-height:1.5; }
.composer-top > .av { width:36px; height:36px; }
.comment-item > .av, .comment-input-row > .av { width:34px; height:34px; font-size:13px; }
.composer-link-preview { margin-top: 10px; width: 100%; }
.composer-linkcard-container { position: relative; width: 100%; }
.composer-linkcard-dismiss {
  position: absolute;
  top: 8px;
  inset-inline-end: 8px;
  /* วงกลม ไม่ใช่วงรี: `width`/`height` อย่างเดียวยังถูกกฎอื่นดันสูงได้ (padding ที่สืบมา หรือ
     ตัวอักษร × ที่ดันความสูงบรรทัด) — ล็อกทั้งสี่ทางแล้วบังคับสัดส่วน 1:1 ไว้เป็นด่านสุดท้าย */
  width: 26px;
  height: 26px;
  min-width: 26px;
  min-height: 26px;
  flex: 0 0 auto;
  padding: 0;
  aspect-ratio: 1 / 1;
  box-sizing: border-box;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.72);
  color: #FFF;
  border: none;
  font-size: 16px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 10;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
  transition: background 0.15s ease, transform 0.15s ease;
}
.composer-linkcard-dismiss:hover {
  background: #EF4444;
  transform: scale(1.1);
}

/* ── Floating Video PiP (Picture-in-Picture Mini Player) ── */
#korat-global-pip-player {
  position: fixed;
  bottom: 24px;
  inset-inline-end: 24px;
  width: 340px;
  min-width: 240px;
  max-width: min(640px, calc(100vw - 24px));
  min-height: 160px;
  max-height: 80vh;
  z-index: 10000;
  background: var(--bg-card, #1A1D2D);
  border: 1px solid var(--border-strong, rgba(255, 255, 255, 0.18));
  border-radius: 16px;
  box-shadow: 0 20px 48px rgba(0, 0, 0, 0.55), 0 0 24px rgba(139, 61, 255, 0.22);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  resize: both;
  animation: pipSlideIn 0.25s cubic-bezier(0.16, 1, 0.3, 1);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}
@keyframes pipSlideIn {
  from { opacity: 0; transform: translateY(20px) scale(0.95); }
  to { opacity: 1; transform: none; }
}
#korat-global-pip-player .video-pip-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  background: rgba(0, 0, 0, 0.5);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  user-select: none;
  cursor: grab;
  touch-action: none;
}
#korat-global-pip-player .video-pip-header:active {
  cursor: grabbing;
}
#korat-global-pip-player .video-pip-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-main, #FFF);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
  margin-inline-end: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
}
#korat-global-pip-player .video-pip-title svg {
  width: 14px;
  height: 14px;
  color: var(--accent-pink, #FF4586);
  flex-shrink: 0;
}
#korat-global-pip-player .video-pip-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}
#korat-global-pip-player .video-pip-btn {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-dim, #A1A1AA);
  display: grid;
  place-items: center;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  transition: all 0.15s ease;
}
#korat-global-pip-player .video-pip-btn:hover {
  background: rgba(255, 255, 255, 0.15);
  color: var(--text-main, #FFF);
}
#korat-global-pip-player .video-pip-btn.danger:hover {
  background: #EF4444;
  color: #FFF;
}
#korat-global-pip-player .video-pip-body {
  position: relative;
  width: 100%;
  flex: 1;
  min-height: 135px;
  background: #000;
}
#korat-global-pip-player .video-pip-body iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: none;
}
.is-pip-floating .video-pip-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 12px;
  background: rgba(0, 0, 0, 0.4);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  user-select: none;
}
.is-pip-floating .video-pip-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-main, #FFF);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
  margin-inline-end: 8px;
}
.is-pip-floating .video-pip-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}
.is-pip-floating .video-pip-btn {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-dim, #A1A1AA);
  display: grid;
  place-items: center;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  transition: all 0.15s ease;
}
.is-pip-floating .video-pip-btn:hover {
  background: rgba(255, 255, 255, 0.15);
  color: var(--text-main, #FFF);
}
.is-pip-floating .video-pip-btn.danger:hover {
  background: #EF4444;
  color: #FFF;
}
.is-pip-floating .video-pip-body {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
}
.post-linkcard-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--bg-input, rgba(0,0,0,0.1));
  border-radius: var(--radius-md, 12px);
}
.post-linkcard-pip-indicator {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  background: var(--bg-card, #1A1D2D);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 13px;
  font-weight: 600;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.post-linkcard-pip-indicator svg {
  width: 16px;
  height: 16px;
  color: var(--accent-pink);
  animation: pipPulse 2s infinite ease-in-out;
}
@keyframes pipPulse {
  0%, 100% { transform: scale(1); opacity: 0.8; }
  50% { transform: scale(1.15); opacity: 1; }
}

@media (max-width: 640px) {
  .post-video-pip-wrap.is-pip-floating {
    bottom: 74px; /* above mobile navigation bar */
    inset-inline-end: 12px;
    width: 280px;
  }
}

/* ── มือถือ: กันเนื้อหาล้นออกนอกจอ ──────────────────────────────────────
   v3 เป็นเดโมจอกว้าง ไม่เคยเจอกรณีคอลัมน์แคบ ⇒ ลูกของกริดที่ min-width เป็น
   auto จะดันตัวเองกว้างกว่าจอแล้วทั้งหน้าเลื่อนตามแนวนอน (หัวเรื่องหลุดจอ) */
html, body { max-width: 100%; overflow-x: hidden; }
.app-shell { width: 100%; max-width: min(1280px, 100%); }
.app-shell > * { min-width: 0; }
.main-content, .left-rail, .right-sidebar { min-width: 0; max-width: 100%; }
.main-content img, .main-content video, .main-content canvas { max-width: 100%; }
.top-header { max-width: 100%; flex-wrap: wrap; row-gap: 8px; }
.top-header .search-box { min-width: 0; }
/* ── หัวจอ: ชื่อร้านยาวดันปุ่มแชร์/ตะกร้าล้นกรอบ (2026-08-26 เจ้าของชี้บนจอจริง
   ที่ #/shop/7) ────────────────────────────────────────────────────────────
   สาเหตุจริง (อ่านโค้ดแล้ว ยังไม่ได้เห็นด้วยตา — เปิดเบราว์เซอร์ไม่ได้):
   `.top-header` (v3.css:336) สูงคงที่ `height:56px` และเป็น `position:sticky`
   ส่วนบรรทัดข้างบน (v3-extra.css เดิม) เติม `flex-wrap:wrap` ให้มันเพื่อกันจอแคบ
   ล้น — แต่ `.header-title-wrap` (main.js:770, ห่อ `<h2 data-title>` ที่พิมพ์
   ชื่อร้าน) ไม่เคยมี `min-width:0` และ `h2` เดิมไม่มี ellipsis เลย ⇒ flex item
   ที่ไม่ยอมหด: ชื่อร้านยาวดันความกว้างรวมเกินคอลัมน์ ⇒ `flex-wrap:wrap` ที่เพิ่งเติม
   จึงพับ `.header-actions` (ปุ่มแชร์+ตะกร้า, main.js:775) ลงแถวที่สอง ซึ่งล้น
   ออกนอกกรอบสูง 56px ของ sticky header (overflow เริ่มต้นคือ visible) ไปทับ
   เนื้อหาที่เลื่อนอยู่ข้างล่าง (ปกร้าน) พอดี — ตรงกับที่เห็น "ตะกร้าตกลงไปอยู่บน
   แบนเนอร์" และปุ่มสองปุ่มถูกบีบชิดกันในแถวที่ล้นจนดูเหมือนทับกัน.
   แก้ที่ราก: ให้ชื่อเรื่องตัดด้วย … แทนการดันบรรทัด และห้ามแถบปุ่มหดจนบีบกัน
   ยืนยันโหนดจริง: main.js:770-775 มี `.header-title-wrap`/`h2`/`.header-actions`
   ตรงตัวทุกคลาส. */
.header-title-wrap { min-width: 0; }
.header-title-wrap h2 {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.header-actions { flex-shrink: 0; }
@media (max-width: 640px) {
  .top-header { position: sticky; top: 0; z-index: 20; }
  /* ห้ามใส่ระยะขอบซ้าย/ขวาบนมือถือ — v3 ให้เนื้อหาเต็มความกว้าง 100%
     (บรรทัดนี้เคยทำให้ทุกหน้าบนมือถือมีขอบว่างสองข้าง) */
  .main-content { padding-inline: 0; }
}
/* ตาราง/โค้ด/ข้อความยาวในหน้าที่ยังไม่ได้แปลงเป็น v3 ต้องไม่ดันจอ */
.main-content table { display: block; overflow-x: auto; max-width: 100%; }
.main-content pre { overflow-x: auto; }

/* ── ชิ้นส่วนกลางจาก ui.js ที่ v3 ไม่มีคลาสให้ ── */
.scrim { inset: auto; top: var(--vv-t, 0px); left: var(--vv-l, 0px);
         width: var(--vv-w, 100%); height: var(--vv-h, 100dvh); }
.scrim > .sheet-modal { display: flex; flex-direction: column; max-height: 100%; }
.sheet-modal > .sheet-body { overflow-y: auto; flex: 1 1 auto; min-height: 0; }
.sheet-header .k3-title { flex: 1; min-width: 0; }
@media (max-width: 640px) {
  .scrim { padding: 12px 10px; }
  .sheet-modal, .dialog {
    width: 100% !important;
    max-width: calc(100vw - 20px) !important;
    border-radius: var(--radius-xl, 20px) !important;
  }
}
.toast-host .toast { position: static; transform: translateY(8px); }
.toast-host .toast.on { transform: none; }
.k3-btn-danger { background: #EF4444; box-shadow: none; }
.k3-btn-danger:hover { background: #DC2626; }
/* ── ตระกูล k3-* ที่โค้ดฝั่งลูกค้าอ้างถึงแต่ v3.css ไม่เคยนิยาม (2026-09-18) ──
   ตรวจด้วย `node web/tools/check_deployed_css_classes.mjs app` · หน้านี้โหลดแค่ v3.css +
   v3-extra.css (เจ้าของตัด app.css/biz.css ออก — ดูคอมเมนต์หัว index.html) ⇒ กฎต้องอยู่ที่นี่
   ไม่ใช่โหลดไฟล์เก่ากลับมา · ไม่ลอกจาก site/bizv3/v3-fixes.css ตรง ๆ เพราะฝั่งนั้นผูกโทเคน
   `--bz-*` ของคอนโซล ที่นี่ผูกโทเคน v3 (`--brand-gradient` · `--bg-input` · `--border`)
   · `.k3-btn-primary` = ปุ่มหลัก: ยืนยันการเติมสีแบรนด์ให้ชัดแม้ถูกวางคู่กับตัวปรับอื่น
   · `.k3-btn-outline` = ปุ่มรอง: โปร่ง + เส้นขอบ (คู่ของ `.k3-btn-ghost` ที่มีพื้นจาง)
   · `.k3-input` = ช่องกรอกในชีต (เดิมเป็น input เปล่าของเบราว์เซอร์ — ไม่มีขอบ ไม่มีพื้น)
   · `.k3-link` = ลิงก์ย้อนกลับ "← บัญชี" ในจอตั้งค่า
   · `.k3-chip-sm` = ชิปเล็กในประวัติการเรียกเก็บ · `.k3-list` = คอลัมน์แถว · `.k3-screen` = จอเดี่ยว */
.k3-btn-primary { background: var(--brand-gradient); color: #FFF; box-shadow: var(--brand-glow); }
.k3-btn-primary:hover { background: var(--brand-hover); }
.k3-btn-outline { background: transparent; color: var(--text-main); border: 1px solid var(--border); box-shadow: none; }
.k3-btn-outline:hover { background: var(--bg-input); transform: none; }
.k3-btn.sm { padding: 6px 12px; font-size: 12px; }
.k3-input {
  display: block; width: 100%; box-sizing: border-box;
  padding: 9px 12px; font-size: 14px; line-height: 1.4;
  color: var(--text-main); background: var(--bg-input);
  border: 1px solid var(--border); border-radius: 10px; outline: none;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.k3-input:focus { background: var(--bg-input-focus); border-color: var(--text-dim); }
.k3-input::placeholder { color: var(--text-dim); }
textarea.k3-input { resize: vertical; min-height: 72px; }
select.k3-input { appearance: auto; }
.k3-link { color: var(--text-dim); text-decoration: none; cursor: pointer; }
.k3-link:hover { color: var(--text-main); text-decoration: underline; }
.k3-chip-sm { display: inline-flex; align-items: center; font-size: 11px; line-height: 1.2; }
.k3-list { display: flex; flex-direction: column; gap: 6px; }
.k3-screen { display: block; min-width: 0; }
.av.sm { width: 32px; height: 32px; } .av.xs, .av.tiny { width: 28px; height: 28px; font-size: 12px; }
.av.xl { width: 96px; height: 96px; font-size: 34px; }
.av-ring { display: inline-block; padding: 2px; border-radius: 50%; background: var(--ring-c, transparent); }
.av-ring.neon { background: var(--ring-c, transparent); box-shadow: 0 0 12px var(--ring-c); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
           overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.ff-pick { position: relative; overflow: hidden; }
.ff-pick input[type="file"] { position: absolute; inset: 0; opacity: 0; cursor: pointer; }

/* ── กฎเดียวที่ทั้งแอปพึ่งพา: `hidden` ต้องซ่อนจริง ──────────────────────
   ของเดิมมีกฎนี้ใน app.css ที่ถูกตัดทิ้ง ⇒ ทุกกฎที่ตั้ง display เอง (.boot,
   .badge-num, .k3-*) จะชนะ [hidden] ของเบราว์เซอร์ ⇒ หน้าจอ "กำลังเปิด Korat…"
   ค้างทับแอปทั้งที่แอปโหลดเสร็จแล้ว */
[hidden] { display: none !important; }

/* ── หน้าโปรไฟล์: กฎที่ v3 ไม่มี ── */
.profile-actions-group { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: flex-end; }
.profile-avatar-large.noimg { display: grid; place-items: center; font-size: 34px; font-weight: 800; color: var(--text-dim); background: var(--bg-input); }
.avatar-img.noimg { display: grid; place-items: center; font-size: 14px; font-weight: 800; color: var(--text-dim); background: var(--bg-input); }
.profile-tabpanel { padding: 0; }
/* ในแท็บของหน้าโปรไฟล์ หัวข้อกับรายการต้องกว้างเท่ากันเป๊ะ —
   หัวข้อเคยกินเต็มความกว้าง ส่วนการ์ดในรายการถูกดันเข้ามาอีกชั้น */
.profile-tabpanel > .section-label,
.profile-tabpanel .section-label.row { padding-inline: 16px; }
.profile-tabpanel .list:not(.k3-body) { padding-inline: 16px; }
.profile-tabpanel .list:not(.k3-body) > .row { margin-inline: 0; }
.profile-tabpanel .bookmarks-header { padding: 14px 20px 0; margin-bottom: 8px; }
.profile-suggest { margin: 12px 16px; }
.profile-editor .form { padding: 14px 20px; }

/* ══ หน้าแชท: กฎที่ v3 ไม่มี (เดโมเป็นจอกว้างสามคอลัมน์เสมอ) ══ */
/* เลขเดาถูกลบแล้ว — ห้องยืดตามพื้นที่จริงด้านล่างแทน */

@media (max-width: 1024px) {
  .chat-layout[data-mode] { grid-template-columns: minmax(0, 1fr); }
  .chat-layout[data-mode="list"] .chat-threads { display: flex; }
  .chat-layout[data-mode="list"] .chat-room { display: none; }
  .chat-layout[data-mode="thread"] .chat-threads { display: none; }
  .chat-layout[data-mode] .thread-meta { display: block; }
  .chat-layout[data-mode] .thread-time { display: inline; }
  .chat-layout[data-mode] .thread-item { justify-content: flex-start; padding: 12px 14px; }
}
a.thread-item, button.thread-item {
  width: 100%; text-align: start; font: inherit; color: inherit;
  text-decoration: none; background: transparent; border: 0; border-bottom: 1px solid var(--border);
}
.av.avatar-sm { width: 34px; height: 34px; font-size: 13px; }
.msg-group > .av.avatar-sm { align-self: flex-end; }
.msg-bubble { white-space: pre-wrap; }
.msg-bubble .quote {
  border-inline-start: 3px solid var(--border-strong); padding-inline-start: 8px;
  margin-bottom: 6px; font-size: 12px; opacity: .8; white-space: normal;
}
.msg-bubble .deleted { opacity: .6; font-style: italic; }
.msg-bubble .autochip {
  display: inline-block; margin-bottom: 6px; padding: 1px 8px; border-radius: var(--radius-pill);
  background: rgba(127,127,127,.18); font-size: 10.5px; font-weight: 700; white-space: normal;
}
.msg-time { display: flex; align-items: center; gap: 6px; }
.msg-time .rr { background: none; border: 0; padding: 0; color: var(--text-dim); cursor: pointer; }
.msg-time .rr.read { color: var(--accent-purple); }
.msg-time .rr svg { width: 13px; height: 13px; display: block; }
.msg-inline-reply-btn {
  background: none;
  border: 0;
  padding: 0 4px;
  color: var(--text-dim);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0.6;
  transition: all 0.15s ease;
  line-height: 1;
}
.msg-inline-reply-btn:hover {
  opacity: 1;
  color: var(--brand-primary, var(--accent-purple));
  transform: scale(1.15);
}
.stamp .msg-inline-reply-btn {
  vertical-align: middle;
  margin-left: 4px;
}
.att img { max-width: 100%; width: auto; max-height: 280px; border-radius: var(--radius-md); display: block; object-fit: cover; }
.att-card {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px; margin-top: 6px;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--bg-input); color: inherit; text-decoration: none; white-space: normal;
  max-width: 100%; box-sizing: border-box;
}
.att-card small { display: block; font-size: 11px; color: var(--text-dim); }
.att-card .grow { min-width: 0; overflow-wrap: anywhere; }
.att-card.call.missed { color: #EF4444; }
.att-audio { margin-top: 6px; max-width: 100%; } .att-audio audio { width: 100%; max-width: 260px; }
.chat-composer { flex-shrink: 0; }
.chat-input-bar textarea {
  flex: 1; min-width: 0; resize: none; max-height: 120px; font: inherit; line-height: 1.4;
  background: var(--bg-input); border: 1px solid var(--border);
  border-radius: var(--radius-pill); padding: 10px 18px; font-size: 14px;
  outline: none; color: var(--text-main);
}
.chat-input-bar textarea:focus { border-color: var(--border-focus); background: var(--bg-input-focus); }
.chat-input-bar .ff-pick { flex-shrink: 0; }
.attach-preview {
  display: flex; align-items: center; gap: 8px; padding: 6px 16px;
  border-top: 1px solid var(--border); font-size: 12px; color: var(--text-dim);
}
.attach-preview img { width: 40px; height: 40px; object-fit: cover; border-radius: var(--radius-sm); }
.filemsg { margin: 0; padding: 6px 16px; font-size: 12px; color: #EF4444; }
.chat-messages-body > .k3-state, .chat-messages-body > .k3-body { margin: auto; width: 100%; }
.msgs { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden !important; display: flex; flex-direction: column; gap: 16px; padding: 12px; box-sizing: border-box; }
.inbox-thread-placeholder { margin: auto; padding: 24px; color: var(--text-dim); font-size: 13px; text-align: center; }

/* Quick Chat Popup Responsive & Anti-Scrollbar Fitting */
.quick-chat-popup .msgs,
.quick-chat-popup .popup-chat-body {
  overflow-x: hidden !important;
  width: 100%;
  box-sizing: border-box;
}
.quick-chat-popup .msg-group {
  max-width: 90%;
}
.quick-chat-popup .msg-bubble {
  max-width: 100%;
  box-sizing: border-box;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.quick-chat-popup .att img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-md);
}
.quick-chat-popup .att-card,
.quick-chat-popup .chat-call-card,
.quick-chat-popup .msg-quote {
  max-width: 100%;
  box-sizing: border-box;
}

/* ── แถบ "ติดตั้งแอป" (install.js) — ฟีเจอร์เดิมของโปรดักชัน v3 ไม่มี
   กฎเดิมอยู่ใน app.css ที่ถูกตัด ⇒ มันเลยกลายเป็นไอคอนลอยมุมล่างซ้าย */
.installbar {
  position: fixed; z-index: 60;
  inset-inline: 12px; bottom: calc(64px + env(safe-area-inset-bottom, 0px) + 8px);
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: var(--radius-lg, 16px);
  background: var(--bg-card); border: 1px solid var(--border);
  box-shadow: 0 8px 28px rgba(0,0,0,.28);
}
@media (min-width: 641px) { .installbar { inset-inline: auto 16px; bottom: 16px; max-width: 360px; } }
.installbar .ib-icon img { width: 36px; height: 36px; border-radius: 10px; display: block; }
.installbar .ib-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.installbar .ib-title { font-size: 13px; font-weight: 700; color: var(--text-main); }
.installbar .ib-body { font-size: 11.5px; color: var(--text-dim); }
.installbar .ib-action {
  flex: 0 0 auto; padding: 7px 14px; border: 0; border-radius: var(--radius-pill);
  background: var(--brand-gradient, var(--accent-purple)); color: #fff; font-weight: 700; font-size: 12.5px; cursor: pointer;
}
.installbar .ib-close {
  flex: 0 0 auto; width: 28px; height: 28px; display: grid; place-items: center;
  border: 0; background: transparent; color: var(--text-dim); cursor: pointer;
}

/* ── หน้าตั้งค่า: กฎที่ v3 ไม่มี ── */
.auth-field textarea {
  min-height: 96px; padding: 10px 14px; border-radius: var(--radius-md);
  border: 1px solid var(--border); background: var(--bg-input); color: var(--text-main);
  font: inherit; font-size: 14px; resize: vertical;
}
.auth-field textarea:focus { outline: none; border-color: var(--border-focus); background: var(--bg-input-focus); }
.auth-field input[type="range"] { height: auto; padding: 0; background: none; border: 0; accent-color: var(--accent-pink); }
.k3-row[role="button"], .k3-row[role="button"] .k3-row-main { cursor: pointer; }
.k3-row[role="button"]:hover { background: var(--bg-input-focus); }
.k3-note a { color: var(--accent-purple, #8B5CF6); text-decoration: none; }
.k3-note a:hover { text-decoration: underline; }

/* ── dock แชทลอย: กฎที่หายไปพร้อม app.css (ตอนนี้ยังไหลลงหน้า) ── */
.dock { display: none; }
@media (min-width: 1025px) {
  .dock { display: flex; position: fixed; inset-inline-end: 16px; bottom: 0;
          align-items: flex-end; gap: 12px; z-index: 60; }
}
.dockcol { display: flex; flex-direction: column; align-items: stretch; gap: 8px; width: 232px; }
.dockbar { display: flex; align-items: center; gap: 8px; padding: 8px 12px;
           background: var(--bg-card); border: 1px solid var(--border);
           border-radius: 12px 12px 0 0; color: var(--text-main); cursor: pointer; }
.dockbar svg { width: 20px; height: 20px; color: var(--text-dim); flex: 0 0 auto; }
.dockbar .lbl { flex: 1; min-width: 0; text-align: start; overflow: hidden;
                text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 700; }
.docklist { background: var(--bg-card); border: 1px solid var(--border);
            border-radius: 12px; max-height: 380px; display: flex; flex-direction: column; }
.docklist header { display: flex; align-items: center; gap: 8px; padding: 8px 10px;
                   border-bottom: 1px solid var(--border); }
.docklist .ttl { font-size: 13px; font-weight: 700; color: var(--text-dim); flex: 1; min-width: 0; }
.docklist .lnk { font-size: 12px; font-weight: 600; color: var(--accent-pink); text-decoration: none; }
.docklist .body { overflow-y: auto; padding: 0 6px 8px; }
.dockwin { width: 300px; height: 420px; display: flex; flex-direction: column;
           background: var(--bg-card); border: 1px solid var(--border);
           border-radius: 12px 12px 0 0; overflow: hidden; }
.dockwin.min { height: auto; }
.dockwin.min .dwbody { display: none; }
.dwhead { display: flex; align-items: center; gap: 8px; padding: 6px 8px;
          border-bottom: 1px solid var(--border); }
.dwhead .nm { flex: 1; min-width: 0; background: none; border: 0; cursor: pointer;
              text-align: start; font-size: 13px; font-weight: 700; color: var(--text-main);
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dwhead .ic { width: 26px; height: 26px; border: 0; background: none; border-radius: 8px;
              color: var(--text-dim); cursor: pointer; }
.dwhead .ic:hover { background: rgba(127,127,127,.12); color: var(--text-main); }
.dwbody { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.dwbody .msgs { flex: 1; min-height: 0; overflow-y: auto; padding: 8px 10px; }
@keyframes k3skel { 0% { background-position: 0% 0; } 100% { background-position: -200% 0; } }
.skel-inline { display: inline-block; width: 64px; height: 26px; border-radius: 999px;
               background: linear-gradient(90deg, var(--border), transparent, var(--border));
               background-size: 200% 100%; animation: k3skel 1.2s linear infinite; }
.btn-follow.ghost { background: transparent; color: var(--text-dim); border: 1px solid var(--border); }
.follow-item .rowacts { flex: 0 0 auto; display: inline-flex; }

/* แท็บฟีดอยู่ในคอลัมน์กลาง ไม่ใช่ในหัวเรื่อง ⇒ ต้องมีความสูงของตัวเอง */
.view.feed .header-tabs {
  height: 52px; padding: 0 16px; gap: 20px;
  overflow-x: auto; scrollbar-width: none;
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 5;
  background: var(--bg-header); backdrop-filter: blur(20px) saturate(180%);
}
.view.feed .header-tabs::-webkit-scrollbar { display: none; }
.view.feed .tab-btn { flex: 0 0 auto; white-space: nowrap; }

/* ปุ่มออกจากระบบย้ายเข้า .user-profile-pill แล้ว (v3 นิยาม .pill-main/.pill-signout เอง)
   จึงไม่ต้องมีกฎที่นี่ — ลบทิ้งเพื่อไม่ให้ทับของต้นฉบับ */

/* ── กฎที่ v3 ไม่มี เพราะเดโมไม่เคยใช้อิลิเมนต์เหล่านี้ ── */
.auth-field select,
.rel-acts select {
  height: 46px; padding: 0 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--bg-input); color: var(--text-main);
  font: inherit; font-size: 14px;
}
.rel-acts select { height: 36px; font-size: 13px; }
.auth-field select:focus, .rel-acts select:focus {
  outline: none; border-color: var(--border-focus); background: var(--bg-input-focus);
}
a.chip-item, a.linkbtn, a.k3-btn { text-decoration: none; }
.notif-item[role="button"] { cursor: pointer; width: 100%; text-align: start; }
.grp-cover { background: var(--brand-gradient); }

/* ── ฟอร์มในชีท: v3 มีแต่ .rz-field input/textarea (ไม่มี select, ไม่มี label ลอย) ── */
.rz-field select,
.rz-editor > input, .rz-editor > select, .rz-editor > textarea {
  padding: 10px 12px; border-radius: var(--radius-md);
  border: 1px solid var(--border); background: var(--bg-input);
  color: var(--text-main); font-size: 13px; font-family: inherit; font-weight: 500;
}
.rz-editor > label { font-size: 12px; font-weight: 700; color: var(--text-dim); }
.rz-link input { flex: 1; min-width: 160px; padding: 8px 12px;
  border-radius: var(--radius-md); border: 1px solid var(--border);
  background: var(--bg-input); color: var(--text-main); font-size: 12px; }

/* แท็บ 5–6 อันบนจอ 360px: `flex:1` ของ .notif-tab บีบจนตัดคำ ⇒ ให้เลื่อนแนวนอน */
.notifs-header-bar { overflow-x: auto; overflow-y: hidden; flex-wrap: nowrap;
  -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.notifs-header-bar::-webkit-scrollbar { display: none; }
.notifs-header-bar > .notif-tab { flex: 0 0 auto; white-space: nowrap; padding: 14px 14px; }

/* ── ตัวนับบรรทัดเดียว + แผงอีโมจิ + ชิปเช็คอิน (v3 ไม่มีทั้งสามอย่าง) ── */
.counterbar-line { display: flex; align-items: baseline; gap: 6px;
  flex-wrap: nowrap; min-width: 0; font-size: 11px; }
.counterbar-line > * { min-width: 0; overflow: hidden;
  white-space: nowrap; text-overflow: ellipsis; }
.counterbar-line .tagcap { font-size: 11px; color: var(--text-dim);
  text-align: start; font-variant-numeric: tabular-nums; flex: 0 1 auto; }
.counterbar-line .tagcap.bad { color: #EF4444; font-weight: 700; }
.counterbar-line .neon-quota { flex: 1 1 auto; flex-wrap: nowrap; }
.counterbar-sep { color: var(--text-dim); flex: 0 0 auto; }
.counterbar-sep[hidden] { display: none; }
.counterbar-line:has(.tagcap.bad) { flex-wrap: wrap; }
/* The "captured tags" chip strip (tagpicker.js `.tagfound`) lives inside the
   same `.tagpick` node as `.tagcap`, which this bar otherwise forces onto one
   nowrap/ellipsis line (`.counterbar-line > *` above). A chip row clipped to
   one line and ellipsised would hide exactly the tags it exists to confirm,
   so both the node and the row itself opt back out of that clipping and the
   whole bar wraps to make room. */
.counterbar-line .tagpick { overflow: visible; white-space: normal; text-overflow: clip; }
.counterbar-line .tagfound { overflow: visible; white-space: normal; flex: 1 1 100%; }
.counterbar-line:has(.tagfound:not([hidden])) { flex-wrap: wrap; }
.emoji-pop { width: min(320px, calc(100vw - 24px)); padding: 8px; }
.emoji-head { padding: 0 0 6px; }
.emoji-search { width: 100%; font-size: 13px; padding: 6px 10px; }
.emoji-cats { display: flex; gap: 2px; overflow-x: auto; padding: 0 0 6px;
  border-bottom: 1px solid var(--border); }
.emoji-cat { flex: 0 0 auto; border: 0; background: none; cursor: pointer;
  font-size: 17px; line-height: 1; padding: 5px 6px; border-radius: 8px; opacity: .6; }
.emoji-cat[aria-selected="true"] { opacity: 1; background: rgba(127,127,127,.14); }
.emoji-grid { display: grid; grid-template-columns: repeat(8, 1fr);
  gap: 2px; max-height: 216px; overflow-y: auto; padding-top: 6px; }
.emoji-key { border: 0; background: none; cursor: pointer; font-size: 20px;
  line-height: 1; padding: 4px 0; border-radius: 8px; }
.emoji-key:hover { background: rgba(127,127,127,.16); }
.emoji-empty { font-size: 12px; color: var(--text-dim); padding: 10px 4px; margin: 0; }
.emoji-wrap { flex: 0 0 auto; }
.comment-field-wrap .emoji-wrap .tool-btn { width: 30px; height: 30px; }
.chat-input-bar { overflow: visible; }
.chip-place { background: rgba(14,165,233,.14); color: #0EA5E9; }
.post-location .place-link { color: inherit; text-decoration: none; }
.post-location .place-link:hover { text-decoration: underline; }
.shopdine { display: contents; }

/* ── ไดเรกทอรี: กฎที่ v3 ไม่มี ── */
.shop-status-warn { background: rgba(245, 158, 11, 0.85); color: #FFF; }
.shop-cover-ph { display:flex; align-items:center; justify-content:center;
  width:100%; height:100%; font-size:34px; }
.shop-rating-badge.none { background:none; color:var(--text-dim); font-weight:600; }
.directory-viewbar.pager { justify-content:center; }

/* ── หน้าร้านเดี่ยว #/shop/<id>: เนื้อหาใต้หัวร้านชิดขอบจอ (2026-08-26) ──────
   `renderShop` (shop.js — ห้ามแตะ) ต่อ `promoHost`/`tabBar`/`body` เข้ากับ
   `.view` ตรง ๆ (`view.replaceChildren(head, promoHost, tabBar, body)`) ไม่มี
   คลาสไหนตรงกับกฎ margin-inline เดิม (`.k3-card`/`.k3-section`/`.rel-page`/
   `.k3-body`/`.dirgrid`/... — grep ยืนยันแล้วไม่มีสักคลาสอยู่ในหน้านี้) ⇒
   การ์ดสินค้า/ป้ายโปรโมชัน/บล็อกคิวถึงชนขอบจอพอดี. สโคปด้วย
   `.view:has(> .bizhead)` — ผูกกับหัวร้านค้าปลีกเท่านั้น (คลาสเดียวกับที่
   shop.js:581 ใส่ไว้บนหัวร้าน) **ไม่แตะกฎกว้างของ `.ptabs`/`.profile-tab`/
   `.shoppage` เลยสักบรรทัด** — ปกร้าน (`.bizhead`) และแถบแท็บ (`.ptabs`) ยังเต็ม
   ขอบจอเหมือนเดิมตามดีไซน์โปรไฟล์ทั่วไป มีแค่ "เนื้อหาในแท็บ" ที่ได้ระยะขอบ */
.view:has(> .bizhead) .product-grid,
.view:has(> .bizhead) .section-label.k3-group-label,
.view:has(> .bizhead) > [data-promo] .shop-highlights,
.view:has(> .bizhead) .q-board,
.view:has(> .bizhead) .q-list,
.view:has(> .bizhead) .q-take,
.view:has(> .bizhead) .q-board-note,
.view:has(> .bizhead) .job-empty {
  margin-inline: 12px;
}
@media (min-width: 641px) {
  .view:has(> .bizhead) .product-grid,
  .view:has(> .bizhead) .section-label.k3-group-label,
  .view:has(> .bizhead) > [data-promo] .shop-highlights,
  .view:has(> .bizhead) .q-board,
  .view:has(> .bizhead) .q-list,
  .view:has(> .bizhead) .q-take,
  .view:has(> .bizhead) .q-board-note,
  .view:has(> .bizhead) .job-empty {
    margin-inline: 16px;
  }
}

/* ── มุมมอง "List" ของไดเรกทอรี (2026-08-26 เจ้าของสั่งตรงบนจอจริง) ──────────
   v3.css:3361-3363 ทำ .as-list เป็น "การ์ดแนวตั้งเต็มความกว้าง รูปสูง 220px" —
   เจ้าของสั่งตรงกันข้าม: การ์ดต้องเล็กลง รูปอยู่ซ้าย ข้อความอยู่ขวา (แนวนอน)
   ⇒ override เฉพาะ `.as-list` เท่านั้น **ไม่แตะ `.directory-grid:not(.as-list)`**
   (มุมมอง Grid) เด็ดขาดตามที่สั่ง. โครงสร้าง `.shop-card` มีลูก 3 ก้อนเรียงกัน
   (`.shop-cover-wrap` → `.shop-body` → `.shop-footer-actions`, ยืนยันด้วย
   grep `directory.js`) จึงใช้ CSS grid areas ให้รูปอยู่คอลัมน์ซ้ายเต็มความสูง
   และข้อความ+ปุ่มอยู่คอลัมน์ขวา แทนการจัดเรียง flex แนวนอนตรง ๆ ซึ่งจะดันปุ่ม
   ไปเป็นคอลัมน์ที่สาม */
.directory-grid.as-list { grid-template-columns: 1fr; gap: 8px; }
.directory-grid.as-list .shop-card {
  display: grid;
  /* ★ สามคอลัมน์แถวเดียว: รูป → ข้อความ → ปุ่ม
     เดิมเป็นสองคอลัมน์สองแถว (ปุ่มอยู่ *ใต้* ข้อความ) ⇒ แถวสูงขึ้นเท่าตัวและปุ่มกลาย
     เป็นแถบเต็มความกว้าง · แบบสามคอลัมน์อ่านเป็น "แถวรายการ" จริง ๆ สายตาไล่ซ้ายไปขวา
     และการ์ดเตี้ยลง เห็นร้านได้มากขึ้นต่อหนึ่งหน้าจอ */
  grid-template-columns: 96px minmax(0, 1fr) auto;
  grid-template-areas: "cover body foot";
  align-items: center;
}
.directory-grid.as-list .shop-cover-wrap {
  grid-area: cover;
  width: 96px;
  height: 100%;            /* ยกเลิก 220px เดิม — เต็มความสูงของแถว ไม่ใช่สูงคงที่ */
  aspect-ratio: auto;      /* บังคับจัตุรัสไม่ได้แล้ว เพราะแถวเตี้ยกว่า 96px ⇒ รูปจะล้น */
  min-height: 84px;
}
.directory-grid.as-list .shop-cover-img { height: 100%; object-fit: cover; }
.directory-grid.as-list .shop-body {
  grid-area: body;
  padding: 8px 4px 8px 10px;
  gap: 3px;
  min-width: 0;            /* ไม่มีตัวนี้ ข้อความยาวจะดันปุ่มหลุดขอบการ์ด */
}
.directory-grid.as-list .shop-name {
  font-size: 14px; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.directory-grid.as-list .shop-desc,
.directory-grid.as-list .shop-highlights { display: none; }   /* การ์ดเล็กลง — ตัดรายละเอียดรอง ชื่อ+สถานะ+ที่ตั้งพอ */
/* ⚠️ ปุ่มเคยถูกบังคับ `style="flex:1"` ไว้ในตัวสร้างมาร์คอัพ ⇒ ในมุมมอง List มันยืด
   เต็มความกว้างของคอลัมน์ขวาแล้วกลายเป็น **แถบสีเต็มการ์ด** ที่หนักกว่าชื่อร้านเอง
   (เจ้าของเห็นบนจอจริงแล้วสั่งแก้) · ตอนนี้ปุ่มมีคลาส `.shop-cta` แทน inline style
   ⇒ มุมมอง Grid ยังยืดเต็มความกว้างเหมือนเดิม · มุมมอง List หดเป็นปุ่มจริงชิดขวา */
.shop-footer-actions .shop-cta { flex: 1; }

.directory-grid.as-list .shop-footer-actions {
  grid-area: foot;
  padding: 0 10px;
  background: none;
  border-top: 0;
  align-self: center;
}
.directory-grid.as-list .shop-footer-actions .shop-cta {
  flex: 0 0 auto;              /* ★ หัวใจของการแก้: เลิกยืดเต็มความกว้าง */
  min-height: 36px;
  padding: 7px 14px;
  font-size: 12px;
}
/* สถานะเปิด/ปิดยังเป็นป้ายทับมุมรูปเหมือนเดิม (`.shop-status-tag` เป็นลูกของ
   `.shop-cover-wrap` — ย้ายด้วย CSS ล้วนไม่ได้) แค่ย่อขนาดให้พอดีรูป 96px */
.directory-grid.as-list .shop-status-tag {
  top: 4px; left: 4px; font-size: 9px; padding: 2px 5px;
}
.directory-grid.as-list .shop-header-row { flex-wrap: wrap; }
.directory-grid.as-list .shop-rating-badge { font-size: 11px; padding: 1px 5px; }
.directory-grid.as-list .shop-meta { font-size: 11px; gap: 6px; }

/* ── หน้าแท็ก / สมุดที่อยู่ / สมาชิก: กฎที่ v3 ไม่มี ── */
.explore-hero-card[data-taghero] { background-image: none; background: var(--brand-gradient); }
.k3-row[data-tagcomment] .k3-row-name {
  white-space: normal; overflow: visible; font-weight: 400; line-height: 1.5;
}
button.k3-row {
  width: 100%; text-align: start; font: inherit; color: inherit; cursor: pointer;
}
button.k3-row[aria-checked="true"] {
  border-color: var(--accent-pink); background: var(--bg-input-focus);
}
button.k3-row:hover { background: var(--bg-input-focus); }
.k3-btn-row { flex-wrap: wrap; }

/* ── หน้าสินค้า (shop.js): แกลเลอรีเลื่อนแนวนอน + แถบซื้อ ── */
.k3-gallery { display:flex; gap:6px; overflow-x:auto; padding:10px 14px 0;
  scrollbar-width:none; -webkit-overflow-scrolling:touch; }
.k3-gallery::-webkit-scrollbar { display:none; }
.k3-gallery img, .k3-gallery-ph { flex:0 0 auto; width:min(72vw,260px); height:190px;
  border-radius:var(--radius-md); border:1px solid var(--border); }
.k3-gallery img { object-fit:cover; cursor:zoom-in; }
.k3-gallery-ph { display:grid; place-items:center; font-size:40px; background:var(--bg-input); }
.k3-buybar { display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding:10px 14px 14px; }
.k3-buybar .k3-btn { flex:1 1 140px; }
.qty-stepper input.qty-value { width:48px; padding:0; background:transparent;
  border:0; outline:none; font:inherit; text-align:center; -moz-appearance:textfield; }
.qty-stepper input.qty-value::-webkit-outer-spin-button,
.qty-stepper input.qty-value::-webkit-inner-spin-button { -webkit-appearance:none; margin:0; }
.profile-cover > img { width:100%; height:100%; object-fit:cover; display:block; }
.profile-cover.noimg { display:grid; place-items:center; font-size:40px; }
.orderlines.k3-bill > .k3-bill-line { align-items:center; }

/* ── แถบป้ายกำกับในคอลัมน์รายการแชท (v3 วางไว้ในหัวเรื่อง เราวางในแพนรายการ) ── */
/* เจ้าของ 2026-08-22: «แชท» กับชิป «ทั้งหมด» ชิดกันเกินไป — `.top-header` เป็น flex ที่ไม่มี gap
   และชั้นวางป้ายกิน flex:1 จนดันมาติดชื่อเรื่องพอดี · ใช้ `margin-inline-start` ไม่ใช่ `margin-left`
   เพราะแอปมีภาษาอาหรับ ⇒ ต้องสลับข้างเองเมื่อทิศทางกลับด้าน */
.top-header .chat-labels-row { flex: 1; min-width: 0; margin-inline-start: 14px; }
.top-header .chat-labels-row .header-labels { flex: 1; min-width: 0; overflow-x: auto; }
.top-header .chat-labels-row .label-chip-add { flex-shrink: 0; }
.chat-threads .chat-labels-row {
  flex: 0 0 auto;
  padding: 8px 14px;
  border-bottom: 1px solid var(--border);
}
.chat-threads .chat-labels-row .header-labels { flex: 1; padding-bottom: 2px; }
.chat-threads .chat-labels-row .label-chip-add { flex-shrink: 0; }
.chat-layout.collapsed .chat-labels-row { display: none !important; }

/* ── คอนโซลบนโดเมนหลัก: หัวหน้า/ตาราง/การ์ดสรุป (v3 ไม่มีคำศัพท์พวกนี้เลย) ── */
.k3-pagehead { display:flex; align-items:center; gap:10px; padding:4px 4px 8px; }
.k3-pagehead .ic { display:grid; place-items:center; width:34px; height:34px; flex:0 0 auto;
  border-radius:10px; background:var(--bg-input); border:1px solid var(--border); color:var(--text-dim); }
.k3-pagehead .ic svg { width:20px; height:20px; }
.k3-pagehead-title { font-size:17px; font-weight:800; color:var(--text-main); margin:0; }
.k3-acts { display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding:8px 0; }
.k3-acts.sm, td.k3-acts { padding:0; gap:6px; }
.k3-card-foot { display:flex; align-items:center; gap:8px; padding:10px 14px;
  border-top:1px solid var(--border); }
.k3-pad { padding:10px 14px; }
.k3-big { font-size:24px; font-weight:800; color:var(--text-main);
  font-family:var(--font-display); font-variant-numeric:tabular-nums; }
.k3-strong { font-weight:800; color:var(--text-main); }
.k3-struck { opacity:.6; }
.k3-struck td:first-child, .k3-struck .k3-row-name { text-decoration:line-through; }
.k3-warn { color:#F59E0B; } .k3-bad { color:#EF4444; } .k3-good { color:#22C55E; }
.k3-note-warn { color:#F59E0B; } .k3-note-bad { color:#EF4444; } .k3-note-good { color:#22C55E; }
.k3-chip[aria-selected="true"], .k3-chip[aria-checked="true"] {
  background:var(--bg-input-focus); color:var(--text-main); border-color:var(--border-focus); font-weight:700; }
.k3-needs-dot { display:inline-block; width:6px; height:6px; margin-inline-start:5px;
  border-radius:50%; background:#F59E0B; vertical-align:middle; }
.k3-tbl-scroll { overflow-x:auto; }
.k3-tbl { width:100%; border-collapse:collapse; font-size:13px; }
.k3-tbl th { padding:8px 12px; text-align:start; font-size:11px; font-weight:800;
  color:var(--text-dim); background:var(--bg-input); border-bottom:1px solid var(--border); white-space:nowrap; }
.k3-tbl td { padding:9px 12px; border-bottom:1px solid var(--border);
  color:var(--text-main); vertical-align:top; }
.k3-tbl tbody tr:last-child td { border-bottom:none; }
.k3-tbl .k3-num { text-align:end; font-variant-numeric:tabular-nums; white-space:nowrap; }
.k3-tbl-tap { cursor:pointer; }
.k3-tbl-tap:hover td { background:var(--bg-card-hover); }
.k3-tbl-tap:focus-visible { outline:2px solid var(--border-focus); outline-offset:-2px; }
.k3-tbl-break td { background:var(--bg-input); font-size:11px; font-weight:800; color:var(--text-dim); }
.k3-tbl-hot td:first-child { box-shadow:inset 3px 0 0 #F59E0B; }
.k3-tbl .k3-out { opacity:.55; }
@media (max-width:640px) {
  .k3-tbl-stack thead { display:none; }
  .k3-tbl-stack, .k3-tbl-stack tbody, .k3-tbl-stack tr, .k3-tbl-stack td { display:block; width:100%; }
  .k3-tbl-stack tr { border:1px solid var(--border); border-radius:var(--radius-md);
    background:var(--bg-input); margin-bottom:8px; padding:4px 0; }
  .k3-tbl-stack td { border-bottom:none; padding:5px 12px; display:flex; gap:10px; align-items:baseline; }
  .k3-tbl-stack td::before { content:attr(data-label); flex:0 0 40%;
    font-size:11px; font-weight:800; color:var(--text-dim); }
  .k3-tbl-stack td:empty { display:none; }
  .k3-tbl-stack .k3-num { text-align:end; justify-content:space-between; }
  .k3-tbl-stack .k3-tbl-break td::before { content:none; }
}
.k3-stat-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr)); gap:8px; }
.k3-hours { display:flex; flex-direction:column; gap:6px; }
.k3-hours-head { display:flex; gap:8px; font-size:11px; font-weight:800; color:var(--text-dim); padding:0 4px; }
.k3-hours-row { display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding:6px 4px;
  border-bottom:1px solid var(--border); }
.k3-hours-row .field { flex:0 0 auto; }

/* ══════════════════════════════════════════════════════════════════════════
   ชั้นเชื่อม: คำศัพท์ร่วมของแอปที่ตายไปพร้อม app.css
   ─────────────────────────────────────────────────────────────────────────
   นี่ไม่ใช่ดีไซน์ใหม่. เจ้าของสั่งตัด app.css ทิ้ง ⇒ คลาสร่วมที่ ~400 โหนด
   ข้ามไฟล์ใช้กันอยู่ (.row .list .field .hint …) ไม่มีกฎเหลือในทั้ง v3.css และ
   ไฟล์นี้ ⇒ หน้าที่ยังไม่ถูกแปลงเป็น v3 กลายเป็นข้อความเปล่าไหลลงมา.
   ทุกบล็อกข้างล่างคือการ **แม็ปคำเก่าไปยังสำนวนของ v3** ตัวต่อตัว:
     .row ⇢ .k3-row · .l1/.l2 ⇢ .k3-row-name/.k3-row-sub · .list ⇢ .k3-body
     .field ⇢ .auth-field input · .label ⇢ .auth-field (+ span) · .hint ⇢ .k3-sub
     .acts ⇢ .k3-btn-row · .card/.panel ⇢ .k3-card · .sk* ⇢ .k3-skel
   เรขาคณิต (padding/gap/size) ยกมาจาก app.css เดิมตรง ๆ เพื่อไม่ให้หน้าที่เคย
   ถูกจูนแล้วขยับ · สีใช้โทเคนของ v3 ล้วน (โหมดสว่างจึงถูกตามอัตโนมัติ)
   ยกเว้นสีสถานะที่เป็นค่าคงที่ตามกฎ.

   ★ ทำไมทุกตัวมี `:not(...)` ★
   ไฟล์นี้โหลด **หลัง** v3.css ⇒ กฎคลาสเดี่ยวของเราชนะฝาแฝดของ v3 ที่
   specificity เท่ากันด้วยลำดับซอร์ส. แต่การแปลงหน้าใช้วิธี **ใส่สองคลาสพร้อมกัน**
   (`class="row k3-row"`, `card k3-card`, `l1 k3-row-name`, `acts k3-acts`,
   `section-label k3-group-label`, `sk k3-skel`, `pcard product-card`,
   `shot product-cover`, `nm product-name`, `editor rz-editor`) ⇒ ถ้าไม่กัน
   คำเก่าจะทับหน้าที่แปลงเสร็จแล้ว (ฟีด · โปรไฟล์ · แชท · ไดเรกทอรี · สินค้า ·
   งาน · บัตรคิว · ตั้งค่า). `:not()` ทำให้กฎนี้แตะเฉพาะโหนดที่ยังไม่มีเจ้าภาพ.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── รายการ + แถว ⇢ .k3-body / .k3-row ─────────────────────────────────────
   ระยะตาม CLAUDE.md: list content 8/16 · gap 6 · row padding 7/10 · radius 14 */
.list:not(.k3-body) { display: flex; flex-direction: column; gap: 6px; padding: 8px 16px; }
.list.cards:not(.k3-body) { gap: 8px; }
.row:not(.k3-row):not(.k3-bill-line) {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px;
  border-radius: var(--radius-md);
  background: var(--bg-input);
  border: 1px solid var(--border);
  text-align: start;              /* .row เป็น <button> ในหลายหน้า — UA ให้ center */
  transition: border-color .12s ease, background-color .12s ease;
}
.row:not(.k3-row):hover { border-color: var(--border-strong); }
/* ปุ่มในกล่องยืนยันไม่ใช่แถวรายการ — `.dialog .row` ข้างบนตั้ง flex/justify ไว้แล้ว
   แต่ (0,2,0) ไม่ได้ล้าง background/border ที่กฎบนเพิ่งใส่ให้ ⇒ ล้างที่นี่ */
.dialog .row { background: none; border: 0; padding: 0; }
.grow { flex: 1 1 auto; min-width: 0; }   /* app.css เคยเขียนซ้ำ ~25 ที่แบบมีสโคป */
/* `overflow`/`text-overflow` ไม่มีผลกับกล่อง inline เลยตาม spec (span คือ inline
   โดยปริยาย) ⇒ ต้องมี `display: block` ไม่งั้นข้อความยาวไหลล้นกล่องแม่แบบไม่ถูก
   ตัดเงียบ ๆ — ชื่อตอนยาวใน .eprow (series.js) ล้นขอบขวาเพราะขาดบรรทัดนี้ */
.l1:not(.k3-row-name) { display: block; font-size: 14px; font-weight: 500; color: var(--text-main);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.l2:not(.k3-row-sub) { display: block; font-size: 12px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.meta { font-size: 11px; color: var(--text-dim); }
.row > .meta { flex: 0 0 auto; text-align: end; max-width: 46%; }
/* หัวข้อกลุ่ม: ห้าม uppercase — ไทย/อาหรับไม่มีตัวพิมพ์ใหญ่ ลำดับชั้นจะหายไป
   เฉพาะภาษาที่แอปนี้มีผู้อ่านจริง. ใช้ขนาด+น้ำหนัก+ระดับสีจาง แทน */
.section-label:not(.k3-group-label) {
  font-size: 13px; font-weight: 700; color: var(--text-dim);
  padding: 12px 16px 2px; text-align: start;
}
.section-label.row { display: flex; align-items: center; gap: 8px; background: none; border: 0; }
/* "ความคิดเห็น0" ติดกันไม่มีช่องว่าง — ตัวเลขจำนวนความคิดเห็นต่อท้ายหัวข้อ
   ต้องมีช่องว่าง/วงเล็บคั่นจากคำ */
.comments-head .n { margin-inline-start: 4px; color: var(--text-dim); font-weight: 700; }
.comments-head .n:not([hidden])::before { content: "("; }
.comments-head .n:not([hidden])::after { content: ")"; }
@media (min-width: 640px) { .row:not(.k3-row):not(.k3-bill-line) { padding: 8px 12px; } }

/* ── ฟอร์ม ⇢ .auth-field / .auth-field input ─────────────────────────────── */
.field:not(.k3-chip) {
  width: 100%; height: 46px; padding: 0 14px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--bg-input); color: var(--text-main);
  font-size: 14px; font-family: inherit;
}
.field:focus, .field:focus-visible {
  outline: none; border-color: var(--border-focus); background: var(--bg-input-focus);
}
.field::placeholder { color: var(--text-dim); }
.field.sm { height: 36px; font-size: 13px; padding: 0 10px; }
textarea.field { height: auto; min-height: 84px; padding: 10px 14px; line-height: 1.5; resize: vertical; }
/* `.label` ในแอปนี้เป็น <label> ที่ **ห่อ** .field ไว้ข้างใน (acctlist, factory,
   procurement) ไม่ใช่ข้อความลอย ⇒ ต้องเป็นคอลัมน์แบบ .auth-field ไม่ใช่ block */
.label { display: flex; flex-direction: column; gap: 5px;
  font-size: 12px; font-weight: 700; color: var(--text-dim); text-align: start; }
.editor:not(.rz-editor) { display: flex; flex-direction: column; gap: 8px; }
.pair { display: grid; grid-template-columns: 1fr; gap: 8px; }   /* มือถือมาก่อน */
@media (min-width: 520px) { .pair { grid-template-columns: 1fr 1fr; } }
.acts:not(.k3-acts) { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.toolbar { display: flex; align-items: center; gap: 8px; padding: 8px 16px 0; flex-wrap: wrap; }
.toolbar .field { flex: 1 1 180px; min-width: 0; width: auto; }
.toolbar .btn { flex: 0 0 auto; }

/* ── ข้อความรอง ⇢ .k3-row-sub / .k3-note ─────────────────────────────────── */
.hint { margin: 0; font-size: 12px; color: var(--text-dim); overflow-wrap: anywhere; }
.hint.warn { color: #F59E0B; } .hint.good { color: #22C55E; } .hint.bad { color: #EF4444; }
.sub:not(.k3-sub) { font-size: 11px; color: var(--text-dim); }
.muted { font-size: 12px; color: var(--text-dim); }
.dim { color: var(--text-dim); }
.lede { margin: 0 0 16px; font-size: 13px; color: var(--text-muted); text-align: center; }
.count { font-size: 12px; font-variant-numeric: tabular-nums; }
.tick { flex: 0 0 auto; color: #22C55E; font-weight: 700; }
/* `.note` เป็นกล่องคำอธิบาย ไม่ใช่ `.k3-note` (ซึ่งเป็นบรรทัดท้ายการ์ด) */
.note { margin-block: 8px; padding: 10px 12px; border-radius: var(--radius-md);
  border: 1px solid var(--border); background: var(--bg-input);
  display: flex; flex-direction: column; gap: 3px;
  font-size: 12px; color: var(--text-muted); }
.note.info { border-color: rgba(14,165,233,.3); background: rgba(14,165,233,.10); }
.note.info .note-title { color: #0EA5E9; font-weight: 700; }

/* ── การ์ด/แผง ⇢ .k3-card ────────────────────────────────────────────────── */
.card:not(.k3-card) {
  display: flex; flex-direction: column; gap: 6px;
  padding: 10px 12px; border-radius: var(--radius-md);
  background: var(--bg-card); border: 1px solid var(--border);
  box-shadow: var(--card-shadow);
}
.card.row:not(.k3-card) { flex-direction: row; align-items: center; gap: 8px; }
.card.row.warn:not(.k3-card) { border-color: rgba(245,158,11,.45); }
.tappable { cursor: pointer; }
.card.tappable:not(.k3-card):hover { border-color: var(--border-strong); }
.panel { display: flex; flex-direction: column; gap: 8px;
  padding: 12px; border-radius: var(--radius-lg);
  background: var(--bg-card); border: 1px solid var(--border); box-shadow: var(--card-shadow); }
.panel h3 { margin: 0; font-size: 14px; font-weight: 700; }

/* ── ยอดรวมในบิล/ใบสั่งผลิต (factory, plugincart) ── */
.totals { display: flex; flex-direction: column; gap: 2px; }
.tline { display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  font-size: 12px; color: var(--text-dim); }
.tline > span:last-child { flex: 0 0 auto; font-variant-numeric: tabular-nums; }
.tline.grand { font-size: 14px; font-weight: 700; color: var(--text-main); }
.tline .amt { color: var(--accent-pink); font-weight: 700; }

/* ── การ์ดสินค้า/ห้องพักที่ยังไม่แปลง (book.js, stay.js, work.js) ───────────
   ทุกตัวกัน `.product-*` ไว้ เพราะ shop.js ใส่สองคลาสคู่กัน (`shot product-cover`,
   `nm product-name`, `pr product-price-row`, `by product-shop`,
   `badge product-off|product-out-tag`) และฝั่ง v3 นั้นถูกจูนแล้ว ห้ามทับ */
.shot:not(.product-cover) {
  position: relative; width: 100%; height: 100%; overflow: hidden;
  border-radius: var(--radius-sm); background: var(--bg-input);
  display: grid; place-items: center; font-size: 24px;
}
.shot:not(.product-cover) img { width: 100%; height: 100%; object-fit: cover; }
/* พ่อที่ไม่ได้บอกความสูงมาเอง (k3-thumb บอก 40px มาแล้ว จึงต้องกันไว้) */
.photo:not(.k3-thumb) > .shot, .mcard > .shot { aspect-ratio: 4 / 3; height: auto; }
.nm:not(.product-name) { margin: 0; font-size: 13px; font-weight: 600; line-height: 1.35;
  color: var(--text-main); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pr:not(.product-price-row) { font-size: 13px; color: var(--text-main); }
.pr s { color: var(--text-dim); font-size: 11px; }
.pr b { color: var(--accent-pink); }
.by:not(.product-shop) { font-size: 11px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* `.badge` ที่เหลือ (นอก shop.js) เป็นป้ายในบรรทัด ไม่ใช่ป้ายทับรูป */
.badge:not(.product-off):not(.product-out-tag) {
  display: inline-flex; align-items: center; padding: 2px 7px;
  border-radius: 10px; font-size: 10px; font-weight: 800;
  background: var(--bg-input); color: var(--text-muted); border: 1px solid var(--border);
}
.badge.sale { background: #EF4444; color: #FFF; border-color: transparent; }
.badge.out  { background: rgba(0,0,0,.7); color: #FFF; border-color: transparent; }

/* ── โครงกระดูก ⇢ .k3-skel (ใช้ keyframes k3-shimmer ของ v3 ซ้ำ ไม่สร้างใหม่)
   นี่คือสถานะ *กำลังโหลด* ล้วน ๆ — ความล้มเหลวมี stateBox("failed") ของตัวเอง */
.sk:not(.k3-skel) {
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--bg-input) 25%, var(--bg-input-focus) 50%, var(--bg-input) 75%);
  background-size: 200% 100%; animation: k3-shimmer 1.2s linear infinite;
}
.sk.circle { border-radius: 50%; }
.sk-lines { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.sk-row { display: flex; align-items: center; gap: 8px; padding: 7px 10px;
  border-radius: var(--radius-md); background: var(--bg-input); }
.sk-card { display: flex; flex-direction: column; gap: 8px; padding: 8px;
  border-radius: var(--radius-lg); background: var(--bg-card);
  border: 1px solid var(--border); box-shadow: var(--card-shadow); }
.sk-card .top { display: flex; align-items: center; gap: 8px; }
/* โครงโพสต์ต้องมีจังหวะเดียวกับ .post-card จริง ไม่งั้นพอโหลดเสร็จจะกระตุก */
.sk-post { position: relative; background: var(--bg-card); overflow: hidden; }
.sk-post::after { content: ""; position: absolute; inset-inline: 0; bottom: 0;
  height: 1px; background: var(--border); pointer-events: none; }
.list.cards > .sk-post:last-child::after { display: none; }
.sk-post .head { display: flex; align-items: center; gap: 8px; padding: 12px 12px 0; }
.sk-post .lines { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.sk-post .txt { display: flex; flex-direction: column; gap: 7px; padding: 8px 12px 0; }
.sk-post .media { margin-top: 8px; border-radius: 0; aspect-ratio: 16 / 10; }
.sk-post .foot { display: flex; gap: 16px; margin-top: 8px;
  padding: 8px 12px; border-top: 1px solid var(--border); }
@media (min-width: 640px) {
  .sk-post .head { padding: 16px 16px 0; }
  .sk-post .txt  { padding: 8px 16px 0; }
  .sk-post .foot { padding: 8px 16px; }
}

/* auth.js/signup-finish.js — v3 ไม่มีคลาสพวกนี้เพราะ demo ไม่มีพาสคีย์/QR/ตัวเลือกภาษา */
.auth-ways { display: flex; flex-direction: column; gap: 10px; }
.auth-way { color: var(--text-muted); }
.auth-fieldhint { text-align: left; margin: -6px 0 12px; }
.auth-langrow {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 14px;
}
.auth-langrow .lang-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 36px;
  padding: 0 14px;
  border-radius: var(--radius-md, 12px);
  border: 1px solid var(--border);
  background: var(--bg-card);
  color: var(--text-main);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.2s ease;
  box-sizing: border-box;
}
.auth-langrow .lang-trigger svg {
  width: 15px;
  height: 15px;
  color: var(--text-muted);
}
.auth-langrow .lang-trigger:hover {
  background: var(--bg-input-focus);
  border-color: var(--border-focus);
  color: var(--text-main);
  transform: translateY(-1px);
}
.auth-langrow .sitelink {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 36px;
  padding: 0 14px;
  border-radius: var(--radius-md, 12px);
  border: 1px solid var(--border);
  background: var(--bg-card);
  color: var(--text-muted);
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
  transition: all 0.2s ease;
  box-sizing: border-box;
}
.auth-langrow .sitelink:hover {
  background: var(--bg-input-focus);
  border-color: var(--border-focus);
  color: var(--text-main);
  transform: translateY(-1px);
}
.auth-langrow .sitelink svg {
  width: 15px;
  height: 15px;
}
.auth-cancel-btn { width: 100%; background: none; border: 0; cursor: pointer;
                   font-family: inherit; font-weight: 700; }
.auth-foot .linkbtn { color: var(--accent-purple, #8B5CF6); font-weight: 700; }

/* มือถือ ≤420px: v3 ตั้ง .auth-card max-width 420px ตายตัว ⇒ ล้นจอที่ 390
   (เดโมทดสอบบนจอกว้างอย่างเดียว) ⇒ บีบตามจอจริง ไม่แตะ v3.css */
.auth-shell { padding: 16px; box-sizing: border-box; }
.auth-card { max-width: min(420px, 100%); box-sizing: border-box; }
@media (max-width: 420px) { .auth-card { padding: 20px 16px 16px; } }
/* v3 ใช้ `place-items:center` ⇒ ลูกถูกวัดขนาดตามเนื้อหา (max-content) ไม่ใช่ตามจอ
   ⇒ ที่ 390px การ์ดกว้างเกินจอแล้วถูกตัดขอบ. ให้ยืดตามคอลัมน์แล้วค่อยจัดกลางเอง */
.auth-shell { justify-items: stretch; align-items: center; }
.auth-card { justify-self: center; }

/* ── หน้าที่พัก/ร้านอาหาร/บริการ (book.js) ── */
.shopbuy { position: sticky; bottom: 0; z-index: 5; }
.shopbuy > .k3-buybar { background: var(--bg-card); }
input.qty-value { width: 44px; text-align: center; background: none; border: 0;
  color: inherit; font: inherit; -moz-appearance: textfield; }
input.qty-value::-webkit-outer-spin-button,
input.qty-value::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.product-age-tag { position: absolute; top: 10px; left: 10px; padding: 3px 8px;
  border-radius: var(--radius-pill); background: #8B5CF6; color: #FFF;
  font-size: 11px; font-weight: 800; }
.rz-editor > .k3-note, .rz-editor > .k3-group-label,
.rz-editor > .k3-bill, .rz-editor > .k3-chip-row { padding-inline: 0; }
.shopfacts { display: flex; flex-direction: column; }
.rel-page .product-grid, .rel-page .category-chips-bar { padding-inline: 0; }
.k3-row.today { border-color: #8B5CF6; }
/* ค้ำอีกชั้น: บังคับความกว้างจากจอจริง (dvw) ไม่ให้ตัวการ์ดตัดสินเอง */
.auth-shell { width: 100%; max-width: 100vw; overflow-x: hidden; }
.auth-card { width: 100%; max-width: min(420px, calc(100vw - 32px)); }

/* ── รีโพสต์ · คลื่นเสียง · ผู้ชมสตอรี่ (v3 ไม่มีคลาสพวกนี้) ── */
.post-quote { margin-top: 10px; padding: 10px; border: 1px solid var(--border);
  border-radius: var(--radius-md, 12px); background: var(--bg-input, rgba(255,255,255,.04));
  cursor: pointer; transition: background .18s ease; }
.post-quote:hover { background: var(--bg-input-focus, rgba(255,255,255,.07)); }
.post-quote-dead { cursor: default; }
.post-quote-dead:hover { background: var(--bg-input, rgba(255,255,255,.04)); }
.post-quote-tag { display:flex; align-items:center; gap:5px; font-size:11.5px; font-weight:600;
  color: var(--text-dim); margin-bottom:6px; }
.post-quote-tag svg { width:13px; height:13px; flex-shrink:0; }
.post-quote-head { display:flex; align-items:center; gap:7px; margin-bottom:5px; }
.post-quote-head .avatar-img, .post-quote-head .av { width:22px; height:22px; border-radius:50%;
  object-fit:cover; flex-shrink:0; font-size:10px; }
.post-quote-name { font-size:12.5px; font-weight:700; color:var(--text-main);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.post-quote-time { font-size: 12px; color:var(--text-dim); margin-inline-start:auto; flex-shrink:0; }
.post-quote-text { font-size:13px; line-height:1.5; color:var(--text-muted);
  display:-webkit-box; -webkit-line-clamp:6; -webkit-box-orient:vertical; overflow:hidden; }
.post-quote-reason { font-size: 12px; color:var(--text-dim); margin-top:3px; }
.post-quote-media { position:relative; margin-top:7px; border-radius:10px; overflow:hidden; }
.post-quote-media img { width:100%; max-height:180px; object-fit:cover; display:block; }
.audio-waveform span { transition: background .12s linear; }
.audio-waveform span.on { background: currentColor; }
.audio-play-btn:disabled { opacity:.5; cursor:not-allowed; }
.audio-bubble audio { display:none !important; }

/* ── ส่งต่อข้อความ — ชีตเลือกห้องปลายทาง (`tpl-forward-sheet`/`tpl-forward-row`,
   chat.js#openForwardSheet, เพิ่ม 2026-09-04) ── */
.fwd-sheet { display: flex; flex-direction: column; gap: 10px; }
.fwd-sheet-preview {
  margin: 0; color: var(--text-dim); font-size: 13px; white-space: pre-wrap;
  overflow-wrap: anywhere; max-height: 3.6em; overflow: hidden;
}
.fwd-sheet-list { display: flex; flex-direction: column; gap: 2px; max-height: 300px; overflow-y: auto; }
.fwd-row { padding-block: 8px; }
.fwd-row-status { flex: 0 0 auto; width: 18px; height: 18px; display: grid; place-items: center; color: var(--text-dim); }
.fwd-row-status svg { width: 16px; height: 16px; }
.fwd-row.picked .fwd-row-status { color: var(--a2); }
.fwd-row.done .fwd-row-status { color: #22C55E; }
.fwd-row.fail .fwd-row-status { color: #EF4444; }
.fwd-row-why { color: #EF4444; }
.fwd-sheet-actions { display: flex; gap: 10px; }
.fwd-sheet-actions .btn { flex: 1; }

/* ── อัดข้อความเสียงบนเว็บ (`tpl-voice-record-bar`/`tpl-voice-staged-bar`,
   chat.js chatComposer(), เพิ่ม 2026-09-04) ── */
.chat-voice-record-bar { align-items: center; gap: 10px; }
.voice-record-dot {
  width: 10px; height: 10px; border-radius: 50%; background: #EF4444; flex: 0 0 auto;
  animation: korat-voice-pulse 1s ease-in-out infinite;
}
@keyframes korat-voice-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.voice-record-time { font-variant-numeric: tabular-nums; color: var(--text-main); flex: 1 1 auto; }
.chat-voice-staged { display: flex; align-items: center; gap: 8px; padding-block: 6px; }
.chat-voice-staged .att-audio { flex: 1 1 auto; min-width: 0; margin-block-start: 0; }
.chat-voice-staged .audio-bubble { min-width: 0; }
.chat-voice-staged .remove-btn {
  position: static; width: 22px; height: 22px; border-radius: 50%; background: #EF4444;
  color: #FFF; font-size: 13px; line-height: 1; display: flex; align-items: center;
  justify-content: center; cursor: pointer; flex: 0 0 auto;
}
.icon-btn-ghost[disabled] { opacity: .4; cursor: default; pointer-events: none; }
.story-viewer-row .av { width:34px; height:34px; border-radius:50%; font-size:13px; flex-shrink:0; }

/* ── อัปโหลดวิดีโอในแชท — แถบความคืบหน้า (`tpl-chat-upload-bar`, chat.js, 2026-09-05) ── */
.chat-upload-bar { align-items: center; gap: 10px; }
.upload-bar-label { color: var(--text-main); font-size: 13px; white-space: nowrap; }
.upload-bar-progress {
  flex: 1 1 auto; height: 6px; appearance: none; border: none; border-radius: 4px; overflow: hidden;
}
.upload-bar-progress::-webkit-progress-bar { background: var(--surface-2); border-radius: 4px; }
.upload-bar-progress::-webkit-progress-value { background: var(--a2); border-radius: 4px; }
.upload-bar-progress::-moz-progress-bar { background: var(--a2); border-radius: 4px; }
.upload-bar-pct { color: var(--text-dim); font-size: 12px; font-variant-numeric: tabular-nums; }

/* ── ฟองวิดีโอในแชท (chat.js attachmentHtml "video", 2026-09-05) ── */
.att-video { position: relative; margin-block-start: 4px; max-width: 260px; border-radius: 10px; overflow: hidden; }
.att-video video { display: block; width: 100%; max-height: 320px; background: #000; border-radius: 10px; }
.att-video .att-video-dur {
  position: absolute; right: 8px; bottom: 8px; background: rgba(0,0,0,.6); color: #fff;
  font-size: 11px; font-weight: 700; padding: 2px 7px; border-radius: 999px; pointer-events: none;
}

/* ── ฟองสติกเกอร์ในแชท — ไม่มีพื้นฟอง ไม่มีกรอบ (chat.js "sticker", 2026-09-05) ── */
.att-sticker { margin-block-start: 4px; }
.att-sticker img { display: block; width: 132px; height: 132px; object-fit: contain; }
.att-sticker-gone {
  display: flex; flex-direction: column; gap: 4px; width: 132px; padding: 10px;
  border-radius: 14px; background: var(--surface-2); color: var(--text-dim); font-size: 11px;
}

/* ── แผงเลือกสติกเกอร์ (`tpl-sticker-picker` และเพื่อน, chat.js openStickerSheet,
   stickers.js, 2026-09-05) ── */
.sticker-picker { display: flex; flex-direction: column; gap: 12px; }
.sticker-picker-notice { margin: 0; }
.sticker-picker-loading { display: flex; flex-direction: column; gap: 8px; }
.sticker-picker-loading .skeleton-row {
  height: 72px; border-radius: 12px; background: var(--surface-2);
  animation: korat-skeleton-pulse 1.1s ease-in-out infinite;
}
@keyframes korat-skeleton-pulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
.sticker-picker-failed { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; color: #EF4444; }
.sticker-picker-empty { color: var(--text-dim); font-size: 13px; margin: 0; }
.sticker-picker-list { display: flex; flex-direction: column; gap: 14px; max-height: 60vh; overflow-y: auto; }
.sticker-pack-section { display: flex; flex-direction: column; gap: 8px; }
.sticker-pack-head { display: flex; align-items: center; gap: 6px; }
.sticker-pack-name { font-weight: 700; font-size: 13px; color: var(--text-dim); }
.sticker-pack-official {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 999px;
  background: rgba(34,197,94,.16); color: #22C55E; font-size: 11px; font-weight: 700;
}
.sticker-pack-lib-btn.active { color: var(--a2); }
.sticker-pack-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.sticker-item { padding: 0; border: none; background: none; cursor: pointer; aspect-ratio: 1; }
.sticker-item-img { width: 100%; height: 100%; object-fit: contain; }

/* ── มือถือ: เนื้อหาต้องเต็มความกว้างจริง ──────────────────────────────
   v3 บรรทัด 1795 ตั้ง `.app-shell{padding:0}` ที่ ≤640px และ `.main-content`
   ไม่มีระยะขอบแนวนอนของตัวเอง ⇒ อะไรที่ทำให้เกิดขอบสองข้างคือของที่เราเติมเอง */
@media (max-width: 640px) {
  .app-shell { padding: 0 !important; gap: 0 !important; }
  .main-content { border-inline: none; padding-inline: 0; }
  /* ฟีดเต็มขอบตาม v3 (การ์ดโพสต์ไม่มีกรอบข้าง) — แต่หน้าที่เป็นการ์ดมีกรอบ
     (เพื่อน · กลุ่ม · แจ้งเตือน · ไดเรกทอรี ฯลฯ) ต้องมีระยะขอบ ไม่งั้นกรอบชนจอ */
  .view-panel, .view-panel > .view, .posts-stream { padding-inline: 0; }
  .rel-page, .k3-body, .dirgrid, .job-list, .list.v3-rows { padding-inline: 12px; }
  /* การ์ดที่วางตรง ๆ ในหน้า (Korat ID · แผน · ตั้งค่า ฯลฯ) ก็ต้องมีขอบเหมือนกัน
     ไม่งั้นกรอบการ์ดชนขอบจอซ้าย-ขวา — คุมที่ตัวการ์ด ไม่ใช่ไล่ทีละหน้า */
  .view > .k3-card, .view > .k3-section, .view-panel > .k3-card { margin-inline: 12px; }
  .rel-page > .notifs-header-bar, .rel-page > .job-tabs, .rel-page > .ptabs { padding-inline: 0; }
  .post-card, .composer-card { border-radius: 0; border-inline: 0; }
  .profile-header-wrap, .profile-cover { border-radius: 0; }
}

/* ── ห้องแชทต้องชิดขอบล่างจริง: ยืดตามพื้นที่ ไม่ใช่ลบเลขจากความสูงจอ ── */
.main-content { display: flex; flex-direction: column; min-height: 0; }
.main-content > .view-panel, .view-panel > .view, .chatsplit-view { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.chat-layout { flex: 1; min-height: 0; }
.chat-room { min-height: 0; }
.chat-room .chat-messages-body { flex: 1; min-height: 0; overflow-y: auto; }
.chat-composer { flex-shrink: 0; padding-bottom: env(safe-area-inset-bottom, 0px); }
@media (min-width: 1025px) {
  .quick-chat-popup { right: calc(var(--rail-right-w, 320px) + 32px); z-index: 60; }
}
.chat-lenwarn { margin: 0; padding: 2px 14px 0; font-size: 11px; }
.chat-lenwarn.bad { color: #EF4444; font-weight: 700; }
/* ── ข้อความแนะนำ (Saved Replies Panel) ── */
.k3-tplpanel {
  border-top: 1px solid var(--border);
  background: var(--bg-card);
  backdrop-filter: blur(20px);
  max-height: 44vh;
  overflow-y: auto;
  padding: 10px 14px 12px;
  animation: slideUpTpl 0.18s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes slideUpTpl {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
.k3-tplhead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding-bottom: 8px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.06));
}
.k3-tpltitle-box {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex: 1;
  min-width: 0;
}
.k3-tpltitle {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-main);
  white-space: nowrap;
}
.k3-tplsub {
  font-size: 11px;
  color: var(--text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.k3-tplclose {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 16px;
  color: var(--text-dim);
  border: none;
  background: transparent;
  cursor: pointer;
  transition: all 0.15s ease;
}
.k3-tplclose:hover {
  background: var(--bg-hover);
  color: var(--text-main);
}
.k3-tplbody {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.k3-tplbar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.k3-tplempty {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--bg-input);
  border: 1px dashed var(--border);
  border-radius: var(--radius-md, 10px);
  color: var(--text-dim);
  font-size: 12px;
  width: 100%;
}
.k3-tplempty-icon {
  font-size: 14px;
  opacity: 0.7;
}
.k3-tplempty-text {
  margin: 0;
}
.k3-tplchip-item {
  display: inline-flex;
  align-items: center;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 2px 4px 2px 10px;
  transition: all 0.15s ease;
  gap: 4px;
}
.k3-tplchip-item:hover {
  border-color: var(--brand);
  background: var(--bg-hover);
}
.k3-tplchip {
  border: none;
  background: transparent;
  color: var(--text-main);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  padding: 3px 0;
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
}
.k3-tpldel {
  border: none;
  background: transparent;
  color: var(--text-dim);
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0;
  transition: all 0.15s;
}
.k3-tpldel:hover {
  background: rgba(239, 68, 68, 0.15);
  color: #EF4444;
}
.k3-tplform {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-top: 4px;
  border-top: 1px dashed var(--border-subtle, rgba(255, 255, 255, 0.06));
}
.k3-tplinput-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.k3-tplinput {
  flex: 1;
  min-width: 0;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 8px 14px;
  font-size: 13px;
  color: var(--text-main);
  outline: none;
  transition: all 0.2s ease;
}
.k3-tplinput:focus {
  border-color: var(--border-focus);
  background: var(--bg-input-focus);
  box-shadow: 0 0 0 3px rgba(139, 61, 255, 0.15);
}
.k3-tplsave-btn {
  flex: 0 0 auto;
  height: 34px;
  padding: 0 16px;
  border-radius: var(--radius-pill);
  font-size: 12px;
  font-weight: 600;
  background: var(--brand-gradient);
  color: #FFF;
  border: none;
  cursor: pointer;
  box-shadow: var(--brand-glow);
  transition: all 0.2s ease;
}
.k3-tplsave-btn:hover {
  background: var(--brand-hover);
  transform: translateY(-1px);
}
.k3-tplscope-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.k3-scope-pill {
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: 600;
  border: 1px solid var(--border);
  background: var(--bg-input);
  color: var(--text-dim);
  cursor: pointer;
  transition: all 0.15s ease;
}
.k3-scope-pill[aria-checked="true"],
.k3-scope-pill.active {
  background: var(--brand-gradient);
  color: #FFF;
  border-color: transparent;
  box-shadow: 0 2px 8px rgba(139, 61, 255, 0.25);
}
.k3-scopenote {
  font-size: 11px;
  color: var(--text-dim);
  margin-inline-start: 4px;
}
.k3-callsheet, .k3-mutesheet { display: flex; flex-direction: column; gap: 10px; }
.k3-mediagrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.k3-mediagrid img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 10px; cursor: zoom-in; }

/* ── หน้าแชท: ตรึงทั้งหน้าไว้ที่ความสูงจอ ให้เลื่อนเฉพาะรายการข้อความ ────
   ปัญหาที่เจ้าของเจอ: ต้องเลื่อนทั้งหน้าลงไปจนสุดถึงจะเจอกล่องพิมพ์
   เพราะ `.app-shell` เป็น min-height:100vh (ยืดได้ไม่จำกัด) ⇒ ห้องยืดตาม
   แล้วกล่องพิมพ์ไปอยู่ท้ายเอกสาร. เฉพาะเส้นทางแชทเท่านั้น หน้าอื่นเลื่อนตามปกติ */
.app-shell[data-route="chat"],
.app-shell[data-route="mchat"] {
  height: 100dvh; min-height: 0; overflow: hidden;
}
.app-shell[data-route="chat"] .main-content,
.app-shell[data-route="mchat"] .main-content { overflow: hidden; min-height: 0; }
.app-shell[data-route="chat"] .left-rail,
.app-shell[data-route="mchat"] .left-rail { overflow-y: auto; }
@media (max-width: 640px) {
  /* แถบล่าง 4 ช่องเป็น position:fixed ⇒ ห้องต้องหลบความสูงของมัน ไม่ใช่ให้ทับ */
  .app-shell[data-route="chat"] .main-content,
  .app-shell[data-route="mchat"] .main-content {
    /* 64px มาจาก margin-bottom ของ v3.css เองแล้ว — เติมซ้ำทำให้เหลือช่องว่างตาย 68px */
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
}

/* ── กล่องพิมพ์ในหน้าต่างแชทลอย: v3 ออกแบบไว้แค่ input เดียว
   แต่ของเรามีปุ่มข้อความสำเร็จรูป + แนบรูป + อีโมจิ ⇒ ช่องพิมพ์ถูกบีบจนตัวหนังสือตกบรรทัด */
.quick-chat-popup .chat-input-bar,
.quick-chat-popup .popup-chat-input-bar {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 10px calc(8px + env(safe-area-inset-bottom, 0px));
  flex-wrap: nowrap; min-width: 0;
}
.quick-chat-popup .chat-input-bar > .icon-btn-ghost,
.quick-chat-popup .chat-input-bar > .ff-pick,
.quick-chat-popup .chat-input-bar > .emoji-wrap,
.quick-chat-popup .chat-input-bar > button:not(.chat-send-btn) {
  flex: 0 0 auto; width: 30px; height: 30px; padding: 0;
  display: grid; place-items: center;
}
.quick-chat-popup .chat-input-bar textarea,
.quick-chat-popup .chat-input-bar input[type="text"] {
  flex: 1 1 auto; min-width: 0; width: auto;
  height: 34px; min-height: 34px; max-height: 84px;
  padding: 7px 12px; line-height: 1.25; font-size: 13px;
  white-space: pre-wrap; overflow-y: auto;
}
.quick-chat-popup .chat-send-btn,
.quick-chat-popup .popup-send-btn { flex: 0 0 auto; width: 36px; height: 36px; }
/* แถวเดียวกันนี้บนมือถือมีที่น้อยกว่า ⇒ ปุ่มเล็กลงอีกขั้น */
@media (max-width: 420px) {
  .quick-chat-popup .chat-input-bar > .icon-btn-ghost { width: 28px; height: 28px; }
}

/* ปุ่มในแถวอวาตาร์ของโปรไฟล์: ไอคอนกลมขนาดเท่ากัน แล้วปุ่มแก้ไขอยู่ท้ายแถว */
.profile-actions-bar .profile-actions-group { display: flex; align-items: center; gap: 8px; }
.profile-actions-bar .icon-btn-ghost { width: 36px; height: 36px; flex: 0 0 auto; border: 1px solid var(--border); border-radius: 999px; }
.profile-actions-bar .icon-btn-ghost svg { width: 18px; height: 18px; }

/* ── Floating Dropdown Menus (openMenu / .menu / .nav-menu) ── */
.menu,
.menu.nav-menu {
  min-width: 200px;
  max-width: 320px;
  background: var(--bg-card, #1A1D2D);
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 14px);
  padding: 6px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.35), 0 4px 14px rgba(0, 0, 0, 0.2);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  display: flex;
  flex-direction: column;
  gap: 3px;
  z-index: 9995;
  outline: none;
}

.menu :is(button, a[role="menuitem"], .menu-item, .nav-item) {
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  width: 100% !important;
  box-sizing: border-box !important;
  padding: 9px 12px !important;
  border-radius: 9px !important;
  border: none !important;
  background: transparent !important;
  color: var(--text-main) !important;
  font-size: 13.5px !important;
  font-weight: 500 !important;
  text-align: start !important;
  text-decoration: none !important;
  cursor: pointer !important;
  line-height: 1.4 !important;
  transition: background 0.15s ease, color 0.15s ease !important;
  user-select: none !important;
  margin: 0 !important;
}

.menu :is(button, a[role="menuitem"], .menu-item, .nav-item):hover,
.menu :is(button, a[role="menuitem"], .menu-item, .nav-item):focus-visible {
  background: var(--bg-input-focus, rgba(255, 255, 255, 0.08)) !important;
  color: var(--text-main) !important;
  outline: none !important;
}

.menu :is(button, a[role="menuitem"], .menu-item, .nav-item).danger,
.menu :is(button, a[role="menuitem"], .menu-item, .nav-item)[style*="color:#EF4444"],
.menu :is(button, a[role="menuitem"], .menu-item, .nav-item)[style*="color: #EF4444"],
.menu :is(button, a[role="menuitem"], .menu-item, .nav-item)[style*="color:#ef4444"] {
  color: var(--accent-red, #EF4444) !important;
}

.menu :is(button, a[role="menuitem"], .menu-item, .nav-item).danger:hover,
.menu :is(button, a[role="menuitem"], .menu-item, .nav-item)[style*="color:#EF4444"]:hover,
.menu :is(button, a[role="menuitem"], .menu-item, .nav-item)[style*="color: #EF4444"]:hover {
  background: rgba(239, 68, 68, 0.12) !important;
  color: var(--accent-red, #EF4444) !important;
}

.menu :is(button, a[role="menuitem"], .menu-item, .nav-item).warn {
  color: var(--amber, #F59E0B) !important;
}

.menu :is(button, a[role="menuitem"], .menu-item, .nav-item).warn:hover {
  background: rgba(245, 158, 11, 0.12) !important;
}

.menu .menu-icon,
.menu :is(button, a[role="menuitem"], .menu-item, .nav-item) > svg {
  width: 17px !important;
  height: 17px !important;
  flex: 0 0 auto !important;
  opacity: 0.85 !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: inherit !important;
}

.menu .menu-label,
.menu :is(button, a[role="menuitem"], .menu-item, .nav-item) > span:not(.menu-icon) {
  flex: 1 1 auto !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}

/* ชื่อผู้โพสต์ต้องไม่ตกบรรทัด — บีบด้วย ellipsis แทน (มือถือชื่อยาวจะขึ้นสองบรรทัด
   เพราะ .post-user-meta ไม่ได้ตั้ง min-width:0 ⇒ flex ให้ความกว้างตามเนื้อหาแล้วตัดบรรทัด) */
.post-header { min-width: 0; }
.post-user-meta { min-width: 0; flex: 1 1 auto; }
.post-author-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; }
.post-author-row .author-name {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.post-user-meta .user-handle, .post-user-meta .post-time {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.post-meta-row { min-width: 0; }
.post-more-btn { flex: 0 0 auto; }

/* มือถือ: v3 ใส่ชื่อ + @ผู้ใช้ + เวลา ไว้แถวเดียวกัน (จอกว้างพอ)
   ที่ 390px แถวเดียวทำให้ทุกอย่างถูกตัดด้วยจุดไข่ปลาจนอ่านไม่ออก
   ⇒ ให้ชื่ออยู่บรรทัดแรก แล้ว @ผู้ใช้ + เวลา ตกลงบรรทัดที่สองแทนการตัดคำ */
@media (max-width: 640px) {
  .post-author-row { flex-wrap: wrap; row-gap: 2px; }
  .post-author-row .author-name {
    flex: 1 1 100%; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .post-meta-row .user-handle,
  .post-meta-row .post-time { font-size: 12px; }
}

/* ที่ 390px แถวชื่อมีได้ถึง 6 ชิ้น (ชื่อ · ติ๊ก · Korat ID · @ผู้ใช้ · เวลา · เฉพาะเพื่อน)
   ⇒ v3 มี 5 และไม่มี «เฉพาะเพื่อน» ⇒ ซ่อนสองป้ายที่ไม่ใช่ตัวตนบนจอแคบ
   (ยังอยู่ในหน้าโพสต์เดี่ยวและจอกว้าง — ไม่ได้ลบข้อมูลทิ้ง) */
@media (max-width: 640px) {
  .post-meta-row .k3-badge { display: none; }
}

/* ปุ่มโพสต์เป็นไอคอนล้วนตามที่เจ้าของสั่ง (ข้อความโชว์เฉพาะตอนกำลังอัปโหลด/โพสต์) */
.btn-publish-icon { min-width: 44px; padding-inline: 14px; }
.btn-publish-icon [data-sendlabel]:not([hidden]) { margin-inline-end: 6px; }

/* แถบป้ายต้องอยู่ในแถวหัว 56px แถวเดียวแบบ v3 — ห้ามตกบรรทัดแล้วทับ «💬 แชท» */
.app-shell[data-route="chat"] .top-header { flex-wrap: nowrap; }
.app-shell[data-route="chat"] .top-header .header-actions {
  flex: 1 1 auto; min-width: 0; justify-content: flex-end;
}
.app-shell[data-route="chat"] .top-header .header-actions > [data-colacts] {
  flex: 1 1 auto; min-width: 0; display: flex;
}
.app-shell[data-route="chat"] .top-header .header-title-wrap { flex: 0 0 auto; }
.app-shell[data-route="chat"] .top-header .header-actions > .icon-btn-ghost { flex: 0 0 auto; }
/* v3 ซ่อนหัวเรื่องที่ ≤900px เพื่อให้ชิปกินทั้งแถว — แต่กฎนั้นครอบทั้งแอป
   ⇒ หน้าอื่นต้องมีหัวเรื่องเหมือนเดิม */
@media (max-width: 900px) {
  .app-shell:not([data-route="chat"]) .header-title-wrap h2 { display: block; }
}

/* ── แถวพิมพ์ข้อความ: ไอคอนชิดกัน ช่องพิมพ์กว้างเต็มที่เหลือ ── */
.chat-input-bar {
  gap: 2px;
  padding-top: 6px;
  padding-bottom: 8px;
  padding-inline: 8px;
}
.chat-input-bar > .icon-btn-ghost,
.chat-input-bar > .ff-pick,
.chat-input-bar > .emoji-wrap,
.chat-input-bar > button:not(.chat-send-btn) { flex: 0 0 auto; width: 34px; height: 34px; }
.chat-input-bar textarea { flex: 1 1 auto; min-width: 0; margin-inline: 6px; }
.chat-input-bar .chat-send-btn { margin-inline-start: 4px; }

/* ── รายการโทร: v3 มีฟองเดียว ของเรามีการ์ดซ้อนในฟองอีกชั้น ──
   ข้างในฟองข้อความไม่ต้องมีกรอบ/พื้นของตัวเองอีก */
.msg-bubble .att-card.call {
  border: 0; background: transparent; padding: 0; margin: 0;
}
.msg-bubble .att-card.call small { color: inherit; opacity: .85; }
.msg.mine .msg-bubble .att-card.call, .msg-group.outgoing .att-card.call { color: #fff; }

/* ── การ์ดเมนู/สินค้า: ล็อกสัดส่วนรูปให้เท่ากันทุกใบ ────────────────────
   v3 ตั้ง `.product-cover { height: 170px }` แต่การ์ดของเราบางใบไม่มีรูป
   (แสดงไอคอนแทน) และรูปที่สูงกว่ากรอบดันการ์ดจนสูงไม่เท่ากันทั้งแถว */
.product-grid { align-items: start; }
.product-card { display: flex; flex-direction: column; height: 100%; }
.product-cover, .shot.product-cover {
  height: 170px; min-height: 170px; flex: 0 0 auto;
  overflow: hidden; display: grid; place-items: center;
}
.product-cover > img, .shot.product-cover > img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.product-body { flex: 1 1 auto; display: flex; flex-direction: column; }
.product-actions, .k3-btn-row.product-actions { margin-top: auto; }
@media (max-width: 640px) {
  .product-cover, .shot.product-cover { height: 140px; min-height: 140px; }
}

/* ── ตัวเปิดรูป (v3 `.lightbox-*`) + แผงเลือกซีรีส์ ── */
.lightbox-shell.no-side { grid-template-columns: minmax(0, 1fr); }
.lightbox-panel-post { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.lightbox-post > * { flex: 1; min-width: 0; }
.lightbox-bar { position: absolute; top: 10px; inset-inline-end: 10px; z-index: 4;
  display: flex; align-items: center; gap: 6px; }
.lightbox-btn { width: 32px; height: 32px; display: grid; place-items: center;
  border: 0; border-radius: 50%; background: rgba(0,0,0,.45); color: #FFF;
  font-size: 15px; line-height: 1; cursor: pointer; text-decoration: none; }
.lightbox-btn:hover { background: rgba(0,0,0,.7); }
.lightbox-note { font-size: 11.5px; color: rgba(255,255,255,.7); max-width: 40vw;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lightbox-note.warn { color: #F59E0B; }
.lightbox-hint { position: absolute; bottom: 10px; inset-inline-start: 12px; margin: 0;
  font-size: 11px; color: rgba(255,255,255,.45); pointer-events: none; }
.lightbox-acts { display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 12px;
  border-top: 1px solid var(--border); }
.lightbox-act { display: inline-flex; align-items: center; gap: 5px;
  padding: 7px 10px; border: 0; border-radius: var(--radius-pill);
  background: var(--bg-input); color: var(--text-muted);
  font-size: 12.5px; font-weight: 600; cursor: pointer; }
.lightbox-act.on { color: var(--accent-green, #22C55E); }
.lightbox-act .ic svg { width: 15px; height: 15px; }
.lightbox-act .n { color: var(--text-dim); font-weight: 700; }
.lightbox-img { transition: transform .18s ease; will-change: transform; }
.lightbox-img.soft { filter: blur(.4px); }
.lightbox-modal.zoomed .lightbox-img,
.lightbox-modal.dragging .lightbox-img { transition: none; }
.lightbox-modal.dragging { background: rgba(0, 0, 0, calc(.85 * var(--lightbox-dim, 1))); }
.serieslist { display: flex; flex-direction: column; gap: 4px;
  max-height: min(46vh, 380px); overflow-y: auto; margin: 4px 0; }
.dlgfield { display: flex; flex-direction: column; gap: 5px; margin-top: 10px;
  font-size: 12.5px; font-weight: 600; color: var(--text-dim); }

/* ── จอสาย (webrtc.js) ── */
.k3-call{position:fixed;inset:0;z-index:1200;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:12px;padding:16px;
  background:rgba(8,10,18,.96);color:#fff;text-align:center}
.k3-call-incoming,.k3-call-active{display:flex;flex-direction:column;align-items:center;gap:10px}
.k3-call-active{width:100%;max-width:720px}
.k3-call-avatar{width:96px;height:96px}
.k3-call-name{font-size:20px;font-weight:700}
.k3-call-sub,.k3-call-status,.k3-call-timer{opacity:.8}
.k3-call-timer{font-variant-numeric:tabular-nums}
.k3-call-note{opacity:.6;font-size:12px;max-width:40ch}
.k3-call-remote{width:100%;max-height:60vh;background:#000;border-radius:16px;object-fit:cover}
.k3-call-local{position:fixed;right:16px;bottom:96px;width:120px;border-radius:12px;
  background:#000;object-fit:cover}
.k3-call-actions,.k3-call-controls{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;margin-top:8px}
.k3-call-actions{gap:16px}

/* ── กล่องคอมเมนต์: ตรึงไว้ล่างจอเสมอ (v3 `.comment-input-row` ติดล่างการ์ด) ── */
/* ต้องตรึงจริงที่ขอบล่างจอ — `sticky` ไม่พอเพราะพ่อของมันเลื่อนไปกับหน้า
   เจ้าของบอกซ้ำหลายรอบว่ามันยังไม่ชิดล่าง ⇒ ใช้ fixed ผูกกับจอตรง ๆ */
.commentbox.commentbox-sticky {
  position: sticky; bottom: 0; z-index: 20;
  background: var(--bg-card); border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.commentbox-sticky .comment-input-row { padding: 8px 12px; }
.commentbox-sticky .comment-field-wrap { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px; }
.commentbox-sticky .comment-input { flex: 1 1 auto; min-width: 0; }

/* แถวปุ่มในแผงข้างของตัวเปิดรูป: ไอคอนต้องขนาดเท่ากันและอยู่ในปุ่มเดียวกับข้อความ
   (ไอคอนหัวใจของฟีดไม่มีขนาดของตัวเอง ⇒ ในแผงนี้มันพองเป็นขนาดเริ่มต้นของ svg) */
.lightbox-acts { align-items: center; }
.lightbox-act { flex: 0 0 auto; line-height: 1; }
.lightbox-act svg, .lightbox-act .heart-icon {
  width: 18px; height: 18px; flex: 0 0 auto; display: block;
}
.lightbox-act .ic { display: inline-flex; align-items: center; }
.lightbox-panel-post .post-actions { gap: 10px; padding: 10px 12px; }
.lightbox-panel-post .post-actions .action-btn { gap: 6px; }
.lightbox-panel-post .post-actions svg { width: 20px; height: 20px; flex: 0 0 auto; }

/* ปุ่มปิดตัวเปิดรูป: v3 ตั้งไว้ 36px ซึ่งใหญ่เกินบนจอจริง — ย่อลงให้พอเหมาะ
   แต่ยังมีพื้นที่กดอย่างน้อย 40px ตามข้อกำหนดขนาดปุ่มบนมือถือ */
.lightbox-close {
  top: 12px; right: 14px;
  width: 40px; height: 40px; padding: 0;
  display: grid; place-items: center;
  font-size: 22px; line-height: 1;
  border-radius: 50%; background: rgba(0,0,0,.45);
}
.lightbox-close:hover { background: rgba(0,0,0,.7); }
@media (max-width: 640px) { .lightbox-close { top: 8px; right: 8px; width: 36px; height: 36px; font-size: 20px; } }

/* พื้นที่เผื่อไม่ให้กล่องคอมเมนต์ทับคอมเมนต์ใบสุดท้าย + หลบแถบล่างบนมือถือ */
.app-shell[data-route="post"] .main-content { padding-bottom: 96px; }
@media (max-width: 640px) {
  /* มือถือ: ตรึงกับจอจริง วางชิดบนแถบเมนูล่างพอดี ไม่เหลือช่องว่างคั่น
     (sticky ทิ้งพื้นหลังของหน้าไว้ใต้กล่อง ⇒ เห็นเป็นแถบขาวโล่ง) */
  .commentbox.commentbox-sticky {
    position: fixed; left: 0; right: 0;
    bottom: calc(64px + env(safe-area-inset-bottom, 0px));
    padding-bottom: 0; z-index: 40;
  }
  .app-shell[data-route="post"] .main-content { padding-bottom: 132px; }
}

/* ⚠ กล่องคอมเมนต์ที่ตรึงกับจอ ต้องไม่หลุดออกมาทับตัวเปิดรูป/กล่องโต้ตอบ
   ในแผงข้างของ lightbox มันต้องอยู่กับที่ตามปกติ ไม่ใช่ตรึงกับหน้าจอ */
.lightbox-modal .commentbox.commentbox-sticky,
.scrim .commentbox.commentbox-sticky,
.sheet-modal .commentbox.commentbox-sticky {
  position: static; left: auto; right: auto; bottom: auto; width: auto; z-index: auto;
  border-top: 1px solid var(--border);
}

/* ตัวนับตัวอักษร: แสดงตัวเลข 0/500 เสมอ ชัดเจน และเปลี่ยนสีเมื่อใกล้เต็ม/เกินลิมิต */
.charcount {
  display: inline-flex;
  align-items: center;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-dim, #94A3B8);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  user-select: none;
  padding: 4px 8px;
  border-radius: 6px;
  transition: all 0.15s ease;
}
.charcount .num { display: inline !important; }
.charcount.near .num { color: var(--amber, #F59E0B) !important; font-weight: 700 !important; }
.charcount.over .num {
  color: var(--red, #EF4444) !important;
  font-weight: 800 !important;
  background: rgba(239, 68, 68, 0.12);
  padding: 2px 6px;
  border-radius: 4px;
}

/* ชื่อ/บรรทัดรองในแถวคน: ตัดด้วย … ไม่ให้แถวสูงไม่เท่ากันทั้งหน้า */
.rel-row .follow-name, .rel-row .follow-handle {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ไอคอนแทนอีโมจิ: ล็อกขนาดต่อบทบาท ไม่ให้ svg พองเป็น 300×150 */
.k3-h3-icon, .k3-row-icon, .k3-fact-icon, .k3-av-icon {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto; color: inherit; vertical-align: -.18em;
}
.k3-h3-icon svg { width: 18px; height: 18px; }
.k3-row-icon svg { width: 20px; height: 20px; }
.k3-fact-icon svg { width: 14px; height: 14px; }
.k3-av-icon svg { width: 20px; height: 20px; }
.k3-av-icon { color: var(--text-dim); }
.k3-h3-icon { margin-inline-end: 6px; }
.k3-state svg { width: 28px; height: 28px; }

/* แถวปุ่มของตัวเปิดรูป: ทุกปุ่มขนาดเดียวกัน ระยะเท่ากัน และอยู่แนวเดียวกับปุ่มปิด */
.lightbox-bar { top: 12px; inset-inline-end: 62px; gap: 8px; align-items: center; }
.lightbox-btn { width: 40px; height: 40px; border-radius: 50%; padding: 0; }
.lightbox-btn svg { width: 20px; height: 20px; display: block; }
@media (max-width: 640px) {
  .lightbox-bar { inset-inline-end: 52px; top: 8px; gap: 6px; }
  .lightbox-btn { width: 36px; height: 36px; }
  .lightbox-btn svg { width: 18px; height: 18px; }
}
/* แถวปุ่มใต้โพสต์: กระจายเต็มความกว้างเท่า ๆ กัน ไม่กองซ้าย */
.lightbox-panel-post .post-actions { justify-content: space-between; }
.lightbox-panel-post .post-actions .action-btn { flex: 1 1 0; justify-content: center; }

/* ── ตัวเปิดรูป: กล่องคอมเมนต์และแถวปุ่มต้องอยู่ชิดขอบล่างของกล่องเสมอ ──
/* ── แผงด้านข้างตัวดูรูป (Lightbox Sidebar & Mobile Layout) ── */
.lightbox-shell {
  display: grid;
  grid-template-columns: 360px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  width: min(1120px, 94vw);
  height: min(700px, 88vh);
  border-radius: var(--radius-lg, 18px);
  overflow: hidden;
  background: var(--bg-card);
  box-shadow: var(--modal-shadow);
}

.lightbox-side {
  height: 100%;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg-card);
  border-right: 1px solid var(--border);
  overflow: hidden;
}

/* `.lightbox-panelbody` is the ONE scroller for the whole side panel — long
   caption text (up to the 5,000-char plan ceiling) and the comment thread
   both live inside it, so the reader scrolls ONE surface, not two nested
   mini-scrollboxes. `.lightbox-acts` and the comment composer are `position:
   sticky` (see below) against THIS element, which is why it — not
   `.lightbox-panel-post` — is the one that scrolls. */
.lightbox-panelbody {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
  height: 100%;
}

.lightbox-panel-post {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: visible;
}

.lightbox-post {
  flex: 0 0 auto;
  border-bottom: 1px solid var(--border);
  padding: 10px 14px;
}

.lightbox-post .post-header {
  margin-bottom: 0;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
}

.lightbox-post .post-user-meta {
  flex: 1 1 auto;
  min-width: 0;
}

.lightbox-post .post-more-btn {
  flex: 0 0 auto;
  margin-left: auto;
}

/* No cap, no inner scrollbar: a 5,000-character post reads exactly like a
   50-character one — it just makes the ONE scroller (`.lightbox-panelbody`)
   taller. `.lb-more` ("อ่านต่อ") from `postBodyNode({ clamp: true })` still
   shows the first 255 characters first; expanding it grows this element in
   place instead of opening a second surface. */
.lightbox-caption {
  flex: 0 0 auto;
  border-bottom: none;
  padding: 10px 14px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-main);
}

/* Sticks to the top of `.lightbox-panelbody` once the caption above it has
   scrolled past — the like/comment/share row a report specifically asked to
   never be "pushed away". */
.lightbox-acts {
  position: sticky;
  top: 0;
  z-index: 6;
}

.lightbox-comments {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 0;
  position: relative;
}

.lightbox-comments .comments-thread {
  flex: 1 1 auto;
  min-height: 0;
  padding: 10px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Sticks to the bottom of `.lightbox-panelbody` — the comment composer must
   never scroll out of reach either, whatever the caption's length. */
.lightbox-comments .composer-container,
.lightbox-panel-post .composer-container {
  flex: 0 0 auto;
  margin-top: auto;
  border-top: 1px solid var(--border);
  background: var(--bg-card);
  position: sticky;
  bottom: 0;
  z-index: 15;
}

.lightbox-modal .commentbox {
  position: static !important;
  background: var(--bg-card) !important;
  padding: 0 !important;
  border-top: 0 !important;
  display: block !important;
  width: 100% !important;
}

.lightbox-modal .comment-input-row {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  padding: 8px 12px !important;
}

.lightbox-modal .comment-field-wrap {
  flex: 1 1 auto !important;
  min-width: 0 !important;
  display: flex !important;
  align-items: center !important;
  gap: 6px !important;
  background: var(--bg-input) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-pill, 999px) !important;
  padding: 4px 10px !important;
}

.lightbox-modal .comment-input {
  flex: 1 1 auto !important;
  min-width: 0 !important;
  border: none !important;
  background: transparent !important;
  padding: 4px 6px !important;
  font-size: 13px !important;
  color: var(--text-main) !important;
  outline: none !important;
  resize: none !important;
}

.lightbox-modal .send-comment-btn {
  flex: 0 0 auto !important;
  padding: 4px 12px !important;
  border-radius: var(--radius-pill, 999px) !important;
  background: var(--brand-gradient) !important;
  color: #FFF !important;
  font-size: 12px !important;
  font-weight: 700 !important;
  border: none !important;
  cursor: pointer !important;
}

.lightbox-acts {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: 6px 12px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--bg-card);
  gap: 6px;
}

.lightbox-act {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 7px 10px;
  border-radius: var(--radius-md, 8px);
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s ease;
}

.lightbox-act:hover {
  background: var(--bg-input);
  color: var(--text-main);
}

.lightbox-act.on {
  color: var(--accent-pink, #E11D48);
}

.lightbox-act.on svg {
  fill: currentColor;
}

.lightbox-act .ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.lightbox-act svg, .lightbox-act .heart-icon {
  width: 18px;
  height: 18px;
  display: block;
}

.lightbox-act .n {
  font-size: 12px;
  font-weight: 700;
  opacity: 0.85;
}

/* ── Lightbox Mobile Responsiveness Override ── */
@media (max-width: 860px) {
  .lightbox-shell {
    grid-template-columns: 1fr !important;
    grid-template-rows: minmax(160px, 40%) minmax(260px, 60%) !important;
    width: min(96vw, 600px) !important;
    height: min(92vh, 720px) !important;
    max-height: 92vh !important;
  }

  .lightbox-stage {
    order: 1 !important;
    min-height: 160px !important;
  }

  .lightbox-side {
    order: 2 !important;
    border-right: none !important;
    border-top: 1px solid var(--border) !important;
    height: 100% !important;
    max-height: 100% !important;
    min-height: 0 !important;
    display: flex !important;
    flex-direction: column !important;
  }

  /* `.lightbox-panelbody` stays the one scroller on mobile too (see the
     desktop rule above) — only its own box needs a hard 100% height here,
     because on mobile `.lightbox-side` is the bottom 60% of a fixed-height
     sheet, not free to grow with the page. */
  .lightbox-panelbody {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: 100% !important;
  }

  .lightbox-panel-post {
    flex: 1 1 auto !important;
    min-height: 0 !important;
  }

  .lightbox-comments {
    flex: 1 1 auto !important;
    min-height: 100px !important;
  }
}

/* Comment Box Input Styling & No scrollbar track in single line */
.comment-input-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  width: 100%;
  box-sizing: border-box;
}
.comment-field-wrap {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 3px 6px 3px 14px;
  min-height: 36px;
  box-sizing: border-box;
}
textarea.comment-input {
  flex: 1 1 auto;
  min-width: 0;
  background: transparent;
  border: none;
  outline: none;
  font-size: 13px;
  line-height: 1.4;
  color: var(--text-main);
  resize: none;
  overflow-y: hidden;
  scrollbar-width: none;
  font-family: inherit;
  padding: 4px 0;
  height: 22px;
  max-height: 100px;
  box-sizing: border-box;
}
textarea.comment-input::-webkit-scrollbar {
  display: none;
}
.send-comment-btn {
  flex: 0 0 auto;
  padding: 4px 14px;
  height: 28px;
  border-radius: var(--radius-pill);
  background: var(--brand-gradient);
  color: #FFF;
  font-size: 12px;
  font-weight: 700;
  border: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.15s ease;
}
.send-comment-btn:hover {
  opacity: 0.92;
}
.tool-btn.emoji-inline,
.comment-field-wrap [data-emojislot] {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  cursor: pointer;
  padding: 0;
  color: var(--text-dim);
}
.tool-btn.emoji-inline:hover {
  color: var(--text-main);
}
.tool-btn.emoji-inline svg {
  width: 18px;
  height: 18px;
}

/* ── หน้าโพสต์เดี่ยวบนเดสก์ท็อป ──
   1) การ์ดคอมเมนต์ต้องมีระยะขอบสองข้าง ไม่ชนกรอบคอลัมน์
   2) กล่องพิมพ์ต้องตรึงล่างจอจริง — `sticky` ไม่ทำงานเพราะพ่อของมันสูงเท่ากล่องเอง
      (ไม่มีระยะให้เลื่อน) ⇒ ตรึงกับจอ แล้วคำนวณความกว้างจากคอลัมน์กลางของ v3
      (grid 210/260px + 340px + gap 16px + padding 12px, กล่องกลาง max 1280px) */
/* ── หน้าโพสต์เดี่ยว (data-route="post"): ฟอร์มคอมเมนต์กว้างเต็มคอลัมน์ชิดขอบซ้าย-ขวา ── */
.app-shell[data-route="post"] .comments-list {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}
.app-shell[data-route="post"] .comments-thread {
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.app-shell[data-route="post"] .composer-container,
.app-shell[data-route="post"] .commentbox.commentbox-sticky {
  position: sticky;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 25;
  width: 100%;
  margin: 0;
  padding: 10px 16px;
  box-sizing: border-box;
  background: var(--bg-card);
  border-top: 1px solid var(--border);
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.04);
}
.app-shell[data-route="post"] .commentbox-sticky .comment-input-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin: 0;
  padding: 0;
}
.app-shell[data-route="post"] .commentbox-sticky .comment-field-wrap {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
}
@media (max-width: 640px) {
  .app-shell[data-route="post"] .composer-container,
  .app-shell[data-route="post"] .commentbox.commentbox-sticky {
    position: fixed;
    left: 0;
    right: 0;
    bottom: calc(64px + env(safe-area-inset-bottom, 0px));
    z-index: 40;
    padding: 8px 12px;
  }
}

/* ── กล่องสร้างสตอรี่ ── เดสก์ท็อปเป็นกล่องแนวกว้าง: พรีวิวซ้าย ตัวเลือกขวา
   มือถือเรียงลงมาเป็นคอลัมน์เดียวเหมือนเดิม */
.dialog.story-dialog {
  max-width: 880px; max-height: min(90vh, 820px); overflow: auto;
  padding: 20px 22px 18px;
}
.story-dialog-cols { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 20px; align-items: start; }
.story-dialog-preview { position: sticky; top: 0; }
.story-dialog-fields { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.story-dialog-fields .dlgfield { margin: 0; }
.story-dialog .field { width: 100%; }
.story-dialog-acts { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.story-dialog [data-swatches] .swatch,
.story-dialog [data-swatches] button { flex: 0 0 auto; }
@media (max-width: 720px) {
  .dialog.story-dialog { max-width: 420px; padding: 18px; }
  .story-dialog-cols { grid-template-columns: 1fr; gap: 14px; }
  .story-dialog-preview { position: static; max-width: 220px; margin-inline: auto; }
}

/* ── บันทึกการโทรในห้องแชท (Modern Call Record Card) ── */
.msg-bubble:has(> .chat-call-card),
.msg-bubble:has(> .att-card.call),
.bubble:has(> .chat-call-card),
.bubble:has(> .att-card.call) {
  background: none !important;
  box-shadow: none !important;
  padding: 0 !important;
  border: 0 !important;
}

.chat-call-card {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 18px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
  max-width: 320px;
  min-width: 170px;
  user-select: none;
}

.chat-call-card:hover {
  border-color: var(--border-strong, var(--border));
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
  transform: translateY(-1px);
}

.chat-call-card .call-icon-badge {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: transform 0.2s ease;
}

.chat-call-card:hover .call-icon-badge {
  transform: scale(1.06);
}

.chat-call-card .call-icon-badge svg {
  width: 20px;
  height: 20px;
}

/* สถานะ: สายที่คุยสำเร็จ (Completed Call with duration) */
.chat-call-card.call-completed .call-icon-badge {
  background: rgba(16, 185, 129, 0.12);
  color: #10B981;
}
[data-theme="dark"] .chat-call-card.call-completed .call-icon-badge {
  background: rgba(16, 185, 129, 0.2);
  color: #34D399;
}

/* สถานะ: สายที่ไม่ได้รับ / ยกเลิก / ปลายทางไม่ว่าง (Missed / Unreached / Busy) */
.chat-call-card.call-missed .call-icon-badge {
  background: rgba(239, 68, 68, 0.12);
  color: #EF4444;
}
[data-theme="dark"] .chat-call-card.call-missed .call-icon-badge {
  background: rgba(239, 68, 68, 0.2);
  color: #F87171;
}

.chat-call-card .call-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  text-align: start;
}

.chat-call-card .call-title {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text-main);
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-call-card.call-missed .call-title {
  color: #EF4444;
}
[data-theme="dark"] .chat-call-card.call-missed .call-title {
  color: #F87171;
}

.chat-call-card .call-desc {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-dim);
  line-height: 1.2;
}

/* รูปร่างมุมบับเบิลให้เข้ากับฝั่ง Outgoing / Incoming */
.msg-group.outgoing .chat-call-card,
.msg.mine .chat-call-card {
  border-bottom-right-radius: 4px;
}
.msg-group.incoming .chat-call-card,
.msg:not(.mine) .chat-call-card {
  border-bottom-left-radius: 4px;
}

/* ===== แท็บในหน้าโปรไฟล์ (albums, series, friends, followers, personal-info) ===== */
.profile-tab-pane,
.albums-tab,
.series-tab,
.friends-tab,
.followers-tab,
.personal-info-tab {
  padding: 14px 16px;
  box-sizing: border-box;
}
@media (min-width: 768px) {
  .profile-tab-pane,
  .albums-tab,
  .series-tab,
  .friends-tab,
  .followers-tab,
  .personal-info-tab {
    padding: 16px 20px;
  }
}

.albums-tab { display: flex; flex-direction: column; gap: 12px; }
.albums-tab .section-label.row { padding: 0; margin-bottom: 2px; }
.album-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin-top: 4px;
}
@media (min-width: 600px)  { .album-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; } }
@media (min-width: 900px)  { .album-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; } }
@media (min-width: 1200px) { .album-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; } }

.album-card {
  display: flex; flex-direction: column; text-align: start;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--card-shadow);
  padding: 0; cursor: pointer; font: inherit; color: inherit;
  min-width: 0; min-height: 0;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.album-card:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong, var(--border));
  box-shadow: 0 6px 20px rgba(0,0,0,0.12);
}
.album-cover {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  min-height: 0;
  overflow: hidden;
  background: var(--bg-input, var(--bg-header));
}
.album-cover img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.album-cover.noimg {
  display: flex; align-items: center; justify-content: center;
  position: relative; width: 100%; aspect-ratio: 1 / 1;
}
.album-cover.noimg .k3-row-icon svg { width: 32px; height: 32px; color: var(--text-dim); }
.album-count {
  position: absolute; left: 8px; bottom: 8px; padding: 2px 8px;
  border-radius: var(--radius-pill); background: rgba(0,0,0,0.68); color: #FFF;
  font-size: 11px; font-weight: 700; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
}
.album-vis {
  position: absolute; right: 8px; top: 8px; padding: 2px 8px;
  border-radius: var(--radius-pill); background: rgba(0,0,0,0.68); color: #FFF;
  font-size: 11px; font-weight: 700; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
}
.album-meta { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; min-width: 0; }
.album-meta .l1 { font-size: 14px; font-weight: 700; color: var(--text-main); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.album-meta .l2 { font-size: 12px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.album-back { margin-bottom: 8px; }
.album-head { display: flex; flex-direction: column; gap: 8px; padding: 4px 0 12px; }
.album-sub-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 4px;
}
.album-sub-count {
  font-size: 13px;
  color: var(--text-dim);
  font-weight: 600;
}
.album-photogrid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 8px;
}
@media (min-width: 600px)  { .album-photogrid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; } }
@media (min-width: 900px)  { .album-photogrid { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; } }
.album-photo {
  position: relative; width: 100%; aspect-ratio: 1 / 1;
  border-radius: var(--radius-sm, 10px); overflow: hidden; background: var(--bg-input, var(--bg-header));
}
.album-photo img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in;
}
.album-photo-del {
  position: absolute; top: 4px; right: 4px; width: 24px; height: 24px;
  border-radius: 50%; border: none; background: rgba(0,0,0,0.68); color: #FFF;
  font-size: 13px; line-height: 1; display: flex; align-items: center; justify-content: center; cursor: pointer;
  z-index: 2;
}
.album-photo-del:hover { background: #EF4444; }

/* ── ซีรีส์ (series.js) & ส่วนหัวแท็บโปรไฟล์ ── */
.series-tab { display: flex; flex-direction: column; gap: 14px; }
.profile-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 2px 0 6px;
}
.profile-section-title-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
}
.profile-section-title {
  font-size: 18px;
  font-weight: 800;
  color: var(--text-main);
  letter-spacing: -0.01em;
}
.profile-section-badge {
  font-size: 12px;
  font-weight: 700;
  color: var(--accent-purple, #8B5CF6);
  background: rgba(139, 92, 246, 0.12);
  padding: 2px 8px;
  border-radius: 999px;
}
.btn-profile-action {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-main);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
  transition: all 0.15s ease;
}
.btn-profile-action:hover {
  border-color: var(--accent-purple, #8B5CF6);
  color: var(--accent-purple, #8B5CF6);
  box-shadow: 0 2px 8px rgba(139, 92, 246, 0.12);
  transform: translateY(-1px);
}
.btn-profile-action .btn-icon {
  display: inline-flex;
  align-items: center;
  color: var(--accent-purple, #8B5CF6);
}

.series-cards-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}
@media (min-width: 768px) {
  .series-cards-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
  }
}
.profile-series-card {
  display: flex;
  align-items: stretch;
  gap: 14px;
  padding: 12px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02);
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
  position: relative;
  overflow: hidden;
}
.profile-series-card:hover {
  border-color: var(--accent-purple, #8B5CF6);
  box-shadow: 0 4px 16px rgba(139, 92, 246, 0.08);
  transform: translateY(-1px);
}
.profile-series-media {
  width: 72px;
  min-width: 72px;
  height: 72px;
  border-radius: 12px;
  overflow: hidden;
  position: relative;
  cursor: pointer;
  flex-shrink: 0;
  background: var(--bg-input);
}
.profile-series-cover {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.profile-series-placeholder {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.12), rgba(236, 72, 153, 0.12));
  color: var(--accent-purple, #8B5CF6);
}
.profile-series-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  cursor: pointer;
}
.profile-series-top {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.profile-series-badge {
  font-size: 10.5px;
  font-weight: 800;
  text-transform: uppercase;
  color: var(--accent-purple, #8B5CF6);
  background: rgba(139, 92, 246, 0.1);
  padding: 1px 6px;
  border-radius: 4px;
}
.profile-series-time {
  font-size: 11.5px;
  color: var(--text-dim);
}
.profile-series-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-main);
  margin: 0 0 4px 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.profile-series-desc {
  font-size: 12.5px;
  color: var(--text-dim);
  line-height: 1.4;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.profile-series-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  align-self: center;
}
.btn-icon-series {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-dim);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: all 0.15s ease;
}
.btn-icon-series:hover {
  background: var(--bg-input);
  color: var(--text-main);
  border-color: var(--border);
}
.btn-icon-series.danger:hover {
  background: rgba(239, 68, 68, 0.1);
  color: #EF4444;
  border-color: rgba(239, 68, 68, 0.2);
}

/* ── แท็บเพื่อน และ แท็บผู้ติดตาม (friends.js, profile.js) ── */
.friends-tab, .followers-tab {
  display: flex; flex-direction: column; gap: 8px;
}
.friends-tab .follow-list, .followers-tab .follow-list {
  display: flex; flex-direction: column; gap: 8px;
}
.friends-tab .rel-row.follow-item,
.followers-tab .rel-row.follow-item {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--card-shadow);
  cursor: pointer; transition: background 0.15s ease, border-color 0.15s ease;
}
.friends-tab .rel-row.follow-item:hover,
.followers-tab .rel-row.follow-item:hover {
  background: var(--bg-input, var(--bg-header));
  border-color: var(--border-strong, var(--border));
}
.friends-tab .follow-info,
.followers-tab .follow-info {
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.friends-tab .follow-name,
.followers-tab .follow-name {
  font-size: 14px; font-weight: 700; color: var(--text-main);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.friends-tab .follow-handle,
.followers-tab .follow-handle {
  font-size: 12px; color: var(--text-dim);
}

/* แถบแท็บโปรไฟล์: เกิน 4 แท็บให้ปัดซ้าย-ขวาแทนการบีบปุ่มจนอ่านไม่ออก */
.profile-nav-tabs { scroll-snap-type: x proximity; scrollbar-width: none; }
.profile-nav-tabs::-webkit-scrollbar { display: none; }
.profile-nav-tabs .profile-tab {
  flex: 0 0 auto; min-width: 25%; scroll-snap-align: start; white-space: nowrap;
}

/* ปุ่มรับสายในจอสายเรียกเข้า — v3 ไม่มีบทนี้ (เดโมรับสายเอง) */
.call-dock-btn.btn-accept {
  background: linear-gradient(135deg, #22C55E 0%, #16A34A 100%);
  color: #FFFFFF; box-shadow: 0 4px 20px rgba(34, 197, 94, 0.5);
}
.call-dock-btn.btn-accept:hover { background: #16A34A; transform: scale(1.08); }

/* ===== หน้า Korat ID + แผ่นซื้อพรีเมียม: กฎที่เคยอยู่ใน app.css ซึ่งเว็บไม่โหลดแล้ว ===== */

/* ── โทเคนเก่าที่หน้าเดิม (Korat ID/พรีเมียม) ยังอ้างถึง — ผูกกลับเข้าโทเคนของ v3
   เพื่อให้กฎที่ยกมาจาก app.css ทำงานในธีมปัจจุบันโดยไม่ต้องแก้ทุกบรรทัด ── */
:root {
  --sp-1: 2px; --sp-2: 4px; --sp-3: 6px; --sp-4: 8px; --sp-5: 12px; --sp-6: 16px; --sp-7: 24px; --sp-8: 32px;
  --fs-micro: 11px; --fs-sm: 12px; --fs-base: 13px; --fs-row: 14px; --fs-body: 15px;
  --fs-title: 17px; --fs-h: 20px; --fs-hero: 30px;
  --r-xs: 8px; --r-sm: 10px; --r-md: 12px; --r-lg: 16px; --r-xl: 22px; --r-btn: 24px; --r-pill: 999px;
  --bg: var(--bg-app); --s1: var(--bg-card); --s2: var(--bg-header); --s3: var(--bg-input, var(--bg-header));
  --field: var(--bg-input, var(--bg-header));
  --line: var(--border); --line-strong: var(--border-strong, var(--border));
  --ink: var(--text-main); --dim: var(--text-dim); --dim2: var(--text-muted, var(--text-dim));
  --a1: var(--accent-purple, #7C3AED); --a2: var(--accent-pink, #EC4899); --a3: var(--accent-blue, #3B82F6);
  --amber: #F59E0B; --blue: #3B82F6; --purple: #8B5CF6; --sky: #0EA5E9; --green: #22C55E; --red: #EF4444;
  /* `--bz-*` เป็นชุดโทเคนของ biz.css (คอนโซลธุรกิจเท่านั้น, สโคป
     `:root[data-console="business"]`) — บางไฟล์ที่ใช้ร่วมกันทั้งสองโฮสต์
     (plugincart.js / callinvite.js / chat.js / handover.js / main.js) อ้าง
     `var(--bz-xxx)` ตรง ๆ โดยหลายจุดไม่มีค่า fallback ต่อท้าย ⇒ บน koratland.com/app
     (ไม่โหลด biz.css เลย) ตัวแปรว่างเปล่า สีสถานะ/เส้นขอบ/พื้นหลังเลยหายไปเงียบ ๆ
     แทนที่จะไปตามล่าทุกจุดเรียกทีละบรรทัด ผูก alias ให้ตรงนี้ครั้งเดียว ชี้ไปที่
     โทเคนของ v3 ที่มีความหมายเดียวกันอยู่แล้ว — ไม่ใช่สีใหม่ ไม่ผูกกับ accent */
  --bz-dim: var(--dim); --bz-ink: var(--ink); --bz-line: var(--line); --bz-surface2: var(--s2);
  --bz-accent: var(--a1); --bz-amber: var(--amber); --bz-green: var(--green);
  --bz-red: var(--red); --bz-sky: var(--sky);
}

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px var(--sp-4); border-radius: var(--r-sm); font-size: var(--fs-sm); font-weight: 600;
  background: var(--s3); color: var(--dim); border: 1px solid transparent;
  transition: all 0.18s ease; }
.chip.amber { background: rgba(245, 158, 11, 0.16); color: var(--amber); border-color: rgba(245, 158, 11, 0.3); }
.chip.blue { background: rgba(59, 130, 246, 0.16);  color: var(--blue);  border-color: rgba(59, 130, 246, 0.3); }
.chip.purple { background: rgba(139, 92, 246, 0.16); color: var(--purple); border-color: rgba(139, 92, 246, 0.3); }
.chip.sky { background: rgba(14, 165, 233, 0.16); color: var(--sky); border-color: rgba(14, 165, 233, 0.3); }
.chip.green { background: rgba(34, 197, 94, 0.16); color: var(--green); border-color: rgba(34, 197, 94, 0.3); }
.chip.red { background: rgba(239, 68, 68, 0.16);   color: var(--red);   border-color: rgba(239, 68, 68, 0.3); }

/* plugincart.js — ใช้ทั้งบน koratland.com/app และคอนโซลธุรกิจ แต่ biz.css
   (ต้นทางเดิมของคลาสนี้) โหลดเฉพาะฝั่งคอนโซล ⇒ ไม่มีกฎนี้ ข้อความรองใต้บรรทัด
   สินค้า/ใบแจ้งหนี้/ผลการยกเลิกจะไม่มีสไตล์เลยบนเว็บลูกค้า */
.biz-row-sub { font-size: var(--fs-sm); color: var(--dim); }
/* ==========================================================================
   Commerce surfaces — the business console, the shop and the group screens.

   Everything below reuses the existing ladder (.row, .list, .chip, .btn,
   .state) and only adds the shapes those primitives cannot make: an order card
   with its own line items, a form laid out in pairs, a report tile, and a
   seven-bar chart. No new colour is invented — the status palette is literal
   and already defined at the top of this file.
   ========================================================================== */

/* ---------- toolbar above a list ---------- */
.toolbar { display: flex; gap: 8px; align-items: center; padding: 8px 16px 0; flex-wrap: wrap; }
.plan-hero { padding: var(--sp-5) 0 var(--sp-4); text-align: center; }
.plan-hero .plan-name { font-size: var(--fs-h); font-weight: 800; color: var(--ink); margin: 0 0 2px; }
.plan-hero .plan-tag { font-size: var(--fs-sm); color: var(--dim); margin: 0 0 var(--sp-5); }
.plan-hero .plan-price { font-size: var(--fs-hero); font-weight: 800; color: var(--ink); line-height: 1.1; }
.plan-hero .plan-price small { font-size: var(--fs-base); font-weight: 500; color: var(--dim); }
.plan-hero .plan-tax { font-size: var(--fs-micro); color: var(--dim2); margin: 2px 0 0; }
.plan-hero .chip { margin-top: var(--sp-4); }
.plan-notforsale { display: inline-flex; align-items: center; gap: 4px; margin-top: var(--sp-4);
  padding: 4px var(--sp-4); border-radius: var(--r-pill); font-size: var(--fs-sm); font-weight: 600;
  background: color-mix(in srgb, var(--amber) 16%, transparent); color: var(--amber); }
.plan-switch { display: flex; gap: var(--sp-3); overflow-x: auto; padding: 2px 0 var(--sp-4); scrollbar-width: none; }
.plan-switch::-webkit-scrollbar { display: none; }
.plan-groups { display: flex; flex-direction: column; gap: var(--sp-5); padding-bottom: var(--sp-6); }
.plan-group-label { margin: 0; font-size: var(--fs-base); font-weight: 700; color: var(--dim); padding: 0 2px; }
.plan-group-card { background: var(--s2); border: 1px solid var(--line); border-radius: var(--r-lg);
  overflow: hidden; display: flex; flex-direction: column; }
.plan-feat { display: flex; align-items: flex-start; gap: var(--sp-4); padding: var(--sp-4) var(--sp-5);
  border: 0; background: transparent; width: 100%; text-align: start; color: var(--ink); cursor: default; }
.plan-group-card .plan-feat + .plan-feat { border-top: 1px solid var(--line); }
.plan-feat .plan-feat-ic { flex: 0 0 auto; width: 22px; height: 22px; display: flex; align-items: center;
  justify-content: center; font-size: 15px; line-height: 1; }
.plan-feat .plan-feat-ic.check { color: var(--green); }
.plan-feat .plan-feat-body { flex: 1; min-width: 0; }
.plan-feat .plan-feat-label { font-size: var(--fs-row); font-weight: 500; }
.plan-feat .plan-feat-detail { font-size: var(--fs-sm); color: var(--dim); margin-top: 2px; overflow-wrap: anywhere; }
.plan-checklist .plan-feat { padding-inline: 2px; }
.plan-quote { padding: var(--sp-4) var(--sp-5); margin-bottom: var(--sp-5); border-radius: var(--r-md);
  background: var(--s2); border: 1px solid var(--line); font-size: var(--fs-sm); color: var(--dim); }
.plan-quote strong { color: var(--ink); font-size: var(--fs-row); }
.plan-buyfoot .plan-terms { margin: 0; font-size: var(--fs-micro); color: var(--dim2); text-align: center; }
.plan-buyfoot .plan-terms a { color: var(--dim); text-decoration: underline; }
.plan-list-hint { margin: 0; text-align: center; }
.plan-list-row { display: flex; align-items: center; gap: var(--sp-4); width: 100%; text-align: start;
  background: var(--s2); border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--sp-5); cursor: pointer; }
.plan-list-row:hover { border-color: color-mix(in srgb, var(--a2) 40%, var(--line)); }
.plan-list-row.current { border-color: var(--a2); background: color-mix(in srgb, var(--a2) 8%, var(--s2)); }
.plan-list-row .grow .l1 { display: flex; align-items: center; gap: 6px; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border-radius: var(--r-pill, 9999px);
  font-size: var(--fs-micro, 12px);
  font-weight: 600;
  border: 1px solid var(--border, rgba(255,255,255,0.1));
  background: var(--bg-input, rgba(255,255,255,0.06));
  color: var(--text-main, inherit);
}
.chip.green { background: rgba(16, 185, 129, 0.12) !important; color: #10b981 !important; border-color: rgba(16, 185, 129, 0.25) !important; }
.chip.bad { background: rgba(239, 68, 68, 0.12) !important; color: #ef4444 !important; border-color: rgba(239, 68, 68, 0.25) !important; }
.chip.warn { background: rgba(245, 158, 11, 0.12) !important; color: #f59e0b !important; border-color: rgba(245, 158, 11, 0.25) !important; }
.chip.info { background: rgba(59, 130, 246, 0.12) !important; color: #3b82f6 !important; border-color: rgba(59, 130, 246, 0.25) !important; }
/* The period suffix stays ON the line, one step smaller and dimmer — a unit,
   not a second fact. (`display: block` is what put it on its own line.) */
.pricecol small,
.pricecol .unit {
  display: inline;
  font-weight: 400;
  font-size: var(--fs-micro);
  color: var(--dim2);
  margin-inline-start: 1px; }
.plan-list-row .l2 { white-space: normal; overflow-wrap: anywhere; }
.pricecol { font-size: var(--fs-base); }
.idpreview-body { display: flex; align-items: center; gap: var(--sp-5); min-width: 0; }
.idpreview-txt { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.idpreview-name {
  display: flex; align-items: center; min-width: 0;
  font-size: var(--fs-title); font-weight: 800; color: var(--ink);
  overflow-wrap: anywhere; }
.idpreview-sub {
  font-size: var(--fs-sm); color: var(--dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.idpreview-hint { margin: 0; }
.idpreview .av.xl { width: 52px; height: 52px; font-size: 20px; }
.idpreview-name { font-size: var(--fs-row); }
.plan-list-row,
.koratid-tier {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--pricecol-w);
  align-items: center;
  column-gap: var(--sp-4); }
/* ==========================================================================
   NEON ON CONTENT — the post card in the feed, and the comment bubble.

   ★ WHY THIS IS NOT THE AVATAR'S TECHNIQUE COPIED ★
   The ring works because a CIRCLE's outline does not change when you rotate it,
   so the spinning layer can BE the ring. A card is a rounded RECTANGLE: rotate
   the visible band and the band itself swings off the card. So the two jobs are
   split across two elements —
     `.neonfx`          holds still, is clipped to the card's radius, and has a
                        mask that cuts its own middle out, leaving a 2px frame;
     `.neonfx::before`  is the big conic gradient that TURNS inside it.
   The hole never moves, the light does. Still nothing but `transform`, still no
   layout, still no `@property`.

   ★ THE COST, AND WHY A LONG FEED STAYS SMOOTH ★
   Five glowing cards in view = five composited layers, each painting its
   gradient once and then only being re-transformed by the compositor: no
   layout, no style recalc, nothing touching the card's own text or photos.
   Three separate rations keep it there:
     · `animation-play-state: paused` by default. Only `.neon-live` runs, and
       neon.js grants that to at most FIVE on-screen cards at a time via one
       shared IntersectionObserver.
     · `.neon-halt` on <html> (tab hidden) pauses every one of them.
     · `contain: paint` on the layer, so its repaint can never escape the card.
   A card that is out of view, over the budget, or on a hidden tab still shows
   the glow and the gradient — it simply does not turn. It never degrades to a
   plain card, because "plain" is what people who did not pay get.
   ========================================================================== */
.post.neon,
.comment.neon > .bubble,
.idpreview-post.neon {
  position: relative;
  /* The static half of the identity — present before anything moves and kept
     in every reduced/paused state below. */
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--neon-c) 55%, transparent),
    0 0 10px color-mix(in srgb, var(--neon-c) 34%, transparent),
    0 0 26px color-mix(in srgb, var(--neon-c) 18%, transparent),
    var(--card-shadow);
  /* Still here for `.comment > .bubble` and `.idpreview-post`, which do have a
     border. A feed `.post` has none any more; the `0 0 0 1px` ring above is the
     same line at 55% instead of 45%, drawn on the outside of the box, so the
     card lost nothing when the border went. */
  border-color: color-mix(in srgb, var(--neon-c) 45%, var(--line)); }
/* The plan does not sell a COLOUR for content neon, so it follows the app's own
   accent unless the holder's ring colour is handed down (`--neon-c` is set on
   the card by whoever knows it). One variable, one place to change. */
.post.neon, .comment.neon > .bubble, .idpreview-post.neon { --neon-c: var(--a2); }
.post.neon > .neonfx,
.comment.neon > .bubble > .neonfx,
.idpreview-post.neon > .neonfx {
  position: absolute;
  inset: 0;
  /* ★ `inherit`, never a token. The frame is a masked layer sitting exactly on
     top of the card, so its corner MUST be the card's corner — the moment the
     two are written independently they drift, and the drift shows up as a lit
     arc floating off the corner of a square card (the owner caught precisely
     that in the demo). `.post` is now square, `.comment > .bubble` is still
     `--r-md`, and this one line is correct for both without knowing either. */
  border-radius: inherit;
  overflow: hidden;
  pointer-events: none;
  z-index: 3;
  contain: paint;
  /* The frame: 2px of gradient, the middle cut out. The mask does NOT rotate —
     only the layer underneath it does. */
  padding: 2px;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude; }
.post.neon > .neonfx::before,
.comment.neon > .bubble > .neonfx::before,
.idpreview-post.neon > .neonfx::before {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  /* A SQUARE wider than the card's diagonal, centred — so the gradient covers
     every corner at every angle and no edge of the frame is ever left unlit. */
  width: 280%;
  aspect-ratio: 1;
  margin: -140% 0 0 -140%;
  background: conic-gradient(
    from 0deg,
    transparent 0deg,
    color-mix(in srgb, var(--neon-c) 50%, transparent) 55deg,
    var(--neon-c) 120deg,
    #fff 160deg,
    var(--neon-c) 200deg,
    color-mix(in srgb, var(--neon-c) 50%, transparent) 270deg,
    transparent 360deg);
  animation: neon-spin 3.4s linear infinite;
  animation-play-state: paused;      /* ← the default is OFF; see neon.js */
  transform: rotate(0deg); }
/* Only what the observer says is on screen, and only within the budget. */
.post.neon.neon-live > .neonfx::before,
.comment.neon.neon-live > .bubble > .neonfx::before,
.idpreview-post.neon.neon-live > .neonfx::before {
  animation-play-state: running;
  will-change: transform; }
.post.neon > .neonfx::before,
  .comment.neon > .bubble > .neonfx::before,
  .idpreview-post.neon > .neonfx::before { animation: none; }
.idpreview-post .pv-head { display: flex; align-items: center; gap: var(--sp-4); }
.idpreview-post .pv-name { font-size: var(--fs-row); font-weight: 700; }
.idpreview-post .pv-when { font-size: var(--fs-micro); color: var(--dim2); }
.idpreview-post .pv-body { margin-top: var(--sp-4); font-size: var(--fs-body); color: var(--ink); }
.idpreview-av { display: inline-flex; flex: 0 0 auto; }
.premium-card-hint { margin: 0; }
.premium-cta:hover { background: transparent; }
.premium-cta .l1 { display: block; font-size: var(--fs-row); font-weight: 700; color: var(--ink); }
.premium-cta .l2 { display: block; font-size: var(--fs-sm); color: var(--dim); margin-top: 1px; }
.premium-cta:hover > .btn { background: var(--brand-hover); }
.premium-sec, .bill-stack { gap: var(--sp-3); }
.plan-cancomplete > div { color: var(--ink); }

/* ==========================================================================
   Settings, Account & Subpages Layout (Padding, Margin & Centering)
   ========================================================================== */
.view.rel-page,
.view:has(> .k3-card),
.view:has(> .k3-section),
.app-shell[data-route="account"] .view,
.app-shell[data-route="blocked"] .view,
.app-shell[data-route="devices"] .view,
.app-shell[data-route="id"] .view,
.app-shell[data-route="lifecycle"] .view,
.app-shell[data-route="notif-prefs"] .view,
.app-shell[data-route="personal"] .view,
.app-shell[data-route="saved"] .view {
  padding: 16px 20px 32px;
  max-width: 820px;
  width: 100%;
  margin-inline: auto;
  box-sizing: border-box;
}

.view > .k3-card {
  margin-top: 0;
  margin-bottom: 16px;
}

.view.rel-page > .k3-card,
.view.rel-page > div > .k3-card,
.view.rel-page .premium-sec > .k3-card,
.view.rel-page .k3-card,
.view.koratid > .k3-card,
.view.koratid > div > .k3-card,
.view.koratid .premium-sec > .k3-card,
.view.koratid .k3-card {
  width: 100% !important;
  margin-inline: 0 !important;
  margin-top: 0 !important;
  margin-bottom: 20px !important;
  box-sizing: border-box !important;
}

@media (max-width: 640px) {
  .view.rel-page,
  .view:has(> .k3-card),
  .view:has(> .k3-section),
  .app-shell[data-route="account"] .view,
  .app-shell[data-route="blocked"] .view,
  .app-shell[data-route="devices"] .view,
  .app-shell[data-route="id"] .view,
  .app-shell[data-route="lifecycle"] .view,
  .app-shell[data-route="notif-prefs"] .view,
  .app-shell[data-route="personal"] .view,
  .app-shell[data-route="saved"] .view {
    padding: 12px 14px 24px;
  }
}

/* ==========================================================================
   RTL (Arabic) 10-Language Support: Mirroring & Navigation Glyphs
   ========================================================================== */
html[dir="rtl"] [data-back] svg,
html[dir="rtl"] .icon-btn-ghost[data-back] svg {
  transform: scaleX(-1);
}
html[dir="rtl"] .k3-card-head {
  flex-direction: row;
}
html[dir="rtl"] .k3-row {
  flex-direction: row;
}
html[dir="rtl"] .k3-row-main {
  text-align: right;
}


/* การ์ดในหน้าที่ไม่ใช่ฟีด ต้องไม่ชนเส้นขอบคอลัมน์ — เดิมมีระยะขอบเฉพาะจอมือถือ
   ทำให้บนเดสก์ท็อป/แท็บเล็ตกรอบการ์ดแนบติดเส้นคั่นคอลัมน์พอดี */
@media (min-width: 641px) {
  .view > .k3-card, .view > .k3-section, .view-panel > .k3-card,
  .rel-page, .k3-body, .dirgrid, .job-list, .list.v3-rows { margin-inline: 12px; }
  .rel-page > .notifs-header-bar, .rel-page > .job-tabs, .rel-page > .ptabs { margin-inline: 0; }
}

/* ===== หน้าตั้งค่าย่อย: กฎที่เคยอยู่ใน app.css (บิล · แบนเนอร์ · ปุ่มเต็มความกว้าง) ===== */
.btn.block { width: 100%; }
.banner {
  display: flex; align-items: center; gap: var(--sp-4);
  margin: var(--sp-4) var(--sp-6) 0; padding: var(--sp-4) var(--sp-5); border-radius: var(--r-md);
  font-size: var(--fs-sm);
  background: rgba(245, 158, 11, 0.14);
  color: var(--amber);
  border: 1px solid rgba(245, 158, 11, 0.3); }
.banner .grow { flex: 1; min-width: 0; }
.banner.bad {
  background: rgba(239, 68, 68, 0.14);
  color: var(--red);
  border-color: rgba(239, 68, 68, 0.3); }
.banner.stack { display: block; }
.banner.stack > * + * { margin-top: 2px; }
.banner .dim { color: inherit; opacity: .82; }
/* ==========================================================================
   Long-string safety

   Arabic, German and Russian all run noticeably longer than Thai, and a server
   error can arrive as an unbroken URL. Nothing here may widen the page: the
   body must never scroll sideways in ANY language.
   ========================================================================== */
.state .headline, .state .detail, .banner .grow, .toast,
.auth .err, .auth .ok, .dialog p { overflow-wrap: anywhere; }
.no-print, .rail, .dock, .appbar, .aside, .banner, .state.loading { display: none !important; }
.bill-sub { font-size: var(--fs-sm); color: var(--dim); line-height: 1.5; overflow-wrap: anywhere; }
.bill-amount {
  font-size: var(--fs-title); font-weight: 800; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
/* A card with no buttons at all (paid, or awaiting review) must not keep the
   rule — an empty bordered strip reads as something that failed to render.
   `:empty` alone is NOT enough and that is the trap: the cancel button's slot
   span is appended before the server has answered, so the row always has a
   child node and is never `:empty`. It is the presence of a BUTTON that
   decides. `:has()` is already used in this file (`.form:has(> .fgroup)`,
   `label.field:has(> input[type="checkbox"])`), so this needs no new support. */
.bill-acts:empty,
.bill-acts:not(:has(.btn)) { display: none; }
.bill-acts .btn {
  flex: 1 1 auto;
  /* 120 = the widest of the section's own labels at --fs-base without
     compressing; two of them plus the 6px gap fit inside a 320px screen once
     the 16px page gutter and the card's 12px padding are taken off (246 < 264). */
  min-width: 120px; }
.bill-amount { font-variant-numeric: tabular-nums; white-space: nowrap; }
.u-fixed { flex: 0 0 auto; white-space: nowrap; }

/* ===== คลาสที่โค้ดใช้มาตลอดแต่ไม่เคยมีสไตล์ที่ไหนเลย (ยืนยันแล้วว่าไม่มีแม้ใน app.css)
   นิยามให้ตรงกับระบบ v3: ใช้โทเคนธีม ไม่ฮาร์ดโค้ดสี ยกเว้นสีสถานะที่เป็นค่าคงที่ ===== */
.bz-pagehead, .biz-card-head {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 14px; border-bottom: 1px solid var(--border);
  font-size: 15px; font-weight: 700; color: var(--text-main);
}
.bz-more { margin-inline-start: auto; }
.chip-status { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px;
  border-radius: 999px; font-size: 12px; font-weight: 700;
  background: var(--bg-input, var(--bg-header)); color: var(--text-dim); }
.chip-status.ok { color: #22C55E; } .chip-status.warn { color: #F59E0B; } .chip-status.bad { color: #EF4444; }

/* ด่านตรวจสิทธิ์ (verifygate) */
.gate { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: 14px; background: var(--bg-card); }
.gate-load { color: var(--text-dim); font-size: 13px; }
.gate-ok { color: #22C55E; font-size: 13px; font-weight: 600; }
.gate-warn { color: #F59E0B; font-size: 13px; font-weight: 600; }

/* วิธีชำระเงิน */
.pm-list { display: flex; flex-direction: column; gap: 8px; }
.pm-form { display: flex; flex-direction: column; gap: 10px; }
.pm-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.pm-chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px;
  border-radius: 999px; border: 1px solid var(--border); background: var(--bg-input, var(--bg-header));
  color: var(--text-main); font-size: 13px; font-weight: 600; cursor: pointer; }
.pm-chip.on, .pm-chip[aria-pressed="true"] { border-color: var(--accent-purple, #7C3AED); color: var(--accent-purple, #7C3AED); }
.pm-badge { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 700; background: rgba(34,197,94,.16); color: #22C55E; }
.pm-err { color: #EF4444; font-size: 12.5px; }
.pm-intl { color: var(--text-dim); font-size: 12px; }
.pm-qr { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.pm-qrshot { max-width: 220px; width: 100%; border-radius: 12px; display: block; }
.def { color: var(--text-dim); font-size: 12px; }

/* ยืนยันตัวตน — ตัวเลือกไฟล์ + รูปตัวอย่าง */
.verify-file-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.verify-file-btn { display: inline-flex; align-items: center; gap: 6px; }
.verify-preview, .image-preview { display: flex; flex-wrap: wrap; gap: 8px; }
.verify-thumb, .image-thumb {
  position: relative; width: 96px; height: 96px; border-radius: 12px; overflow: hidden;
  background: var(--bg-input, var(--bg-header)); border: 1px solid var(--border);
}
.verify-thumb img, .image-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.verify-thumb-remove {
  position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; border: 0;
  border-radius: 50%; background: rgba(0,0,0,.62); color: #FFF; font-size: 12px; line-height: 1;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.verify-thumb-remove:hover { background: #EF4444; }

/* แผงเอกสาร/ภาษา */
.dl-panel { display: flex; flex-direction: column; gap: 10px; padding: 12px 14px; }

/* ── Lightbox Backdrop Cursor & RTL ── */
.lightbox-modal {
  cursor: pointer;
}
.lightbox-shell {
  cursor: default;
}
html[dir="rtl"] .lightbox-side {
  border-right: none;
  border-left: 1px solid var(--border);
}

/* ==========================================================================
   Wide Modal / Plan Sheet & Receipt Sheet on Desktop
   ========================================================================== */
.plan-sheet .sheet-modal {
  width: 860px !important;
  max-width: min(900px, calc(100vw - 32px)) !important;
  max-height: min(92vh, 800px) !important;
  border-radius: var(--radius-lg, 20px) !important;
  display: flex !important;
  flex-direction: column !important;
  box-shadow: 0 20px 50px -10px rgba(0, 0, 0, 0.4), 0 0 0 1px var(--border-strong) !important;
  overflow: hidden !important;
}

.plan-sheet .sheet-body {
  padding: 0 !important;
  overflow: hidden !important;
  display: flex !important;
  flex-direction: column !important;
  flex: 1 1 auto !important;
  min-height: 0 !important;
}

.plan-detail-view {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  height: 100%;
}

.plan-detail-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 16px 22px;
}

.plan-detail-grid {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: 20px;
  align-items: start;
}

.plan-col-left,
.plan-col-right {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

@media (max-width: 720px) {
  .plan-sheet .sheet-modal {
    width: 100% !important;
    max-width: calc(100vw - 20px) !important;
    max-height: 94dvh !important;
    border-radius: var(--radius-xl, 20px) !important;
  }
  .plan-detail-grid {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  .plan-detail-scroll {
    padding: 12px 14px;
  }
  .plan-buyfoot {
    flex-direction: column !important;
    gap: 10px !important;
    padding: 12px 16px !important;
  }
  .plan-buyfoot .plan-terms {
    text-align: center !important;
  }
  .plan-buyfoot .plan-buy-btn {
    width: 100% !important;
  }
  .plan-list {
    grid-template-columns: 1fr !important;
    padding: 12px 14px !important;
    max-height: 70vh !important;
  }
}

.plan-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 12px;
  padding: 16px 20px;
  max-height: 65vh;
  overflow-y: auto;
}

.chip.pick {
  cursor: pointer;
  transition: all 0.15s ease;
}
.chip.pick:hover {
  border-color: var(--brand-primary, #7C3AED) !important;
}
.chip.pick.on {
  border-color: var(--brand-primary, #7C3AED) !important;
  background: rgba(124, 58, 237, 0.15) !important;
  color: var(--brand-primary, #7C3AED) !important;
  font-weight: 700 !important;
}

.receipt-sheet .sheet-modal {
  width: 640px !important;
  max-width: min(720px, calc(100vw - 32px)) !important;
  max-height: min(92vh, 820px) !important;
  border-radius: var(--radius-lg, 20px) !important;
}

@media (max-width: 720px) {
  .receipt-sheet .sheet-modal {
    width: 100% !important;
    max-width: calc(100vw - 20px) !important;
    max-height: 94dvh !important;
    border-radius: var(--radius-xl, 20px) !important;
  }
  .receipt-sheet .receipt-card {
    padding: 14px 14px !important;
  }
}

/* ==========================================================================
   Compose Modal ("สร้างโพสต์ใหม่" / "New post") Desktop Width & Polish
   ========================================================================== */
.compose-scrim .sheet-modal {
  width: 580px !important;
  max-width: min(620px, calc(100vw - 32px)) !important;
  border-radius: var(--radius-lg, 20px) !important;
  box-shadow: 0 24px 60px -12px rgba(0, 0, 0, 0.4), 0 0 0 1px var(--border-strong) !important;
  overflow: hidden !important;
}

.compose-scrim .sheet-header {
  padding: 16px 20px !important;
}

.compose-scrim .sheet-header h3 {
  font-size: 16px !important;
  font-weight: 800 !important;
  color: var(--text-main) !important;
}

.compose-scrim .sheet-body {
  padding: 0 !important;
}

.compose-scrim .composer-card.in-modal {
  border-bottom: 0 !important;
  padding: 18px 20px 20px !important;
}

.compose-scrim .composer-card.in-modal .composer-input-area textarea {
  min-height: 120px !important;
  font-size: 16px !important;
  line-height: 1.5 !important;
}

@media (max-width: 640px) {
  .compose-scrim .sheet-modal {
    width: 100% !important;
    max-width: calc(100vw - 20px) !important;
  }
  .compose-scrim .sheet-header {
    padding: 14px 16px !important;
  }
  .compose-scrim .composer-card.in-modal {
    padding: 14px 16px 16px !important;
  }
}

/* ── สร้างป้ายกำกับแชท (Create Chat Label Modal) ── */
.sheet-modal:has(.create-label-modal-form) {
  width: 400px;
  max-width: calc(100vw - 28px);
}
.create-label-modal-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 100%;
  box-sizing: border-box;
}
.create-label-modal-form .label-form-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  box-sizing: border-box;
}
.create-label-modal-form .label-form-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-main);
}
.create-label-modal-form .label-name-input {
  width: 100%;
  box-sizing: border-box;
  height: 42px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 12px);
  padding: 0 14px;
  font-size: 14px;
  color: var(--text-main);
  outline: none;
  transition: all 0.2s ease;
}
.create-label-modal-form .label-name-input:focus {
  border-color: var(--border-focus);
  background: var(--bg-input-focus);
  box-shadow: 0 0 0 3px rgba(139, 61, 255, 0.15);
}
.create-label-modal-form .label-color-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
  justify-items: center;
  width: 100%;
  box-sizing: border-box;
  padding: 4px 0;
}
.create-label-modal-form .label-color-btn {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s ease;
  padding: 0;
}
.create-label-modal-form .label-color-btn:hover {
  transform: scale(1.1);
}
.create-label-modal-form .label-color-btn.active {
  border-color: var(--text-main);
  box-shadow: 0 0 0 2px var(--bg-card), 0 0 10px rgba(0, 0, 0, 0.25);
  transform: scale(1.08);
}
.create-label-modal-form .label-color-btn svg {
  display: none;
  stroke: #FFF;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.4));
}
.create-label-modal-form .label-color-btn.active svg {
  display: block;
}
.create-label-modal-form .label-modal-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 6px;
  padding-top: 14px;
  border-top: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.06));
}
.create-label-modal-form .label-cancel-btn {
  padding: 8px 18px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: var(--bg-input);
  color: var(--text-main);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s ease;
}
.create-label-modal-form .label-cancel-btn:hover {
  background: var(--bg-hover);
}
.create-label-modal-form .label-submit-btn {
  padding: 8px 22px;
  border-radius: var(--radius-pill);
  background: var(--brand-gradient);
  color: #FFF;
  border: none;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: var(--brand-glow);
  transition: all 0.2s ease;
}
.create-label-modal-form .label-submit-btn:hover {
  background: var(--brand-hover);
  transform: translateY(-1px);
}

/* ── สมุด "จัดการป้ายกำกับ" (แก้ชื่อ/สี/ลบ/จัดลำดับ/ปักหมุด) — web/app/chatlabels.js ──
   ฟอร์มแก้ไข (.chatlabel-edit-form) ใช้คลาส .create-label-modal-form ร่วมกับกล่องสร้าง
   ป้ายเดิมด้านบนอยู่แล้ว (ชื่อ/จานสี/ปุ่มยกเลิก-บันทึก) — ที่นี่เติมแค่ส่วนที่ไม่มีอยู่ก่อน:
   รายการแถวเรียงลำดับได้ และปุ่มลบของฟอร์มแก้ไข */
.chatlabel-manage {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  box-sizing: border-box;
}
.chatlabel-manage-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
}
.chatlabel-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 6px;
  border-radius: var(--radius-md, 12px);
  transition: background 0.15s ease;
}
.chatlabel-row:hover { background: var(--bg-hover); }
.chatlabel-row.dragging { opacity: 0.45; }
.chatlabel-drag-handle {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: grab;
  padding: 0;
}
.chatlabel-drag-handle:active { cursor: grabbing; }
.chatlabel-dot {
  flex-shrink: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
}
.chatlabel-name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 14px;
  color: var(--text-main);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chatlabel-system-hint {
  flex-shrink: 0;
  font-size: 11px;
  color: var(--text-muted);
  padding: 2px 7px;
  border-radius: var(--radius-pill);
  background: var(--bg-input);
}
.chatlabel-icon-btn {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.chatlabel-icon-btn:hover:not(:disabled) { background: var(--bg-hover); color: var(--text-main); }
.chatlabel-icon-btn:disabled { opacity: 0.3; cursor: default; }
.chatlabel-add-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  padding: 10px;
  border-radius: var(--radius-pill);
  border: 1px dashed var(--border);
  background: transparent;
  color: var(--brand, var(--text-main));
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s ease;
}
.chatlabel-add-btn:hover { background: var(--bg-hover); }
.chatlabel-retry-btn {
  width: 100%;
  padding: 8px;
  border-radius: var(--radius-md, 12px);
  border: 1px solid var(--border);
  background: var(--bg-input);
  color: var(--text-main);
  font-size: 13px;
  cursor: pointer;
}
.chatlabel-delete-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  padding: 9px;
  margin-top: 4px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  background: transparent;
  color: var(--danger, #EF4444);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s ease;
}
.chatlabel-delete-btn:hover { background: rgba(239, 68, 68, 0.1); }

/* ── Korat ID & Billing History Modern Styling ── */
.billing-invoice-card {
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}
.billing-invoice-card:hover {
  border-color: var(--border-strong, var(--border)) !important;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.05);
  transform: translateY(-1px);
}

.k3-history-row {
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}
.k3-history-row:hover {
  border-color: var(--border-strong, var(--border)) !important;
}

.premium-card {
  position: relative;
  overflow: hidden;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.premium-card:hover {
  box-shadow: 0 8px 24px rgba(124, 58, 237, 0.12);
}

/* ── Facebook-style Chat Actions, Reactions, Quotes & Replies ── */
.msg-group {
  position: relative;
}

.msg-stack {
  position: relative;
}

/* Row wrapping the bubble and floating action buttons */
.msg-bubble-wrap {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  position: relative;
}

/* Meta Row containing timestamp and action buttons under message */
.msg-meta-row {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 3px;
  max-width: 100%;
}

.msg-group.outgoing .msg-meta-row,
.msg.mine .msg-meta-row {
  flex-direction: row-reverse;
  justify-content: flex-start;
}

.msg-group.incoming .msg-meta-row,
.msg:not(.mine) .msg-meta-row {
  flex-direction: row;
  justify-content: flex-start;
}

/* Action Bar under bubble */
.msg-actions-bar {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  opacity: 0.65;
  transition: opacity 0.15s ease, transform 0.15s ease;
  flex-shrink: 0;
  user-select: none;
  z-index: 20;
}

.msg-group:hover .msg-actions-bar,
.msg:hover .msg-actions-bar,
.msg-stack:hover .msg-actions-bar,
.msg-meta-row:hover .msg-actions-bar,
.msg-actions-bar:focus-within,
.msg-actions-bar.open,
.msg-actions-bar:has(.open) {
  opacity: 1;
  pointer-events: auto;
}

.msg-action-item {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Sleek Circular Action Button */
.msg-action-icon-btn {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: none;
  background: rgba(0, 0, 0, 0.05);
  color: var(--text-dim, #71717A);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);
  box-sizing: border-box;
}

[data-theme="dark"] .msg-action-icon-btn {
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.7);
}

.msg-action-icon-btn:hover {
  background: rgba(0, 0, 0, 0.12);
  color: var(--text-main, #18181B);
  transform: scale(1.12);
}

[data-theme="dark"] .msg-action-icon-btn:hover {
  background: rgba(255, 255, 255, 0.2);
  color: #FFFFFF;
}

.msg-action-icon-btn:active {
  transform: scale(0.92);
}

.msg-action-icon-btn svg {
  display: block;
  pointer-events: none;
}

/* Quick Reactions Popover (Floating emoji pill above 😊) */
.msg-react-wrap {
  position: relative;
}

.msg-quick-reactions-popover {
  position: absolute;
  bottom: calc(100% + 8px);
  background: var(--bg-card, #FFFFFF);
  border: 1px solid var(--border, rgba(0, 0, 0, 0.08));
  border-radius: 999px;
  padding: 4px 6px;
  display: none;
  align-items: center;
  gap: 2px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18), 0 2px 6px rgba(0, 0, 0, 0.08);
  backdrop-filter: blur(16px);
  z-index: 100;
  white-space: nowrap;
}

[data-theme="dark"] .msg-quick-reactions-popover {
  background: #1E1E2E;
  border-color: rgba(255, 255, 255, 0.12);
  box-shadow: 0 6px 28px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.3);
}

.msg-group.outgoing .msg-quick-reactions-popover,
.msg.mine .msg-quick-reactions-popover {
  right: 0;
  left: auto;
  transform-origin: bottom right;
}

.msg-group.incoming .msg-quick-reactions-popover,
.msg:not(.mine) .msg-quick-reactions-popover {
  left: 0;
  right: auto;
  transform-origin: bottom left;
}

.msg-react-wrap.open .msg-quick-reactions-popover,
.msg-react-wrap:hover .msg-quick-reactions-popover {
  display: flex;
  animation: fbPopoverPop 0.18s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

@keyframes fbPopoverPop {
  0% {
    opacity: 0;
    transform: scale(0.6) translateY(8px);
  }
  100% {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

.quick-rx-btn {
  border: none;
  background: transparent;
  font-size: 20px;
  line-height: 1;
  padding: 4px 5px;
  border-radius: 50%;
  cursor: pointer;
  transition: transform 0.15s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  user-select: none;
}

.quick-rx-btn:hover {
  transform: scale(1.38) translateY(-4px);
}

.quick-rx-btn:active {
  transform: scale(1.1);
}

/* More Menu Dropdown */
.msg-more-wrap {
  position: relative;
}

.msg-more-menu {
  position: absolute;
  bottom: calc(100% + 8px);
  background: var(--bg-card, #FFFFFF);
  border: 1px solid var(--border, rgba(0, 0, 0, 0.08));
  border-radius: 12px;
  padding: 5px;
  display: none;
  flex-direction: column;
  min-width: 140px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16), 0 2px 6px rgba(0, 0, 0, 0.06);
  backdrop-filter: blur(16px);
  z-index: 100;
}

[data-theme="dark"] .msg-more-menu {
  background: #1E1E2E;
  border-color: rgba(255, 255, 255, 0.12);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.3);
}

.msg-group.outgoing .msg-more-menu,
.msg.mine .msg-more-menu {
  right: 0;
  left: auto;
  transform-origin: bottom right;
}

.msg-group.incoming .msg-more-menu,
.msg:not(.mine) .msg-more-menu {
  left: 0;
  right: auto;
  transform-origin: bottom left;
}

.msg-more-wrap.open .msg-more-menu {
  display: flex;
  animation: fbPopoverPop 0.15s cubic-bezier(0.16, 1, 0.3, 1);
}

.msg-menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  border: none;
  background: transparent;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-main, #27272A);
  cursor: pointer;
  text-align: left;
  transition: background 0.12s ease, color 0.12s ease;
  white-space: nowrap;
}

[data-theme="dark"] .msg-menu-item {
  color: #F4F4F5;
}

.msg-menu-item:hover {
  background: rgba(0, 0, 0, 0.06);
  color: var(--brand-primary, #6366F1);
}

[data-theme="dark"] .msg-menu-item:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #FFFFFF;
}

.msg-menu-item svg {
  flex-shrink: 0;
  opacity: 0.85;
}

/* Reaction Pills (Pinned at the bottom of the bubble) */
.msg-reactions-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: -8px;
  margin-bottom: 2px;
  z-index: 5;
  position: relative;
}

.msg-group.outgoing .msg-reactions-bar,
.msg.mine .msg-reactions-bar {
  justify-content: flex-end;
  padding-right: 6px;
}

.msg-group.incoming .msg-reactions-bar,
.msg:not(.mine) .msg-reactions-bar {
  justify-content: flex-start;
  padding-left: 6px;
}

.msg-reaction-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border-radius: 999px;
  padding: 2px 7px;
  font-size: 11.5px;
  line-height: 1.2;
  border: 1px solid var(--border, rgba(0, 0, 0, 0.1));
  background: var(--bg-card, #FFFFFF);
  color: var(--text-main, #3F3F46);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  cursor: pointer;
  transition: all 0.15s ease;
  user-select: none;
}

[data-theme="dark"] .msg-reaction-pill {
  background: #252538;
  border-color: rgba(255, 255, 255, 0.12);
  color: #F4F4F5;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}

.msg-reaction-pill:hover {
  transform: scale(1.08);
  background: rgba(0, 0, 0, 0.04);
}

[data-theme="dark"] .msg-reaction-pill:hover {
  background: rgba(255, 255, 255, 0.12);
}

.msg-reaction-pill.mine {
  border-color: var(--brand-primary, #6366F1);
  background: rgba(99, 102, 241, 0.08);
  color: var(--brand-primary, #6366F1);
  font-weight: 600;
}

[data-theme="dark"] .msg-reaction-pill.mine {
  background: rgba(99, 102, 241, 0.22);
  border-color: rgba(99, 102, 241, 0.6);
  color: #A5B4FC;
}

.qr-frame {
  width: 100%;
  max-width: 195px;
  aspect-ratio: 1 / 1;
  background: #FFFFFF;
  border-radius: var(--radius-md, 12px);
  padding: 10px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08), 0 0 0 1px var(--border);
  display: grid;
  place-items: center;
  margin-inline: auto;
  box-sizing: border-box;
}
.qr-frame svg {
  display: block;
  width: 100%;
  height: 100%;
}
.qr-frame.empty {
  display: grid;
  place-items: center;
  font-size: 40px;
  color: var(--text-dim);
  background: var(--bg-input);
}

/* The verify matching number card - Compact, clean & light-friendly */
.auth-qr .qr-match-box,
.qr-match-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 180px;
  padding: 6px 10px;
  border-radius: var(--radius-md, 12px);
  background: color-mix(in srgb, var(--accent-purple, #8B3DFF) 7%, var(--bg-card, #FFFFFF));
  border: 1px solid color-mix(in srgb, var(--accent-purple, #8B3DFF) 22%, var(--border, #E2E8F0));
  box-shadow: 0 2px 8px rgba(139, 61, 255, 0.06);
  margin-block: 4px 2px;
  box-sizing: border-box;
}
.auth-qr .qr-matchlede,
.qr-matchlede {
  margin: 0 0 2px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-dim, #64748B);
  text-align: center;
  line-height: 1.2;
}
.auth-qr .qr-match,
.qr-match {
  margin: 1px 0;
  font-size: 32px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: .06em;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--accent-purple, #8B3DFF);
}
.auth-qr .qr-match-warn,
.qr-match-warn {
  margin: 2px 0 0;
  font-size: 10px;
  font-weight: 500;
  line-height: 1.2;
  text-align: center;
  color: var(--amber, #D97706);
}

[data-theme="dark"] .auth-qr .qr-match-box,
[data-theme="dark"] .qr-match-box {
  background: color-mix(in srgb, var(--accent-purple, #8B3DFF) 14%, var(--bg-input, #151628));
  border: 1px solid color-mix(in srgb, var(--accent-purple, #8B3DFF) 35%, var(--border, #262840));
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
}
[data-theme="dark"] .auth-qr .qr-matchlede,
[data-theme="dark"] .qr-matchlede {
  color: #C4B5FD;
}
[data-theme="dark"] .auth-qr .qr-match,
[data-theme="dark"] .qr-match {
  color: #D8B4FE;
  text-shadow: 0 0 16px rgba(192, 132, 252, 0.4);
}
[data-theme="dark"] .auth-qr .qr-match-warn,
[data-theme="dark"] .qr-match-warn {
  color: #FBBF24;
}

.msg-reaction-pill .rx-num {
  font-size: 11px;
  font-weight: 600;
  opacity: 0.85;
}

/* Quoted Message inside bubble */
.msg-quote {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 4px 8px;
  border-radius: 8px;
  margin-bottom: 4px;
  cursor: pointer;
  transition: opacity 0.15s ease, filter 0.15s ease;
  font-size: 11.5px;
  line-height: 1.25;
  user-select: none;
}

.msg-quote:hover {
  filter: brightness(0.95);
  opacity: 0.92;
}

/* Incoming bubble quote */
.msg-bubble.incoming .msg-quote,
.bubble:not(.mine) .msg-quote {
  background: rgba(0, 0, 0, 0.05);
  border-left: 3px solid var(--brand-primary, #6366F1);
  color: var(--text-main, #18181B);
}

[data-theme="dark"] .msg-bubble.incoming .msg-quote,
[data-theme="dark"] .bubble:not(.mine) .msg-quote {
  background: rgba(255, 255, 255, 0.07);
}

.msg-bubble.incoming .msg-quote-header,
.bubble:not(.mine) .msg-quote-header {
  display: flex;
  align-items: center;
  gap: 4px;
  font-weight: 700;
  color: var(--brand-primary, #6366F1);
  font-size: 10.5px;
  line-height: 1.2;
}

.msg-bubble.incoming .msg-quote-body,
.bubble:not(.mine) .msg-quote-body {
  color: var(--text-dim, #71717A);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 240px;
  font-size: 11.5px;
  line-height: 1.25;
}

/* Outgoing bubble quote */
.msg-bubble.outgoing .msg-quote,
.bubble.mine .msg-quote {
  background: rgba(255, 255, 255, 0.2);
  border-left: 3px solid rgba(255, 255, 255, 0.9);
  color: #FFFFFF;
}

.msg-bubble.outgoing .msg-quote-header,
.bubble.mine .msg-quote-header {
  display: flex;
  align-items: center;
  gap: 4px;
  font-weight: 700;
  color: #FFFFFF;
  font-size: 10.5px;
  line-height: 1.2;
}

.msg-bubble.outgoing .msg-quote-body,
.bubble.mine .msg-quote-body {
  color: rgba(255, 255, 255, 0.9);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 240px;
  font-size: 11.5px;
  line-height: 1.25;
}

/* Reply Preview Banner above Composer */
.chat-reply-preview {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 16px;
  background: var(--bg-card, #FFFFFF);
  border-top: 1px solid var(--border, rgba(0, 0, 0, 0.08));
  border-left: 4px solid var(--brand-primary, #6366F1);
  animation: slideDownReply 0.2s cubic-bezier(0.16, 1, 0.3, 1);
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.03);
}

[data-theme="dark"] .chat-reply-preview {
  background: #181824;
  border-top-color: rgba(255, 255, 255, 0.08);
}

@keyframes slideDownReply {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.reply-preview-badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(99, 102, 241, 0.1);
  color: var(--brand-primary, #6366F1);
  flex-shrink: 0;
}

.reply-preview-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}

.reply-preview-sender {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--brand-primary, #6366F1);
}

.reply-preview-text {
  font-size: 12.5px;
  color: var(--text-dim, #71717A);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.reply-preview-cancel {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-dim, #71717A);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  transition: all 0.15s ease;
  flex-shrink: 0;
}

.reply-preview-cancel:hover {
  background: rgba(0, 0, 0, 0.06);
  color: var(--text-main, #18181B);
}

[data-theme="dark"] .reply-preview-cancel:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #FFFFFF;
}

/* Quoted message jump pulse */
@keyframes msgPulse {
  0% { transform: scale(1); }
  30% { transform: scale(1.03); filter: drop-shadow(0 0 8px rgba(99, 102, 241, 0.6)); }
  100% { transform: scale(1); filter: none; }
}

.msg-highlight-pulse .msg-bubble,
.msg-highlight-pulse .bubble {
  animation: msgPulse 1.2s ease;
}

/* ── Mobile Layout Polish (Fix offscreen drawer shadow bleed & bottom nav shadow) ── */
.mobile-drawer {
  box-shadow: none !important;
  visibility: hidden;
  pointer-events: none;
}

.mobile-drawer.open {
  box-shadow: 16px 0 48px rgba(0, 0, 0, 0.4) !important;
  visibility: visible;
  pointer-events: auto;
}

.mobile-nav {
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.04) !important;
}

[data-theme="dark"] .mobile-nav,
.theme-dark .mobile-nav {
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.4) !important;
}

/* ── หน้าต่างแชร์โพสต์ (Repost / Share as my own post Modal) ── */
.sheet-modal:has(.repost-sheet-content) {
  width: 540px !important;
  max-width: min(540px, calc(100vw - 28px)) !important;
  border-radius: 20px !important;
  background: rgba(13, 14, 28, 0.78) !important;
  backdrop-filter: blur(28px) saturate(190%) !important;
  -webkit-backdrop-filter: blur(28px) saturate(190%) !important;
  box-shadow: 0 24px 64px -8px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(255, 255, 255, 0.06) !important;
  border: 1px solid rgba(255, 255, 255, 0.12) !important;
  overflow: hidden !important;
}

[data-theme="light"] .sheet-modal:has(.repost-sheet-content),
.theme-light .sheet-modal:has(.repost-sheet-content) {
  background: rgba(255, 255, 255, 0.82) !important;
  backdrop-filter: blur(28px) saturate(190%) !important;
  -webkit-backdrop-filter: blur(28px) saturate(190%) !important;
  box-shadow: 0 20px 50px -10px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.04) !important;
  border: 1px solid rgba(0, 0, 0, 0.09) !important;
}

.sheet-modal:has(.repost-sheet-content) .sheet-header {
  padding: 16px 20px !important;
  border-bottom: 1px solid var(--border, rgba(0, 0, 0, 0.08)) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
}

.sheet-modal:has(.repost-sheet-content) .sheet-header > span,
.sheet-modal:has(.repost-sheet-content) .sheet-header .sheet-title {
  font-size: 17px !important;
  font-weight: 700 !important;
  color: var(--text-main, #1E293B) !important;
  letter-spacing: -0.01em !important;
}

[data-theme="dark"] .sheet-modal:has(.repost-sheet-content) .sheet-header > span,
[data-theme="dark"] .sheet-modal:has(.repost-sheet-content) .sheet-header .sheet-title {
  color: #F1F5F9 !important;
}

.sheet-modal:has(.repost-sheet-content) .sheet-close {
  width: 32px !important;
  height: 32px !important;
  border-radius: 50% !important;
  background: var(--bg-input, rgba(0, 0, 0, 0.05)) !important;
  color: var(--text-muted, #64748B) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  cursor: pointer !important;
  transition: all 0.15s ease !important;
  border: none !important;
}

.sheet-modal:has(.repost-sheet-content) .sheet-close:hover {
  background: var(--border, rgba(0, 0, 0, 0.1)) !important;
  color: var(--text-main, #0F172A) !important;
}

.sheet-modal:has(.repost-sheet-content) .sheet-body {
  padding: 18px 22px 20px !important;
  max-height: calc(85vh - 70px) !important;
  overflow-y: auto !important;
}

.repost-sheet-content {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.repost-author-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.repost-sharer-avatar {
  width: 44px !important;
  height: 44px !important;
  min-width: 44px !important;
  min-height: 44px !important;
  max-width: 44px !important;
  max-height: 44px !important;
  border-radius: 50% !important;
  overflow: hidden !important;
  flex-shrink: 0 !important;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1) !important;
}

.repost-sharer-avatar img,
.repost-sharer-avatar .avatar-img,
.repost-sharer-avatar .av {
  width: 100% !important;
  height: 100% !important;
  border-radius: 50% !important;
  object-fit: cover !important;
  display: block !important;
}

.repost-sharer-info {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.repost-sharer-name {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-main, #1E293B);
  line-height: 1.2;
}

[data-theme="dark"] .repost-sharer-name {
  color: #F1F5F9;
}

.repost-audience-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-dim, #64748B);
  background: var(--bg-input, rgba(0, 0, 0, 0.05));
  padding: 3px 10px;
  border-radius: var(--radius-pill, 999px);
  width: fit-content;
}

[data-theme="dark"] .repost-audience-badge {
  background: rgba(255, 255, 255, 0.08);
  color: #94A3B8;
}

.repost-audience-badge svg {
  opacity: 0.8;
}

.repost-input-wrap {
  position: relative;
  background: transparent;
  border: none;
  padding: 2px 0;
}

.repost-textarea {
  width: 100%;
  min-height: 72px;
  max-height: 140px;
  background: transparent;
  border: none;
  outline: none;
  font-family: inherit;
  font-size: 15.5px;
  line-height: 1.5;
  color: var(--text-main, #1E293B);
  resize: none;
  padding: 0;
}

[data-theme="dark"] .repost-textarea {
  color: #F1F5F9;
}

.repost-textarea::placeholder {
  color: var(--text-dim, #94A3B8);
  font-size: 15px;
}

.repost-input-tools {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding-top: 4px;
}

.repost-input-tools .tool-btn {
  font-size: 20px;
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 4px;
  border-radius: 8px;
  transition: background 0.15s ease;
}

.repost-input-tools .tool-btn:hover {
  background: var(--bg-input, rgba(0, 0, 0, 0.05));
}

.repost-preview-card {
  border: 1px solid var(--border, rgba(0, 0, 0, 0.1));
  border-radius: 14px;
  background: var(--bg-input, rgba(0, 0, 0, 0.02));
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.03);
}

[data-theme="dark"] .repost-preview-card {
  background: rgba(255, 255, 255, 0.03);
  border-color: rgba(255, 255, 255, 0.08);
}

.repost-preview-header {
  display: flex;
  align-items: center;
  gap: 10px;
}

.repost-preview-avatar {
  width: 34px !important;
  height: 34px !important;
  min-width: 34px !important;
  max-width: 34px !important;
  border-radius: 50% !important;
  overflow: hidden !important;
  flex-shrink: 0 !important;
}

.repost-preview-avatar img,
.repost-preview-avatar .avatar-img,
.repost-preview-avatar .av {
  width: 100% !important;
  height: 100% !important;
  border-radius: 50% !important;
  object-fit: cover !important;
  display: block !important;
}

.repost-preview-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  min-width: 0;
}

.repost-preview-name {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text-main, #1E293B);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

[data-theme="dark"] .repost-preview-name {
  color: #F1F5F9;
}

.repost-preview-time {
  font-size: 12px;
  color: var(--text-dim, #94A3B8);
  flex-shrink: 0;
  margin-left: auto;
}

.repost-preview-text {
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-main, #334155);
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

[data-theme="dark"] .repost-preview-text {
  color: #CBD5E1;
}

.repost-preview-media {
  position: relative;
  border-radius: 12px;
  overflow: hidden;
  margin-top: 2px;
  max-height: 200px;
  border: 1px solid var(--border, rgba(0, 0, 0, 0.08));
}

.repost-preview-media img {
  width: 100%;
  height: 200px;
  object-fit: cover;
  display: block;
}

.repost-media-count {
  position: absolute;
  bottom: 8px;
  right: 8px;
  background: rgba(0, 0, 0, 0.7);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: var(--radius-pill, 999px);
  backdrop-filter: blur(4px);
}

.repost-chain-hint {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--amber, #D97706);
  background: rgba(245, 158, 11, 0.08);
  padding: 9px 13px;
  border-radius: 10px;
  border: 1px solid rgba(245, 158, 11, 0.2);
}

.repost-privacy-note {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  color: var(--text-dim, #64748B);
  line-height: 1.4;
}

.repost-privacy-note svg {
  flex-shrink: 0;
  opacity: 0.7;
}

.repost-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 6px;
  padding-top: 14px;
  border-top: 1px solid var(--border, rgba(0, 0, 0, 0.08));
}

.repost-cancel-btn {
  padding: 9px 20px;
  border-radius: var(--radius-pill, 999px);
  border: 1px solid var(--border, rgba(0, 0, 0, 0.15));
  background: transparent;
  color: var(--text-muted, #64748B);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s ease;
}

.repost-cancel-btn:hover {
  background: var(--bg-input, rgba(0, 0, 0, 0.05));
  color: var(--text-main, #0F172A);
}

.repost-submit-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 9px 26px;
  border-radius: var(--radius-pill, 999px);
  border: none;
  background: var(--brand-gradient, linear-gradient(135deg, #8B5CF6 0%, #6366F1 100%));
  color: #FFFFFF;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(139, 92, 246, 0.35);
  transition: all 0.15s ease;
}

.repost-submit-btn .btn-ic svg {
  width: 16px;
  height: 16px;
  display: block;
}

.repost-submit-btn:hover {
  filter: brightness(1.08);
  transform: translateY(-1px);
  box-shadow: 0 6px 20px rgba(139, 92, 246, 0.45);
}

.repost-submit-btn:disabled {
  opacity: 0.6;
  transform: none;
  cursor: not-allowed;
}

/* ── หน้าต่างสายย่อลอย (Call PiP Floating Widget Fix) ── */
.call-pip-floating-widget {
  padding: 8px 12px !important;
  gap: 10px !important;
  border-radius: var(--radius-pill, 999px) !important;
}

.call-pip-avatar {
  width: 38px !important;
  height: 38px !important;
  border-radius: 50% !important;
  flex-shrink: 0 !important;
  overflow: hidden !important;
}

.call-pip-end {
  width: 32px !important;
  height: 32px !important;
  min-width: 32px !important;
  min-height: 32px !important;
  max-width: 32px !important;
  max-height: 32px !important;
  border-radius: 50% !important;
  background: #EF4444 !important;
  border: none !important;
  color: #FFFFFF !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  cursor: pointer !important;
  padding: 0 !important;
  margin: 0 !important;
  flex-shrink: 0 !important;
  overflow: hidden !important;
  transition: transform 0.15s ease, background 0.15s ease !important;
}

.call-pip-end:hover {
  background: #DC2626 !important;
  transform: scale(1.08) !important;
}

.call-pip-end svg {
  width: 14px !important;
  height: 14px !important;
  max-width: 14px !important;
  max-height: 14px !important;
  display: block !important;
  flex-shrink: 0 !important;
}




/* ── ตัดข้อความยาวในการ์ดฟีด ── ตัดที่จำนวนบรรทัด ไม่ใช่จำนวนตัวอักษร
   ข้อความธรรมดา 10 บรรทัด · โพสต์ข้อความล้วน (ตัวอักษรใหญ่กว่า) 8 บรรทัด */
.post-text.feed-clamp {
  display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden;
  /* 6 บรรทัดบนเว็บ ไม่ใช่ 10 เหมือนแอป — คอลัมน์กลางของเว็บกว้างกว่าจอมือถือเกือบสองเท่า
     ⇒ ข้อความ 500 ตัวอักษรกินแค่ ~5–6 บรรทัด ปุ่มจึงไม่เคยโผล่เลยถ้าตั้งไว้ที่ 10 */
  -webkit-line-clamp: 6;
}
.post-card.text-only .post-text.feed-clamp { -webkit-line-clamp: 5; }
.feed-more { display: inline-block; margin-top: 4px; font-size: 13px; font-weight: 700; }

/* ===== การ์ดพรีวิวลิงก์ในโพสต์ (linkcard.js) ===== */
.post-link {
  color: var(--accent-blue, #3B82F6);
  text-decoration: underline;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.post-linkcard {
  margin-top: 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 16px);
  overflow: hidden;
  background: var(--bg-card);
  display: block;
  color: inherit;
  text-decoration: none;
  box-shadow: var(--card-shadow);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.post-linkcard:hover {
  border-color: var(--border-strong, var(--border));
  box-shadow: 0 6px 20px rgba(0,0,0,0.12);
}
.post-linkcard-link {
  display: block;
  color: inherit;
  text-decoration: none;
}
.post-linkcard-skel {
  height: 84px;
  background: var(--bg-input, var(--bg-header));
  animation: pulse 1.5s infinite;
}
.post-linkcard-media {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--bg-input, var(--bg-header));
  overflow: hidden;
}
.post-linkcard-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.post-linkcard-iframe {
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  display: block;
}
.post-linkcard-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 56px;
  height: 56px;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.68);
  color: #FFFFFF;
  cursor: pointer;
  display: grid;
  place-items: center;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  transition: transform 0.15s ease, background 0.15s ease;
  z-index: 2;
}
.post-linkcard-play:hover {
  background: rgba(0, 0, 0, 0.85);
  transform: scale(1.08);
}
.post-linkcard-play svg {
  width: 26px;
  height: 26px;
}
.post-linkcard-body {
  padding: 10px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.post-linkcard-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-main);
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.post-linkcard-desc {
  font-size: 12.5px;
  color: var(--text-dim);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.post-linkcard-domain {
  font-size: 11.5px;
  color: var(--text-dim);
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
}
.post-linkcard-domain svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.post-linkcard-openout {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent-blue, #3B82F6);
  padding: 2px 14px 10px;
  display: inline-block;
  text-decoration: none;
}
.post-linkcard-openout:hover {
  text-decoration: underline;
}

/* ── QR Login (qrlogin.js) ───────────────────────────────────────────────── */
.qrlogin {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 100%;
}
.qr-lede {
  margin: 0 0 2px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-main);
  text-align: center;
}
.qr-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 180px;
  width: 100%;
}
.qr-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 100%;
}


.qr-countdown {
  margin: 4px 0 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-muted);
}
.qr-countdown bdi {
  font-variant-numeric: tabular-nums;
  color: var(--text-main);
  font-weight: 700;
}
.qr-device {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--text-dim);
  text-align: center;
}
.qr-note {
  margin: 4px 0 0;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--text-dim);
  text-align: center;
}
.qr-status {
  margin: 4px 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-main);
  text-align: center;
}
.qr-status.ok { color: #22C55E; }
.qr-status.err { color: #EF4444; }
.qr-warn {
  margin: 4px 0;
  padding: 6px 12px;
  border-radius: var(--radius-md, 8px);
  font-size: 12px;
  line-height: 1.4;
  background: rgba(245, 158, 11, 0.15);
  color: #F59E0B;
  border: 1px solid rgba(245, 158, 11, 0.35);
  text-align: center;
}
.qr-back-row {
  display: flex;
  justify-content: center;
  width: 100%;
  margin-top: 8px;
}
.qr-back-btn {
  width: 100%;
  max-width: 320px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: var(--radius-md, 12px);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-main);
  background: var(--bg-card);
  border: 1px solid var(--border);
  cursor: pointer;
  transition: all 0.2s ease;
}
.qr-back-btn:hover {
  background: var(--bg-input-focus);
  border-color: var(--border-focus);
  transform: translateY(-1px);
}
.qr-back-btn svg {
  width: 16px;
  height: 16px;
  color: var(--text-muted);
}

/* Top bar header language pill */
.header-actions .lang-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  height: 32px;
  padding: 0 10px;
  border-radius: var(--radius-pill, 9999px);
  border: 1px solid var(--border);
  background: var(--bg-card);
  color: var(--text-main);
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.2s ease;
  box-sizing: border-box;
}
.header-actions .lang-trigger svg {
  width: 14px;
  height: 14px;
  color: var(--text-muted);
}
.header-actions .lang-trigger:hover {
  background: var(--bg-input-focus);
  border-color: var(--border-focus);
  color: var(--text-main);
}

/* Chat bubble adaptation for linkcard */
.msg-stack .post-linkcard,
.msg .bubble .post-linkcard {
  max-width: 320px;
  width: 100%;
  margin-top: 6px;
  border-radius: var(--radius-md, 12px);
}
.msg-group.outgoing .msg-stack .post-linkcard,
.msg.mine .post-linkcard {
  margin-left: auto;
}

/* ===== ปุ่มเลื่อนเปิด/ปิด (.switch) — ยกมาจาก app.css ที่เว็บเลิกโหลดแล้ว =====
   notifprefs.js กับ serviceprofile.js เรียกคลาสนี้อยู่จริง แต่ไม่มีกฎไหนโหลด
   ⇒ สวิตช์เป็นกล่องเปล่าไม่มีสี ทุกค่าที่นี่ผูกกับโทเคนธีม จึงตามมืด/สว่าง/auto เอง */
.switch { position: relative; display: inline-block; width: 44px; height: 24px; flex: none; }
.switch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.switch span {
  position: absolute; inset: 0; border-radius: 999px;
  background: var(--s3); border: 1px solid var(--line); transition: background .15s;
  pointer-events: none;
}
.switch span::after {
  content: ""; position: absolute; top: 2px; inset-inline-start: 2px;
  width: 18px; height: 18px; border-radius: 50%; background: var(--dim);
  transition: transform .15s, background .15s;
}
.switch input:checked + span {
  background: color-mix(in srgb, var(--green) 35%, transparent);
  border-color: var(--green);
}
.switch input:checked + span::after { transform: translateX(20px); background: var(--green); }
html[dir="rtl"] .switch input:checked + span::after { transform: translateX(-20px); }
.switch input:disabled + span { opacity: .5; }
.switch input:disabled { cursor: not-allowed; }
/* ล้าง outline ที่ไหน ต้องคืน outline ที่นั่นเสมอ — สวิตช์ความเป็นส่วนตัวที่คนใช้คีย์บอร์ดมองไม่เห็นวงโฟกัส คือที่ที่แย่ที่สุดที่จะทำหาย */
.switch input:focus-visible + span { outline: 2px solid var(--a2); outline-offset: 2px; }

/* การ์ดลิงก์กะทัดรัด (`.post-linkcard.compact` — ตัว MODIFIER ของ `.post-linkcard` เดิม
   ไม่ใช่การ์ดใบที่สอง) ใช้เฉพาะในคอมเมนต์ (`feed.js` ส่ง `{ compact: true }` ให้
   `buildLinkCard` เฉพาะที่คอมเมนต์เท่านั้น — โพสต์ในฟีดยังเป็นทรงเดิม รูปเต็มความกว้างด้านบน)
   รูปสี่เหลี่ยมจัตุรัสซ้าย ~60px ข้อความขวา รวมสูง ~64–72px ใช้ flex แถวธรรมดา (ไม่ใช้
   left/right ตายตัว) เพื่อให้พลิกเองตาม `dir="rtl"` ที่ตั้งบน root โดย i18n.js */
.post-linkcard.compact {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  max-width: 320px;
  width: 100%;
  margin-top: 6px;
  border-radius: var(--radius-md, 12px);
}
.post-linkcard.compact .post-linkcard-link {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  width: 100%;
  min-width: 0;
}
/* รูป — สี่เหลี่ยมจัตุรัส ไม่ใช้ aspect-ratio 16:9 ของการ์ดโพสต์ และ "ไม่มีรูป = ไม่มี
   div นี้เลย" (ดู renderGenericCard/renderYoutubeCover ใน linkcard.js — เงื่อนไขเดิม
   ที่ข้าม div ถ้าไม่มี image_url ยังทำงานเหมือนเดิม ที่นี่แค่กำหนดขนาดตอนมันมีจริง) */
.post-linkcard.compact .post-linkcard-media {
  width: 60px;
  height: 60px;
  flex: none;
  aspect-ratio: unset;
  border-inline-end: 1px solid var(--border);
}
.post-linkcard.compact .post-linkcard-body {
  padding: 6px 10px;
  justify-content: center;
  gap: 2px;
  min-width: 0;
  flex: 1;
}
.post-linkcard.compact .post-linkcard-title {
  font-size: 12.5px;
  line-height: 1.32;
  -webkit-line-clamp: 2;
}
/* คำอธิบายยาวไม่มีที่ในการ์ดสูง ~64–72px — ซ่อนไว้ (ยังอยู่ใน DOM เผื่อคลาส .compact
   ถูกถอดออกชั่วคราวตอนเล่นวิดีโอ YouTube ใน playInline()) */
.post-linkcard.compact .post-linkcard-desc,
.post-linkcard.compact .post-linkcard-openout {
  display: none;
}
.post-linkcard.compact .post-linkcard-domain {
  font-size: 10.5px;
}
/* ปุ่มเล่น YouTube เดิม 56px กว้างเกือบเท่ารูปสี่เหลี่ยม 60px ทั้งใบ — ย่อให้พอดีช่อง */
.post-linkcard.compact .post-linkcard-play {
  width: 28px;
  height: 28px;
}
.post-linkcard.compact .post-linkcard-play svg {
  width: 14px;
  height: 14px;
}
/* สถานะ "โหลดพรีวิวไม่สำเร็จ" ในคอมเมนต์ไม่หายเงียบ — เหลือแถวโดเมนอย่างน้อย
   (renderDomainOnly() ใน linkcard.js) ต่างจากโพสต์ในฟีดที่ยัง render เป็นความว่างเปล่า
   ตามเดิม (สเปกเดิม: ลิงก์ไม่มีพรีวิวต้องไม่ขึ้นการ์ดพัง) */
.post-linkcard.compact.post-linkcard-domainonly .post-linkcard-body {
  padding: 8px 10px;
  justify-content: center;
}
/* โครงกำลังโหลด — สูงเท่าการ์ดจริง (มีรูป) กันคอมเมนต์กระโดดตอนพรีวิวโหลดเสร็จ */
.post-linkcard.compact .post-linkcard-skel {
  height: 64px;
}
/* YouTube ที่กำลังเล่นอยู่ (playInline ถอดคลาส .compact ชั่วคราว — ดู linkcard.js) ใช้
   ทรงเต็มความกว้าง 16:9 เดิมของ `.post-linkcard-video`, ไม่ใช่ช่องสี่เหลี่ยมจัตุรัส 60px */

/* ==========================================================================
   Image crop sheet (imagecrop.js) — product/room/food/service cover photos.
   Its own `.scrim` stacked on top of an already-open editor sheet, never
   `openSheet()` (that is a singleton and would close the editor underneath).
   ========================================================================== */
.imgcrop-scrim { z-index: 9995; } /* one above the ordinary sheet's 9990 */
.imgcrop-modal { width: 100%; max-width: 420px; display: flex; flex-direction: column; }
.imgcrop-body { display: flex; flex-direction: column; gap: 12px; align-items: stretch; }
.imgcrop-stage {
  position: relative; width: 100%; max-width: 340px; margin: 0 auto;
  overflow: hidden; border-radius: 16px; background: #000;
  touch-action: none; cursor: grab; border: 1px solid var(--border);
}
.imgcrop-stage:active { cursor: grabbing; }
.imgcrop-stage img {
  position: absolute; top: 0; left: 0; transform-origin: 0 0;
  will-change: transform; -webkit-user-drag: none; user-select: none;
  max-width: none; max-height: none; /* natural size is the base for scale() */
}
.imgcrop-zoom { width: 100%; max-width: 340px; margin: 0 auto; accent-color: var(--accent-pink); }
.imgcrop-hint { text-align: center; margin: 0; }
.imgcrop-acts { justify-content: flex-end; }
@media (max-width: 640px) {
  .imgcrop-modal { width: 100% !important; }
}

/* ==========================================================================
   "สั่งเมนูเดิมซ้ำ" (web parity, 2026-08-18) — book.js `menuCard()`.
   ป้ายจำนวนบนมุมขวาบนของรูปเมนู เมื่อเมนูนั้นอยู่ในตะกร้าแล้ว (รวมทุกบรรทัดของ
   เมนูนั้น แม้ตัวเลือกต่างชุดกันจะแยกเป็นคนละบรรทัดในตะกร้า) — ไม่ใช่สีสถานะ
   (amber/blue/…) เพราะนี่ไม่ใช่สถานะออเดอร์ จึงใช้ไล่สีแบรนด์แทน ตามกฎ
   "สีสถานะใช้ค่าคงที่ ไม่ผูกกับ accent" ซึ่งใช้กับ badge สถานะเท่านั้น
   ป้ายจำนวนในตะกร้าไม่ใช่ป้ายสถานะ. */
.product-qty-badge {
  position: absolute; top: 8px; right: 8px;
  min-width: 20px; height: 20px; padding: 0 5px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--brand-gradient);
  color: #FFF;
  font-size: 11px; font-weight: 800;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .35);
}

/* ==========================================================================
   แชทเว็บให้เท่าแอป (KORAT_WEB_PARITY.md, 2026-08-19) — แก้ไข/ลบข้อความ,
   ปักหมุดข้อความ+ห้อง, ค้นหาข้อความในห้อง. `web/app/app.css` ไม่ถูกโหลดจริง
   (ดูคอมเมนต์ใน site/app/index.html: "ไม่มี app.css อีกแล้ว") ⇒ กฎใหม่ต้องอยู่
   ที่นี่จึงจะมีผล ไม่ใช่การแตะไฟล์ที่ไม่ใช่ของ subagent นี้โดยพลการ — ไฟล์เดียวที่
   จะทำให้ปุ่มใหม่มีหน้าตาจริง.
   ========================================================================== */

/* แก้ไขข้อความ — สลับ span เดิมเป็นกล่องนี้ใน `.msg-bubble` เดียวกัน */
.msg-edit-box { display: flex; flex-direction: column; gap: 6px; min-width: 160px; }
.msg-edit-input {
  width: 100%; min-height: 44px; resize: vertical; font: inherit; color: inherit;
  background: rgba(127, 127, 127, 0.12); border: 1px solid var(--border);
  border-radius: 10px; padding: 6px 8px;
}
.msg-edit-actions { display: flex; justify-content: flex-end; gap: 6px; }

/* แก้ไขคอมเมนต์ — ท่าเดียวกับ .msg-edit-* ข้างบน (feed.js:startInlineCommentEdit) */
.comment-edit-box { display: flex; flex-direction: column; gap: 6px; margin: 4px 0; }
.comment-edit-input {
  width: 100%; min-height: 44px; resize: vertical; font: inherit; color: inherit;
  background: rgba(127, 127, 127, 0.12); border: 1px solid var(--border);
  border-radius: 10px; padding: 6px 8px;
}
.comment-edit-actions { display: flex; justify-content: flex-end; gap: 6px; }

/* ปุ่ม "เก็บลงไฮไลต์" บนตัวดูสตอรี่ — ใช้ฐาน `.story-modal-close` (สี/ตำแหน่งบน
   `.story-modal-header` เดิม) แต่ยกเลิก margin-left:auto ของมัน (ให้ปุ่มปิด ×
   เป็นตัวเดียวที่ดันไปขวาสุด) แล้วเว้นช่องว่างด้านขวาของตัวเองแทน */
.story-savehl-btn { margin-right: 6px; font-size: inherit; display: inline-flex; }

/* ══════════════════════════════════════════════════════════════════════════
   ไฮไลต์สตอรี่บนหน้าโปรไฟล์ (storyhighlights.js) — ไม่มีมาร์คอัพต้นแบบใน
   demo/social/v3 (เป็นฟีเจอร์ใหม่จริง ไม่ใช่ของที่ demo มีแล้วแต่ยังไม่ได้ลอก) ⇒
   คลาสชุดนี้เกิดพร้อมกฎ CSS ในไฟล์เดียวกัน ไม่ใช่ชื่อลอยที่ JS แต่งเอง
   ══════════════════════════════════════════════════════════════════════════ */
.profile-highlights-row {
  display: flex; gap: 14px; overflow-x: auto; padding: 10px 16px 6px;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.profile-highlights-row::-webkit-scrollbar { display: none; }
.profile-highlight-item {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  width: 68px; flex: 0 0 auto; cursor: pointer; background: none; border: none;
  padding: 0; font: inherit; color: inherit;
}
.profile-highlight-circle {
  width: 60px; height: 60px; border-radius: 50%; background-size: cover;
  background-position: center; background-color: var(--bg-input);
  border: 2px solid var(--border); display: grid; place-items: center;
  color: var(--text-dim);
}
.profile-highlight-item.add .profile-highlight-circle { border-style: dashed; }
.profile-highlight-label {
  font-size: 11px; color: var(--text-dim); max-width: 68px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; text-align: center;
}
.profile-highlight-skel .profile-highlight-circle { background: var(--bg-input); }

/* ชีตจัดการไฮไลต์ (สร้าง/เปลี่ยนชื่อ/สิทธิ์การมองเห็น/ลบ) — โครงชีตใช้ `openSheet` เดิม */
.highlight-form-row { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.highlight-form-row label { font-size: 12px; color: var(--text-dim); font-weight: 700; }
.highlight-vis-options { display: flex; gap: 8px; flex-wrap: wrap; }
.highlight-vis-opt {
  padding: 6px 12px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--bg-input); color: var(--text-main); font-size: 13px; cursor: pointer;
}
.highlight-vis-opt.active { background: var(--brand-gradient); border-color: transparent; color: #fff; }
.highlight-slide-picker { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.highlight-slide-opt {
  position: relative; aspect-ratio: 9 / 16; border-radius: 10px; overflow: hidden;
  background-size: cover; background-position: center; background-color: var(--bg-input);
  border: 2px solid transparent; cursor: pointer;
}
.highlight-slide-opt.picked { border-color: var(--accent-purple); }
.highlight-slide-opt.picked::after {
  content: "✓"; position: absolute; top: 4px; right: 4px; width: 18px; height: 18px;
  border-radius: 50%; background: var(--accent-purple); color: #fff; font-size: 12px;
  display: grid; place-items: center;
}

/* แถบเครื่องมือห้อง — ปุ่มค้นหา + กล่องค้นหา + แบนเนอร์ข้อความที่ปักหมุด */
.chat-toolbar-host { display: flex; flex-direction: column; }
.chat-toolbar-row { display: flex; justify-content: flex-end; padding: 4px 14px; }
.chat-toolbar-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%; border: none; cursor: pointer;
  background: transparent; color: var(--text-muted, #64748B);
}
.chat-toolbar-btn:hover { background: rgba(127, 127, 127, 0.14); color: var(--text-main); }
.chat-search-bar {
  display: flex; align-items: center; gap: 8px; margin: 0 14px 8px;
  padding: 7px 12px; border-radius: var(--radius-pill, 999px);
  background: var(--bg-input); border: 1px solid var(--border); color: var(--text-muted, #64748B);
}
.chat-search-input {
  flex: 1; border: none; background: transparent; color: var(--text-main);
  font-size: 14px; outline: none;
}
.chat-pinned-bar {
  display: flex; align-items: center; gap: 8px; margin: 0 0 4px; padding: 8px 14px;
  background: var(--bg-input); border-block: 1px solid var(--border); cursor: pointer;
  color: var(--accent-purple, #8B5CF6);
}
.chat-pinned-bar-text { flex: 1; min-width: 0; }
.chat-pinned-bar-label { font-size: 10px; font-weight: 700; color: var(--accent-purple, #8B5CF6); }
.chat-pinned-bar-body {
  font-size: 12px; color: var(--text-main); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chat-pinned-bar-action { font-size: 10px; color: var(--text-dim); flex-shrink: 0; }

/* ห้องที่ปักหมุดในลิสต์แชท — ไอคอนหมุดหน้าชื่อ */
.thread-item { position: relative; }
.thread-pin-icon { color: var(--accent-purple, #8B5CF6); flex-shrink: 0; }
.thread-item.thread-pinned { background: rgba(139, 92, 246, 0.06); }

/* คอลัมน์ขวาของแถวแชท: เวลาอยู่บน ⋮ (จัดการ) อยู่ใต้ — ปักหมุด/เปลี่ยนชื่อเล่น/
   ใส่ป้ายกำกับ/บล็อก/ลบแชท ทั้งห้าอยู่ในเมนูนี้ (openMenu ของ ui.js, ตัวเดียวกับ
   ทุกเมนู ⋯ ในแอป) — ไม่ใช่ปุ่มลอยแยก จึงไม่ชนกับปุ่มอื่นตอนจอแคบ */
.thread-right-col {
  display: flex; flex-direction: column; align-items: flex-end; justify-content: center;
  gap: 4px; flex-shrink: 0; align-self: stretch;
}
.thread-kebab-btn.icon-btn-ghost {
  width: 22px; height: 22px; color: var(--text-dim);
}
.thread-kebab-btn.icon-btn-ghost svg { width: 14px; height: 14px; transform: rotate(90deg); }
.thread-kebab-btn.icon-btn-ghost:hover { color: var(--text-main); transform: none; }

/* ── ไลก์/คอมเมนต์/แชร์ของ "ทั้งซีรีส์" (หน้าสารบัญ #/series/<id>, seriessocial.js) ──
   `.comments-thread`/`.composer-container` มีนิยามพื้นฐานอยู่แล้วแต่ล็อกไว้ใต้
   `.lightbox-comments`/`[data-route="post"]` เท่านั้น — หน้าซีรีส์อยู่นอกทั้งสอง scope
   นี้จึงต้องมีชุดของตัวเองแทนที่จะไปพึ่ง route ที่เดาไม่ได้ */
.series-social { margin: 4px 0 10px; }
.comments-section[data-seriescomments] { margin-top: 10px; }
.comments-section[data-seriescomments] .comments-thread {
  display: flex; flex-direction: column; gap: 10px; padding: 10px 0;
}
.comments-section[data-seriescomments] .composer-container {
  padding: 10px 0; border-top: 1px solid var(--border); margin-top: 6px;
}
.comments-section[data-seriescomments] .composer {
  display: flex; align-items: flex-end; gap: 8px;
}
.comments-section[data-seriescomments] .composer textarea {
  flex: 1 1 auto; min-height: 36px; max-height: 120px; resize: none;
  background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius-md, 10px);
  padding: 8px 10px; font-size: 13px; color: var(--text-main); font-family: inherit;
}
.comments-section[data-seriescomments] .reply-banner {
  display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-dim);
  margin-bottom: 6px;
}
.comments-section[data-seriescomments] .reply-banner button {
  border: none; background: transparent; color: var(--accent-pink); font-weight: 600; cursor: pointer;
}
.comments-section[data-seriescomments] .reply-to { color: var(--text-dim); font-weight: 600; }
.comment-signin-cta {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px; background: var(--bg-input); border: 1px solid var(--border);
  border-radius: var(--radius-md, 10px); font-size: 13px; color: var(--text-dim);
}

/* ── อ่านออกเสียง (read-aloud) — แถบในหน้าอ่านตอนของซีรีส์ (series.js `episodeNav`,
   วางเหนือปุ่มตอนก่อนหน้า/ตอนต่อไป) ใช้ `.epnav-box`/`.epnav-line`/`.l1`/`.l2`/`.grow`
   ที่มีอยู่แล้วเป็นโครง เพิ่มแค่ปุ่มกลม + สปินเนอร์ที่ยังไม่มีคลาสของตัวเอง ── */
.ra-box { cursor: default; }
.ra-box[data-elsewhere] { cursor: pointer; }
.ra-round {
  flex-shrink: 0; width: 30px; height: 30px; border-radius: 50%; border: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(139, 92, 246, 0.16); color: var(--accent-purple, #8B5CF6);
}
.ra-round:disabled { cursor: default; opacity: .6; }
.ra-round-ghost { background: transparent; color: var(--text-dim); }
.ra-round-ghost:hover { background: rgba(127, 127, 127, 0.14); }
.ra-icon, .ra-icon-warn { flex-shrink: 0; display: inline-flex; color: var(--accent-purple, #8B5CF6); }
.ra-icon-warn { color: #EF4444; }
.ra-start { margin-top: 10px; }
.ra-spin {
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid rgba(139, 92, 246, 0.3); border-top-color: var(--accent-purple, #8B5CF6);
  animation: ra-spin .8s linear infinite;
}
@keyframes ra-spin { to { transform: rotate(360deg); } }

/* ── ยามที่อยู่/เบอร์โทรในช่องสาธารณะของ `service_requests` ────────────────────
   โครงมาร์กอัพอยู่ใน `index.html` (`#tpl-svc-leak-warning` / `#tpl-svc-leak-hit` /
   `#tpl-svc-moved`) · `svcprivacy.js` เติมแค่ค่ากับสถานะ
   สีเป็นสีสถานะคงที่ตามกฎบ้าน (amber = เตือน · green = สำเร็จ) ไม่ผูกกับ accent
   `[hidden]` ต้องมีกฎของตัวเอง: `display:flex` ด้านล่างทับ `hidden` ของเบราว์เซอร์ได้ */
.svc-leak {
  display: flex; flex-direction: column; gap: 4px; margin: 6px 0 0;
  padding: 10px 12px; border-radius: 12px;
  background: rgba(245, 158, 11, .10); border: 1px solid rgba(245, 158, 11, .55);
}
.svc-leak[hidden] { display: none; }
.svc-leak-head {
  display: flex; align-items: center; gap: 6px; margin: 0;
  font-size: 12px; font-weight: 700; color: #F59E0B;
}
.svc-leak-ico { flex-shrink: 0; width: 16px; height: 16px; }
.svc-leak-fact { margin: 0; font-size: 12px; color: var(--text-main); overflow-wrap: anywhere; }
.svc-leak-sub { margin: 0; font-size: 11px; color: var(--text-muted); overflow-wrap: anywhere; }
.svc-leak-hits { margin: 0; padding: 0; list-style: none; }
.svc-leak-hit {
  font-size: 12px; color: var(--text-muted); overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.svc-leak-hit::before { content: "· "; }
.svc-leak-hit [data-hit-kind]::after { content: ": "; }
.svc-leak-move {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 6px;
  margin-top: 2px; padding: 6px 10px; border-radius: 20px; cursor: pointer;
  border: 1px solid rgba(245, 158, 11, .55); background: transparent;
  font-size: 13px; font-weight: 700; color: #F59E0B;
}
.svc-leak-move:hover { background: rgba(245, 158, 11, .14); }
.svc-moved { display: flex; flex-direction: column; gap: 2px; margin: 6px 0 0; }
.svc-moved[hidden] { display: none; }
.svc-moved-head {
  display: flex; align-items: center; gap: 6px; margin: 0;
  font-size: 12px; font-weight: 700; color: #22C55E;
}
.svc-moved-text {
  margin: 0; font-size: 12px; color: var(--text-muted); overflow-wrap: anywhere; white-space: pre-line;
}

/* ── ห้องแชทย่อยในกลุ่ม (groupRooms.js) ──────────────────────────────────────
   ทางเข้า + รายการห้อง ยืม `.k3-row`/`.unread-count-badge`/`.badge` ที่มีกฎอยู่แล้ว
   (v3.css) — เติมเฉพาะสองอย่างที่ไม่เคยมี: สองไอคอนสลับกันในแถวเดียว (# ปกติ /
   กุญแจของห้องแอดมิน) และชื่อผู้ส่งเหนือฟองข้อความ (ห้องกลุ่มมีมากกว่าสองคน ต่างจาก
   แชทเดี่ยวที่ `.msg-bubble` ไม่เคยต้องบอกว่าใครพิมพ์) */
.croom-list-row { display: flex; }
.croom-entry-row .k3-row-icon,
.croom-list-row .k3-row-icon { flex-shrink: 0; }
.croom-msg-sender {
  font-size: 11px; font-weight: 700; color: var(--text-dim);
  margin: 0 0 2px 2px; display: block;
}
.msg-group.outgoing .croom-msg-sender { display: none; } /* ข้อความของฉันเองไม่ต้องบอกชื่อตัวเอง */
.croom-page { padding-top: 0; }
.croom-topic {
  margin: 0; padding: 8px 14px; font-size: 12px; color: var(--text-dim);
  border-bottom: 1px solid var(--border);
}
.croom-archived-note {
  margin: 0; padding: 6px 14px; font-size: 12px; color: #F59E0B;
  background: rgba(245, 158, 11, .1); text-align: center;
}
.croom-msg-delete { opacity: .55; }
.croom-msg-delete:hover { opacity: 1; color: #EF4444; }
.croom-msgs { display: flex; flex-direction: column; gap: 10px; padding: 10px 14px; }

/* ── สตูดิโอครีเอเตอร์สติกเกอร์ (stickerstudio.js) ─────────────────────────────
   ต้นแบบตัวต่อตัว: KoratStickerStudioScreen.kt — การ์ดปกและกริดใบในชุด ยืม
   `.k3-row`/`.panel`/`.chip`/`.form` ที่มีกฎอยู่แล้ว เติมเฉพาะกรอบรูปสี่เหลี่ยม
   มน + สีพื้นหลังตอนยังไม่มีรูป ที่ยังไม่เคยมีคลาสไหนให้ */
.sticker-studio-thumb {
  width: 48px; height: 48px; flex-shrink: 0; border-radius: 10px;
  background: var(--surface-2, rgba(127, 127, 127, .12));
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.sticker-studio-thumb img { width: 100%; height: 100%; object-fit: cover; }
.sticker-studio-row { cursor: pointer; }
.sticker-studio-row:hover { background: var(--surface-2, rgba(127, 127, 127, .08)); }
