/* responsive.css — ชั้นเก็บตกทุกหน้าจอ (มือถือ · แท็บเล็ต · แล็ปท็อป · จอใหญ่ · จอสั้น)
   ⚠️ โหลด "ท้ายสุดต่อจาก a11y.css" ทุก layout — กฎในนี้ต้องชนะไฟล์หน้า
   ❌ ห้ามใส่สี/ฟอนต์ใหม่ที่นี่ — ไฟล์นี้จัดการเฉพาะ "ขนาด/การจัดวาง/พื้นที่กด"

   ══ ระบบ breakpoint มาตรฐานของ ZEEDSUB ═══════════════════════════
   เดิมโปรเจกต์มี 15 ค่ากระจัดกระจาย (420/480/520/600/640/720/760/800/
   900/1000/1023/1024/1080/1100/1320) ทำให้มีช่วงจอที่ไม่มีใครดูแล
   ต่อจากนี้ของใหม่ให้ยึด 5 ค่านี้เท่านั้น (ของเดิมคงไว้ ไม่ไล่รื้อ):

     ≤ 400px   xs   มือถือเล็ก (iPhone SE, Galaxy Fold ปิด)
     ≤ 640px   sm   มือถือทั่วไป            → gutter หด, การ์ด 1 คอลัมน์
     ≤ 1023px  md   แท็บเล็ตแนวตั้ง         → sidebar เป็น drawer + bottom nav
     ≤ 1279px  lg   แท็บเล็ตแนวนอน/โน้ตบุ๊ก → sidebar กลับมา, rail ยุบ
     ≥ 1600px  xl   จอใหญ่/4K               → คุมจำนวนคอลัมน์ไม่ให้การ์ดจิ๋ว

   แกนที่สองที่เดิม "ไม่มีใครดูแลเลย" = ความสูง
     (max-height:520px)  มือถือแนวนอน — จอสูงแค่ ~400px แต่กว้าง 900+
     ตรงนี้คือจุดที่ editor พังจริง เพราะ 4 คอลัมน์ยังทำงานอยู่ที่ความกว้าง 932
   ══════════════════════════════════════════════════════════════════ */


/* ══ 1. ตาข่ายกันล้นแนวนอน (ชั้นสุดท้าย) ══════════════════════════
   a11y.css กันที่ html/body แล้ว แต่ของที่ "กว้างคงที่" ยังดันจอได้
   จากข้างใน → หนีบทุก element ที่กว้างเกินคอนเทนเนอร์ให้อยู่ในกรอบ */
:where(pre, code, table, iframe, .zs-up-dialog, .sfx-menu){max-width:100%}

/* กล่องที่มีความกว้างคงที่และต้อง scroll ในตัวเอง ไม่ใช่ดัน body */
.table-wrap, .tl-track, .tb-tabs{overscroll-behavior-x:contain}

/* คำ/URL ยาวไม่มีเว้นวรรค (ภาษาไทยไม่มีช่องว่าง → ยาวได้ไม่จำกัด)
   ⚠️ ใส่ที่ระดับข้อความเท่านั้น ห้ามใส่ที่ container ไม่งั้นตัวเลข/ปุ่มโดนหั่น */
.card-body p, .empty-state p, .field .hint, .page-sub,
.st-sub, .up-hint, .alert-msg, .toast .toast-body{overflow-wrap:anywhere}


/* ══ 2. จอเล็กสุด — 400px ลงมา ════════════════════════════════════
   iPhone SE (375) · Galaxy Fold จอนอก (280) · เบราว์เซอร์ที่ซูม 200%
   เป้าหมาย: ทุกอย่างยังกดได้และอ่านออก ไม่มีอะไรล้นขอบ */
@media (max-width:400px){
  /* 💡 --gut ไม่ต้องตั้งที่นี่ — tokens.css ใช้ clamp() ให้ 12px อยู่แล้วบนจอแคบ */

  /* ปุ่มคู่ในแถบ action → เต็มความกว้างเรียงลง ดีกว่าบีบจนอ่านไม่ออก */
  .form-actions{flex-direction:column-reverse;align-items:stretch}
  .form-actions .btn{width:100%}

  /* modal: ปุ่มยืนยัน/ยกเลิกเรียงลง — ยืนยันอยู่บนตามลำดับความสำคัญ
     ⚠️ column-reverse เพราะ markup คือ [ยกเลิก][ยืนยัน] (ยืนยันขวา) */
  .zs-modal-actions{flex-direction:column-reverse}
  .zs-modal-dialog{padding:20px 16px}

  /* หัวข้อหน้าใหญ่เกินบนจอแคบ */
  .page-head h1, .shead h1{font-size:20px}
  .empty-state{padding:32px 14px}
  .empty-state > i{font-size:34px}

  /* การ์ดสถิติ/ตัวเลข — ตัวเลข 32px ล้นได้เมื่อค่าเป็นหลักล้าน */
  .stat .sn{font-size:26px}
  .adm-stat .sn{font-size:22px}
  .adm-rev{font-size:23px}
  .slip-amt{font-size:17px}

  /* แถบสถานะบน landing */
  .hero-stats{flex-direction:column}
  .hero-stats > div + div{border-left:none;border-top:1px solid var(--line)}

  /* bottom nav 5 ช่องบนจอ 320 = 64px/ช่อง · "โปรเจกต์" ที่ 10.5px ≈ 52px เบียดพอดี
     ⚠️ ป้ายเป็น text node ตรง ๆ ใน <a> (ไม่มี <span> ครอบ) → คุมที่ตัว .bn-item เอง */
  .bn-item{
    font-size:9.5px;gap:2px;padding:0 2px;
    overflow:hidden;white-space:nowrap;
  }
}


/* ══ 3. มือถือทั่วไป ≤640px ════════════════════════════════════════ */
@media (max-width:640px){
  /* ทุก grid ที่ประกาศคอลัมน์ตายตัวไว้ในหน้า (inline style ก็โดน) */
  .hub-grid, .adm-stats, .up-tip-grid, .feat-grid, .steps4{
    grid-template-columns:1fr !important;
  }

  /* การ์ดคลิป/โปรเจกต์ 2 ใบต่อแถวบนมือถือ อ่านง่ายกว่าใบเดียวยักษ์ */
  .grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}
  .clipgrid{grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:10px}

  /* แถบเครื่องมือ/ฟิลเตอร์ — ปุ่มค้นหาเต็มแถว */
  .toolbar > form, .admin-search{width:100%}
  .admin-search input{flex:1;min-width:0}

  /* ตารางอ่านยากบนมือถือ — ลดขนาดตัวอักษร+padding แทนการซ่อนคอลัมน์
     ❌ ห้าม display:block (design system ระบุไว้ชัด) */
  .data-table{font-size:12.5px}
  .data-table th, .data-table td{padding:9px 10px}

  /* กล่องยืนยันชิดขอบเกินไปเมื่อมีคีย์บอร์ดเด้ง */
  .zs-modal{padding:12px;align-content:start;padding-top:8vh}

  /* ปุ่มลอยมุมขวาล่างของ .shead ย้ายลงมาเป็นแถวเต็ม */
  .shead .act, .page-head .act{width:100%}
  .shead .act .btn, .page-head .act .btn{flex:1;justify-content:center}
}


/* ══ 4. แท็บเล็ตแนวตั้ง 641–1023px ════════════════════════════════
   iPad (768) · iPad Air (820) · Surface (912)
   sidebar เป็น drawer แล้ว (layout.css) — ที่เหลือคือใช้พื้นที่ให้คุ้ม */
@media (min-width:641px) and (max-width:1023px){
  /* คอลัมน์ขวาที่ยุบลงมา — 2 ใบต่อแถวพอดีบนแท็บเล็ต */
  .up-side, .set-side, .adm-side, .rail{
    display:grid;
    grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
    gap:var(--s4);
  }

  /* ฟอร์ม 2 ช่องกลับมาได้บนแท็บเล็ต (base.css ยุบที่ ≤800 ซึ่งกินแท็บเล็ตไปด้วย) */
  .row-2{grid-template-columns:1fr 1fr}

  /* การ์ดคลิป — แท็บเล็ตกว้างพอสำหรับ 3-4 ใบ */
  .grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}

  /* หน้าจ่ายเงิน/ฟอร์มที่คุมความกว้างไว้ ให้ยืดเต็มแท็บเล็ต */
  .choose-wrap{max-width:none}
}

/* ⚠️ แท็บเล็ตแนวตั้งที่ ≤800px โดน .row-2 ของ base.css ยุบเป็น 1 คอลัมน์
   กฎด้านบนดึงกลับมาแล้ว — ยกเว้นฟอร์มที่ยาวจริง ๆ ให้ยุบตามเดิม */
@media (min-width:641px) and (max-width:800px){
  .field textarea ~ .row-2, .row-2.row-stack{grid-template-columns:1fr}
}


/* ══ 5. แท็บเล็ตแนวนอน / โน้ตบุ๊กเล็ก 1024–1279px ════════════════
   iPad Pro landscape (1024/1180) · MacBook Air ย่อหน้าต่าง
   sidebar กลับมากิน 248px → พื้นที่เนื้อหาเหลือ ~730-930px */
@media (min-width:1024px) and (max-width:1279px){
  /* sidebar แคบลงเล็กน้อย คืนพื้นที่ให้เนื้อหา (gutter ยืดเองด้วย clamp แล้ว) */
  :root{--sidebar-w:216px}
  .nav-item{font-size:13px;gap:10px}

  /* คอลัมน์ขวาของหน้าตั้งค่า/อัปโหลดเบียดเกินไปในช่วงนี้ */
  .up-layout, .set-layout, .adm-layout{grid-template-columns:1fr}
  .up-side, .set-side, .adm-side{
    display:grid;
    grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
    gap:var(--s4);
  }
}


/* ══ 6. จอใหญ่ ≥1600px ════════════════════════════════════════════
   CLAUDE.md: หน้าในระบบเต็มความกว้าง ไม่จำกัด max-width — คงไว้
   แต่ต้องกันการ์ด "จิ๋วเป็นแถบ" เมื่อ auto-fill ได้ 10+ คอลัมน์ */
@media (min-width:1600px){
  .grid{grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}
  .clipgrid{grid-template-columns:repeat(auto-fill,minmax(180px,1fr))}
  /* สถิติ: อย่าให้เกิน 6 ใบต่อแถว ไม่งั้นอ่านเป็นแถบตัวเลขไร้บริบท */
  .statgrid{grid-template-columns:repeat(auto-fit,minmax(min(240px,100%),1fr))}
  .adm-stats{grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
  .hub-grid{grid-template-columns:repeat(auto-fill,minmax(340px,1fr))}
  /* ย่อหน้ายาวเกิน ~90 ตัวอักษรอ่านยาก */
  .card-body > p, .up-tip p, .feat p{max-width:78ch}
}

@media (min-width:2000px){
  .grid{grid-template-columns:repeat(auto-fill,minmax(300px,1fr))}
  .statgrid{grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr))}
}


/* ══ 7. จอสั้น / มือถือแนวนอน ═════════════════════════════════════
   ⚠️ ช่องว่างที่ใหญ่ที่สุดของระบบเดิม — ไม่มี @media ความสูงเลยสักบรรทัด
   iPhone 14 Pro Max แนวนอน = 932×430 → กว้างพอจะไม่เข้ากฎ ≤900
   แต่สูงแค่ 430px: editor เหลือเวทีแสดงผล ~200px = ใช้งานไม่ได้จริง */
@media (max-height:520px) and (orientation:landscape){
  /* --- editor --- */
  .ed-top{height:44px}
  .ed-title{max-width:120px}
  /* บังคับโหมดแท็บเหมือนมือถือ ไม่ว่าจอจะกว้างแค่ไหน */
  .ed-body{grid-template-columns:1fr;grid-template-rows:1fr}
  .ed-rail{
    flex-direction:row;justify-content:center;
    border-right:none;border-top:1px solid var(--line);
    order:3;padding:4px 0;
    padding-bottom:calc(4px + env(safe-area-inset-bottom));
  }
  .ed-col{grid-row:1;grid-column:1}
  .ed-left,.ed-right{border:none;display:none}
  .ed-left.on,.ed-right.on{display:block}
  .ed-stage{padding:8px}
  /* เฟรมอิงความสูงเป็นหลัก — 9:16 บนจอเตี้ยต้องคิดจากสูง ไม่ใช่กว้าง */
  .frame{width:min(200px, 62dvh*0.5625)}
  .transport{width:min(200px, 62dvh*0.5625);margin-top:8px}
  .tbar{margin-top:8px;gap:10px}
  .ed-tl{height:76px}
  .tl-head{padding:5px 12px}

  /* --- ทั้งระบบ --- */
  /* modal สูงเกินจอ → ให้ scroll ในตัวเองและชิดบน */
  .zs-modal{align-content:start;padding-top:10px;padding-bottom:10px}
  .zs-modal-dialog{max-height:calc(100dvh - 20px);padding:18px}
  .zs-modal-icon{font-size:26px;margin-bottom:6px}
  /* หน้าสถานะประมวลผลกินความสูงคงที่ */
  .st-wrap{min-height:0;padding:12px 0}
  .st-card{padding:20px 18px}
  .st-ring{width:48px;height:48px;font-size:19px;margin-bottom:12px}
  /* bottom nav กินพื้นที่ครึ่งจอบนแนวนอน → เตี้ยลง */
  .bottomnav{--bottomnav-h:52px}
  .bn-item{height:52px;font-size:9.5px}
}

/* จอสั้นมาก (แนวนอนของมือถือเล็ก / หน้าต่างถูกย่อ) */
@media (max-height:400px){
  .ed-tl{height:0;overflow:hidden;border-top:none}   /* ซ่อนไทม์ไลน์ ไม่มีที่พอจริง ๆ */
  .tfa-qr img,.tfa-qr canvas{width:120px;height:120px}
  .hero-demo{display:none}
}


/* ══ 8. tap target ที่ยังหลุดเกณฑ์ 44×44 ═════════════════════════
   a11y.css ครอบ .btn/.iconbtn/.nav-item/.bn-item/.rail-b/.seg button/.styb แล้ว
   ที่เหลือด้านล่างคือของที่ "ตกสำรวจ" — ตรวจจากไฟล์จริงทีละตัว
   ⚠️ ตัวที่ขยายขนาดจริงไม่ได้ (จะทำให้เลย์เอาต์เพี้ยน) ใช้ ::after ขยายพื้นที่กด
      ปลอดภัยเฉพาะตัวที่ไม่มีเป้ากดอื่นอยู่ติดกัน */
@media (pointer:coarse){
  /* pagination — เดิม 38×38 (base.css:270) */
  .pagination a, .pagination span{min-width:44px;height:44px}

  /* toggle switch — เดิม 42×24 ใช้ ~20 จุดในหน้า admin/settings
     ขยายพื้นที่กดด้วย ::after ไม่ขยายตัว slider (ไม่งั้นหัวสวิตช์เบี้ยว) */
  .switch{position:relative}
  .switch::after{content:"";position:absolute;left:-4px;right:-4px;top:-10px;bottom:-10px}

  /* แท็บกรอง — เดิม 32px */
  .tb-tab{height:44px}

  /* ปุ่มเล่นและแถบเลื่อนเวลาใน editor */
  .play{width:52px;height:52px;font-size:18px}
  .scrub{height:8px}
  .scrub .knob{width:20px;height:20px}
  /* พื้นที่ลากของ scrub — สูงจริง 8px แต่กดได้ 44px */
  .scrub{position:relative}
  .scrub::after{content:"";position:absolute;left:0;right:0;top:-18px;bottom:-18px}

  /* ปุ่มซูมไทม์ไลน์ — เดิม 24×24 */
  .tl-head .iconbtn{width:38px;height:38px;font-size:13px}

  /* ปุ่มปิดหน้าจ่ายเงินใน iframe — เดิม 34×34 */
  .zs-up-close{width:44px;height:44px}

  /* ลิงก์ในรายการ/เมนูที่แถวเตี้ยกว่า 44 */
  .adm-links a, .up-recent a, .set-pays li, .up-limits li{min-height:44px}
  .lnav-links a, .lfoot-links a{display:inline-flex;align-items:center;min-height:44px}
  .set-more, .up-card-more, .rowhead a{
    display:inline-flex;align-items:center;min-height:44px;
  }

  /* details/summary ที่ใช้เป็นปุ่มพับ */
  .cut-adv summary{min-height:44px;display:flex;align-items:center}

  /* range slider — นิ้วต้องจับหัวได้ (SFX delay/gain, ตัดเสียงเงียบ) */
  input[type=range]{height:44px}
  input[type=range]::-webkit-slider-thumb{width:22px;height:22px}
  input[type=range]::-moz-range-thumb{width:22px;height:22px}

  /* checkbox/radio ที่ยังเป็นของ native */
  input[type=checkbox]:not(.switch input),
  input[type=radio]:not(.mode input){width:22px;height:22px}
}


/* ══ 9. sticky ซ้อนกัน — แถบปลอมตัว + topbar ═════════════════════
   ⚠️ .impersonate-bar (admin.css:5) และ .topbar (layout.css:65) ต่างก็
      position:sticky top:0 z-index:--z-topbar → เลื่อนหน้าแล้วทับกันสนิท
      แถบเตือน "กำลังใช้งานแทนผู้ใช้" หายไปใต้ topbar = แอดมินลืมตัวได้จริง
   วิธีแก้: แถบเตือนอยู่บนสุดเสมอ แล้วดัน topbar ลงมาเท่าความสูงของแถบ
   ค่า --imp-h ถูกวัดจริงด้วย ResizeObserver ใน core/app.js (ความสูงเปลี่ยน
   ตามจอ เพราะปุ่ม "กลับเป็นตัวเอง" ลงบรรทัดใหม่บนมือถือ) */
.impersonate-bar{z-index:calc(var(--z-topbar) + 1)}
.topbar{top:var(--imp-h, 0px)}
/* sidebar ก็ sticky top:0 เหมือนกัน — ดันลงด้วย ไม่งั้นโลโก้ถูกแถบทับ */
.sidebar{top:var(--imp-h, 0px);height:calc(100dvh - var(--imp-h, 0px))}
.rail{top:calc(var(--topbar-h) + var(--imp-h, 0px) + var(--s4))}


/* ══ 10. คีย์บอร์ดมือถือเด้ง ═══════════════════════════════════════
   app.js ตั้ง --zs-kb เป็นความสูงคีย์บอร์ดจาก window.visualViewport
   หน้าที่เป็น "เต็มจอคงที่" ต้องหดตาม ไม่งั้นช่องพิมพ์ถูกคีย์บอร์ดทับ */
.ewrap{height:calc(100dvh - var(--zs-kb, 0px))}
.zs-modal{padding-bottom:calc(20px + var(--zs-kb, 0px))}
/* คีย์บอร์ดเปิดอยู่ → ซ่อน bottom nav ไปเลย คืนพื้นที่ให้เนื้อหา
   (ไม่งั้นแถบ 64px ลอยอยู่เหนือคีย์บอร์ด บังปุ่มบันทึกของฟอร์ม) */
body.zs-kb-open .bottomnav{display:none}
body.zs-kb-open .main{padding-bottom:0}
/* toast ต้องอยู่เหนือคีย์บอร์ด ไม่ใช่ใต้ */
@media (max-width:640px){
  body.zs-kb-open .toast-wrap{bottom:calc(12px + var(--zs-kb, 0px))}
}


/* ══ 10.4 แถบบนของ app shell (.topbar) ล้นจอเล็ก ═════════════════
   ⚠️ .search (layout.css:68) ไม่มี min-width:0 → flex item ไม่ยอมหดต่ำกว่า
      ความกว้างของข้อความข้างใน และข้อความไทย "ค้นหาโปรเจกต์…" ไม่มีเว้นวรรค
      = นับเป็นคำเดียวยาว ~110px หดไม่ได้เลย
      จอ 320: menu 40 + search 110 + ธีม 40 + ออกจากระบบ 40 + userchip 45
      + gap 60 + padding 24 = ~359px → ล้น 39px */
.search{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
@media (max-width:520px){
  /* ยังไม่ใช่ช่องค้นหาที่ทำงานจริง (เป็น div) — บนจอเล็กเอาที่ให้ปุ่มดีกว่า */
  .topbar .search{display:none}
}

/* ══ 10.5 แถบบนของ editor ล้นจอมือถือ ════════════════════════════
   ⚠️ บั๊กจริง: .ed-top เป็น flex ที่ไม่มี wrap และไม่มี overflow
      ของที่อยู่ในแถบ (จอ 375px): ปุ่มกลับ 40 + ชื่อเรื่อง 110 + badge READY ~66
      + undo 40 + redo 40 + ธีม 40 + ปุ่มเรนเดอร์ ~100 + gap 56 + padding 24
      = ~516px → ล้นออกนอกจอ 141px ปุ่ม "เรนเดอร์" (ปุ่มทำเงิน) หลุดขอบขวา
   แก้: ให้ชื่อเรื่องเป็นตัวยืด/หดแทนความกว้างคงที่ แล้วตัดของที่ไม่จำเป็น */
@media (max-width:640px){
  .ed-top{gap:6px;padding:0 8px}
  /* ชื่อเรื่องกินที่เหลือทั้งหมดและหดได้ถึง 0 — ไม่ต้องพึ่ง .tspacer */
  .ed-title{flex:1 1 auto;min-width:0;max-width:none}
  .ed-top .tspacer{display:none}
  /* badge สถานะซ้ำกับข้อมูลในแผงอยู่แล้ว */
  .ed-top .badge{display:none}
  /* ปุ่มเรนเดอร์ต้องเห็นเต็มเสมอ ห้ามหด */
  #edBurn{flex:none}
}
@media (max-width:400px){
  /* จอเล็กสุด: ปุ่มเรนเดอร์เหลือไอคอน + คำสั้น (ยังกดได้ ≥44px) */
  #edBurn{padding:0 10px}
  .ed-top .iconbtn{width:38px}
}


/* ══ 11. เก็บตกรายหน้า ════════════════════════════════════════════ */

/* หน้าอัปโหลด: กล่องลากไฟล์ต้องไม่สูงเกินครึ่งจอบนมือถือ */
@media (max-width:640px){
  .up-drop{min-height:min(200px,34dvh)}
}

/* สลิป: รูปสลิปแนวตั้งสูงมาก คุมความสูงไว้ทุกจอ ไม่ใช่แค่ ≤720 */
.slip-img img{max-height:min(420px,50dvh);object-fit:contain}

/* ตารางแอดมินที่คอลัมน์เยอะ — ให้ min-width สมจริง ไม่งั้นตัวอักษรบีบจนอ่านไม่ออก
   (base.css ตั้ง 520px ซึ่งพอสำหรับ 4-5 คอลัมน์เท่านั้น)
   ไล่นับ <th> จริงแล้ว: renders 8 · queue 7 · users 7 · history/costs 5 · dashboard 4 */
.table-wrap:has(th:nth-child(7)) .data-table{min-width:760px}
.table-wrap:has(th:nth-child(8)) .data-table{min-width:880px}   /* admin/renders.php */

/* ช่อง "สาเหตุ" ในหน้าคิว — str_limit 90 ตัวอักษรทำให้ตารางยืดไป ~1100px
   ต้องลากสกรอลล์ยาวมากกว่าจะถึงคอลัมน์ปุ่ม */
.data-table td.mut{max-width:min(280px,42vw);overflow-wrap:anywhere}

/* ── ข้อความที่มาจากผู้ใช้ ตัดบรรทัดไม่ได้เอง ──────────────────
   display_name จาก LINE/Google เป็นสตริงอะไรก็ได้ (อีเมล/ละตินยาวติดกัน)
   .shead มี overflow-x:clip → ชื่อยาวถูกตัดหายเงียบ ๆ แทนที่จะขึ้นบรรทัดใหม่ */
.page-head h1, .shead h1, .legal h1,
.slip-meta, .slip-meta a, .slip-note,
.up-name, .st-job-name, .choose-name{overflow-wrap:anywhere;min-width:0}

/* ── แถวหัวการ์ดที่มี 2 ชิ้นและไม่มี wrap ───────────────────
   (.card-head ของ base.css มี flex-wrap อยู่แล้ว — ไม่ต้องซ้ำ) */
.set-box-head, .up-card-head{flex-wrap:wrap;row-gap:6px}
.set-box-head > *, .up-card-head > *{min-width:0}

/* ── เมตาใต้การ์ดโปรเจกต์ (badge + badge + ขนาดไฟล์) ───────
   การ์ดที่ ≤640 กว้าง ~150px เหลือเนื้อที่ 124px แต่ของในแถวรวม ~180-200px
   .proj มี overflow:hidden → ชิ้นขวาสุดถูกตัดทิ้ง */
.proj .body .m{flex-wrap:wrap;row-gap:6px}

/* ── ขั้นตอน 1-2-3-4 หน้าอัปคลิป ────────────────────────────
   project.css ยุบ 4→2 ที่ ≤760 แล้ว 2→1 ที่ ≤420 → ช่วง 421-640px
   ได้ 2 คอลัมน์กว้างช่องละ ~177px ลบ padding/เลขขั้น เหลือข้อความ 115px
   แต่คำอธิบายไทยยาว ~142px และ .up-steps มี overflow:hidden = ตัวหนังสือหาย */
@media (max-width:640px){
  .up-steps{grid-template-columns:1fr}
}
.up-step p, .up-step strong{overflow-wrap:anywhere}

/* ── แถบนำทางหน้า public ────────────────────────────────────
   .lnav (landing.css:9) เป็น flex ไม่มี wrap · .brand{flex:none} · .btn{nowrap}
   จอ 320: brand 111 + "แพ็กเกจ" 69 + "เข้าสู่ระบบ" 84 + gap 30 = ~294 > 288 ที่มี
   → ปุ่มเข้าสู่ระบบ (CTA ปากกรวย) ถูก overflow-x:clip ตัดขอบขวา */
@media (max-width:600px){
  .lnav{flex-wrap:wrap;row-gap:8px}
}
@media (max-width:400px){
  .lnav .brand{font-size:16px}
  /* "แพ็กเกจ" มีซ้ำใน .lfoot-links อยู่แล้ว — เก็บ CTA ไว้สำคัญกว่า */
  .lnav .btn:not(.btn-red){display:none}
}

/* เมนูเสียง SFX เป็น position:fixed กว้าง 230px — บนจอ 320 ต้องไม่ล้นขอบ */
.sfx-menu{max-width:calc(100vw - 16px)}

/* 💰 QR พร้อมเพย์ — เดิม 220px คงที่ (billing.css:113)
   บนจอ 320: QR 220 + padding กล่อง 24 + การ์ด 36 + gutter 24 = 304px พอดีเป๊ะ
   เหลือ margin 0 → ขยับนิดเดียวก็ล้น และ QR เล็กเกินสแกนยากบนแท็บเล็ตขึ้นไป
   ⚠️ ต้องเป็นสี่เหลี่ยมจัตุรัสเสมอ ไม่งั้นกล้องอ่านไม่ออก → คุมทั้งกว้างและสูง */
.pay-qrbox svg,
.pay-qrbox canvas,
.pay-qrbox img{
  width:min(240px, 62vw);
  height:min(240px, 62vw);
  max-width:100%;
}
.pay-qrbox{min-height:0;aspect-ratio:auto}
/* สลิปพรีวิวสูงตามจอ ไม่ใช่ 220px คงที่ */
.pay-prev{max-height:min(300px,40dvh)}

/* iframe หน้าอัปเกรดในโหมดจอเตี้ย */
@media (max-height:640px){
  .zs-up{padding:0}
  .zs-up-dialog{height:100dvh;max-width:none;border:none;border-radius:0}
}

/* หน้า public: gutter 6vw บนจอกว้างมากทำให้ขอบห่างเกินไป */
@media (min-width:1400px){
  .lnav, .pub-main, .lfoot, .hero, .lsection{padding-left:0;padding-right:0}
  .lnav, .lfoot{padding-left:24px;padding-right:24px}
}

/* พิมพ์หน้าเว็บ (ใบเสร็จ/ประวัติการเงิน) */
@media print{
  .sidebar, .topbar, .bottomnav, .drawer-backdrop, .toast-wrap,
  .impersonate-bar, .form-actions, .page-head .act{display:none !important}
  #shell{grid-template-columns:1fr}
  .content{padding:0}
  .box, .card{break-inside:avoid}
}
