/* app.css — ระบบดีไซน์ของแอปทั้งหมด (ไฟล์เดียว)
   ยืนยันแล้ว 2026-10-28: โทน H "กรมท่า + น้ำเงิน" จาก design/mockups-v3.html
   กติกา: ทุกหน้าใช้ค่าจากตัวแปรข้างล่างเท่านั้น ห้ามตั้งสี/ขนาดเองในแต่ละหน้า (ดู CLAUDE.md หัวข้อ 6) */

/* ฟอนต์อยู่ในเว็บเราเอง (public/fonts — ดึงด้วย scripts/get-fonts.mjs) ไม่โหลดจาก Google: ไม่ต้องเปิดการเชื่อมต่อไปอีกเว็บ
   ก่อนหน้าเว็บจะทำงาน + ใช้ได้ตอนเน็ตไม่ดี — Noto Sans Thai เป็นไฟล์ปรับน้ำหนักได้ ไฟล์เดียวครอบ 400–600
   font-display: optional + preload ทั้ง 6 ไฟล์ใน <head> ทุกหน้า (ไฟล์อยู่ใน sw.js) = ไม่เห็นฟอนต์เครื่องแวบแล้วสลับเลย
   (ถ้าเปิดครั้งแรกเน็ตช้ามาก หน้านั้นใช้ฟอนต์เครื่องทั้งหน้า ไม่สลับกลางทาง — หน้าถัดไปได้ฟอนต์แอป) — มีชุดทดสอบ */
@font-face { font-family: "Noto Sans Thai"; font-style: normal; font-weight: 400 600; font-display: optional; src: url("/fonts/NotoSansThai-400-600-thai.woff2") format("woff2"); unicode-range: U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC; }
@font-face { font-family: "Noto Sans Thai"; font-style: normal; font-weight: 400 600; font-display: optional; src: url("/fonts/NotoSansThai-400-600-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Prompt"; font-style: normal; font-weight: 500; font-display: optional; src: url("/fonts/Prompt-500-thai.woff2") format("woff2"); unicode-range: U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC; }
@font-face { font-family: "Prompt"; font-style: normal; font-weight: 500; font-display: optional; src: url("/fonts/Prompt-500-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Prompt"; font-style: normal; font-weight: 600; font-display: optional; src: url("/fonts/Prompt-600-thai.woff2") format("woff2"); unicode-range: U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC; }
@font-face { font-family: "Prompt"; font-style: normal; font-weight: 600; font-display: optional; src: url("/fonts/Prompt-600-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

/* ===================== 1. ตัวแปร (tokens) ===================== */
:root {
  /* สีหลัก */
  --navy: #1B1B39;        /* กรมท่า: ตัวหนังสือหลัก, การ์ดวันนี้, เมนูที่เลือก */
  --blue: #3965FA;        /* น้ำเงิน: ปุ่มหลัก (1 ปุ่มต่อหน้า), ลายเส้น, ปุ่มสินค้าที่เลือก */
  --blue-text: #2A4FD6;   /* น้ำเงินสำหรับตัวหนังสือเล็ก (ลิงก์, ป้าย) ให้อ่านง่ายบนพื้นฟ้า */
  --sky: #99B7FC;         /* ฟ้า: วงแหวน, ป้ายเด่น */
  --pale: #E9EBFF;        /* ฟ้าอ่อนมาก: พื้นหน้า, กล่องสรุป */
  --white: #FFFFFF;       /* การ์ด */
  --gray: #EDEDED;        /* เทาอ่อน: กรอบไอคอน, แถบโหลด */

  /* ตัวหนังสือ + เส้น */
  --text: #1B1B39;
  --text-2: #4E5070;      /* ตัวรอง */
  --text-3: #5F6385;      /* ตัวจาง (เข้มพอสำหรับพื้นฟ้า) */
  --line: #D9DDF5;        /* เส้นขอบ 1px */
  --on-navy: #FFFFFF;
  --on-navy-2: #B3B8DD;   /* ตัวรองบนการ์ดกรมท่า */
  --ring-track: rgba(255, 255, 255, .16);

  /* สถานะ: ต้องมีข้อความกำกับเสมอ ห้ามใช้สีอย่างเดียว */
  --good-fg: #2A4FD6;  --good-bg: #E9EBFF;   /* ขายคล่อง / ดี */
  --warn-fg: #8A5300;  --warn-bg: #FFEFC7;   /* เริ่มช้า / ระวัง / ประมาณ */
  --bad-fg:  #B42328;  --bad-bg:  #FDE4E3;   /* จมทุน / ต้องจัดการ / ผิดพลาด */

  /* ตัวอักษร */
  --font-display: "Prompt", "Noto Sans Thai", Tahoma, sans-serif;          /* หัวข้อ + ตัวเลขเงิน (500/600) */
  --font-body: "Noto Sans Thai", "Leelawadee UI", Tahoma, sans-serif;       /* เนื้อความ (400/500/600) */
  --fs-money-xl: 30px;  /* ตัวเลขเงินใหญ่สุดของหน้า */
  --fs-title: 26px;     /* หัวข้อหน้า, ยอดรวมในกล่องสรุป */
  --fs-ring: 26px;      /* ตัวเลขกลางวงแหวน */
  --fs-h: 18px;         /* หัวข้อย่อย */
  --fs-lead: 17px;      /* ชื่อในรายการ, ปุ่ม */
  --fs-body: 16px;
  --fs-small: 13px;     /* ป้าย, คำอธิบาย */
  --fs-tiny: 12px;      /* เล็กสุดที่อนุญาต */

  /* ระยะห่าง: ใช้เฉพาะค่าเหล่านี้ */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 20px; --s6: 24px; --s7: 32px;

  /* มุมโค้ง */
  --r-card: 24px;   /* การ์ด, แผงตะกร้า */
  --r-tile: 20px;   /* ปุ่มสินค้า */
  --r-box: 16px;    /* กล่องสรุปในการ์ด */
  --r-icon: 12px;   /* กรอบไอคอน */
  --r-pill: 999px;  /* ปุ่ม, ช่องกรอก, ป้าย, เมนูล่าง */

  /* ขนาดแตะ */
  --tap: 48px;      /* ปุ่มเล็กสุด */
  --tap-main: 56px; /* ปุ่มหลัก */

  --ease: 150ms ease;
  --spring: cubic-bezier(.34, 1.56, .64, 1); /* เด้งนิดๆ ตอนจบ (ปุ่มคืนตัว แคปซูลเมนู) */
  --ease-out: cubic-bezier(.2, .8, .2, 1);  /* เร็วแล้วค่อยๆ หยุด (ของลอยขึ้น) */
  --nav-ease: var(--spring); --nav-ms: 240ms; /* แคปซูลเมนูล่าง (เครื่องที่รองรับใช้สปริงจริงข้างล่าง) */
  --nav-h: 84px;    /* เมนูล่าง + ระยะห่าง */
  --page-max: 480px;
}

/* สปริงจริง (ความหน่วง 0.7 เลยไป ~5% แล้วเข้าที่) — เครื่องเก่าที่ไม่รู้จัก linear() ใช้ --spring ข้างบน */
@supports (transition-timing-function: linear(0, 1)) {
  :root { --nav-ease: linear(0, 0.05, 0.169, 0.319, 0.475, 0.62, 0.745, 0.846, 0.923, 0.977, 1.013, 1.034, 1.044, 1.046, 1.043, 1.037, 1.03, 1.023, 1.016, 1.011, 1); --nav-ms: 420ms; }
}

/* ===================== 2. พื้นฐาน ===================== */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--pale); color: var(--text);
  font-family: var(--font-body); font-size: var(--fs-body); line-height: 1.5;
  font-variant-numeric: tabular-nums; -webkit-tap-highlight-color: transparent;
}
h1, h2, h3 { font-family: var(--font-display); font-weight: 600; margin: 0; line-height: 1.25; text-wrap: balance; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
button, a { touch-action: manipulation; } /* แตะรัวๆ แล้วไม่ซูม ไม่หน่วง */
/* กดค้างปุ่ม/ลิงก์ไม่ขึ้นเมนูลิงก์ (iPhone) และไม่เลือกข้อความบนปุ่ม — ช่องกรอก ใบเสร็จ ข้อความทั่วไป ยังเลือก/คัดลอกได้ (ui.js กัน Android) */
button, a { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.ico { width: 22px; height: 22px; flex: none; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; animation: none !important; } }

/* เปลี่ยนหน้า: ไม่มีแอนิเมชัน (ปิด 2026-10-28 — ค่อยๆ จาง 0.15 วิ = ข้อมูลขึ้นครบช้าลงเท่านั้น เป้า ≤ 0.2 วิ)
   ไม่กระพริบขาวเพราะ Chrome ค้างจอเดิมไว้จนหน้าใหม่วาดเสร็จเอง + เมนูล่างวาดในเฟรมแรก (js/nav-boot.js)
   หน้าในเมนูล่างเปิดรอไว้ล่วงหน้า (prerender) แตะแล้วสลับทันที */

/* แตะแล้วตอบสนองทันที: ทุกปุ่ม/แถวที่กดได้เปลี่ยนสีตั้งแต่นิ้วแตะ (ไม่รอเปลี่ยนหน้า) */
a.li:active, button.li:active, .menu-item:active, .cat:active, .preset:active, .btn-ghost:active, .icon-btn:active, .link:active { background-color: var(--pale); }
/* เมนูล่าง: แคปซูลกรมท่าเลื่อนไปช่องที่แตะทันที (.nav-pill + .going — ดูหัวข้อ 9) */

/* ===================== 3. โครงหน้า ===================== */
.app { max-width: var(--page-max); margin: 0 auto; min-height: 100dvh; display: flex; flex-direction: column;
  padding-bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px)); }
.page-head { padding: var(--s5) max(var(--s5), env(safe-area-inset-right, 0px)) var(--s2) max(var(--s5), env(safe-area-inset-left, 0px)); display: grid; }
.page-head .eyebrow { font-size: var(--fs-small); color: var(--text-3); }
.page-head h1 { font-size: var(--fs-title); letter-spacing: -.01em; }
.page-body { padding: var(--s2) max(var(--s4), env(safe-area-inset-right, 0px)) var(--s4) max(var(--s4), env(safe-area-inset-left, 0px));
  display: flex; flex-direction: column; gap: var(--s3); }
.page-body > * { flex-shrink: 0; } /* การ์ดสูงเท่าเนื้อหาเสมอ ไม่ถูกบีบ */
.row { display: flex; align-items: center; justify-content: space-between; gap: var(--s2); min-width: 0; }
.stack { display: grid; gap: var(--s2); }

/* ===================== 4. การ์ด ===================== */
.card { position: relative; background: var(--white); border: 1px solid var(--line); border-radius: var(--r-card);
  padding: var(--s4) var(--s5); display: grid; gap: var(--s3); overflow: hidden; }
.lbl { font-size: var(--fs-small); color: var(--text-2); font-weight: 500; }
.muted { font-size: var(--fs-small); color: var(--text-3); }
.money { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-money-xl); line-height: 1.15; letter-spacing: -.01em; }
.amount { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-lead); }

/* การ์ดวันนี้ (กรมท่า) + ลายเส้นคลื่นมุมขวาล่าง */
.card-hero { background: var(--navy); border-color: var(--navy); color: var(--on-navy); }
.card-hero .lbl, .card-hero .muted { color: var(--on-navy-2); }
.card-hero > *:not(.squiggle) { position: relative; z-index: 1; }
.squiggle { position: absolute; right: -10px; bottom: -14px; width: 96px; height: 58px; pointer-events: none; z-index: 0; opacity: .9; }
.squiggle path { fill: none; stroke: var(--blue); stroke-width: 9; stroke-linecap: round; stroke-linejoin: round; }
.hero-main { display: grid; grid-template-columns: 116px minmax(0, 1fr); gap: var(--s4); align-items: center; }

/* วงแหวน: วาดด้วย SVG <circle class="ring-track"> + <circle class="ring-fill"> */
.ring { position: relative; width: 116px; height: 116px; }
.ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring .ring-track { fill: none; stroke: var(--ring-track); stroke-width: 14; }
.ring .ring-fill { fill: none; stroke: var(--sky); stroke-width: 14; stroke-linecap: round; transition: stroke-dasharray 200ms ease; }
.ring .ring-center { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; line-height: 1.1; }
.ring .ring-center b { font-family: var(--font-display); font-size: var(--fs-ring); font-weight: 600; }
.ring .ring-center span { font-size: var(--fs-small); color: var(--on-navy-2); }

/* กล่องสรุปพื้นฟ้าอ่อนในการ์ด (เช่น เงินจมรวม) */
.summary-box { display: grid; gap: 2px; padding: var(--s3) var(--s4); border-radius: var(--r-box); background: var(--pale); }
.summary-box .total { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-title); line-height: 1.2; }

/* รายการ (ชื่อ + เงิน / รายละเอียด + ป้าย) */
.list { display: grid; }
.list-head { font-size: var(--fs-small); color: var(--text-3); }
.li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px var(--s2); padding: var(--s3) 0; border-top: 1px solid var(--line); }
.li:first-child { border-top: 0; }
.li .name { font-weight: 600; font-size: var(--fs-lead); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.li .amount { text-align: right; }
.li .chip { justify-self: end; }
a.li, button.li { color: inherit; text-decoration: none; background: none; border-left: 0; border-right: 0; border-bottom: 0; text-align: left; width: 100%; font: inherit; }

/* ===================== 5. ป้ายสถานะ ===================== */
.chip { display: inline-flex; align-items: center; gap: var(--s1); flex: none; font-size: var(--fs-small); font-weight: 500; line-height: 1;
  padding: 6px 10px; border-radius: var(--r-pill); white-space: nowrap; }
.chip svg { width: 14px; height: 14px; }
.chip-good { color: var(--good-fg); background: var(--good-bg); }
.chip-warn { color: var(--warn-fg); background: var(--warn-bg); }
.chip-bad  { color: var(--bad-fg);  background: var(--bad-bg); }
.chip-sky  { color: var(--navy);    background: var(--sky); }
.chip-muted { color: var(--text-2); background: var(--gray); } /* สถานะกลางๆ เช่น "ของหมด" */
.chip-estimate { color: var(--warn-fg); background: var(--warn-bg); font-size: var(--fs-tiny); padding: 4px 8px; } /* "ประมาณ" / "ยังไม่รู้ต้นทุน" */

/* ===================== 6. ปุ่ม ===================== */
/* ปุ่มหลัก: แคปซูลน้ำเงิน + วงกลมลูกศรท้ายปุ่ม — 1 ปุ่มต่อหน้า */
.btn { min-height: var(--tap-main); width: 100%; border: 0; border-radius: var(--r-pill); background: var(--blue); color: var(--white);
  font-family: var(--font-display); font-weight: 500; font-size: var(--fs-lead);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2); padding: 6px 6px 6px 22px;
  transition: transform var(--ease), opacity var(--ease); }
.btn:active { transform: scale(.98); }
.btn[disabled], .btn[aria-busy="true"] { opacity: .5; pointer-events: none; }
.btn .btn-dot { width: 44px; height: 44px; border-radius: var(--r-pill); background: var(--pale); color: var(--navy); display: grid; place-items: center; flex: none; }
.btn .btn-dot svg { width: 22px; height: 22px; }
.btn-center { justify-content: center; padding: 6px 22px; }
/* ปุ่มรอง: ขอบบาง พื้นขาว */
.btn-ghost { min-height: var(--tap); width: 100%; border-radius: var(--r-pill); border: 1.5px solid var(--line); background: var(--white); color: var(--text);
  font-weight: 500; display: flex; align-items: center; justify-content: center; gap: var(--s2); padding: 0 var(--s5); transition: transform var(--ease); }
.btn-ghost:active { transform: scale(.98); }
.btn-ghost.danger { color: var(--bad-fg); }
.btn-ghost:disabled { opacity: .45; cursor: not-allowed; }
/* ปุ่มยืนยันที่ลบ/ล้าง/ยกเลิกข้อมูล: แดง ไม่มีลูกศร (ห้ามใช้ปุ่มน้ำเงินหลัก) */
.btn-danger { min-height: var(--tap-main); width: 100%; border: 0; border-radius: var(--r-pill); background: var(--bad-fg); color: var(--white);
  font-family: var(--font-display); font-weight: 500; font-size: var(--fs-lead); display: flex; align-items: center; justify-content: center; padding: 0 var(--s5);
  transition: transform var(--ease); }
.btn-danger:active { transform: scale(.98); }
.btn-danger[disabled], .btn-danger[aria-busy="true"] { opacity: .5; pointer-events: none; }
.link { color: var(--blue-text); font-size: var(--fs-small); font-weight: 500; background: none; border: 0; padding: 0; min-height: 32px; text-decoration: none; }
.icon-btn { width: var(--tap); height: var(--tap); border-radius: var(--r-pill); border: 1px solid var(--line); background: var(--white); display: grid; place-items: center; }

/* ===================== 7. ช่องกรอก ===================== */
.field { display: grid; gap: 6px; }
.field > label { font-size: var(--fs-small); color: var(--text-2); font-weight: 500; }
.input, .select, .textarea { width: 100%; min-height: var(--tap); padding: 0 var(--s4); border-radius: var(--r-pill); border: 1px solid var(--line);
  background: var(--white); color: var(--text); font-size: var(--fs-body); }
.textarea { border-radius: var(--r-box); padding: var(--s3) var(--s4); min-height: 96px; resize: vertical; }
.input:focus, .select:focus, .textarea:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(57, 101, 250, .18); }
.input-money { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-h); }
.field .hint { font-size: var(--fs-small); color: var(--text-3); }
.field .error { font-size: var(--fs-small); color: var(--bad-fg); }
.search { display: flex; align-items: center; gap: var(--s2); min-height: 50px; padding: 0 var(--s4); border-radius: var(--r-pill); border: 1px solid var(--line); background: var(--white); color: var(--text-3); }
.search input { flex: 1; min-width: 0; border: 0; background: none; outline: none; font-size: var(--fs-body); color: var(--text); }

/* แถบหมวด (เลื่อนซ้ายขวา) */
.cats { display: flex; gap: var(--s2); overflow-x: auto; scrollbar-width: none; padding-block: var(--s1); }
.cat { flex: none; min-height: 40px; padding: 0 var(--s4); border-radius: var(--r-pill); border: 1px solid var(--line); background: var(--white); color: var(--text-2); font-size: 14px; }
.cat[aria-pressed="true"] { background: var(--sky); color: var(--navy); border-color: var(--sky); font-weight: 500; }

/* ===================== 8. หน้าขาย ===================== */
.quick { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.tile { position: relative; min-height: 132px; padding: var(--s3); border-radius: var(--r-tile); border: 1.5px solid var(--line); background: var(--white); color: var(--text);
  text-align: left; display: grid; grid-template-rows: auto 1fr auto; gap: var(--s2); transition: transform var(--ease), border-color var(--ease); }
.tile:active { transform: scale(.97); }
.tile[aria-pressed="true"] { border-color: var(--blue); }
.tile .thumb { width: 44px; height: 44px; border-radius: var(--r-icon); display: grid; place-items: center; background: var(--pale); color: var(--navy); }
.tile .thumb.alt { background: var(--gray); }
.tile .name { font-weight: 500; line-height: 1.3; font-size: 15px; }
.tile .price { display: flex; justify-content: space-between; align-items: center; gap: var(--s1); }
.tile .price b { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-lead); }
.tile .left { font-size: var(--fs-tiny); padding: 3px 8px; border-radius: var(--r-pill); background: var(--pale); color: var(--text-2); white-space: nowrap; }
.tile .left.low { background: var(--warn-bg); color: var(--warn-fg); font-weight: 500; }
.badge { position: absolute; top: 10px; right: 10px; min-width: 32px; height: 32px; padding: 0 var(--s2); border-radius: var(--r-pill); background: var(--blue); color: var(--white);
  font-family: var(--font-display); font-weight: 600; font-size: var(--fs-body); display: flex; align-items: center; justify-content: center; }

/* แผงตะกร้า + แถบขาย (ติดล่างจอ เหนือเมนู) */
.cart-dock { position: fixed; left: 0; right: 0; bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px)); z-index: 20;
  max-width: var(--page-max); margin: 0 auto; padding: 0 max(var(--s3), env(safe-area-inset-right, 0px)) 0 max(var(--s3), env(safe-area-inset-left, 0px)); }
.sheet { background: var(--white); border: 1px solid var(--line); border-radius: 28px; padding: 14px; display: grid; gap: 10px; }
.cart-lines { display: grid; gap: var(--s1); max-height: 30vh; overflow-y: auto; }
.cart-line { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: var(--s2); }
.cart-line .name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; }
.cart-line .sum { min-width: 60px; text-align: right; font-weight: 600; }
.stepper { display: flex; align-items: center; gap: 2px; }
.stepper button { width: 40px; height: 40px; border-radius: var(--r-pill); border: 1px solid var(--line); background: var(--pale); display: grid; place-items: center; }
.stepper button svg { width: 16px; height: 16px; }
.stepper output { min-width: 28px; text-align: center; font-weight: 600; }
.sell-bar { display: flex; gap: var(--s2); align-items: center; }
.count-dot { flex: none; width: var(--tap-main); height: var(--tap-main); border-radius: var(--r-pill); background: var(--sky); color: var(--navy); display: grid; place-items: center; line-height: 1; text-align: center; }
.count-dot b { font-family: var(--font-display); font-size: 20px; font-weight: 600; display: block; }
.count-dot small { font-size: 11px; } /* ข้อยกเว้นเดียวที่เล็กกว่า 12px: คำว่า "ชิ้น" ใต้ตัวเลข */

/* แถบ "ขายแล้ว · ยกเลิก" 10 วินาที */
.toast { position: fixed; left: 0; right: 0; top: calc(var(--s3) + env(safe-area-inset-top, 0px)); z-index: 40; max-width: calc(var(--page-max) - 32px); margin: 0 auto;
  width: calc(100% - 32px); min-height: 52px; border-radius: var(--r-pill); background: var(--navy); color: var(--white);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2); padding: 6px 6px 6px 18px; font-size: 15px; }
.toast button { min-height: 40px; padding: 0 var(--s4); border-radius: var(--r-pill); border: 0; background: var(--sky); color: var(--navy); font-weight: 600; }
.toast.error { background: var(--bad-fg); }

/* ===================== 9. เมนูล่าง (แคปซูลลอย 4 ช่อง) ===================== */
.nav { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; max-width: var(--page-max); margin: 0 auto;
  padding: 0 max(var(--s3), env(safe-area-inset-right, 0px)) calc(14px + env(safe-area-inset-bottom, 0px)) max(var(--s3), env(safe-area-inset-left, 0px)); }
.nav-inner { padding: 6px; border-radius: var(--r-pill); background: var(--white); border: 1px solid var(--line); display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s1); }
/* ทุกช่องมีไอคอน + ชื่อกำกับ (ผู้ใช้ทั่วไปดูแค่ไอคอนแล้วไม่รู้ว่าคืออะไร) */
.nav a { min-height: 56px; border-radius: var(--r-pill); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  font-size: var(--fs-small); line-height: 1.2; color: var(--text-2); text-decoration: none; white-space: nowrap; }
.nav a[aria-current="page"] { color: var(--white); font-weight: 500; }
/* แคปซูลช่องที่เลือก = ชิ้นแยกใต้ปุ่ม เลื่อนด้วย transform (--i = ช่องที่ 0–3, ทศนิยมได้ — nav-boot.js เลื่อนต่อจากหน้าก่อน)
   แตะช่องอื่น (.going) = แคปซูลเลื่อนไปทันที ตัวหนังสือช่องเดิมกลับเป็นสีปกติ */
.nav-inner { position: relative; }
.nav-pill { position: absolute; top: 6px; bottom: 6px; left: 6px; width: calc((100% - 12px - 3 * var(--s1)) / 4); border-radius: var(--r-pill);
  background: var(--navy); transform: translateX(calc(var(--i, 0) * (100% + var(--s1)))); transition: transform var(--nav-ms) var(--nav-ease); }
.nav a { position: relative; z-index: 1; transition: color var(--ease); }
.nav a.going { color: var(--white); font-weight: 500; }
.nav-inner:has(a.going) a[aria-current="page"]:not(.going) { color: var(--text-2); font-weight: 400; }
/* ไอคอน: ช่องที่เลือก = แบบทึบ ช่องอื่น = แบบเส้น (วางซ้อนกัน สลับด้วย opacity) · แตะ = ไอคอนเด้ง (nav-boot.js) */
.nav-ico { position: relative; display: grid; width: 22px; height: 22px; }
.nav-ico .ico { grid-area: 1 / 1; transition: opacity var(--ease); }
.nav-ico .fill { opacity: 0; }
.nav a[aria-current="page"] .fill, .nav a.going .fill { opacity: 1; }
.nav a[aria-current="page"] .line, .nav a.going .line { opacity: 0; }
.nav-inner:has(a.going) a[aria-current="page"]:not(.going) .fill { opacity: 0; }
.nav-inner:has(a.going) a[aria-current="page"]:not(.going) .line { opacity: 1; }
/* จุดแดง = มีเรื่องต้องจัดการ (มีข้อความ "มีเรื่องต้องจัดการ" สำหรับโปรแกรมอ่านจอ ไม่ใช้สีอย่างเดียว) */
.nav-dot { position: absolute; top: -3px; right: -5px; width: 10px; height: 10px; border-radius: var(--r-pill); background: var(--bad-fg);
  border: 2px solid var(--white); animation: dot-in 320ms var(--spring) both; }
@keyframes dot-in { from { transform: scale(0); } }

/* ===================== 10. ใบเสร็จ (แบบเรียบ ยืนยัน 2026-10-28 แทนแบบกระดาษยับ) ===================== */
/* กระดาษขาวตั้งตรง เงาบางๆ ตัวเลขชิดขวาเรียงตรงกัน ยอดสุทธิตัวใหญ่สุด — js/receipt.js */
.receipt { width: 100%; max-width: 340px; margin: var(--s2) auto; background: var(--white); color: var(--text); border: 1px solid var(--line);
  border-radius: var(--r-box); padding: var(--s5); display: grid; gap: var(--s3); font-size: 15px; line-height: 1.45;
  box-shadow: 0 1px 2px rgba(27, 27, 57, .06), 0 4px 12px rgba(27, 27, 57, .06); }
.rc-head { text-align: center; display: grid; gap: 2px; }
.rc-shop { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-h); }
.rc-sub { font-size: var(--fs-small); color: var(--text-2); }
.rc-meta { display: flex; justify-content: space-between; gap: var(--s2); flex-wrap: wrap; font-size: var(--fs-small); color: var(--text-2);
  padding-bottom: var(--s3); border-bottom: 1px dashed var(--line); }
.rc-lines { display: grid; gap: var(--s3); }
.rc-line { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 var(--s3); }
.rc-name { grid-column: 1 / -1; font-weight: 500; overflow-wrap: anywhere; }
.rc-calc { color: var(--text-2); font-size: var(--fs-small); }
.rc-amt { text-align: right; }
.rc-sums { display: grid; gap: var(--s1); padding-top: var(--s3); border-top: 1px dashed var(--line); }
.rc-row { display: flex; justify-content: space-between; gap: var(--s3); }
.rc-row span:last-child { text-align: right; }
.rc-total { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-title); align-items: baseline; padding-block: var(--s1); }
.rc-total span:first-child { font-size: var(--fs-body); font-family: var(--font-body); font-weight: 500; }
.rc-foot { text-align: center; color: var(--text-2); font-size: var(--fs-small); padding-top: var(--s3); border-top: 1px dashed var(--line); }
.rc-void { justify-self: center; font-weight: 600; color: var(--bad-fg); border: 1.5px solid currentColor; border-radius: var(--r-pill); padding: 0 var(--s3); }

/* ===================== 11. PIN ===================== */
/* จุดบอกจำนวนหลัก: เว้นห่างจากแป้น / ใส่ผิด = แดง + สั่นไปมา */
.pin-dots { display: flex; justify-content: center; gap: var(--s4); padding: var(--s3) 0 var(--s6); }
.pin-dots i { width: 18px; height: 18px; border-radius: var(--r-pill); border: 2px solid var(--navy); transition: background var(--ease), border-color var(--ease); }
.pin-dots i.on { background: var(--navy); }
.pin-dots.wrong i { border-color: var(--bad-fg); background: var(--bad-fg); }
.pin-dots.wrong { animation: pin-shake 400ms ease; }
@keyframes pin-shake { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-8px); } 40% { transform: translateX(8px); } 60% { transform: translateX(-6px); } 80% { transform: translateX(6px); } }
/* แป้นแบบหน้าปลดล็อกมือถือ: วงกลมไม่เกิน 76px กว้างเต็มการ์ดสูงสุด 300px — จอแคบ (320px) ปุ่มย่อตามช่องเองไม่ล้น */
.pin-pad { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s4) var(--s3); width: 100%; max-width: 300px; margin: 0 auto; justify-items: center; }
.pin-pad button { width: 100%; max-width: 76px; aspect-ratio: 1; padding: 0; border-radius: var(--r-pill); border: 1px solid var(--line); background: var(--white);
  display: grid; place-items: center; font-family: var(--font-display); font-size: var(--fs-money-xl); font-weight: 500; color: var(--text);
  transition: background var(--ease), transform var(--ease); }
.pin-pad button:active, .pin-pad button.pressed { background: var(--sky); transform: scale(.94); }
.pin-pad button:disabled { opacity: .45; }
.pin-pad .key-plain, .pin-pad .key-text { border-color: transparent; background: none; }
.pin-pad .key-text { font-family: var(--font-body); font-size: var(--fs-small); color: var(--blue-text); }
.pin-pad .key-plain svg { width: 28px; height: 28px; }
.pin-pad .blank { width: 100%; }
/* หน้าแป้น: ที่ว่างแบ่ง บน 2 : ล่าง 1 → แป้นอยู่ช่วงล่างค่อนกลางจอ; จอเตี้ยไม่มีที่ว่าง = อยู่ตามปกติ เลื่อนได้ ไม่ล้น */
.pin-page.pad-mode .page-body { flex: 1; }
.pin-page.pad-mode .page-body::before { content: ""; flex: 2 1 0; }
.pin-page.pad-mode .page-body::after { content: ""; flex: 1 1 0; }

/* ===================== 12. สถานะหน้า: โหลด / ว่าง / ผิดพลาด ===================== */
/* กำลังโหลด = แถบเทาแทนข้อมูล (ไม่ใช้วงหมุน) */
.skeleton { display: block; border-radius: var(--r-box); background: linear-gradient(90deg, var(--gray) 0%, #F6F6F6 50%, var(--gray) 100%); background-size: 200% 100%;
  animation: skeleton 1.2s ease-in-out infinite; min-height: 16px; }
.skeleton.card-size { min-height: 140px; border-radius: var(--r-card); }
@keyframes skeleton { from { background-position: 100% 0; } to { background-position: -100% 0; } }
/* ว่าง = บอกว่าต้องทำอะไรต่อ + ปุ่มลัด */
.empty { display: grid; gap: var(--s3); justify-items: center; text-align: center; padding: var(--s6) var(--s4); }
.empty .ico { width: 40px; height: 40px; color: var(--blue); }
.empty p { margin: 0; color: var(--text-2); max-width: 32ch; }
/* ผิดพลาด = บอกว่าเกิดอะไร + ทำยังไงต่อ (ไม่โทษผู้ใช้) */
.alert { display: flex; gap: var(--s2); align-items: flex-start; padding: var(--s3) var(--s4); border-radius: var(--r-box); background: var(--bad-bg); color: var(--bad-fg); font-size: 15px; }
.alert.warn { background: var(--warn-bg); color: var(--warn-fg); }
.alert .ico { width: 20px; height: 20px; margin-top: 2px; }

/* แผ่นเลื่อนขึ้นจากล่าง (ยืนยัน / แก้ราคา / ใส่ส่วนลด) */
.backdrop { position: fixed; inset: 0; z-index: 50; background: rgba(27, 27, 57, .4); }
.modal { position: fixed; left: 0; right: 0; bottom: 0; z-index: 51; max-width: var(--page-max); margin: 0 auto; background: var(--white);
  border-radius: 28px 28px 0 0; padding: var(--s5) var(--s5) calc(var(--s5) + env(safe-area-inset-bottom, 0px)); display: grid; gap: var(--s4); max-height: 90dvh; overflow-y: auto; }
.modal h2 { font-size: var(--fs-h); }

/* ===================== 13. หน้าฟอร์ม / รายละเอียด (D2) ===================== */
/* หัวหน้ามีปุ่มย้อนกลับ */
.page-head.with-back { grid-template-columns: var(--tap) minmax(0, 1fr); column-gap: var(--s3); align-items: center; }
.page-head.with-back .back { grid-row: span 2; }
.page-head.with-back h1 { min-width: 0; overflow-wrap: anywhere; }
.page-head.with-back > :not(.back):not(.menu) { grid-column: 2; }
.page-head.with-menu { grid-template-columns: var(--tap) minmax(0, 1fr) var(--tap); }
.page-head .menu { grid-column: 3; grid-row: 1 / span 2; }

/* ปุ่มหลักติดล่างจอ (เหนือเมนูล่าง หรือชิดล่างถ้าหน้าไม่มีเมนู) — ที่ว่างท้ายหน้า ui.js วัดให้เอง (updateBottomSpace) */
.bottom-cta { position: fixed; left: 0; right: 0; z-index: 25; max-width: var(--page-max); margin: 0 auto;
  bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
  padding: var(--s2) max(var(--s4), env(safe-area-inset-right, 0px)) var(--s2) max(var(--s4), env(safe-area-inset-left, 0px)); }
.bottom-cta.no-nav { bottom: 0; padding-bottom: calc(var(--s3) + env(safe-area-inset-bottom, 0px)); background: linear-gradient(transparent, var(--pale) 30%); }

/* ปุ่มเลือกแบบแบ่งช่อง (ประเภท, ต่อหน่วย/ทั้งล็อต) */
.seg { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--s1); padding: var(--s1); border-radius: var(--r-pill); background: var(--pale); border: 1px solid var(--line); }
.seg button { min-height: 44px; border: 0; border-radius: var(--r-pill); background: none; color: var(--text-2); font-weight: 500; }
.seg button[aria-pressed="true"] { background: var(--navy); color: var(--white); }
.seg button:disabled { cursor: not-allowed; }
.seg button:disabled:not([aria-pressed="true"]) { opacity: .45; }

/* ช่องจำนวนมีปุ่ม − / + */
.qty-input { display: grid; grid-template-columns: var(--tap) minmax(0, 1fr) var(--tap); gap: var(--s2); align-items: center; }
.qty-input .icon-btn svg { width: 20px; height: 20px; }
.qty-input .input { text-align: center; font-family: var(--font-display); font-weight: 600; font-size: var(--fs-h); }
.input-wrap { position: relative; display: flex; align-items: center; }
.input-wrap .input { padding-right: 64px; }
.input-wrap .suffix { position: absolute; right: var(--s4); color: var(--text-3); font-size: var(--fs-small); pointer-events: none; }

/* สวิตช์เปิด/ปิด (ใช้กับ <input type="checkbox" role="switch">) */
.switch-row { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); min-height: var(--tap); cursor: pointer; }
.switch-row input { appearance: none; -webkit-appearance: none; flex: none; width: 52px; height: 32px; border-radius: var(--r-pill); background: var(--line); position: relative; cursor: pointer; transition: background var(--ease); margin: 0; }
.switch-row input::after { content: ""; position: absolute; top: 3px; left: 3px; width: 26px; height: 26px; border-radius: var(--r-pill); background: var(--white); transition: transform var(--ease); }
.switch-row input:checked { background: var(--blue); }
.switch-row input:checked::after { transform: translateX(20px); }

/* ปุ่มลัดหน่วย */
.chips-wrap { display: flex; flex-wrap: wrap; gap: var(--s2); }
.chips-wrap .cat { min-height: 36px; padding: 0 14px; }

/* ตัวเลขใหญ่ของหน้า + คำอธิบาย */
.hero-number { display: grid; gap: 2px; }
.hero-number .money { font-size: var(--fs-money-xl); }
.hero-number .money.bad { color: var(--bad-fg); }
.hero-number .pct { font-size: var(--fs-h); }
.hero-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s4); align-items: start; }

/* แถวคู่ ชื่อ–ค่า ในการ์ดข้อมูล */
.kv { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s2) var(--s3); font-size: 15px; }
.kv dt { color: var(--text-2); }
.kv dd { margin: 0; text-align: right; font-weight: 500; }

/* ประวัติความเคลื่อนไหว */
.moves { display: grid; }
.move { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 var(--s2); padding: 10px 0; border-top: 1px solid var(--line); font-size: 15px; }
.move:first-child { border-top: 0; }
.move .q { font-family: var(--font-display); font-weight: 600; text-align: right; }
.move .q.plus { color: var(--good-fg); }
.move .muted { grid-column: 1 / -1; }

/* กล่องสรุปก่อนบันทึก */
.preview { display: grid; gap: 2px; padding: var(--s3) var(--s4); border-radius: var(--r-box); background: var(--pale); font-size: 15px; }
.preview b { font-family: var(--font-display); font-weight: 600; }

/* ลิงก์ที่หน้าตาเป็นปุ่ม */
a.btn, a.btn-ghost { text-decoration: none; }
.btn-ghost .ico { width: 20px; height: 20px; }
.btn-pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2); }

/* การ์ดฟอร์ม + ส่วนพับ "ตั้งค่าเพิ่มเติม" */
.form-card { gap: var(--s4); }
.form-card h2 { font-size: var(--fs-h); }
.more-fields > summary { min-height: var(--tap); display: flex; align-items: center; gap: var(--s2); color: var(--blue-text); font-weight: 500; cursor: pointer; list-style: none; }
.more-fields > summary::-webkit-details-marker { display: none; }
.more-fields > summary .ico { width: 18px; height: 18px; transition: transform var(--ease); }
.more-fields[open] > summary .ico { transform: rotate(90deg); }
.more-fields .stack { gap: var(--s4); }

/* คำเตือนชื่อซ้ำใต้ช่องชื่อ */
.alert a, .alert button.link { color: inherit; font-weight: 600; text-decoration: underline; min-height: 0; font-size: inherit; }

/* รายการสินค้า: แถวที่ 2 (คงเหลือ + ป้าย) */
/* รายการแบบแน่น (หน้ารายการสินค้า) เห็นได้หลายแถวในจอเดียว */
.list.dense .li { padding: var(--s2) 0; gap: 0 var(--s2); }
.list.dense .li .name { line-height: 1.35; }
.li .sub { font-size: var(--fs-small); color: var(--text-3); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chips { display: flex; flex-wrap: wrap; gap: var(--s1); justify-content: flex-end; }
.list-count { font-size: var(--fs-small); color: var(--text-3); padding-inline: var(--s1); }

/* ===================== 14. หน้าขาย (D3) ===================== */
.tile .price { flex-wrap: wrap; }
.tile .left.over { background: var(--bad-bg); color: var(--bad-fg); font-weight: 500; } /* ใส่ตะกร้าเกินของที่มี */
.cart-line .over { color: var(--bad-fg); font-weight: 500; }
.cart-line button.name { border: 0; background: none; padding: 0; min-height: 40px; text-align: left; font-weight: 500; color: inherit; }
.cart-line button.name small { font-weight: 400; }
.cart-foot { display: flex; justify-content: space-between; gap: var(--s3); flex-wrap: wrap; }
.cart-foot .link { min-height: 40px; }
button.count-dot { border: 0; padding: 0; }
button.count-dot:disabled { opacity: .6; cursor: default; }
.sell-bar .btn { flex: 1; min-width: 0; }
.sell-bar .btn > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.preview .link { justify-self: start; }

/* แผ่นรับเงิน: เงินทอน */
.change { font-size: var(--fs-lead); color: var(--text-2); min-height: 1.5em; }
.change b { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-title); color: var(--text); }
.change.short { color: var(--bad-fg); }

/* ===================== 15. ฟอร์มบอกชัดว่ากรอกครบหรือยัง (js/form.js) ===================== */
.field > label .req { font-weight: 400; color: var(--text-3); }
.field.ok .input { border-color: var(--blue); }
.field.ok > label::after { content: ""; display: inline-block; width: 14px; height: 14px; margin-left: var(--s1); vertical-align: -2px; background: var(--blue-text);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l5 5l10 -10'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l5 5l10 -10'/%3E%3C/svg%3E") center / contain no-repeat; }
.field.bad .input { border-color: var(--bad-fg); box-shadow: 0 0 0 3px rgba(180, 35, 40, .12); }
.field.bad > label { color: var(--bad-fg); }
.input::placeholder { color: var(--text-3); opacity: .75; font-weight: 400; font-family: var(--font-body); font-size: var(--fs-body); }

/* ===================== 16. หน้าหลัก (D4b) ===================== */
.card-hero .link { color: var(--sky); }
.ring .ring-fill.zero { visibility: hidden; } /* 0% ไม่ต้องโชว์จุดกลมของปลายเส้น */
.advice { display: flex; gap: var(--s2); align-items: flex-start; }
.advice .ico { color: var(--blue); margin-top: 2px; }
.steps { margin: 0; padding-left: var(--s5); display: grid; gap: var(--s1); color: var(--text-2); }

/* ===================== 17. ประวัติบิล (D5a) ===================== */
.day-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s2); font-size: var(--fs-body); padding-inline: var(--s1); }
.day-head .muted { font-family: var(--font-body); font-weight: 400; }
.li.is-void .amount { text-decoration: line-through; color: var(--text-3); }
.li .sub .pay { display: inline-flex; align-items: center; gap: 2px; vertical-align: bottom; }
.li .sub .pay .ico { width: 14px; height: 14px; }

/* ===================== 18. เพิ่มเติม + ตั้งค่าร้าน (D5b) ===================== */
/* เมนูรายการ: กรอบไอคอน + ชื่อ/คำอธิบาย + ลูกศร */
.menu-item { display: grid; grid-template-columns: 40px minmax(0, 1fr) auto; align-items: center; gap: var(--s3); min-height: var(--tap);
  padding: var(--s2) 0; border-top: 1px solid var(--line); color: inherit; text-decoration: none; }
.menu-item:first-child { border-top: 0; }
button.menu-item { width: 100%; background: none; border-left: 0; border-right: 0; border-bottom: 0; text-align: left; font: inherit; }
.menu-item .ib { width: 40px; height: 40px; border-radius: var(--r-icon); background: var(--pale); color: var(--navy); display: grid; place-items: center; }
.menu-item b { display: block; font-weight: 600; }
.menu-item .ico:last-child { color: var(--text-3); width: 18px; height: 18px; }
/* ชุดเกณฑ์สำเร็จรูป */
.presets { display: grid; gap: var(--s2); }
.preset { display: grid; gap: 2px; text-align: left; padding: var(--s3) var(--s4); border-radius: var(--r-box); border: 1.5px solid var(--line); background: var(--white); color: inherit; }
.preset b { font-size: var(--fs-lead); }
.preset[aria-pressed="true"] { border-color: var(--blue); background: var(--pale); }
.preset[aria-pressed="true"] b::after { content: " · ใช้อยู่"; font-weight: 500; font-size: var(--fs-small); color: var(--blue-text); }
/* คำถามที่พบบ่อย (หน้าช่วยเหลือ) */
.faq { border-top: 1px solid var(--line); }
.faq:first-child { border-top: 0; }
.faq > summary { min-height: var(--tap); display: flex; align-items: center; gap: var(--s2); font-weight: 600; cursor: pointer; list-style: none; padding-block: var(--s2); }
.faq > summary::-webkit-details-marker { display: none; }
.faq > summary .ico { width: 18px; height: 18px; color: var(--text-3); transition: transform var(--ease); }
.faq[open] > summary .ico { transform: rotate(90deg); }
.faq > .stack { padding: 0 0 var(--s3) var(--s6); }
.faq .link { justify-self: start; }

/* ===================== 16. ความเคลื่อนไหว (กติกา: CLAUDE.md หัวข้อ 6 "ความเคลื่อนไหว") =====================
   ใช้เฉพาะ transform / opacity · ข้อมูลขึ้นจอทันที แล้วขยับไปพร้อมกัน (ไม่รอแอนิเมชันจบ) · ลดการเคลื่อนไหว = ปิดหมด (หัวข้อ 2)
   ของลอยขึ้นตอนเข้าหน้า + ตัวเลขนับขึ้น + แผงตะกร้าเด้ง อยู่ใน js/ui.js (riseIn, countUp, bounce) */

/* ปุ่มยุบนิดๆ ตอนกด (เร็ว 80ms) แล้วเด้งคืน (240ms) */
.btn { transition: transform 240ms var(--spring), opacity var(--ease); }
.tile { transition: transform 240ms var(--spring), border-color var(--ease); }
.btn-ghost, .btn-danger, .icon-btn, .count-dot, .stepper button, .toast button, .cat, .preset, .pin-pad button {
  transition: transform 240ms var(--spring), background-color var(--ease); }
.btn:active, .btn-ghost:active, .btn-danger:active, .tile:active, .icon-btn:active, .count-dot:active,
.stepper button:active, .toast button:active, .cat:active, .preset:active { transform: scale(.96); transition-duration: 80ms; }
a.li, button.li, .menu-item { transition: transform 240ms var(--spring), background-color var(--ease); }
a.li:active, button.li:active, .menu-item:active { transform: scale(.985); transition-duration: 80ms; } /* แถวกว้าง ยุบน้อยกว่า */

/* แผ่นเลื่อนขึ้นจากล่าง: ขึ้นแล้วเด้งเลยไป 8px ก่อนเข้าที่ / ปิด = เลื่อนลง (ui.js ใส่ .closing แล้วค่อยเอาออก)
   box-shadow สีขาวใต้แผ่น = ปิดช่องว่างตอนเด้งเลยขึ้นไป (มองไม่เห็นเป็นเงา) */
.modal { animation: sheet-in 280ms var(--ease-out) both; box-shadow: 0 40px 0 var(--white); }
.backdrop { animation: fade-in 180ms ease both; }
.modal.closing { animation: sheet-out 170ms cubic-bezier(.4, 0, 1, 1) both; pointer-events: none; }
.backdrop.closing { animation: fade-out 170ms ease both; pointer-events: none; }
@keyframes sheet-in { 0% { transform: translateY(100%); } 70% { transform: translateY(-8px); } 100% { transform: none; } }
@keyframes sheet-out { to { transform: translateY(100%); } }
@keyframes fade-in { from { opacity: 0; } }
@keyframes fade-out { to { opacity: 0; } }

/* ===================== 17. ติดตั้งแอปลงมือถือ (D6a — js/install.js) ===================== */
/* แถบชวนบนหน้าหลัก: การ์ดขาว ไอคอนมือถือ + ข้อความ + ปุ่มรอง (ปุ่มหลักของหน้ายังเป็น "ตอนนี้ควรทำอะไร") + ปุ่มปิด */
.install-card { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--s3); align-items: start; }
.install-card .ib { width: 44px; height: 44px; border-radius: var(--r-icon); background: var(--pale); color: var(--navy); display: grid; place-items: center; }
.install-card .stack { gap: 2px; }
.install-card .btn-ghost { grid-column: 1 / -1; }
.install-card .icon-btn { border: 0; color: var(--text-3); margin: -8px -8px 0 0; } /* ยังแตะได้ 48px ตามกติกา แค่ไม่มีกรอบ */
.inline-ico { display: inline-flex; vertical-align: -4px; }
.inline-ico .ico { width: 18px; height: 18px; }

/* ===================== 18. รูปใบเสร็จ (D6b — js/receipt-image.js) ===================== */
/* แผ่น "รูปใบเสร็จ" ของเครื่องที่แชร์รูปไม่ได้: รูปเต็มความกว้างแผ่น (สูงสุดเท่าใบเสร็จบนจอ) กดค้างบันทึกได้ */
.receipt-img { width: 100%; max-width: 340px; justify-self: center; border: 1px solid var(--line); border-radius: var(--r-box); }
