/* menu.css — หน้า Menu & Order (WO-354 เฟส 1) · คลาสทั้งหมดขึ้นต้น mn- (ยกเว้นคลาสร่วมของแอปที่ใช้ตามเดิม: .cap .sel .rs-card .rs-chd .rs-n .rs-t .rs-v .hint .ic)
   โทเคนจาก app.css ล้วน: --glass-red-a --sel-glass* --glow-cta* --tile --tile2 --mu --dim --ok-rgb --sel-* --spring --ease --dock-* --side --hd-cut · ไม่แก้ app.css
   กฎแอป (OD-130/143/144): เลย์เอาต์ห้ามขยับ (จองที่ข้อความ/ปุ่มไว้ล่วงหน้า ของชั่วคราวซ้อนทับ) · สีมีความหมายเดียว (แดง = ต้องทำ/เลือก, เขียว = เสร็จ) · transform/opacity ล้วน · html.lite และ reduced-motion ปิดของหนัก */

/* ---------- พื้นมืดโปร่ง "โปร่งใสดำมืด" (OD-363): ทุกชิ้นลอยในหน้านี้เขียน `background:var(--dg-surface);box-shadow:var(--dg-line)` จากรากเดียวใน app.css :root — ไม่นิยามสี/ความทึบ/กรอบเองที่นี่ · ไม่มี backdrop-filter · ม่านหลังการ์ด = var(--dg-scrim) ---------- */

/* ---------- ตัวห่อ: เนื้อหาเมนูอยู่ "ในเอกสาร" เหมือนทุกหน้า (OD-435) — เอกสารเป็นตัวเลื่อนแนวตั้งตัวเดียว (body.docscroll ใน app.css) Safari ถึงพับแถบ URL ตอนเลื่อน ·
   เดิม #menuRoot เป็น fixed + แต่ละหมวดเลื่อนในกล่องของตัวเอง → Safari ไม่เห็นการเลื่อนเลย (แถบ URL ค้าง) · ตอนนี้: h1 sticky (app.css) · .mn-head sticky ใต้ h1 (กฎร่วมกับ Reserved ใน app.css) ·
   หมวดที่ดูอยู่ไหลตามเนื้อในราง .sw-track (ราง/หน้าข้างเคียงสูง 0 = กฎเดียวกับขั้นจอง/Reserved/Membership ใน app.css ไม่เขียนซ้ำที่นี่) · ที่ fixed เหลือเฉพาะ overlay: ตะกร้า (.mn-sheet) · ผลค้นหา (.mn-res) · โครงรอ/ลองอีกครั้ง
   isolation = #menuRoot เป็นชั้นซ้อนของตัวเอง (z-index ภายใน 13/14/20 ไม่แข่งกับ dock/CTA/h1 ข้างนอก — เหมือนตอนเป็น fixed) ---------- */
#menuRoot{--mn-hd:var(--hd-box);--mn-rb:80px;--mn-b:calc(var(--dock-edge) + var(--dock-h));isolation:isolate;animation:pg-in var(--dock-t) var(--dock-ease) backwards}   /* ตั้ง animation เอง: กฎ pg-slide ของ .page.cur เป็น transform บนลูก — ลูก fixed ห้ามมี */
.mn-main,.mn-main > *{box-sizing:border-box}
.mn-main{margin-inline:calc(-1 * var(--side));transition:opacity var(--t-7) var(--ease)}   /* ชนขอบจอ: #menuRoot อยู่ใน .page ที่มี padding ข้าง (เดิมเป็น fixed ไม่ติด padding) */
/* OD-438: ไม่หรี่ .mn-main ซ้ำ — ตัวหรี่ตอนเปิดตะกร้ามีที่เดียวคือม่าน --dg-scrim (เดิม .mn-main.dim{opacity:.10} ซ้อนม่าน → เมนูหลังตะกร้าเหลือ ~3% ดำทึบ ไม่โปร่ง) · ตัวหนังสือผีทะลุการ์ดกันที่ --dg-under-card (wo363) */
.mn-main.dim{opacity:1}
.mn-vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
.mn-track{overflow-anchor:none}   /* สลับหมวด = ความสูงเอกสารเปลี่ยน + menu.js คืนตำแหน่งเลื่อนเอง · ไม่ให้เบราว์เซอร์ปรับตำแหน่งซ้อน */
.mn-pg{padding:0 var(--side)}   /* ราง/หน้า/สูง 0 ของหมวดข้างเคียง = .sw-track (app.css) · แถวแรกอยู่ที่เดิม: ทับขอบล่าง .mn-head 10px (เดิม padding บนของหน้า = หัวข้อ + แถบ − 10) */
.mn-track > .mn-pg:not(.sw-cur){translate:0 calc(var(--sy-y, 0px) - var(--mn-top, 0px))}   /* หมวดข้างเคียงที่โผล่ตอนปัด/กำลังสไลด์ออก: ยกให้แถวที่เคยเห็นอยู่ตรงตำแหน่งเดิมในจอ (--sy-y = ตำแหน่งเอกสารตอนนี้ ตั้งโดย swipeTrack · --mn-top = ตำแหน่งที่จำของหมวดนั้น ตั้งโดย menu.js) */

/* ---------- แถวหัวข้อย่อย: ราง .cap (แท็บหมวด) เต็มแถว · แคปซูลค้นหา (.mn-srch) ซ้อนช่องเดียวกัน — ค้นหาเปิด = สลับกันด้วย opacity ล้วน แถวสูงคงที่ 56 (ไม่มีอะไรขยับ) · ปุ่มเปิดค้นหาอยู่ที่หัวข้อหน้า (.mn-hsb ด้านล่าง) ---------- */
.mn-head{position:sticky;top:var(--mn-hd);z-index:var(--z-sticky);margin-bottom:calc(-10px);padding:6px var(--side) 18px}   /* ตรึงใต้หัวข้อ + ตามหัวข้อย่อ: กฎร่วมกับ Reserved ใน app.css (.mn-head / .cap.pin) */
.mn-row2{display:grid;grid-template-columns:minmax(0,1fr);align-items:center}
.mn-row2 > *{grid-area:1 / 1}
.mn-srch{position:relative;align-self:stretch;border-radius:var(--r-pill);background:var(--dg-surface);box-shadow:var(--dg-line);opacity:0;pointer-events:none;transition:opacity var(--t-4) var(--ease-std)}
.mn-srch.open{opacity:1;pointer-events:auto}
.mn-srch.open + .cap.mn-rail{opacity:0;pointer-events:none}
.mn-sic{position:absolute;left:17px;top:0;bottom:0;display:grid;place-items:center;color:var(--mu)}
.mn-qx:focus-visible,.mn-q:focus-visible{outline-offset:calc(-1 * var(--focus-off))}   /* ชิดในกรอบ (ไม่โดนตัด) · สีกับความหนาจากกฎกลาง app.css */
.mn-q{position:absolute;inset:0;width:100%;height:100%;box-sizing:border-box;padding:0 46px 0 48px;border:0;border-radius:var(--r-pill);background:none;color:var(--tx);font:inherit;font-size:var(--fs-8);-webkit-appearance:none;appearance:none}   /* 16px = iOS ไม่ซูมเอง */
.mn-q::placeholder{color:var(--mu)}
.mn-q::-webkit-search-cancel-button{-webkit-appearance:none}
.mn-qx{position:absolute;right:6px;top:6px;width:var(--tap);height:var(--tap);border:0;border-radius:var(--r-round);padding:0;background:none;color:#fff;display:grid;place-items:center}
.mn-qx svg{width:var(--ic-3);height:var(--ic-3);padding:7px;box-sizing:content-box;border-radius:var(--r-round);background:rgb(255 255 255 / .12)}
.cap.mn-rail{min-width:0;margin-right:calc(-1 * var(--side));display:block;padding:0;touch-action:pan-x pan-y;--sx:0px;transition:opacity var(--t-4) var(--ease-std)}   /* แคปซูล (พื้น/ปลายมน) ไม่มีมาสก์ · เต็มแถวถึงขอบจอด้านขวา */
.mn-sc{position:relative;display:flex;overflow-x:auto;border-radius:var(--r-pill);scrollbar-width:none;padding:var(--sp-1) 0 var(--sp-1) var(--sp-1);
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 var(--fl,0px),#000 calc(100% - var(--fr,0px)),transparent 100%);mask-image:linear-gradient(to right,transparent 0,#000 var(--fl,0px),#000 calc(100% - var(--fr,0px)),transparent 100%)}   /* ปลายราง = ระยะเท่าขอบแคปซูล 4px (selector ป้ายแรก/ท้ายสุดจึงร่วมศูนย์กับปลายมน เหมือน dock) · ขอบจางมาเฉพาะด้านที่ยังมีของเลื่อนต่อ: menu.js (fade) ตั้ง --fl/--fr = min(16px, ระยะที่เลื่อนไปแล้ว/ที่เหลือ) · ตัวเลื่อนข้างในไม่ใช่พื้นแคปซูล (ไม่งั้นปลายมีเงาดำ) */
.mn-sc::after{content:"";flex:none;width:4px}   /* ระยะท้ายรางเป็นของจริง (Safari ตัด padding/margin ท้ายราง flex ที่เลื่อนได้) */
html.lite .mn-sc{-webkit-mask-image:none;mask-image:none}
.mn-sc::-webkit-scrollbar{display:none}
.cap.mn-rail{--mn-pill:calc(var(--mn-tw, 0px) + 2 * var(--sp-5))}   /* OD-411: ความกว้างแคปซูลเลือก = ชื่อหมวดยาวสุด (JS วัดจริง EN+ไทย ครั้งเดียว → --mn-tw) + ขอบข้างละ --sp-5 · ทุกหมวดเท่ากัน */
.cap.mn-rail label{flex:none;padding:0 var(--sp-4);white-space:nowrap;position:relative;transition:transform var(--sel-t) var(--spring)}   /* ป้ายที่ไม่เลือก = แค่ชื่อ เว้นช่องไฟสั้นพอดี (ข้างละ --sp-4) เรียงต่อกัน · ป้ายที่เลือก = กว้างเท่าแคปซูล (ด้านล่าง) · เปลี่ยนหมวดแล้วที่เหลือเลื่อนตาม: menu.js (mark) วางเลย์เอาต์ปลายทางทันทีแล้วเล่นย้อนด้วย transform (ไม่แอนิเมต width) */
.cap.mn-rail input:checked + label{width:var(--mn-pill);padding:0}
.cap.mn-rail .sel{width:var(--mn-pill);transition:transform var(--sel-t) var(--spring)}
.cap.mn-rail label[data-n]:not([data-n=""])::after{content:attr(data-n);position:absolute;top:2px;right:2px;min-width:16px;height:16px;padding:0 var(--sp-1);box-sizing:border-box;border-radius:var(--r-pill);background:#fff;color:#000;font-size:var(--fs-1);font-weight:var(--fw-bold);display:grid;place-items:center;line-height:var(--lh-1)}
.cap.mn-rail input:focus-visible + label{outline:var(--focus-w) solid var(--focus-c);outline-offset:-3px;border-radius:var(--r-pill)}   /* input จริงซ่อน → วงที่ป้ายพี่น้อง */

/* ---------- ปุ่มค้นหา (ตำแหน่งชั่วคราว): หัวข้อหน้า มุมขวาบนข้างปุ่มภาษา (.lang ใน app.css) · ยกตามปุ่มภาษาตอนหัวข้อย่อ · เฉพาะหน้าเมนู (data-dock=3) · ตัวดูรูปเปิด = overlay เริ่มใต้แท็บ ปุ่มจึงอยู่ที่เดิมเองไม่ต้องยก ---------- */
.mn-hsb{display:none;position:fixed;top:calc(18px + env(safe-area-inset-top));right:calc(14px + var(--tap));z-index:var(--z-lang);width:var(--tap);height:var(--tap);place-items:center;padding:0;border:0;background:none;color:var(--tx);transition:transform var(--dock-t) var(--dock-ease),opacity var(--t-6) var(--ease-std)}   /* ขวา = ขอบ 14 + ช่องปุ่มภาษา --tap (ปุ่มภาษากว้าง 34–39 ตามภาษา) */
body[data-dock="3"] .mn-hsb{display:grid}
body.hd-min .mn-hsb{transform:translateY(calc(var(--hd-up) * -1))}   /* เท่ากับ .lang span (app.css) */
#menu > h1{padding-right:calc(76px + var(--tap) + var(--side));margin-bottom:0}   /* margin 0: .mn-head (sticky) ต่อจาก h1 ที่ขอบล่างกล่อง = ตำแหน่งเดิมเดียวกับตอนเป็น absolute (หน้าอื่นเว้น 6 ให้แท็บ .tabs-pin ที่ top = กล่อง + 6) */   /* เว้นที่ขวาเพิ่มให้ปุ่มค้นหา (ข้อความย่อข้างหัวข้อไม่ชน) */

/* ---------- ผลค้นหา (ข้ามทุกหมวด · จัดกลุ่มตามหมวด) ---------- */
.mn-res{position:fixed;inset:0;z-index:var(--z-res);overflow-y:auto;overscroll-behavior-y:contain;background:#000;padding:calc(var(--mn-hd) + var(--mn-rb) - 10px) var(--side) calc(var(--mn-b) + 110px);animation:pg-in var(--t-6) var(--ease)}
.mn-res[hidden]{display:none}
.mn-rh{margin:18px 0 var(--sp-2);display:flex;justify-content:space-between;font-size:var(--fs-5);font-weight:var(--fw-semibold);letter-spacing:var(--ls-2);text-transform:uppercase;color:var(--mu)}
.mn-rh:first-child{margin-top:0}
.mn-res .mn-tx,.mn-res .mn-meta{cursor:pointer}
.mn-none{margin:var(--sp-9) 0;text-align:center;font-size:var(--fs-6);color:var(--mu)}

/* ---------- แถวสินค้า — สูตรชิ้นกลาง (product-row.js · OD-412): เมนู · Welcome Drinks · ซื้อโปรหน้าร้าน ใช้หมวดนี้ที่เดียว (menu.css ลิงก์ทุกหน้า) · (OD-408 · ไม่มีหัวหมวดซ้ำ — ชื่อหมวดอยู่บนแท็บที่เดียว OD-411): สูตรเดียวกับแถวของเสริมหน้าจอง (.deal ใน app.css) — รูปจตุรัสซ้าย · สองบรรทัดชิดขวาของรูป: บรรทัดบน = ชื่อ (ยาวถึงราคา) + ราคาชิดขอบ · บรรทัดล่าง = ป้ายประหยัด/รายละเอียด + ปุ่ม + ชิดขอบ · เส้นบางคั่น · ไม่มีพื้นการ์ด/กรอบ/เงา ---------- */
/* OD-416b: รูปแถวสินค้า (จตุรัส) = ราก --mn-ph (app.css · 72) · แถว = รูป + 2×--sp-2 (88) · ตอนขยายโต ×1.2 · ปุ่ม +/stepper = --tap (44) */
.mn-pg .hint{margin:0 0 var(--sp-1)}
.mn-item{display:grid;grid-template-columns:var(--mn-ph) minmax(0,1fr);column-gap:var(--sp-3);align-items:start;padding:var(--sp-3) 0;box-shadow:0 1px 0 var(--tile2)}   /* OD-414/416b แถวกระชับแต่ไม่อึดอัด: รูปจตุรัส --mn-ph (72 = สูงเท่าราคา+ปุ่ม 44) ซ้าย · ขวาของรูปเป็นสองบรรทัด (.mn-col: .mn-top ชื่อ+ราคา · .mn-bot รายละเอียด+ปุ่ม) · ขอบบนล่าง --sp-2 → แถวสูง 88 (OD-414: 76 · เล็กไปไม่น่ากด) · แถวล่าง (.mn-xp) มีตอนขยายเท่านั้น เต็มความกว้าง */
.mn-item.open{grid-template-columns:calc(var(--mn-ph) * 1.2) minmax(0,1fr)}   /* ขยาย: รูปโตขึ้นนิด (×1.2 ยังจตุรัส) · ราคา/ปุ่มอยู่ที่เดิม */
.mn-item.mn-more{cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent}   /* WO-382: แตะแถว = ขยาย/ยุบคำบรรยาย + ทานคู่ (ไม่ใช่สั่ง · สั่งด้วยปุ่ม + เท่านั้น) · แถวที่ไม่มีอะไรให้ขยายไม่ตอบการแตะ */
.mn-item.so{cursor:default}
.mn-tx[role="button"]:focus-visible{border-radius:6px}
.mn-item.hit{animation:mn-hit 1.6s var(--ease-out)}
@keyframes mn-hit{from{background:rgb(255 255 255 / .1)}to{background:transparent}}
.mn-tx{display:grid;gap:2px;min-width:0;padding-top:2px}   /* ใช้ร่วมกับแถวตะกร้า (.mn-bl) */
.mn-tx b{font-size:var(--fs-8);font-weight:var(--fw-semibold);line-height:var(--lh-4);overflow-wrap:anywhere}
.mn-item .mn-tx{padding-top:0}
.mn-item .mn-tx b{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;text-wrap:balance;max-inline-size:var(--mn-name-w)}   /* OD-425/434: ชื่อ ≤ --mn-name-w บรรทัดเดียว ยาวกว่านั้น 2 บรรทัดสมดุล (Promotion / Mountain King Set) */   /* ชื่อยาวมาก ≤ 2 บรรทัด (… ตัด) แถวไม่สูงเกินควร · ขยายแล้วเห็นเต็ม */
.mn-item.open .mn-tx b{-webkit-line-clamp:unset}
/* ขวาของรูป = .mn-col สองบรรทัด: บน (.mn-top) ชื่อกินความกว้างถึงราคา · ล่าง (.mn-bot) รายละเอียดซ้าย + ปุ่มขวา · ปุ่มอยู่บรรทัดล่างอย่างเดียว ชื่อจึงไม่ถูกบีบ · ตอนขยายรูปโต .mn-col ไม่ขยับ (สูง --mn-ph ชิดบน) */
.mn-col{display:flex;flex-direction:column;justify-content:center;min-width:0;min-height:var(--mn-ph)}
.mn-top{display:flex;align-items:flex-start;gap:var(--sp-3)}
.mn-top .mn-tx{flex:1;min-width:0}
.mn-bot{display:flex;align-items:center;justify-content:flex-end;gap:var(--sp-3);margin-top:auto;min-height:var(--tap)}
.mn-meta{flex:1;min-width:0;display:flex;align-items:center;gap:var(--sp-2);overflow:hidden;white-space:nowrap}   /* บรรทัดเดียว: ป้ายประหยัด (ไม่หด) → โน้ต → รายละเอียด · สองตัวหลังตัดด้วย … เมื่อปุ่มเลือกแล้วกินที่ 124 · ไม่เคยขึ้นบรรทัดใหม่ → ความสูงแถวไม่เปลี่ยน */
.mn-sub{font-size:var(--fs-5);color:var(--mu);line-height:var(--lh-5);overflow-wrap:anywhere}
.mn-meta .mn-sub{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}
.mn-save{display:flex;flex:none;max-width:100%;min-width:0;align-items:center;white-space:nowrap;font-size:var(--fs-4);font-weight:var(--fw-semibold);line-height:var(--lh-6);color:var(--ok)}   /* "−12% Save ฿X" = ชิป .ad-chip + ตัวหนังสือเขียว สูตรเดียวกับ .deal .sv */
.mn-save > .en,.mn-save > .th{min-width:0;overflow:hidden;text-overflow:ellipsis}   /* ป้ายประหยัดไม่หดก่อน (รายละเอียดหดก่อน) · เกินความกว้างบรรทัดจริงๆ ค่อยตัดข้อความด้วย … */
.mn-ls{grid-column:1 / -1;grid-row:2;display:grid}   /* ตัวเลือกกินเต็มความกว้างใต้ชื่อ (ไม่เหลือที่ว่างใต้รูป) */
.mn-ln{display:flex;flex-wrap:wrap;align-items:center;column-gap:var(--sp-3);min-height:var(--tap)}   /* OD-453 ตัวเลือก: ป้าย · ราคา · ปุ่ม บรรทัดเดียวเมื่อพอดี · ป้ายยาว = ป้าย+ราคาอยู่บรรทัดบน (ป้ายได้ที่ถึงราคา) แล้วปุ่ม − n + ลงบรรทัดล่างชิดขวา (ชื่อ/ป้ายไม่ถูกบีบข้างปุ่ม · เหมือนแถวตะกร้า) · ตัดสินตามความยาวป้ายซึ่งคงที่ ไม่เปลี่ยนตามจำนวน → ปุ่มเปลี่ยนสถานะแล้วเลย์เอาต์ไม่ขยับ */
.mn-ln + .mn-ln{box-shadow:inset 0 1px 0 var(--tile2)}
.mn-ln .mn-lp{display:flex;flex:1 1 auto;min-width:0;align-items:baseline;column-gap:var(--sp-3)}   /* ป้าย+ราคาเป็นกลุ่มเดียว: จอแคบ = ปุ่มจำนวนตกลงบรรทัดล่างทั้งก้อน ราคาไม่หลุดจากป้าย (Codex P2 OD-453) */
.mn-ln .mn-vl{flex:1 1 auto;min-width:0}
.mn-ln .mn-pcx,.mn-ln .mn-out{margin-left:auto}
.mn-vl{font-size:var(--fs-6);color:var(--mu);line-height:var(--lh-4)}
.mn-pr{display:flex;align-items:baseline;gap:var(--sp-2)}
.mn-p{font-size:var(--fs-9);font-weight:var(--fw-semibold);line-height:var(--lh-2);font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right}
.mn-p small{display:block;font-size:var(--fs-2);font-weight:var(--fw-medium);color:var(--dim);text-decoration:line-through}   /* ราคาเทียบ (ถ้ามี) ใต้ราคา */
.mn-item.nph .mn-p{font-size:var(--fs-7);font-weight:var(--fw-medium);color:var(--mu)}
.mn-out{flex:none;font-size:var(--fs-5);font-weight:var(--fw-semibold);letter-spacing:var(--ls-1);color:var(--mu)}
.mn-item.so .mn-ph{opacity:.38}
.mn-item.mn-sk{grid-template-columns:var(--mn-ph)}
.mn-item.mn-sk .mn-ph{background:var(--tile2);box-shadow:none}   /* โครงรอของสดครั้งแรก (OD-298): กริดเดียวกับแถวจริง สูงเท่า · นิ่ง ไม่มีอนิเมชัน */
.mn-item.so .mn-tx b{color:var(--mu)}
/* ขยาย/ยุบ: รูปโต/หด + ข้อความเลื่อนตามช่องที่ขยับ (transform ล้วน · จุดยึดมุมซ้ายบน) — ตัวแปรตั้งตามทิศ: open = รูปเริ่มที่ 1/1.2 ของขนาดขยาย, ข้อความเริ่มซ้ายกว่าที่ส่วนต่างความกว้างรูป (--mn-ph × .2) · cl = กลับกัน · ชื่ออนิเมชันต่างกันต่อทิศ (ไม่งั้นเปลี่ยนคลาสแล้วไม่เล่นซ้ำ) · reduced-motion/lite: --sel-anim:none ปิดเอง */
.mn-item.open{--mn-k:.8334;--mn-s:-1}
.mn-item.cl{--mn-k:1.2;--mn-s:1}
@keyframes mn-grow{from{transform:scale(var(--mn-k))}}
@keyframes mn-shrink{from{transform:scale(var(--mn-k))}}
@keyframes mn-nudge{from{transform:translateX(calc(var(--mn-s) * var(--mn-ph) * .2))}}
@keyframes mn-nudge-back{from{transform:translateX(calc(var(--mn-s) * var(--mn-ph) * .2))}}
.mn-item:is(.open,.cl) .mn-ph{transform-origin:0 0}
.mn-item.open .mn-ph{animation:var(--sel-anim,mn-grow) var(--fly-t) var(--spring)}
.mn-item.cl .mn-ph{animation:var(--sel-anim,mn-shrink) var(--fly-t) var(--spring)}
.mn-item.open :is(.mn-tx,.mn-meta){animation:var(--sel-anim,mn-nudge) var(--fly-t) var(--spring)}
.mn-item.cl :is(.mn-tx,.mn-meta){animation:var(--sel-anim,mn-nudge-back) var(--fly-t) var(--spring)}

/* ---------- ภาพจำลอง (ช่อง photo ยังว่าง): ไล่สี + ไอคอนหมวด · แถวเมนู = จตุรัสเสมอ (กว้าง = ช่องรูป · สูง = เท่ากัน) · --h = โทนสีของรายการ ---------- */
.mn-ph{position:relative;display:block;padding:0;border:0;border-radius:var(--r-lg);overflow:hidden;background:linear-gradient(150deg,hsl(var(--h) 28% 27%),hsl(calc(var(--h) + 32) 32% 13%));box-shadow:inset 0 0 0 1px var(--dg-fill);cursor:pointer;transition:transform var(--t-7) var(--ease);contain:layout paint}
.mn-item > .mn-ph{grid-column:1;grid-row:1;width:100%;aspect-ratio:1 / 1}
.mn-ph:active{transform:scale(.95)}
.mn-ph::before{content:"";position:absolute;inset:0;margin:auto;width:42%;height:32%;background:rgb(255 255 255 / .6);-webkit-mask:var(--m) center/contain no-repeat;mask:var(--m) center/contain no-repeat}
.mn-ph img{position:absolute;inset:0;width:100%;height:100%;box-sizing:border-box;padding:5px var(--sp-1);object-fit:contain}   /* รูปสินค้าพื้นโปร่ง/สัดส่วนต่างกัน (ขวดสูง ~1:3.4): พอดีกรอบจตุรัส ไม่ครอป (ช่องจองไว้แล้ว — รูปโหลดมาเลย์เอาต์ไม่ขยับ) */
.mn-ph.mn-cover img{object-fit:cover;padding:0}   /* โปสเตอร์ (ของเสริม): เต็มกรอบจตุรัส */
.mn-ph.mn-pic::before,.mn-vimg.mn-pic::before,.mn-vimg.mn-pic .mn-vtag{display:none}   /* มีรูปจริง = ไม่ต้องไอคอน/ป้ายภาพจำลอง */
span.mn-ph{cursor:default}   /* ช่องนิ่ง (productRow ไม่มี photoLabel): แตะไม่ได้ */
.mn-ph.sm{width:42px;aspect-ratio:3 / 4;border-radius:var(--r-xs);cursor:default;pointer-events:none}

/* ---------- ปุ่มจำนวน (OD-299/302): "+" วงกลมเทา → [−] [เลขในแคปซูลแดงแก้ว] [+] ในกล่องกว้างตายตัว · เลย์เอาต์ไม่ขยับ ---------- */
.mn-pcx{position:relative;display:block;flex:none;width:var(--pcx-w);height:var(--tap)}   /* --pcx-w = 3 วงกลม --tap + 2 ช่องไฟ (OD-452: เลขเป็นวงกลมเท่าปุ่ม − +) · กล่องกว้างตายตัวทุกสถานะ (ทุกบรรทัด/ตะกร้า/ตัวดูรูป): ที่ชื่อเหลือ = เนื้อหา − รูป − ช่องไฟ − กล่องนี้ · ราคาข้างปุ่มจึงไม่ขยับตอนเลือก */
.mn-bot .mn-pcx{width:var(--tap)}   /* ปุ่ม + 44 ตอนยังไม่เลือก · เลือกแล้วกล่อง − n + --pcx-w: เปลี่ยนเฉพาะที่ของรายละเอียดซ้ายมือ (บรรทัดเดียว ตัดด้วย …) ไม่มีอะไรด้านบนขยับ */
.mn-bot .mn-pcx.on{width:var(--pcx-w)}
.mn-pcx button{border:0;padding:0;font:inherit}
.mn-pc-add{position:absolute;top:0;right:0;width:var(--tap);height:var(--tap);border-radius:var(--r-round);background:var(--dg-surface);box-shadow:var(--dg-line);color:#fff;display:grid;place-items:center;transition:opacity var(--t-4) var(--ease-std),transform var(--sel-t) var(--spring);transform-origin:right center}
.mn-pc-add:enabled:active,.mn-pc-q button:enabled:active{transform:scale(.92);background:linear-gradient(var(--dg-fill),var(--dg-fill)),var(--dg-surface)}   /* ตอบรับการกด (HIG): หดเล็กน้อย + พื้นสว่างขึ้นอีกชั้น --dg-fill · transform/พื้นเท่านั้น */
.mn-pc-add:disabled{opacity:var(--op-1)}   /* เพดานรวมของหน้า (หน่วยโปรตามจำนวนคน) เต็ม */
.mn-pc-q{position:absolute;inset:0;display:flex;align-items:center;gap:var(--sp-1);opacity:0;transform:scale(.9);transform-origin:right center;pointer-events:none;visibility:hidden;transition:opacity var(--t-4) var(--ease-std),transform var(--sel-t) var(--spring),visibility 0s var(--t-4)}
.mn-pc-q button{position:relative;flex:none;width:var(--tap);height:var(--tap);border-radius:var(--r-round);background:var(--dg-surface);box-shadow:var(--dg-line);color:#fff;display:grid;place-items:center;transition:transform var(--sel-t) var(--spring)}
.mn-pc-q button::before,.mn-pc-add::before{content:"";position:absolute;inset:-2px}   /* ภาพ 44 กด 48 ทั้งสองแกน (ช่องว่างระหว่างปุ่ม 4 = 2+2 → พื้นที่กดชนกันพอดี ไม่ซ้อน) */
.mn-pc-q button[disabled]{opacity:var(--op-1)}
.mn-pcx svg{width:var(--ic-4);height:var(--ic-4)}
/* เลขจำนวน = วงกลม --tap เท่าปุ่ม − + (OD-452) · กฎเดียวทุก stepper: 1–2 หลักได้วงกลมพอดี (MAX_QTY 20) · ถ้ามี 3 หลักค่อยยืดเป็นแคปซูล (padding-inline) · ห้ามมีกฎความกว้างเลขที่อื่น */
.mn-pc-q b{flex:none;width:auto;min-width:var(--tap);height:var(--tap);padding-inline:var(--sp-2);box-sizing:border-box;border-radius:var(--r-pill);display:grid;place-items:center;color:#fff;font-size:var(--fs-8);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums}
.mn-pcx.on .mn-pc-q b{background:var(--sel-glass);box-shadow:var(--sel-glass-rim),var(--sel-drop)}   /* กระจกเฉพาะตอนมองเห็น */
.mn-pcx.on .mn-pc-add{opacity:0;pointer-events:none;transform:scale(1.08)}
.mn-pcx.on .mn-pc-q{opacity:1;transform:none;pointer-events:auto;visibility:visible;transition:opacity var(--t-4) var(--ease-std),transform var(--sel-t) var(--spring)}
/* ตัวเลือกที่ไม่ใช่ <label> เด้งแบบ selector: คีย์เฟรม sel-pop + โทเคน --sel-pop ชุดเดียวกับ app.css (`label.sel-hit`) · reduced-motion/lite ตั้ง --sel-anim:none ให้เอง */
.mn-ph.sel-hit,.mn-pc-q b.sel-hit,.mn-tk.sel-hit,.mn-ac .bx.sel-hit,.mn-vvs button.sel-hit,.mn-rb.sel-hit{animation:var(--sel-pop)}

/* ---------- การ์ดตะกร้า + บริการ (เปิดจาก CTA · OD-311/320): ฉากมืด = พื้นที่ "นอกการ์ด" แตะแล้วปิด · การ์ด = พื้นที่ออเดอร์ (เลื่อนได้ที่เดียว) · ปุ่มบริการ 5 ปุ่มกลมแยกกัน ตำแหน่งตายตัวเหนือ CTA ---------- */
.mn-sheet{--cb:calc(var(--mn-b) + 18px + var(--cta-h) + 14px);--cbb:var(--cb);--comp-h:calc(2 * var(--tap) + var(--ic-2) + var(--sp-2) + 2 * var(--sp-3));position:fixed;inset:0;z-index:var(--z-sheet);background:var(--dg-scrim);opacity:0;touch-action:none;transition:opacity var(--t-7) var(--ease)}   /* ฉากหลัง = ม่านดำโปร่ง (--dg-scrim) จางเข้า ไม่เบลอ (OD-326 สูตร POS) — เห็นแค่เนื้อหาลอย แถวบริการ และ CTA */
.mn-sheet[hidden]{display:none}
.mn-sheet.on{opacity:1}
.mn-sheet[data-svc="1"]{--cbb:calc(var(--cb) + var(--cta-h) + 14px)}   /* เช็กอินแล้ว: เนื้อหาลอยอยู่เหนือแถวบริการ */
.mn-panel{--mu:#aaaaaf;position:absolute;left:var(--side);right:var(--side);bottom:var(--cbb);max-height:calc(100vh - var(--mn-hd) - var(--cbb) - 10px);max-height:calc(100dvh - var(--mn-hd) - var(--cbb) - 10px);display:flex;flex-direction:column;outline:none;transform-origin:50% 100%;transform:translateY(14px) scale(.97);transition:transform var(--sel-t) var(--spring)}   /* OD-330: คอลัมน์การ์ดกว้างเท่า .rs-card (หน้าจอง/รายการเมนู: --side) · ตัวห่อไม่มีพื้น — การ์ดแต่ละใบมีพื้นเอง · "งอก" ขึ้นจากตำแหน่ง CTA */
.mn-sheet.on .mn-panel{transform:none}
.mn-order{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior-y:contain;touch-action:pan-y;padding:18px 0 var(--sp-7);-webkit-mask-image:linear-gradient(to bottom,transparent,#000 18px,#000 calc(100% - 22px),transparent);mask-image:linear-gradient(to bottom,transparent,#000 18px,#000 calc(100% - 22px),transparent);display:grid;grid-auto-rows:max-content;gap:10px;align-content:start;transition:opacity var(--t-7) var(--ease)}   /* grid-auto-rows:max-content = แถวไม่ถูกบีบต่ำกว่าเนื้อ (.mn-rounds มี min-height จองที่ → ตอนมีหลายรอบแล้วสูงเกินจอ มันเคยหดจนการ์ดล้นทับบรรทัดสถานะ) · ขอบบน/ล่างจางเข้าม่าน (ไม่ใช่ขอบกรอบ) */
.mn-sheet[data-armed="1"] .mn-card > *{opacity:var(--op-4)}   /* เลือกบริการอยู่ = เนื้อในการ์ดออเดอร์จางลง แต่ยังแตะได้ (แตะ = กลับโหมดออเดอร์) · จางที่เนื้อใน ไม่จางที่ตัวการ์ด: พื้นการ์ด (--dg-under-card) ต้องทึบเท่าเดิม ไม่งั้นเมนูหลังการ์ดทะลุมาชนตัวหนังสือ (OD-438) */
.mn-card{display:grid;grid-template-columns:minmax(0,1fr);gap:14px;padding:14px var(--sp-4) var(--sp-4);border:0;outline:none;border-radius:var(--r-xl);background:var(--dg-surface-card);box-shadow:var(--dg-line)}   /* การ์ดของใครของมัน (OD-330): ไม่มีเส้น/กรอบ/เงา · พื้นโปร่งโทเคนเดียวกับปุ่มบริการและ CTA ว่าง · มุมเท่า .rs-card */
.mn-rounds{display:grid;gap:10px}
.mn-rounds:empty{display:none}
.mn-sheet[data-svc="1"] .mn-rounds{min-height:60px}   /* เช็กอินแล้ว: จองที่ของแถวแรกที่จะโผล่ไว้ล่วงหน้า (สูงสุด = หัวรอบที่สั่ง 60 · คำขอบริการ 48) — การ์ดตะกร้าที่ยึดขอบล่างไม่กระโดดตอนแถว "ส่งแล้ว" ขึ้น (เลย์เอาต์ห้ามขยับ) */
.mn-sheet[data-svc="1"] .mn-rounds:empty{display:block}
.mn-sheet.enter .mn-card{animation:mn-card-in .38s var(--ease) backwards;animation-delay:calc(var(--i, 0) * 36ms)}   /* เข้าทีละใบ ห่าง ≤ 40ms (transform/opacity ล้วน) */
@keyframes mn-card-in{from{opacity:0;transform:translateY(12px)}}
.mn-bk{display:grid;gap:14px}
.mn-smy{display:grid;gap:var(--sp-2)}
.mn-smy[hidden]{display:none}
.mn-card .rs-n{background:var(--dg-surface);box-shadow:var(--dg-line)}
.mn-alg.done .rs-n,.mn-alg.miss .rs-n{box-shadow:none}   /* สถานะ เขียว/แดง = สีล้วน ไม่มีกรอบพื้นผิว */
.mn-closebtn{position:absolute;top:8px;left:8px;z-index:var(--z-3);height:36px;padding:0 var(--sp-4);border:0;border-radius:var(--r-pill);background:#fff;color:#000;font:inherit;font-size:var(--fs-6);font-weight:var(--fw-semibold);white-space:nowrap}
.mn-closebtn:not(:focus){width:1px;height:1px;padding:0;overflow:hidden;clip-path:inset(50%)}   /* ซ่อนจากสายตาแต่โฟกัสได้ (คีย์บอร์ด/screen reader): โฟกัสแล้วโผล่เป็นเม็ดมุมซ้ายบน — ไม่มี ✕ บนการ์ด */
/* ลากลงปิด (OD-381 · ui.js data-dismiss): ที่จับ + หัวการ์ดเป็นจุดเริ่มลาก (touch-action:none ตามที่ ui.js ต้องการ) · รายการข้างใน (.mn-order) เลื่อนเองได้ตามปกติ · ที่จับยื่นเหนือการ์ดเท่าระยะ padding บนของ .mn-order (ไม่ทับเนื้อหา) */
.mn-grab{position:absolute;left:0;right:0;top:calc(-1 * var(--sp-6));height:var(--tap);display:grid;place-items:center;color:var(--tx);touch-action:none}
.mn-grab::before{content:"";width:36px;height:5px;border-radius:var(--r-pill);background:currentColor;opacity:var(--op-1)}
.mn-panel.dz-back{transition:transform var(--sel-t) var(--spring),translate var(--sel-t) var(--spring)}   /* .mn-panel ตั้ง transition ของตัวเอง (ทับ .dz-back ของ app.css) → ใส่ translate ด้วย ให้เด้งกลับ/ไหลออกนุ่ม */
.mn-sheet.mn-fly :is(.mn-panel,.mn-svc,.mn-comp){visibility:hidden}   /* ลากปิดจนพ้นจอแล้ว: ui.js คืนชิ้นที่ลากกลับที่เดิมทันที → ซ่อนไว้ ปล่อยแต่ฉากหลังจางหาย (ไม่เห็นการ์ดกระโดดกลับ) */
.mn-ohd{display:flex;align-items:center;flex-wrap:wrap;gap:6px 10px;min-height:28px}
.mn-ohd{touch-action:none}
.mn-ohd h3{margin:0;font-size:19px;white-space:nowrap}
.mn-test{flex:none;margin-left:auto;padding:3px 9px;border-radius:var(--r-pill);background:rgb(0 0 0 / .3);color:var(--mu);font-size:var(--fs-2);font-weight:var(--fw-semibold);letter-spacing:var(--ls-1)}
.mn-tbl{margin:0;font-size:var(--fs-5);color:var(--mu)}   /* เลขโต๊ะ (เล็ก · ซ่อนถ้าไม่รู้) */
.mn-tbl[hidden]{display:none}
.mn-bc{position:relative;flex:none;min-width:24px;height:24px;padding:0 7px;box-sizing:border-box;border-radius:var(--r-sm);background:rgb(0 0 0 / .3);font-size:var(--fs-5);font-weight:var(--fw-semibold);display:inline-grid;place-items:center}   /* เลขจำนวนของในตะกร้า — สั่งอีกครั้งสำเร็จ = เครื่องหมายถูกเขียวที่มุม */
.mn-bc[hidden]{display:none}
.mn-bcb{position:absolute;top:-7px;right:-7px;width:16px;height:16px;border-radius:var(--r-round);background:var(--ok);color:#fff;display:none;place-items:center;box-shadow:0 0 0 2px #000}
.mn-bcb svg{width:10px;height:10px}
.mn-bc.ok .mn-bcb{display:grid}
.mn-vatn{margin:0 0 10px;font-size:var(--fs-4);line-height:var(--lh-6);color:var(--mu)}   /* ราคายังไม่รวม VAT (OD-327): บรรทัดเดียวบนสุดของรายการ */
.mn-sr{display:flex;justify-content:space-between;align-items:baseline;font-size:var(--fs-7);color:var(--mu)}
.mn-sr b{font-weight:var(--fw-semibold);color:var(--tx);font-variant-numeric:tabular-nums}
.mn-sr.tot{padding-top:10px;box-shadow:inset 0 1px 0 rgb(255 255 255 / .1);color:var(--tx);font-weight:var(--fw-semibold)}
.mn-sr.tot b{font-size:var(--fs-12)}
.mn-sr.mu b{color:var(--mu);font-weight:var(--fw-medium)}
.mn-test[hidden]{display:none}
.mn-panel.nb .mn-note,.mn-panel.nb .mn-alg{display:none}   /* ตะกร้าว่าง = ไม่มีโน้ต/แพ้อาหาร (ไม่มีความหมาย) */
/* OD-453 แถวตะกร้า = แถวสินค้าเดียวกับเมนู: รูปซ้ายคุมทั้งสามบรรทัด · ขวา = ชื่อเต็มความกว้างคอลัมน์ (≤3 บรรทัดสมดุล) / ราคาของบรรทัด (ใต้ชื่อ) / บรรทัดล่าง .mn-bot ชิ้นเดียวกับแถวเมนู = โน้ตซ้าย + ปุ่ม − n + ขวา (--tap) · ชื่อไม่เคยแชร์บรรทัดกับปุ่ม */
.mn-bl{display:grid;grid-template-columns:42px minmax(0,1fr);column-gap:var(--sp-3);align-items:start;padding:10px 0}
.mn-bl + .mn-bl{box-shadow:inset 0 1px 0 rgb(255 255 255 / .1)}
.mn-bl > .mn-ph{grid-row:1 / span 3}
.mn-bl > :not(.mn-ph){grid-column:2}
.mn-bl .mn-tx{padding-top:0}
.mn-bl .mn-tx b{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden;text-wrap:balance}
.mn-bl > .mn-p{margin-top:var(--sp-1);text-align:left}
.mn-bl.so .mn-tx b{color:var(--mu)}
.mn-bl.mn-editing .mn-pcx,.mn-bl.mn-editing .mn-pcx .mn-pc-q{visibility:hidden}   /* พิมพ์โน้ต: ช่องพิมพ์ยื่นไปทับที่ปุ่มจำนวน (ซ่อนไว้ · ตำแหน่งเดิม) = ไม่ดันเลย์เอาต์ */
@media (max-width:359px){.mn-bl{grid-template-columns:minmax(0,1fr)}.mn-bl > .mn-ph{display:none}.mn-bl > :not(.mn-ph){grid-column:1}}   /* จอแคบ (≤359 · 320): คอลัมน์ข้อความเหลือ ~186 → ช่องโน้ตข้างปุ่มเหลือ ~34 (<--tap) · รูปในตะกร้าเป็นแค่ไอคอนหมวด (ไม่ใช่รูปสินค้า) = ซ่อนเพื่อคืนที่ให้ชื่อ/โน้ต (ทุกเป้ากดยังเต็ม --tap) */

.mn-sum .hint{margin:6px 0 0}
.mn-sum .mn-vatn{margin:0}   /* หมายเหตุ VAT ชิดยอดก่อนภาษี (OD-382) · ≥11px ไม่ซ่อน */
.mn-algtag{display:inline-flex;align-items:center;gap:5px;max-width:100%;width:fit-content;margin-top:3px;padding:2px 9px 2px 6px;border-radius:var(--r-pill);background:rgb(0 0 0 / .3);color:var(--tx);font-size:var(--fs-3);font-weight:var(--fw-semibold);line-height:var(--lh-5)}
.mn-algtag .ic{flex:none;width:var(--ic-1);height:var(--ic-1)}
.mn-rh2{margin:6px 0 0;font-size:var(--fs-5);font-weight:var(--fw-semibold);letter-spacing:var(--ls-2);text-transform:uppercase;color:var(--mu)}
.mn-rd{gap:var(--sp-2);padding:var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-3)}
.mn-rh{display:flex;align-items:center;gap:var(--sp-2)}
.mn-rtog{flex:1;min-width:0;display:grid;grid-template-columns:32px minmax(0,1fr) auto;gap:10px;align-items:center;text-align:left;min-height:var(--tap);border-radius:var(--r-md);color:inherit}   /* แถวหัวรอบทั้งแถว = ปุ่มกาง/ย่อ (aria-expanded) · ไม่ครอบปุ่ม Reorder */
.mn-rt{display:grid;gap:1px;min-width:0;font-size:var(--fs-7)}
.mn-rt b{font-weight:var(--fw-semibold)}
.mn-rt time,.mn-rq time{font-size:var(--fs-3);color:var(--mu);font-variant-numeric:tabular-nums}
.mn-rbody{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--sp-1);padding:0 var(--sp-1) 6px 42px}   /* minmax(0,…) = โน้ตยาวตัดด้วย … ไม่ดันการ์ดกว้างเกินจอ */
.mn-rbody[hidden]{display:none}
.mn-rl{display:flex;justify-content:space-between;gap:var(--sp-3);font-size:var(--fs-6)}
.mn-rl b{font-weight:var(--fw-semibold);color:var(--mu);font-variant-numeric:tabular-nums}
.mn-rn{font-size:var(--fs-5);color:var(--ok)}
.mn-rq{display:flex;align-items:center;gap:10px;padding:var(--sp-2) var(--sp-3);border-radius:16px;font-size:var(--fs-6)}   /* คำขอบริการ = การ์ดบางของตัวเอง */
.mn-rq b{flex:1;min-width:0;font-weight:var(--fw-semibold);overflow-wrap:anywhere}
.mn-rqt{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden;white-space:pre-line;color:var(--mu);font-size:var(--fs-5);font-weight:var(--fw-medium);line-height:var(--lh-6)}   /* ข้อความโน้ตที่ลูกค้าส่ง (ผ่าน esc แล้ว) ใต้ชื่อคำขอ · เก็บการขึ้นบรรทัดใหม่ (pre-line) · ย่อ 3 บรรทัด · ยาวกว่านั้นแตะกางอ่านเต็ม (.open · menu.js markMore) */
.mn-rqt[data-more]{cursor:pointer}
.mn-rqt.open{display:block;-webkit-line-clamp:unset}
.mn-rd.done,.mn-rq.done{opacity:.7}   /* เสร็จแล้ว: จางเล็กน้อยแต่อยู่ตลอด session (.7 = ตัวขาวยังเกิน 4.5:1 บนการ์ด) */
.mn-reorder{flex:none;width:var(--tap);height:var(--tap);border-radius:var(--r-round);background:var(--dg-surface-card);box-shadow:var(--dg-line);color:#fff;display:grid;place-items:center}
.mn-reorder .ic{width:var(--ic-4);height:var(--ic-4)}
.mn-oi{flex:none;width:32px;height:32px;border-radius:var(--r-round);background:var(--dg-surface-card);box-shadow:var(--dg-line);color:rgb(255 255 255 / .75);display:grid;place-items:center}
.mn-oi .ic{width:var(--ic-3);height:var(--ic-3)}
.mn-os{padding:3px 10px;border-radius:var(--r-pill);background:rgb(255 255 255 / .1);color:var(--mu);font-size:var(--fs-3);font-weight:var(--fw-semibold);white-space:nowrap}
.mn-os.ack,.mn-os.served,.mn-os.done{color:var(--ok)}
.mn-note,.mn-anl{display:grid;gap:6px}
.mn-fl,.mn-anl > span{font-size:var(--fs-5);font-weight:var(--fw-semibold);color:var(--mu)}
.mn-note textarea,.mn-anl textarea,.mn-comp textarea{display:block;width:100%;height:72px;box-sizing:border-box;padding:var(--sp-3) var(--sp-4);border:0;border-radius:var(--r-lg);background:rgb(0 0 0 / .3);color:var(--tx);font:inherit;font-size:var(--fs-8);line-height:var(--lh-6);resize:none}   /* ช่องพิมพ์ = พื้นโปร่งดำ + เส้นบาง (ช่องเดียว ไม่ใช่กรอบการ์ด) · สูงตายตัว */
.mn-note textarea:focus,.mn-anl textarea:focus,.mn-comp textarea:focus{box-shadow:inset 0 0 0 1.5px var(--tx)}
.mn-status{margin:0;min-height:18px;font-size:var(--fs-5);line-height:var(--lh-7);color:var(--mu)}   /* บรรทัดสถานะ Add to Reservation / Send (เฟส 2 ต่อ) · จองความสูงไว้ */
.mn-status:empty{min-height:0}

/* ---------- แพ้อาหาร (OD-302): สวิตช์ + ชิป 10 สารของ POS (เลือกหลายอัน = แดงแก้วแบบ selector) + โน้ตแพ้อาหาร ---------- */
.mn-sw{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);min-height:48px;cursor:pointer;font-size:var(--fs-8);font-weight:var(--fw-semibold);position:relative}
.mn-sw input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}   /* checkbox จริง role=switch ทับทั้งแถว */
.mn-tk{flex:none;position:relative;width:52px;height:32px;border-radius:var(--r-pill);background:rgb(0 0 0 / .3);transition:background-color var(--t-7) var(--ease),box-shadow var(--t-7) var(--ease)}
.mn-tk::after{content:"";position:absolute;top:3px;left:3px;width:26px;height:26px;border-radius:var(--r-round);background:#fff;transition:transform var(--sel-t) var(--spring)}
.mn-sw input:checked + .mn-tk{background:var(--ok)}   /* สวิตช์เปิด = เขียวระบบ (OD-383 ข้อ 28 · เขียว = เสร็จ/เปิดแล้ว) ตัวเดียวกับ --ok ทุกที่ */
.mn-sw input:checked + .mn-tk::after{transform:translateX(20px)}
.mn-sw input:focus-visible + .mn-tk{box-shadow:var(--focus-shadow)}   /* สวิตช์: input จริงซ่อน → วงโฟกัสที่ราง (ใช้ --focus-shadow เพราะรางไม่มีเงาอื่น) */
.mn-ac input:focus-visible + .bx{outline:var(--focus-w) solid var(--focus-c);outline-offset:var(--focus-off)}
.mn-algbd{display:grid;gap:var(--sp-3);animation:pg-in var(--t-7) var(--ease)}
.mn-algbd[hidden]{display:none}
.mn-algrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-2)}
.mn-ac{position:relative;display:block}
.mn-ac input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
.mn-ac .bx{display:flex;align-items:center;gap:10px;min-height:48px;padding:6px 14px 6px var(--sp-3);border-radius:24px;background:rgb(0 0 0 / .3);color:var(--mu);font-size:var(--fs-6);font-weight:var(--fw-medium);line-height:var(--lh-3);transition:color var(--t-7) var(--ease),background-color var(--t-7) var(--ease),box-shadow var(--t-7) var(--ease)}
.mn-ac .bx .ic{flex:none;width:var(--ic-5);height:var(--ic-5)}
.mn-ac input:checked + .bx{color:#fff;background:var(--sel-glass);box-shadow:var(--sel-glass-rim),var(--sel-drop)}   /* ติ๊กแล้ว = แดงแก้วสูตรเดียวกับ .cap .sel (หลายอันพร้อมกันได้) · ไม่พึ่งสีอย่างเดียว: ตัวเลขนับที่หัวการ์ด */
.mn-anl{display:grid;gap:6px}

.mn-ant{margin:0;font-size:var(--fs-5);line-height:var(--lh-8);color:var(--mu)}

/* ---------- ปุ่มบริการ 6 ปุ่ม (OD-320 · OD-421/423): กลมสูงเท่า CTA (--cta-h) แยกกัน ไม่มีแคปซูลรวม · กระจายเต็มความกว้างเนื้อหา (ขอบ 16px) · อยู่ที่เดิมเสมอ ---------- */
.mn-svc{position:absolute;left:var(--dock-edge);right:var(--dock-edge);bottom:var(--cb);height:var(--cta-h);display:flex;justify-content:center;align-items:center;gap:var(--svc-gap);pointer-events:none}   /* ช่องไฟ = --svc-gap คงที่ 8 (Google a11y: เป้าแตะห่างกัน ≥8dp) · วงกลม = --svc-d (app.css :root) · ที่จอแคบสุดที่ 44+8 ไม่พอเท่านั้นช่องถึงหดเหลือ --sp-1 · อยู่กลาง ห่างบน CTA 14 — ไม่กางเต็ม dock (OD-325) */
.mn-sheet[data-svc="0"] .mn-svc{display:none}
.mn-rb{position:relative;flex:0 1 auto;min-width:0;width:var(--svc-d);height:auto;aspect-ratio:1;border:0;border-radius:var(--r-round);padding:0;isolation:isolate;background:var(--dg-surface);box-shadow:var(--dg-line);color:#fff;display:grid;place-items:center;pointer-events:auto}
.mn-rb .ic{width:26px;height:26px}
.mn-sheet.enter .mn-rb,.mn-svc.in .mn-rb{animation:mn-card-in .38s var(--ease) backwards;animation-delay:calc(var(--i, 0) * 36ms)}   /* ปุ่มบริการเด้งเข้าแบบเดียวกับการ์ด (keyframes/เวลา/stagger เดียวกัน) ซ้ายไปขวา · .in = แถวบริการเพิ่งโผล่ตอนเช็กอินระหว่างเปิดอยู่ · ปิดการ์ด = ทั้งแผ่นจางหายตาม .mn-sheet */
.mn-rb::before{content:"";position:absolute;inset:-2px}   /* ภาพ = สูง CTA กด +4 (ช่องว่างจอ 320 เหลือ 5px: ห้ามพื้นที่กดซ้อนกัน) */
.mn-rb:focus-visible{outline-offset:3px}
.mn-rb:disabled{opacity:var(--op-3)}
.mn-rb::after{content:"";position:absolute;inset:0;z-index:var(--z-under);border-radius:inherit;background:var(--sel-glass);box-shadow:var(--sel-glass-rim),var(--sel-drop);opacity:0;transition:opacity var(--t-7) var(--ease)}   /* เลือก = selector แดงแก้ว (ไม่มี ✕) · เป็นชั้นซ้อนที่จางด้วย opacity: พื้นดำโปร่งเป็นไล่เฉดสี ไล่สีเข้าแดงไม่ได้ */
.mn-rb.armed::after,.mn-rb[aria-pressed="true"]::after{opacity:1}
.mn-rb.req{overflow:visible}   /* ส่งแล้วยังค้าง = เครื่องหมายถูกเขียวเล็กที่มุมปุ่ม (.mn-bg) อย่างเดียว ไม่มีวงเขียวรอบปุ่ม ไม่มีป้ายเวลา (OD-324) */
.mn-bg{position:absolute;top:-4px;right:-4px;z-index:var(--z-2);width:20px;height:20px;border-radius:var(--r-round);background:var(--ok);color:#fff;display:grid;place-items:center;pointer-events:none;box-shadow:0 0 0 2px #000}
.mn-bg svg{width:12px;height:12px}
.mn-bg[hidden]{display:none}
.mn-tkb{position:absolute;top:-4px;right:-4px;z-index:var(--z-2);width:20px;height:20px;border-radius:var(--r-round);background:var(--tile);color:transparent;box-shadow:inset 0 0 0 2px var(--tx);display:grid;place-items:center;pointer-events:none}   /* ติ๊กของตัวเลือกย่อย (OD-423): ไม่ติ๊ก = วงเปล่ามีขอบ · ติ๊ก = วงขาวมีเครื่องหมายถูก (รูปร่างต่าง ไม่พึ่งสีอย่างเดียว · ขาว/ดำเทียบกันเกิน 3:1) · ไม่ใช้เขียวเพราะเขียว = "ส่งแล้ว" */
.mn-tkb svg{width:12px;height:12px}
.mn-rb[aria-pressed="true"] .mn-tkb{background:var(--tx);color:var(--tile);box-shadow:none}
.mn-chip{position:absolute;left:var(--dock-edge);right:var(--dock-edge);bottom:calc(var(--cb) + var(--cta-h) + 4px);z-index:var(--z-3);display:flex;justify-content:center;pointer-events:none}   /* ลอยเหนือแถวบริการ ซ้อนทับขอบล่างการ์ดนิดเดียว (ส่วนนั้นเป็นขอบจางของการ์ด ไม่ใช่แถว) — ไม่ดันอะไร · h1 ของหน้า (z15) อยู่เหนือฉากมืด จึงห้ามลอยขึ้นไปถึงหัวข้อ */
.mn-chip[hidden]{display:none}
.mn-chipx{display:inline-flex;align-items:center;gap:var(--sp-2);max-width:100%;padding:var(--sp-1);border-radius:var(--r-pill);background:var(--dg-surface-card);box-shadow:var(--dg-line);font-size:var(--fs-5);font-weight:var(--fw-semibold);line-height:var(--lh-5);pointer-events:auto}   /* เม็ดโปร่งเบา (กระจกเบา 1 ชิ้น · ชั่วคราว) */
.mn-chipx.err,.mn-chipx.soon{padding:var(--sp-2) var(--sp-4)}
.mn-chipx.err{color:var(--red-text)}
.mn-chipx .ic{flex:none;width:var(--ic-2);height:var(--ic-2)}
.mn-chipx.mn-sub{flex-direction:column;gap:var(--sp-1);padding:var(--sp-2) var(--sp-4);border-radius:var(--r-xl);text-align:center}   /* ตัวบอกโหมดตัวเลือกย่อย: 1-2 บรรทัด ซ้อนทับ ไม่ดันอะไร */
.mn-chipn{color:var(--mu);font-size:var(--fs-4);font-weight:var(--fw-medium)}   /* ที่ขอไว้แล้วแต่ถูกบังชั่วคราว (ทิชชู่/แก้ว/โน้ต/บิล) */
/* ช่องพิมพ์โน้ตถึงพนักงาน (OD-421): ซ้อนทับตรงที่ก้นการ์ดตะกร้า เหนือแถวบริการ · สูงคงที่ --comp-h (ช่องพิมพ์ + ตัวนับ) · ไม่ดันอะไร · ชิปแจ้งผิดพลาดลอยเหนือมันแทนที่จะถูกบัง */
.mn-comp{position:absolute;left:var(--side);right:var(--side);bottom:var(--cbb);height:var(--comp-h);z-index:var(--z-3);box-sizing:border-box;display:grid;grid-template-rows:minmax(0,1fr) auto;gap:var(--sp-2);padding:var(--sp-3);border-radius:var(--r-xl);background:var(--dg-surface-card);box-shadow:var(--dg-line);animation:mn-card-in var(--t-8) var(--ease) backwards}
.mn-comp[hidden],.mn-sheet[data-svc="0"] .mn-comp{display:none}
.mn-comp textarea{height:100%;touch-action:pan-y}
.mn-comp textarea::placeholder{color:var(--mu)}
.mn-compn{justify-self:end;min-height:var(--ic-2);font-size:var(--fs-3);line-height:var(--lh-3);color:var(--mu);font-variant-numeric:tabular-nums}
.mn-sheet[data-mode="note"] .mn-chip{bottom:calc(var(--cbb) + var(--comp-h) + var(--sp-1))}

/* ---------- ตัวดูรูปเต็มจอ แบบ A (OD-380 · WO-379) · overlay กลางของ ui.js (.qrbig: ปัดลง/Esc/Back/แตะพื้นปิด) · รูปเต็มกว้างจอชนขอบ ตั้งแต่ใต้แถวแท็บถึงเหนือ CTA · ไม่มีการ์ด/มุมโค้ง/กรอบ · z 4 = ต่ำกว่า .cta (5) .dock (6) → ทั้งสองอยู่ที่เดิม ---------- */
.qrbig.mn-vwo{--mn-pvb:calc(var(--dock-edge) + var(--dock-h) + 78px);--mn-vtp:calc(var(--hd-box) + 70px - var(--hd-cut));clip-path:inset(var(--mn-vtp) 0 0 0);transition:clip-path var(--t-6) var(--ease-std);display:block;background:none;animation:none;-webkit-user-select:none;user-select:none}   /* OD-417 ราก: overlay เริ่มใต้แถวแท็บ (clip-path = ไม่วาดและไม่รับสัมผัสเหนือ --mn-vtp) → header/แท็บ/ค้นหา/ภาษาตัวจริงของหน้าเมนูอยู่ที่เดิมทุกสถานะ ไม่ต้องยก/ไม่มีสำเนา/ไม่ต้องย่อตามตัวดูรูป · --mn-vtp = ใต้แถวแท็บตอนหัวข้อ "ย่อ" (OD-444: ตัวดูรูปเปิด = menu.js บังคับ hd-min เสมอ จึงเริ่มใต้แท็บที่ยกขึ้น --hd-cut · ปิด = หัวข้อกลับตามเดิม) · --mn-pvb = ขอบล่างของรูป (เหนือ CTA เว้นเท่าช่องบน) · z-index ของ ui.js (50) คงไว้ · .cta/.dock ถูกยกเหนือด้วย body.mn-vw ด้านล่าง */
body.mn-vw .cta,body.mn-vw .dock{z-index:var(--z-viewer-ui)}   /* CTA + dock อยู่ที่เดิมเป๊ะตอนเปิดตัวดูรูป (OD-302) */
/* แถวแท็บ + ปุ่มค้นหาตัวจริงของหน้าเมนูยกเหนือ overlay แบบเดียวกับ .cta/.dock (ไม่ทำสำเนา) · หัวข้อหน้า "MENU & ORDER" + ปุ่มภาษาไม่ยก = overlay ทึบบังไว้ ตัวดูรูปไม่มีแถวหัวข้อ/ปุ่มภาษา (OD-380) · #menuRoot เป็น stacking context ของมันเอง จึงยกทั้งกล่อง แต่ทึบเฉพาะส่วนที่ต้องใช้: รางเมนูซ่อน (รูปใน overlay แทน) · ผลค้นหาคลุมตัวดูรูปเหมือนหน้านอก · กดทะลุกล่องที่เหลือลง overlay */
body.mn-vw #menuRoot .mn-track{opacity:0;transition:opacity var(--fly-t) var(--ease)}   /* รายการเมนูใต้ตัวดูรูปจางหายตามฉากที่จางเข้า (กันแถวโผล่ในแถบว่างใต้แท็บตอนหัวข้อย่อ) · inert ตั้งจาก menu.js ให้พ้นคีย์บอร์ด/screen reader */
body.mn-vw.mn-vx #menuRoot .mn-track{opacity:1}   /* ปัดลง/กำลังปิด: รายการเมนูโผล่ใต้ฉากที่จาง (menu.js ใส่ mn-vx) */
body.mn-vw.mn-vres .mn-vwo{pointer-events:none}
body.mn-vw.mn-vres .mn-vwo > *{opacity:0;pointer-events:none}   /* ผลค้นหาโชว์อยู่ = เนื้อตัวดูรูปใต้มันซ่อน (ผลค้นหาหน้าตาเหมือนหน้านอก) · ปิดค้นหา/เลือกผล = กลับมา · opacity ล้วน เลย์เอาต์ไม่ขยับ */
/* OD-359: ตัวดูรูปเปิด = CTA ทึบเต็ม (ctaFadeDecision รู้จาก cfg.viewer → ไม่จางตามสัญญาณเลื่อนของ dock) และตอนว่าง (แคปซูลทึบ #131315 บนฉากมืด) เห็นรูปทรงด้วยกรอบ --dg-line ของ .mn-cap (OD-363: ทุกพื้นผิวมีกรอบเดียวกัน) · ไอคอนขาวเต็ม · มีของ = ปุ่มแดงตามปกติ */
body.mn-vw .cta.mn-cta.calm .mn-ci{opacity:1;color:#fff}
.qrbig.mn-vwo svg{width:auto;height:auto;border-radius:0;background:none}   /* ล้างกฎ `.qrbig svg` (QR ขาวใหญ่) ของ app.css ที่โดนไอคอน SVG ในตัวดูรูป */
.qrbig.mn-vwo .mn-vb svg{width:var(--ic-4);height:var(--ic-4)}
.qrbig.mn-vwo .mn-vpl svg{width:var(--ic-5);height:var(--ic-5)}
.qrbig.mn-vwo .mn-pcx svg{width:var(--ic-3);height:var(--ic-3)}
.qrbig.mn-vwo .mn-pcx.pvc svg{width:var(--ic-4);height:var(--ic-4)}
.qrbig.mn-vwo{touch-action:pan-x;overscroll-behavior:none}   /* OD-378: .qrbig ตั้ง touch-action:none (ให้ปัดลงปิดทำงาน) — iOS Safari รวมค่านี้เข้าทั้งพื้นที่ ทำให้ปัดซ้าย-ขวาในราง (pan-x) ไม่ติด · pan-x เท่ากับรางจึงไม่ขัดกัน · ปัดลงปิดยังได้เพราะ pan-x ไม่ให้เบราว์เซอร์แย่งท่าแนวตั้ง */
.mn-vtrk{position:absolute;inset:0;display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;overscroll-behavior:none;touch-action:pan-x}
.mn-vtrk::-webkit-scrollbar{display:none}
.mn-vsl{flex:0 0 100%;position:relative;box-sizing:border-box;scroll-snap-align:center;scroll-snap-stop:always}   /* เปลือกเต็มกว้างราง · เนื้อวาดเฉพาะใกล้ที่ดู (menu.js loadNear) */
.mn-vimg{position:absolute;inset:0;overflow:hidden}   /* สี่เหลี่ยมชนขอบ: ไม่มีมุมโค้ง ไม่มีกรอบ */
.mn-vimg,.mn-vwo:is(.mn-vopen,.mn-vclose) .mn-vsl{background:linear-gradient(150deg,hsl(var(--h) 28% 27%),hsl(calc(var(--h) + 32) 32% 13%))}   /* พื้นไล่สีโทนเมนู · ตอนเปิด/ปิดพื้นนี้ย้ายไปอยู่ที่สไลด์ (หน้าต่างมุมโค้ง) ส่วนรูปที่ย่อ/ขยายอยู่ในหน้าต่างบนพื้นเดียวกัน → หน้าต่างไม่เคยโผล่ช่องว่างรอบรูป */
.mn-vwo:is(.mn-vopen,.mn-vclose) .mn-vimg{background:none}
.mn-vimg::before{content:"";position:absolute;inset:var(--mn-vtp) 0 var(--mn-pvb) 0;margin:auto;width:40%;height:calc((100% - var(--mn-vtp) - var(--mn-pvb)) * .3);background:rgb(255 255 255 / .6);-webkit-mask:var(--m) center/contain no-repeat;mask:var(--m) center/contain no-repeat}
.mn-vimg img,.mn-vimg .mn-vvid{position:absolute;left:0;top:var(--mn-vtp);width:100%;height:calc(100% - var(--mn-vtp) - var(--mn-pvb));box-sizing:border-box;padding:calc(var(--tap) + var(--sp-4)) 0 0;object-fit:contain;object-position:center bottom}   /* เว้นที่ใต้ ✕/ตัวนับ · ฐานรูปชิดล่าง = อยู่ใต้ม่านดำของชื่อ/ราคา (สินค้าไม่ถูกครอป) */
.mn-vtag{position:absolute;left:50%;top:calc(var(--mn-vtp) + (100% - var(--mn-vtp) - var(--mn-pvb)) * .65 + var(--sp-3));transform:translateX(-50%);padding:3px 9px;border-radius:var(--r-pill);background:rgb(0 0 0 / .35);color:rgb(255 255 255 / .6);font-size:var(--fs-2);font-weight:var(--fw-semibold);letter-spacing:var(--ls-3);text-transform:uppercase;white-space:nowrap}   /* ป้ายภาพจำลอง ซ้อนบนรูป ใต้ไอคอน */
/* ตัวเล่นคลิป (WO-383): <video> ใช้เรขาคณิตเดียวกับรูป (กฎ .mn-vimg img ด้านบน) ซ้อนทับ · โปร่งใสจนเล่นจริง (.mn-vplay ← menu.js) · ไม่รับสัมผัส = ปัดซ้ายขวา/ซูม/แตะสองครั้งทำงานผ่านรูปเหมือนเดิม
   ปุ่มเล่น (clip เท่านั้น): กลางพื้นที่รูป · ≥ --tap · พื้นผิวสูตรเดียวกับปุ่มอื่น (--dg-surface) · เล่นอยู่ = ไอคอนหยุด (ทึบเต็ม: เป็นปุ่มควบคุม ต้องเห็นชัด ≥3:1) */
.mn-vvid{pointer-events:none;opacity:0}
.mn-vimg.mn-vplay .mn-vvid{opacity:1}
.mn-vpl{position:absolute;z-index:var(--z-1);left:50%;top:calc(var(--mn-vtp) + (100% - var(--mn-vtp) - var(--mn-pvb)) / 2);transform:translate(-50%,-50%);width:calc(var(--tap) * 1.5);height:calc(var(--tap) * 1.5);min-width:var(--tap);min-height:var(--tap);border:0;border-radius:var(--r-round);padding:0;background:var(--dg-surface);box-shadow:var(--dg-line);color:var(--tx);display:grid;place-items:center;pointer-events:auto}
.mn-vpl-p,.mn-vpl-z{display:grid;place-items:center}
.mn-vpl-z,.mn-vgo .mn-vpl-p{display:none}
.mn-vgo .mn-vpl-z{display:grid}
/* ปุ่มบนรูป: ✕ ซ้าย · ตัวนับขวา (ซ้อนบนรูป ไม่มีแถวของตัวเอง) · ไม่รับการแตะนอกตัวปุ่ม → แตะ/ปัดตกลงรูป */
.mn-vtop{position:absolute;z-index:var(--z-2);top:calc(var(--mn-vtp) + var(--sp-3));left:var(--sp-3);right:var(--sp-3);display:flex;align-items:center;justify-content:space-between;pointer-events:none}
.mn-vtop .mn-vb{pointer-events:auto}
.mn-vb{position:relative;width:var(--tap);height:var(--tap);border:0;border-radius:var(--r-round);padding:0;background:var(--dg-surface);box-shadow:var(--dg-line);color:#fff;display:grid;place-items:center}   /* พื้นผิวสูตรเดียวกับทุกชิ้น (OD-363) */
.mn-vb svg{width:var(--ic-4);height:var(--ic-4)}
.mn-vct{height:32px;padding:0 var(--sp-3);border-radius:var(--r-pill);background:var(--dg-surface-card);box-shadow:var(--dg-line);display:grid;place-items:center;font-size:var(--fs-7);font-weight:var(--fw-semibold);font-variant-numeric:tabular-nums;color:var(--tx)}
.mn-vprog{position:absolute;z-index:var(--z-2);left:0;right:0;top:var(--mn-vtp);height:3px;background:var(--dg-fill);pointer-events:none}   /* แถบความคืบหน้า 3px ขอบบนรูป (รางจางสูตรเดียวกับพื้นการ์ด) */
.mn-vprog i{position:absolute;inset:0;background:var(--tx);transform:scaleX(var(--p,0));transform-origin:0 50%;transition:transform var(--t-6) var(--ease-std)}   /* transform ล้วน */
/* ชื่อ + ราคา + ปุ่ม + ซ้อนล่างรูปบนไล่ดำ: linear-gradient ล้วน (ห้ามเบลอ/filter) · โทเคนม่าน --dg-scrim · ยึดขอบล่างรูป (ตัวเลือกขนาดโผล่เฉพาะรายการที่มี >1 บรรทัด ไม่จองแถวว่าง → ส่วนที่เพิ่มงอกขึ้นด้านบน ไม่ดันรูป) */
.mn-vft{position:absolute;z-index:var(--z-2);left:0;right:0;bottom:var(--mn-pvb);display:grid;gap:var(--sp-3);padding:calc(2 * var(--sp-9)) var(--sp-4) var(--sp-4);pointer-events:none}
.mn-vft button{pointer-events:auto}
.mn-vvs{display:flex;gap:var(--sp-2);overflow-x:auto;scrollbar-width:none}
.mn-vvs:empty{display:none}
.mn-vvs::-webkit-scrollbar{display:none}
.mn-vvs button{flex:none;height:34px;padding:0 14px;border:0;border-radius:var(--r-pill);background:var(--dg-surface-card);box-shadow:var(--dg-line);color:var(--tx);font:inherit;font-size:var(--fs-5);font-weight:var(--fw-medium)}
.mn-vvs button.on{background:var(--sel-glass);box-shadow:var(--sel-glass-rim)}
.mn-vrow{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--sp-4);min-height:var(--tap)}
.mn-vnm{display:grid;gap:2px;min-width:0;align-self:center}
.mn-vnm b{font-size:var(--fs-12);font-weight:var(--fw-semibold);line-height:var(--lh-4);overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow-wrap:anywhere}   /* ชื่อยาว = 2 บรรทัดแล้วตัด … (ยึดล่าง งอกขึ้นบน) */
.mn-vp{font-size:var(--fs-8);color:var(--tx);font-variant-numeric:tabular-nums;white-space:nowrap}
.mn-vout{height:var(--tap);padding:0 var(--sp-4);border-radius:var(--r-pill);background:var(--dg-surface-card);box-shadow:var(--dg-line);display:grid;place-items:center;color:var(--tx)}   /* หมด = ป้ายซ้อนบนรูป แทนปุ่ม + */
.mn-vout[hidden]{display:none}
/* ชิป "เพิ่งเพิ่ม ×n" ลอยกลางบนรูป (ซ้อนทับ ไม่ดันอะไร · transform+opacity ล้วน เล่นด้วย animate()) */
.mn-vchip{position:absolute;z-index:var(--z-3);left:50%;top:calc(var(--mn-vtp) + var(--sp-3) + 6px);max-width:50%;height:32px;padding:0 var(--sp-4);border-radius:var(--r-pill);background:var(--dg-surface-card);box-shadow:var(--dg-line);display:grid;place-items:center;font-size:var(--fs-5);font-weight:var(--fw-semibold);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--tx);opacity:0;transform:translateX(-50%);pointer-events:none}
/* แตะครั้งเดียว = โหมดเต็มจอ (WO-382 · OD-394 · OD-403): ทุกอย่างหายหมด (header/แท็บ/CTA/dock/ปุ่มบน ✕ ← ตัวนับ/แถบ/ชื่อ+ราคา+ปุ่ม +−/คำใบ้/ทานคู่) เหลือรูป + เฟดดำบน/ล่างตัวเดิม + ชื่อเมนู (บน) + คำบรรยาย (ล่าง) · แตะอีกที = กลับ · หายด้วย opacity + pointer-events:none (เลย์เอาต์ไม่ขยับ) */
.mn-vtop,.mn-vprog,.mn-vft,.mn-vhint{transition:opacity var(--t-6) var(--ease-std)}
.mn-vwo.mn-imm :is(.mn-vtop,.mn-vprog,.mn-vft,.mn-vhint){opacity:0}
.mn-vwo.mn-imm :is(.mn-vtop .mn-vb,.mn-vft button){pointer-events:none}
/* แตะสองครั้ง = +1 (OD-374): เอฟเฟกต์กลางรูป/คำใบ้ครั้งแรก · transform+opacity ล้วน เล่นครั้งเดียวด้วย animate() · ไม่รับการแตะ */
.mn-vpop{position:absolute;inset:0;margin:auto;width:var(--cta-h);height:var(--cta-h);border-radius:var(--r-round);background:var(--dg-surface);box-shadow:var(--dg-line);color:var(--tx);display:grid;place-items:center;opacity:0;pointer-events:none}
.mn-vpop.mn-no{color:var(--mu)}
.qrbig.mn-vwo .mn-vpop svg{width:var(--ic-5);height:var(--ic-5)}
.mn-vhint{position:absolute;z-index:var(--z-2);left:50%;top:calc(var(--mn-vtp) + var(--tap) + var(--sp-6));transform:translateX(-50%);padding:var(--sp-2) var(--sp-4);border-radius:var(--r-pill);background:var(--dg-surface-card);box-shadow:var(--dg-line);color:var(--tx);font-size:var(--fs-5);font-weight:var(--fw-medium);white-space:nowrap;opacity:0;pointer-events:none}
.mn-vhint[hidden]{display:none}

/* ---------- ซูมลอย (พินช์ · menu.js "ซูมลอย" · OD-396): สองนิ้วลง = สำเนารูปยกขึ้นชั้นบนสุด · สี่เหลี่ยมล้วนบนพื้นดำเต็มจอ (บัง UI ทั้งหมด) · transform ตามนิ้วทันที (ไม่มี transition ระหว่างอยู่) · ค้างซูมได้ รับการลาก/แตะเอง (touch-action:none) · กลับปกติ = .mn-zout เด้งกลับ + พื้นจาง และไม่รับการแตะ (ปัดหลังกลับทำงานได้ทันที) ---------- */
.mn-zl{position:fixed;inset:0;z-index:var(--z-zoom);background:var(--black);touch-action:none;animation:pg-in var(--t-4) var(--ease-std) backwards}
.mn-zb{position:absolute;transform-origin:50% 50%;will-change:transform}
.mn-zl.mn-zout{opacity:0;pointer-events:none;transition:opacity var(--sel-t) var(--ease-std)}
.mn-zl.mn-zout .mn-zb{transition:transform var(--sel-t) var(--ease)}
.mn-zsrc{visibility:hidden}   /* ตัวจริงใต้เลเยอร์: ซ่อนแต่ไม่ขยับเลย์เอาต์ */
html.lite .mn-zl,html.lite .mn-zl.mn-zout,html.lite .mn-zl.mn-zout .mn-zb{animation:none;transition:none}
@media (prefers-reduced-motion:reduce){.mn-zl{animation:none}}

/* ---------- ตัวดูรูป v3 (WO-382 · OD-394/396/397) ---------- */
/* ชั้นของตัวดูรูป: .mn-vbd = ฉากดำ (จางตามนิ้วตอนปัดลง) · .mn-vbody = ทุกอย่างที่เลื่อน/หดตามนิ้ว · overlay เองโปร่งใส เพื่อให้เห็นหน้าเมนูผ่านฉากที่จาง */
.mn-vbd{position:absolute;inset:0;background:var(--black);opacity:calc(1 - var(--dp,0) * var(--vf-drag-fade))}
.mn-vbody{position:absolute;inset:0;transform-origin:50% 50%}
.mn-vwo.dz-on{translate:none}   /* ui.js .dz-on เลื่อนทั้ง overlay · ที่นี่เลื่อน/หดเฉพาะ .mn-vbody (ฉากอยู่กับที่แล้วจาง) */
.mn-vwo.dz-on .mn-vbody{transform:translateY(var(--dy,0px)) scale(calc(1 - var(--dp,0) * var(--vf-drag-shrink)))}
.mn-vwo.dz-back .mn-vbody{transition:transform var(--sel-t) var(--spring)}
.mn-vwo.dz-back .mn-vbd{transition:opacity var(--sel-t) var(--ease-std)}
/* เฟดดำบน/ล่าง = linear-gradient ล้วน (--vf-*) · ไม่มีชั้นเบลอ (เบลอ 0 = เบาสุด) */
.mn-vtf,.mn-vbf{position:absolute;z-index:var(--z-1);left:0;right:0;pointer-events:none}
.mn-vtf{top:0;height:var(--vf-top-h);background:var(--vf-top);transform-origin:50% 0;transition:transform var(--t-8) var(--ease)}
.mn-vbf{bottom:0;height:var(--vf-bot-h);background:var(--vf-bot)}
.mn-vwo.mn-imm .mn-vtf{transform:scaleY(var(--vf-imm-top))}   /* เต็มจอ: เฟดบนยาวขึ้นให้ชื่อใหญ่อยู่บนพื้นทึบพอ */
body.mn-vim .cta.mn-cta,body.mn-vim .dock{opacity:0;pointer-events:none}   /* เต็มจอ: CTA/dock (ยกเหนือ overlay) หายด้วย opacity ไม่ขยับ · header/แท็บ/ค้นหา/ภาษาถูก overlay คลุมเอง (clip ขยายเต็มจอด้านล่าง) · ทางออก = แตะรูปอีกที */
.qrbig.mn-vwo.mn-imm{clip-path:inset(0)}
body.mn-vw .cta.mn-cta{transition:background var(--t-8) var(--ease),color var(--t-8) var(--ease),opacity var(--t-6) var(--ease-std)}
body.mn-vw .dock{transition:width var(--dock-t) var(--dock-bounce),opacity var(--t-6) var(--ease-std)}
/* ← (ซ้าย · มีเฉพาะตอนมาจากลิงก์ทานคู่ · จองที่ไว้ ไม่ขยับ) · ✕ (ขวา · ปิดทั้งหมด) · เต็มจอ: หายทั้งแถว (กฎด้านบน) */
.mn-vwo[data-hist="0"] .mn-vbk{visibility:hidden}
/* โหมดเต็มจอ: ชื่อบน · คำบรรยายล่าง (ทานคู่ไม่แสดง · OD-403 · ตำแหน่งใหม่รอเจ้าของเลือก) */
.mn-vttl{position:absolute;z-index:var(--z-2);left:var(--sp-6);right:var(--sp-6);top:calc(env(safe-area-inset-top) + var(--tap) + var(--sp-4));opacity:0;transform:translateY(var(--sp-2));pointer-events:none;transition:opacity var(--t-6) var(--ease-std),transform var(--t-8) var(--ease)}
.mn-vttl b{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;font-size:var(--fs-14);font-weight:var(--fw-bold);line-height:var(--lh-4);overflow-wrap:anywhere;text-shadow:var(--vf-shadow)}
.mn-vwo.mn-imm .mn-vttl{opacity:1;transform:none}
.mn-vmr{position:absolute;z-index:var(--z-2);left:var(--sp-6);right:var(--sp-6);bottom:calc(env(safe-area-inset-bottom) + var(--sp-7));display:grid;gap:var(--sp-3);opacity:0;transform:translateY(var(--sp-3));pointer-events:none;transition:opacity var(--t-6) var(--ease-std),transform var(--t-8) var(--ease)}
.mn-vwo.mn-imm .mn-vmr{opacity:1;transform:none}
.mn-vwo.mn-imm .mn-vpr{display:none}   /* ทานคู่ไม่รับสัมผัส/ไม่ถูกวาดในโหมดเต็มจอ (ตัวแม่ .mn-vmr pointer-events:none · ลูกสืบทอด) */
.mn-vmr[hidden],.mn-vdsc[hidden],.mn-vpr[hidden]{display:none}
.mn-vdsc{margin:0;font-size:var(--fs-6);line-height:var(--lh-8);color:var(--vf-tx);text-shadow:var(--vf-shadow);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.mn-vpr{display:grid;gap:var(--sp-2)}
.qrbig.mn-vwo .mn-pga svg{width:var(--ic-4);height:var(--ic-4)}
.mn-vpr .mn-pl{color:var(--vf-tx-mu)}
/* ราคา/ตัวเลือกของค่าบริการ (ไม่ใช่อาหาร · แสดงอย่างเดียว ไม่ใช่ปุ่ม) */
.mn-vvs .mn-vv{flex:none;display:grid;place-items:center;height:34px;padding:0 var(--sp-3);border-radius:var(--r-pill);background:var(--dg-surface-card);box-shadow:var(--dg-line);color:var(--tx);font-size:var(--fs-5);font-weight:var(--fw-medium);white-space:nowrap}
/* ทานคู่กับ: รูปกลม (แตะ = ไปเมนูนั้น) + ชื่อ (ลิงก์เดียวกัน) + ปุ่ม + · ทุกชิ้น ≥44px · ใช้ทั้งในตัวดูรูปและในแถวที่ขยาย */
.mn-pl{font-size:var(--fs-3);font-weight:var(--fw-semibold);letter-spacing:var(--ls-3);text-transform:uppercase;color:var(--mu)}
.mn-pc{display:flex;gap:var(--sp-2);overflow-x:auto;scrollbar-width:none}
.mn-pc::-webkit-scrollbar{display:none}
.mn-chp{flex:none;display:flex;align-items:center;gap:var(--sp-1);height:calc(var(--tap) + var(--sp-2));padding:var(--sp-1);border-radius:var(--r-pill);background:var(--dg-surface-card);box-shadow:var(--dg-line);color:var(--tx)}
.mn-ph.mn-pt{flex:none;width:var(--tap);aspect-ratio:1 / 1;border-radius:var(--r-round)}
.mn-pgn{max-width:calc(var(--tap) * 2.5);min-width:var(--tap);min-height:var(--tap);padding:0 var(--sp-2) 0 var(--sp-1);border:0;background:none;color:var(--tx);font-size:var(--fs-5);font-weight:var(--fw-medium);text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mn-pga{flex:none;display:grid;place-items:center;width:var(--tap);height:var(--tap);border:0;border-radius:var(--r-round);background:var(--dg-fill);color:var(--tx);font-size:var(--fs-7);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums}
.mn-pga svg{width:var(--ic-4);height:var(--ic-4)}
.mn-pga.on{background:var(--sel-glass);box-shadow:var(--sel-glass-rim)}
.mn-pga:disabled{opacity:var(--op-2)}
/* แถวที่ขยาย (OD-408/413): คำบรรยาย + ทานคู่ใต้แถวหัว กินเต็มความกว้างแถว (ไม่ย่นอยู่แค่คอลัมน์ข้อความ) · เฟดเข้า ไม่ขยับของอื่นนอกจากแถวที่อยู่ล่างลงไป */
.mn-xp{grid-column:1 / -1;grid-row:2;min-width:0;display:grid;gap:var(--sp-3);padding-top:var(--sp-2);animation:pg-in var(--t-6) var(--ease-std)}
.mn-item.v .mn-xp{grid-row:3}
.mn-dsc{margin:0;font-size:var(--fs-5);line-height:var(--lh-6);color:var(--tx);overflow-wrap:anywhere}
.mn-xp .mn-pr2{display:grid;gap:var(--sp-2)}
/* เปิด/ปิดตัวดูรูป (OD-417): ตัวขยับมีตัวเดียว = .mn-vimg จริง (ไม่มีสำเนา/ตัวบิน/การ์ดซ้อน) · menu.js วัดท่ารูปเล็กเขียนเป็นตัวแปร --mo-tf (ย่อ+เลื่อน) --mo-clip (หน้าต่าง = กรอบรูปเล็ก มุมโค้งเท่ารูปเล็ก) แล้วใส่คลาส mn-vopen (เปิด) / mn-vclose (ปิด) → keyframes นี้เล่นจากท่ารูปเล็กไปปกติ: หน้าต่างโตจนเต็มพร้อมมุม → 0 ในชิ้นเดียว ไม่มีกรอบการ์ดค้าง ไม่มีการสลับตัวตอนจบ
   ชื่อเมนูในตัวดูรูป (.mn-vnm b) เลื่อน/ย่อจากชื่อในแถว (--no-tf) · ฉาก/ปุ่ม/เฟด/ราคา จางเข้า-ออกอย่างเดียว · ความยาว --fly-t (ตัวตั้งความเร็ว) เส้นโค้ง --ease · ลดการเคลื่อนไหว/โหมดเบา = --fly-t 0s (ท้ายบล็อกนี้) */
.mn-vimg,.mn-vnm b{transform-origin:0 0}
@keyframes mn-vmo{from{transform:var(--mo-tf,none)}to{transform:none}}
@keyframes mn-vmo-out{from{transform:none;opacity:1}to{transform:var(--mo-tf,none);opacity:var(--mo-op,1)}}
@keyframes mn-vwin{from{clip-path:var(--mo-clip,inset(0 round 0))}to{clip-path:inset(0 round 0)}}
@keyframes mn-vwin-out{from{clip-path:inset(0 round 0)}to{clip-path:var(--mo-clip,inset(0 round 0))}}
@keyframes mn-vnm{from{transform:var(--no-tf,none)}to{transform:none}}
@keyframes mn-vnm-out{from{transform:none}to{transform:var(--no-tf,none)}}
@keyframes mn-vfade{from{opacity:0}}
@keyframes mn-vfade-out{to{opacity:0}}
.mn-vwo.mn-vopen .mn-vimg{animation:mn-vmo var(--fly-t) var(--ease) backwards}
.mn-vwo.mn-vopen .mn-vsl{animation:mn-vwin var(--fly-t) var(--ease) backwards}
.mn-vwo.mn-vclose .mn-vimg{animation:mn-vmo-out var(--fly-t) var(--ease) forwards}
.mn-vwo.mn-vclose .mn-vsl{animation:mn-vwin-out var(--fly-t) var(--ease) forwards}
.mn-vwo.mn-vopen .mn-vnm b{animation:mn-vnm var(--fly-t) var(--ease) backwards}
.mn-vwo.mn-vclose .mn-vnm b{animation:mn-vnm-out var(--fly-t) var(--ease) forwards}
.mn-vwo.mn-vopen .mn-vbd{animation:mn-vfade var(--fly-t) var(--ease) backwards}
.mn-vwo.mn-vopen .mn-vbody > :not(.mn-vtrk){animation:mn-vfade calc(var(--fly-t) * .7) var(--ease-std) calc(var(--fly-t) * .3) backwards}   /* ปุ่ม/ชื่อ/เฟดจางเข้าหลังรูปโตไปแล้วส่วนหนึ่ง (ไม่ให้ชื่อซ้อนชื่อในแถวตอนเริ่ม) */
.mn-vwo.mn-vclose .mn-vbd{animation:mn-vfade-out var(--fly-t) var(--ease) forwards}
.mn-vwo.mn-vclose .mn-vbody > :not(.mn-vtrk){animation:mn-vfade-out calc(var(--fly-t) * .6) var(--ease-std) forwards}
@media (prefers-reduced-motion:reduce){.qrbig.mn-vwo,#menuRoot{--fly-t:0s}}
html.lite .qrbig.mn-vwo,html.lite #menuRoot{--fly-t:0s}   /* โทเคนเปิดปิดอ่านจากสองที่นี้เท่านั้น (overlay ตัวดูรูป · รายการเมนูที่จางตามฉาก) → ปิดตรงนี้ ไม่นิยามโทเคนใน :root ของ menu.css (กฎ wo354) */
@media (prefers-reduced-motion:reduce){.mn-vtf,.mn-vtop,.mn-vttl,.mn-vmr,.mn-vwo.dz-back .mn-vbody,.mn-vwo.dz-back .mn-vbd{transition:none}}
html.lite .mn-vwo.dz-back .mn-vbody,html.lite .mn-vwo.dz-back .mn-vbd{transition:none}

/* ---------- CTA ตัวเดียวของแอป (#cta) ตอนอยู่หน้าเมนู (OD-351/352): ข้างในสร้างโดย ctaPaint() (menu-cta.js) · สถานะ calm/ready/wait/done/retry ----------
   สูตรจาก Bridge/specs/CTA-STEPPER-REFERENCE.md: ทุกชั้นเป็นแคปซูล/ชิ้นที่วางปลายทางครั้งเดียว ไม่ขยับ · แตก/รวม = data-split ตัวเดียวบน #cta สั่ง transition ของ transform/opacity เท่านั้น
   (ห้าม animate width/height/gap/grid/radius/สีพื้น/เงา — เทสต์ wo370 ตรวจ) · will-change เฉพาะ 4 ชิ้น · พื้นกรอบ #cta ไม่มีสีเอง: .mn-cap (เรียบ) ใต้ .mn-fill (สีสถานะ) */
.cta.mn-cta{--e-in:cubic-bezier(.05,.7,.1,1);--e-out:cubic-bezier(.3,0,.8,.15);display:block;padding:0;color:#fff}
#cta.mn-cta,#cta.mn-cta.login{background:none}   /* สีพื้นอยู่ที่ .mn-cap/.mn-fill (ชั้น opacity) · id = ชนะ .cta.wait / #cta.login ของ app.css */
.mn-cap,.mn-fill,.mn-glow{position:absolute;inset:0;border-radius:inherit;pointer-events:none}
.mn-cap{background:var(--dg-surface);box-shadow:var(--dg-line);transition:opacity var(--t-3) var(--ease-linear)}   /* แคปซูลเรียบ = CTA ว่าง/เทา: พื้นผิว+กรอบสูตรเดียวกับทุกชิ้น (OD-363) · ชั้นเดียวที่วาดตอนรวม; ตอนแตก ชั้นนี้จางออกพร้อมชิ้นจางเข้า (ไม่วาดซ้อนสองชั้นค้าง → ไม่ดำซ้อน/ไม่มีรอยต่อ) */
.mn-fill{opacity:0;background:var(--red-cta);transition:opacity .45s var(--ease)}   /* เปลี่ยนสถานะ (ว่าง→พร้อม→เสร็จ) = ชั้นสีจาง opacity (ไม่ไล่ background-color) */
.cta.mn-cta.ready .mn-fill,.cta.mn-cta.retry .mn-fill,.cta.mn-cta.done .mn-fill{opacity:1}
.cta.mn-cta.ready.login .mn-fill{background:var(--lineg)}
.cta.mn-cta.done .mn-fill{background:var(--ok)}
.cta.mn-cta.retry .mn-fill{box-shadow:inset 0 0 0 2px rgb(255 255 255 / .35)}
.mn-base{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;gap:10px;padding:0 var(--cta-pad);border-radius:inherit;transition:opacity var(--t-3) var(--ease-linear) var(--t-1)}
.cta.mn-cta.calm,.cta.mn-cta.wait{opacity:1;box-shadow:none;animation:none}
.cta.mn-cta.wait{pointer-events:auto}   /* กดได้ = ตอบกลับด้วยเหตุ (nudge) ไม่ใช่ปุ่มตาย */

.cta.mn-cta.ready{--g:var(--glow-cta);--g-up:var(--glow-cta-up);box-shadow:var(--g);animation:var(--breath);}   /* แดง glow หายใจ (ตะกร้า/Send ของออเดอร์) */
.cta.mn-cta.ready.login{--g:var(--glow-line-strong);--g-up:var(--glow-line-strong-up)}
.cta.mn-cta.done{box-shadow:0 0 24px rgb(var(--ok-rgb) / .45);animation:none}
.cta.mn-cta.retry{animation:none}
.mn-ci .ic{width:26px;height:26px}
.mn-g{display:flex;align-items:center;gap:var(--sp-1)}   /* [ตะกร้า] ป้าย ยอด: ช่องไฟชิดสุดที่ยังอ่านง่าย — ให้ Send ฿9,999.99 อยู่ใน 180px (OD-393) */
.mn-bi{position:relative;flex:none;display:grid;place-items:center;width:28px;height:28px;margin-right:var(--sp-1)}   /* + ป้ายจำนวนยื่นออกขวา 6px → ช่องไฟถึงป้ายรวม 8px · ไม่ทับตัวอักษร (วัดในภาพ WO-380) */
.mn-bi .ic{width:24px;height:24px}
.mn-bi b{position:absolute;top:-4px;right:-6px;min-width:18px;height:18px;padding:0 5px;box-sizing:border-box;border-radius:var(--r-pill);background:#fff;color:#000;font-size:var(--fs-2);font-weight:var(--fw-bold);display:grid;place-items:center;line-height:var(--lh-1)}
.mn-ct{font-variant-numeric:tabular-nums}
.mn-lb{display:inline-flex;align-items:center;gap:var(--sp-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.mn-ck svg{width:var(--ic-5);height:var(--ic-5);display:block}

/* บริการนับจำนวน (แก้ว · จานช้อน) = แตกเป็น [−][n][+][ป้าย]: เลย์เอาต์ปลายทางวางครั้งเดียว — ช่อง 44/44/44/ยืด คงที่ ขอบนอกซ้าย/ขวาของ − กับป้ายติดขอบแถว --cta-split-w ตลอด (แถวกึ่งกลางแคปซูล --cta-w × --cta-h · ล้นข้างละเท่ากัน)
   แตก: ชิ้น − กับ n เลื่อนจากช่อง + (translateX) + ทุกชิ้นจางเข้า · แคปซูล .mn-cap จางออกตามหลัง · แดง (ป้าย + เลข) โผล่เมื่อรูปทรงครบ (OD-331) พร้อมเด้งเล็ก scale · รวม = ย้อนกลับ ออกเร็วกว่าเข้า */
.cta.mn-cta.svc{box-shadow:none;animation:none}
.mn-parts{display:grid;grid-template-columns:var(--tap) var(--tap) var(--tap) minmax(0,1fr);gap:6px;position:absolute;top:4px;left:calc((var(--cta-w) - var(--cta-split-w)) / 2);width:var(--cta-split-w);height:var(--tap)}   /* แถวแตกกว้าง --cta-split-w วางกึ่งกลางแคปซูล (ล้นสองข้างเท่ากัน · ตำแหน่งนิ่ง ไม่ animate) */
.mn-pb,.mn-pn,.mn-ps{position:relative;isolation:isolate;min-width:0;height:100%;border:0;border-radius:var(--r-2xl);padding:0;color:#fff;display:grid;place-items:center;background:var(--dg-surface);box-shadow:var(--dg-line);opacity:0;transform:scale(.92);pointer-events:none;will-change:transform,opacity;transition:transform var(--t-4) var(--e-out),opacity var(--t-3) var(--ease-linear)}
/* ชั้นที่ animate opacity ตอนแตก/รวม ที่แพงตอน raster (glow เบลอ 48px · วงเรืองในแก้วแดง 35px) ต้อง "มีอยู่แล้ว" ก่อนกด: ไม่งั้นทุกครั้งที่กดเบราว์เซอร์สร้างชั้นใหม่ ~8 ชั้น (วัดใน Chrome: +8 ตอนแตก +4 ตอนรวม ทุกครั้ง) แล้วทิ้ง → บน iOS ครั้งแรกๆ ต้องจอง backing store + raster เงาใหญ่กลางแอนิเมชัน = กระตุก จนหน่วยความจำอุ่น (OD-395) · ชั้นเรียบ (.mn-cap/.mn-fill/.mn-base) ไม่แพง ไม่ตรึง · will-change:opacity ล้วน */
.mn-glow,.mn-lg,.mn-pn::after,.mn-ps::after{will-change:opacity}
/* อุ่นเครื่องตอนสร้างปุ่ม (เข้าหน้าเมนู): ชิ้นที่ opacity 0 ไม่ถูกสร้างเป็นชั้น/raster จนกว่าจะโผล่ → กดครั้งแรกต้องสร้าง+raster กลางแอนิเมชัน (วัด: ครั้งที่ 1 สร้างชั้นเกินครั้งหลังๆ) · ที่นี่เล่นกะพริบ .01 ครั้งเดียว .06 วิ ตอนโหนดเกิด (ตาไม่เห็น) ให้ชั้นพร้อมก่อนกด · กฎ animation เฉพาะสถานะ (mn-pop · mn-breath) ทับตัวนี้เอง */
.mn-pb,.mn-pn,.mn-ps,.mn-lg,.mn-glow,.mn-pn::after,.mn-ps::after{animation:mn-warm var(--t-3) var(--ease-linear)}
@keyframes mn-warm{from,to{opacity:.01}}
.mn-parts [data-part="minus"]{--dx:100px}   /* ระยะจากช่องตัวเองไปทับช่อง + */
.mn-parts [data-part="count"]{--dx:50px}
#cta[data-split="0"] [data-part="minus"],#cta[data-split="0"] [data-part="count"]{transform:translateX(var(--dx)) scale(.92)}
#cta[data-split="1"] .mn-pb,#cta[data-split="1"] .mn-pn,#cta[data-split="1"] .mn-ps{opacity:1;transform:none;pointer-events:auto;transition:transform .32s var(--e-in),opacity var(--t-3) var(--ease-linear)}
#cta[data-split="1"] .mn-pn{transition-delay:.03s}
#cta[data-split="1"] .mn-ps{transition-delay:.06s}
#cta[data-split="1"] .mn-cap{opacity:0;transition:opacity var(--t-3) var(--ease-linear) var(--t-1)}
#cta[data-split="1"] .mn-fill{opacity:0;transition:opacity var(--t-2) var(--ease-linear)}
#cta[data-split="1"] .mn-base{opacity:0;transition:opacity var(--t-1) var(--ease-linear)}
.mn-pb svg{width:var(--ic-4);height:var(--ic-4)}
.mn-pn{font-size:var(--fs-9);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums}
.mn-ps{grid-template-columns:minmax(0,1fr);font:inherit;font-size:var(--fs-7);font-weight:var(--fw-semibold);padding:0 var(--sp-3)}
.mn-pn::after,.mn-ps::after{content:"";position:absolute;inset:0;z-index:var(--z-under);border-radius:inherit;opacity:0;transition:opacity var(--t-2) var(--ease-linear)}   /* ชั้นแดงใต้ตัวอักษร: fade opacity ไม่ไล่สีพื้น */
.mn-pn::after{background:var(--sel-glass);box-shadow:var(--sel-glass-rim),var(--sel-drop)}   /* จำนวน = selector แดงแก้ว (กระจกของเจ้าของ ไม่แตะ) */
.mn-ps::after{background:var(--red-cta);transform-origin:100% 50%}   /* ขอบขวาไม่ขยับตอนเด้ง */
#cta[data-split="1"] .mn-pn::after,#cta[data-split="1"] .mn-ps::after{opacity:1;transition:opacity var(--t-3) var(--ease-linear) var(--t-5);animation:mn-pop .22s var(--ease) var(--t-5)}
@keyframes mn-pop{45%{transform:scale(1.06)}}
.mn-pb:disabled svg{opacity:var(--op-3)}
.mn-ps:disabled{color:rgb(255 255 255 / .4)}   /* ปิดใช้งาน = หรี่เฉพาะไอคอน/ตัวอักษร ไม่หรี่พื้น */
/* ป้ายบนชิ้นสุดท้าย: ช่องกว้างคงที่ (--cta-lab-w) ตัดด้วย ... ไม่ย่อฟอนต์ · Glass/Glasses ซ้อนช่องเดียว (กว้างเท่ากัน) สลับด้วย opacity — ไม่ขยับเลย์เอาต์ · ไทยรูปเดียวกันทุกจำนวน = ไม่สลับ (กันตัวหนังสือวูบ) */
.mn-nm{display:grid;justify-items:center;min-width:0;max-width:100%}
.mn-l1,.mn-l2{grid-area:1/1;min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:opacity var(--t-3) var(--ease-linear)}
.mn-l2,.mn-ps[data-pl="1"] .mn-l1{opacity:0}
.mn-ps[data-pl="1"] .mn-l2{opacity:1}
body.th .mn-l2{display:none}
body.th .mn-ps .mn-l1{opacity:1}
/* glow ของปุ่มที่ต้องกด: ชั้นนิ่ง box-shadow ไม่เปลี่ยนตลอดอายุ · หายใจ = opacity ล้วน (ไม่มี contain/overflow ตัด) · .mn-lg = หลังชิ้นป้าย (บริการนับ) · .mn-glow = ทั้งแคปซูล (บริการไม่นับ: .solo) */
.mn-lg{position:absolute;top:0;right:0;bottom:0;width:var(--cta-lab-w);border-radius:var(--r-2xl);box-shadow:var(--glow-cta-up);opacity:0;pointer-events:none;transition:opacity var(--t-2) var(--ease-linear)}
#cta[data-split="1"] .mn-lg{opacity:var(--op-6);transition:opacity var(--t-4) var(--ease-linear) var(--t-5);animation:mn-breath var(--breath-t) var(--ease-inout) .6s infinite}
.mn-glow{box-shadow:var(--glow-cta-up);opacity:0;transition:opacity var(--t-4) var(--ease-linear)}
#cta.mn-cta.solo{box-shadow:none;animation:none}   /* แดงเต็มก้อนแต่เงาอยู่ที่ .mn-glow (ไม่ใช้ box-shadow หายใจของ .ready) */
#cta.solo .mn-glow{opacity:var(--op-6);animation:mn-breath var(--breath-t) var(--ease-inout) infinite}
#cta.solo.busy{color:rgb(255 255 255 / .4)}
#cta.solo.busy .mn-glow{animation-play-state:paused}
@keyframes mn-breath{50%{opacity:1}}
@media (prefers-reduced-motion:reduce){.mn-cap,.mn-fill,.mn-base,.mn-glow,.mn-lg,.mn-pb,.mn-pn,.mn-ps,.mn-pn::after,.mn-ps::after,.mn-l1,.mn-l2{transition:none!important;animation:none!important}}
html.lite :is(.mn-cap,.mn-fill,.mn-base,.mn-glow,.mn-lg,.mn-pb,.mn-pn,.mn-ps,.mn-pn::after,.mn-ps::after,.mn-l1,.mn-l2){transition:none!important;animation:none!important}

@media (prefers-reduced-motion:reduce){.mn-main,.mn-head,.mn-srch,.cap.mn-rail,.mn-hsb,.cap.mn-rail .sel,.cap.mn-rail label,.mn-pc-add,.mn-pc-q,.mn-pc-q button,.mn-tk,.mn-tk::after,.mn-ac .bx,.mn-ph,.mn-sheet,.mn-panel,.mn-order,.mn-rb{transition:none}.mn-sheet.enter .mn-card{animation:none}.mn-sheet.enter .mn-rb,.mn-svc.in .mn-rb{animation:none}.mn-comp{animation:none}.mn-res,.mn-item.hit,.mn-algbd{animation:none}}
html.lite .mn-order{-webkit-mask-image:none;mask-image:none}



/* ---------- ข้อความ 2 บรรทัดข้างหัวข้อตอนย่อ (OD-294): ใส่คลาส mn-sub2 ที่ .hd-sub ของหน้า #menu · บน = ก่อนหน้า (เล็ก เทา) · ล่าง = ล่าสุด (ใหญ่กว่า สีชื่อรายการ) ---------- */
.hd-sub.mn-sub2{position:relative;align-content:center}
.mn-sp{min-height:12.5px;font-size:var(--fs-1);line-height:var(--lh-4);color:var(--mu)}
.mn-sl{font-size:11.5px;line-height:var(--lh-4);font-weight:var(--fw-semibold);color:var(--tx)}
.hd-sub.mn-sub2.mn-rolling .mn-sl{animation:mn-roll var(--t-8) var(--ease)}   /* แอดใหม่: บรรทัดล่างเลื่อนขึ้นมาจากล่าง (transform/opacity ล้วน) */
.hd-sub.mn-sub2.mn-rolling .mn-sp{animation:mn-roll-up var(--t-8) var(--ease)}
@keyframes mn-roll{from{transform:translateY(8px);opacity:0}}
@keyframes mn-roll-up{from{transform:translateY(8px);opacity:.4}}
html.lite .hd-sub.mn-sub2.mn-rolling .mn-sl,html.lite .hd-sub.mn-sub2.mn-rolling .mn-sp{animation:none}
@media (prefers-reduced-motion:reduce){.hd-sub.mn-sub2.mn-rolling .mn-sl,.hd-sub.mn-sub2.mn-rolling .mn-sp{animation:none}}

/* ---------- ไอคอนหมวด (ภาพจำลองรูป + วงกลมหัวหมวด) ---------- */
.mn-g-fork{--m:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M7 3v6a2.5 2.5 0 0 0 5 0V3M9.5 3v18M17 21V3c-2.2 1.5-3 4-3 7.5V14h3'/></svg>")}
.mn-g-cocktail{--m:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M4.5 5h15L12 13.5zM12 13.5V20M8 20h8'/></svg>")}
.mn-g-glass{--m:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M6.5 4h11l-1.4 16.2a1 1 0 0 1-1 .8H8.9a1 1 0 0 1-1-.8zM7 9.5h10'/></svg>")}
.mn-g-shot{--m:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M7.5 5h9l-1 14.2a1 1 0 0 1-1 .8h-5a1 1 0 0 1-1-.8zM7.9 10.5h8.2'/></svg>")}
.mn-g-wine{--m:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M7.5 3.5h9c.4 5-1.2 8-4.5 8s-4.9-3-4.5-8zM12 11.5V20M8.5 20h7'/></svg>")}
.mn-g-bottle{--m:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M10 3h4v4.2l2 3.3V20a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-9.5l2-3.3zM8 14h8'/></svg>")}
.mn-g-mug{--m:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M5 6.5h11V19a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1zM16 9h2.2a1.8 1.8 0 0 1 1.8 1.8v2.4a1.8 1.8 0 0 1-1.8 1.8H16M8.5 10v6M12.5 10v6'/></svg>")}
.mn-g-flame{--m:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3c.8 3.6 5.5 5.4 5.5 10.2a5.5 5.5 0 0 1-11 0c0-2.4 1.2-3.7 2.3-4.8.3 1.5 1.2 2.4 2 2.6C10.6 8.5 10.7 5.6 12 3z'/></svg>")}

/* ---------- ระหว่างรอเมนูจากหลังบ้าน (โครงเปล่าสูงเท่าแถวจริง — ของมาแล้วไม่ขยับ) · โหลดไม่ได้ = ข้อความธรรมดา + ปุ่มลองอีกครั้ง ---------- */
.mn-skel{position:fixed;inset:0;padding:calc(var(--mn-hd) + var(--mn-rb) - 10px) var(--side) 0;overflow:hidden}
.mn-skr{display:grid;grid-template-columns:66px minmax(0,1fr);gap:14px;padding:14px 0;align-items:start;animation:mn-sk 1.4s var(--ease-inout) infinite}
.mn-skr i{display:block;aspect-ratio:3/4;border-radius:var(--r-md);background:var(--tile)}
.mn-skr b{display:block;height:16px;width:60%;border-radius:8px;background:var(--tile);margin-top:var(--sp-1)}
@keyframes mn-sk{50%{opacity:.45}}
.mn-fail{position:fixed;inset:0;display:grid;align-content:center;justify-items:center;gap:14px;padding:0 var(--side);text-align:center;color:var(--mu);font-size:var(--fs-7)}
.mn-fail p{margin:0}
.mn-retry{height:var(--tap);padding:0 22px;border:0;border-radius:var(--r-pill);background:#fff;color:#000;font:inherit;font-size:var(--fs-7);font-weight:var(--fw-semibold)}
html.lite .mn-skr{animation:none}
@media (prefers-reduced-motion:reduce){.mn-skr{animation:none}}
body.mn-open .demo{opacity:0;pointer-events:none}   /* ปุ่ม Demo (เฉพาะ staging) ลอยทับแถวบริการ 5 ปุ่ม — ซ่อนตอนการ์ดเปิด */
body.mn-open #menu > h1{pointer-events:none}   /* การ์ดเปิด: แตะที่หัวข้อหน้า (z15 อยู่เหนือฉากมืด) ทะลุไปที่ฉาก = ปิดการ์ด (OD-330 แตะตรงไหนที่ไม่ใช่การ์ดก็ปิด) */

/* ---------- โน้ตรายบรรทัด (OD-340) · แถวสูง 30px คงที่ทุกสถานะ (ปุ่ม ↔ ช่องพิมพ์ แทนที่กัน ไม่ดันอะไร) · กล่องแตะสูง 44px ด้วย margin ลบ ---------- */
.mn-nr{flex:1 1 0;display:flex;align-items:center;gap:6px;min-width:0;height:var(--tap);margin:0;padding:0;border:0;background:none;box-sizing:border-box;color:var(--mu);font-size:var(--fs-5);font-weight:var(--fw-medium);line-height:var(--lh-5);text-align:left;min-width:0}
.mn-nr svg,.mn-nr .ic{flex:none;width:var(--ic-1);height:var(--ic-1)}
.mn-nr > span:not(.mn-vh){min-width:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;overflow-wrap:break-word}   /* OD-453 โน้ตอยู่ข้างปุ่มจำนวน (พื้นที่แคบ): ≤2 บรรทัด … ตัด · 2×lh-5 < --tap สูงกล่องคงที่ */
.mn-nr.mn-has{color:var(--tx)}
.mn-nr:focus-visible{outline-offset:calc(-1 * var(--focus-off));border-radius:var(--r-xs)}
.mn-nr.mn-ed{display:block;margin-right:calc(-1 * (var(--pcx-w) + var(--sp-3)))}   /* ช่องพิมพ์ = เต็มความกว้างคอลัมน์ (ยื่นทับที่ปุ่มจำนวนที่ซ่อนอยู่) */
.mn-nin{display:block;width:100%;height:36px;box-sizing:border-box;margin:var(--sp-1) 0;padding:0 14px;border:0;border-radius:var(--r-sm);background:rgb(0 0 0 / .3);color:var(--tx);font:inherit;font-size:var(--fs-8);line-height:var(--lh-5)}   /* 16px = iOS Safari ไม่ซูมเข้าตอนโฟกัส */
.mn-nin:focus{box-shadow:inset 0 0 0 1.5px var(--tx)}
.mn-rln{display:flex;align-items:center;gap:6px;margin:-2px 0 0;font-size:var(--fs-5);color:var(--mu)}   /* โน้ตในการ์ดรอบที่ส่งแล้ว: อ่านอย่างเดียว 1 บรรทัด */
.mn-rln .ic{flex:none;width:13px;height:13px}
.mn-rln span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
