/* Innovalue Store — product.css
 * หน้าสินค้า:
 *   ครึ่งบน  = รูปซ้าย + แผงเลือกตัวเลือก/ราคาขวา (จบในตัว)
 *   ครึ่งล่าง = รายละเอียดเต็มความกว้างจอ ไม่แบ่งซ้ายขวา
 */

.crumb { margin-bottom: 12px; font-size: 14px; color: var(--ink-mute); padding-block: 18px 0; }
.crumb a { color: var(--ink-soft); text-decoration: none; }
.crumb a:hover { color: var(--purple); }

/* ═══════════ แบนเนอร์เต็มจอ (hero) ═══════════
   ★ อัตราส่วน 3:1 ตรงกับไฟล์จริง (เช่น plastic-fan-hero.jpg 1600×533)
     ถ้าใช้ background-size:cover กับกรอบคนละสัดส่วนจากไฟล์ จะโดนตัดขอบบน-ล่าง/ซ้าย-ขวา
     ผิดจากที่ตากล้องตั้งใจจัดองค์ประกอบไว้ — ให้ทีมกราฟิกถ่าย/crop มาที่ 3:1 เป๊ะ
     (ดูตาราง "สเปกรูป" ที่คุยกันไว้ก่อนหน้า) */
.pdp-hero {
  width: 100%;
  aspect-ratio: 3 / 1;
  background-size: cover;
  background-position: center;
  background-color: var(--surface-2);   /* กันจอวาบขาวระหว่างรอรูปโหลด */
}
@media (max-width: 880px) {
  .pdp-hero { aspect-ratio: 16 / 9; }   /* จอแคบ 3:1 จะแบนเกินไป อ่านรายละเอียดในรูปไม่ออก */
}

/* ═══════════ ครึ่งบน ═══════════ */

/* ★ ข้อความไทยไม่มีช่องว่างระหว่างคำเสมอไป (เช่น "แนวตั้ง", "ประชาสัมพันธ์บนโต๊ะและเคาน์เตอร์")
   ถ้าเบราว์เซอร์หาจุดตัดคำไม่ได้ ข้อความจะไหลยาวเป็นบรรทัดเดียวจนดันทั้งหน้าล้นขวา (เกิดจริงบนจอมือถือแคบ)
   บังคับตัดคำได้ทุกตัวอักษรถ้าจำเป็น กันไว้ทั้งหน้าสินค้า — ไม่กระทบ .buybar-name ฯลฯ ที่ตั้ง white-space:nowrap ไว้เฉพาะจุด */
.pdp, .pdp-section, .pdp-cta, .buybar { overflow-wrap: anywhere; }
/* ★ .config-body/#opts/.chips เป็น grid ซ้อนหลายชั้น — grid ลูกแต่ละชั้นมี min-width:auto เป็นค่าเริ่มต้น
   (ไม่ใช่ 0) ถ้าเนื้อหาข้างในกว้างกว่าที่ตั้งใจ มันแอบดันกล่องแม่ให้กว้างตามได้ทุกชั้นที่ไม่ได้ตั้ง min-width:0 ไว้
   กันทุกชั้นในคราวเดียวกันไปเลย กว่าจะไล่ตั้งทีละ class */
.config *, .pdp-section * { min-width: 0; }

.pdp {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 440px;
  gap: 40px;
  align-items: start;
  padding-block: 20px 56px;
}
.pdp > * { min-width: 0; }

/* ── แกลเลอรี ── */
.gallery { position: sticky; top: 84px; }

.gal-main {
  aspect-ratio: 1 / 1;
  max-width: 500px; /* 👈 เพิ่มบรรทัดนี้ (ปรับตัวเลขลด-เพิ่มได้ตามต้องการ) */
  margin: 0 auto;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: #fff;      /* พื้นขาว ไม่แย่งสายตากับตัวรูป */
  padding: 8px;
  display: grid; place-items: center;
  color: var(--ink-mute); font-size: 14px;
  overflow: hidden;
}
.gal-main { position: relative; cursor: zoom-in; }
/* ★ 2026-09-24 — ทำไม position:absolute แทน width/height:100% ธรรมดา:
   .gal-main เป็น display:grid ที่ไม่มี grid-template-rows ชัดเจน (สูงมาจาก aspect-ratio เฉยๆ)
   Chrome ไม่ถือว่าความสูงที่มาจาก aspect-ratio เป็นค่า "แน่นอน (definite)" พอให้ลูก resolve
   height:100% ได้ตรงๆ เลย fallback ไปคำนวณความสูงจาก "ความกว้าง ÷ อัตราส่วนจริงของรูป" แทน
   ★ บั๊กที่เจอจริง (2026-09-24): กรอบ 3:1 (.prep-guide-wrap .gal-main) ที่ padding 8px ทำให้ content-box
   มีอัตราส่วนเพี้ยนจาก 3:1 เล็กน้อย (ไม่ตรงกับรูปเป๊ะ) รูปเลยถูกคำนวณสูงเกิน padding ไปกิน
   ขอบมุมโค้งของกรอบ — เจอง่ายกับรูปทดสอบ (บั๊กจริงมีทุกที่ที่ใช้ .gal-main แต่รูปจริงมีขอบขาวใน
   ตัวไฟล์อยู่แล้วเลยไม่ทันสังเกต) แก้ด้วย position:absolute+inset ตัด percentage-height ของ grid
   ออกไปเลย ให้คำนวณจากกรอบ (top/left/right/bottom) ตรงๆ แทน ไม่ง้อ aspect-ratio ของพ่อ */
.gal-main img { position: absolute; top: 8px; left: 8px; right: 8px; bottom: 8px; width: calc(100% - 16px); height: calc(100% - 16px); object-fit: contain; }

/* ป้ายบอกว่ากดดูรูปเต็มได้ — โผล่ตอนเอาเมาส์ชี้ */
.gal-zoom {
  position: absolute; right: 14px; bottom: 14px;
  background: rgba(36,27,43,.78); color: #fff;
  font-size: 12.5px; padding: 6px 12px; border-radius: 999px;
  opacity: 0; transition: .15s; pointer-events: none;
}
.gal-main:hover .gal-zoom { opacity: 1; }

/* thumbnail ที่กำลังถูกเลือก */
.gal-thumbs div.on { border-color: var(--purple); box-shadow: inset 0 0 0 1px var(--purple); }

/* ★ เดิมเป็น grid 5 คอลัมน์ตายตัว — รูปเยอะตกไปแถว 2 ดูไม่เรียบร้อย รูปน้อยก็ดูโหว่ (2026-09-19)
   เปลี่ยนเป็นแถวเดียวเลื่อนซ้าย-ขวา รูปเล็กขนาดคงที่เสมอ ไม่ว่าจะมีกี่รูปก็ไม่ล้นแถว/ไม่ดูโหว่ */
.gal-thumbs {
  display: flex;
  justify-content: center;           /* รูปน้อยไม่ล้นแถว → อยู่กึ่งกลางแทนที่จะชิดซ้ายโดดๆ */
  gap: 10px;
  margin-top: 10px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  padding-bottom: 4px;               /* กันเงา/scrollbar ชนขอบล่างพอดี */
  scrollbar-width: thin;
}
.gal-thumbs div {
  flex: 0 0 72px;                    /* ขนาดคงที่เสมอ ไม่ยืด/หดตามจำนวนรูป */
  aspect-ratio: 1;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  overflow: hidden;
  cursor: pointer;
  scroll-snap-align: start;
  transition: .15s;
}
.gal-thumbs div:hover { border-color: var(--purple); }
.gal-thumbs img { width: 100%; height: 100%; object-fit: cover; }

/* ── ลิงก์ Template เล็กๆ ใต้รูป ──
   ของเดิมเป็น section ใหญ่ด้านล่างหน้า ย้ายมาตรงนี้เพราะเป็นข้อมูลประกอบ ไม่ใช่พระเอก
   ตัวเต็มจะไปโผล่อีกทีในขั้นตอน "เตรียมไฟล์งาน" ซึ่งเป็นจังหวะที่ลูกค้าต้องใช้จริง */
.tpl-mini {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px;
  margin-top: 14px; padding-top: 14px;
  border-top: 1px dashed var(--line);
  font-size: 13.5px;
}
.tpl-mini-label { color: var(--ink-mute); font-weight: 600; }
.tpl-mini a {
  color: var(--purple); text-decoration: none;
  border-bottom: 1px dotted var(--purple-br);
  padding-bottom: 1px;
}
.tpl-mini a:hover { border-bottom-style: solid; }


/* ── แผงเลือกตัวเลือก ── */
.pdp-title { margin: 0 0 6px; font-size: 32px; line-height: 1.2; }
.pdp-sub { color: var(--ink-soft); margin: 0; font-size: 15px; }

.config {
  position: sticky; top: 84px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: #fff;
  box-shadow: var(--shadow);
  overflow: hidden;
}
.config-body { padding: 22px; display: grid; gap: 20px; }

#opts { display: grid; gap: 20px; }

.optgroup > .lbl { display: flex; align-items: baseline; gap: 8px; margin-bottom: 10px; }
.optgroup .lbl b { font-size: 15.5px; }
.optgroup .lbl span { font-size: 13px; color: var(--ink-mute); margin-left: auto; }

.chips { display: grid; gap: 8px; grid-template-columns: repeat(2, 1fr); }
.chip { position: relative; }
.chip input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.chip span {
  display: block;
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  padding: 11px 13px;
  font-size: 14.5px; line-height: 1.35;
  cursor: pointer; transition: .12s; background: #fff;
}
.chip span small { display: block; color: var(--ink-mute); font-size: 12.5px; }
.chip input:checked + span { border-color: var(--purple); background: var(--purple-lt); box-shadow: inset 0 0 0 1px var(--purple); }
.chip input:focus-visible + span { outline: 2px solid var(--yellow); outline-offset: 2px; }
.chip span:hover { border-color: var(--purple-br); }

.qty-row { display: flex; align-items: center; gap: 10px; }
.qty-row input[type=number] {
  font: inherit; width: 130px; padding: 11px 12px;
  border: 1.5px solid var(--line); border-radius: var(--r-sm); text-align: center;
}
.qty-row input:focus { border-color: var(--purple); outline: none; }

/* ปุ่ม − [จำนวน] + (2026-09-25) — กล่องเดียวกัน ขอบร่วมกัน · ตัดลูกศรขึ้นลงของเบราว์เซอร์ออก (มีปุ่มแล้ว) */
/* ★ 2026-09-28 (เจ้าของขอ) — ยืดเต็มความกว้างกล่องตัวเลือก ปุ่ม −/+ คงขนาด ช่องตัวเลขตรงกลางยืดแทน
   อยากเปลี่ยนความกว้าง: แก้ width ตรงนี้ (เช่น 260px หรือ 60%) · ความกว้างปุ่ม: .qty-stepper button · ความสูง: padding ของ input */
.qty-stepper {
  display: flex; align-items: stretch; width: 100%;
  border: 1.5px solid var(--line); border-radius: var(--r-sm); overflow: hidden; background: #fff;
}
.qty-row .qty-stepper input[type=number] { flex: 1; min-width: 0; }
.qty-stepper:focus-within { border-color: var(--purple); }
.qty-stepper button {
  width: 46px; border: 0; background: var(--surface-2); color: var(--ink);
  font: inherit; font-size: 20px; line-height: 1; cursor: pointer;
}
.qty-stepper button:hover { background: var(--purple-lt); color: var(--purple); }
.qty-stepper button:active { background: var(--purple-br); }
.qty-row .qty-stepper input[type=number] {
  width: 84px; border: 0; border-inline: 1.5px solid var(--line); border-radius: 0;
  font-size: 18px; -moz-appearance: textfield; appearance: textfield;
}
.qty-stepper input::-webkit-outer-spin-button,
.qty-stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.qty-presets { display: flex; gap: 6px; flex-wrap: wrap; }
.qty-presets button {
  font: inherit; font-size: 13.5px; padding: 7px 12px; border-radius: 999px;
  border: 1px solid var(--line); background: #fff; cursor: pointer; transition: .12s;
}
.qty-presets button:hover { border-color: var(--purple-br); background: var(--purple-lt); }
.qty-presets button.on { border-color: var(--purple); background: var(--purple-lt); color: var(--purple); font-weight: 700; }

/* ── กล่องราคา ── */
.pricebox { background: var(--purple-lt); border-top: 1px solid var(--purple-br); padding: 20px 22px 22px; }
.price-line { display: flex; justify-content: space-between; align-items: baseline; font-size: 14.5px; color: var(--ink-soft); }
.price-line + .price-line { margin-top: 6px; }
.price-total { display: flex; justify-content: space-between; align-items: baseline; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--purple-br); }
.price-total span { font-size: 15px; font-weight: 700; }
.price-total b { font-size: 30px; color: var(--purple); line-height: 1; }
.price-total b small { font-size: 15px; font-weight: 600; }
.eta { font-size: 13.5px; color: var(--ink-soft); margin-top: 10px; }
.eta b { color: var(--ink); }
.pricebox .btn { margin-top: 16px; }
.server-note { font-size: 12px; color: var(--ink-mute); margin-top: 10px; text-align: center; }

/* ═══════════ ครึ่งล่าง — เต็มความกว้างจอ ═══════════ */

.pdp-section { padding-block: 64px; border-top: 1px solid var(--line); }
.pdp-section.alt { background: var(--surface-2); }

/* คุมความกว้างข้อความให้อ่านสบาย แต่พื้นหลังยังเต็มจอ */
.wrap-narrow { max-width: 860px; }

.pdp-section-title {
  font-size: 30px;
  margin: 0 0 14px;
  letter-spacing: -.01em;
}
.pdp-section-title::after {
  content: "";
  display: block;
  width: 56px; height: 4px;
  background: var(--yellow);
  border-radius: 2px;
  margin-top: 12px;
}

.pdp-lead {
  color: var(--ink-soft);
  font-size: 16.5px;
  line-height: 1.8;
  margin: 0 0 24px;
  white-space: pre-line;
}

.pdp-section-img {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: #fff;
}

/* ตารางสเปค */
.spec-table { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: 15.5px; }
.spec-table th, .spec-table td {
  text-align: left; padding: 14px 16px;
  border-bottom: 1px solid var(--line); vertical-align: top;
  overflow-wrap: anywhere;
}
.spec-table th { width: 32%; color: var(--ink-soft); font-weight: 600; background: #fff; }
.pdp-section.alt .spec-table th { background: var(--surface-2); }

/* ── แถบปิดท้าย ── */
.pdp-cta {
  background: var(--purple);
  color: #fff;
  text-align: center;
  padding-block: 56px;
  border-top: 4px solid var(--yellow);
}
.pdp-cta h2 { font-size: 28px; margin: 0 0 8px; }
.pdp-cta p { color: rgba(255,255,255,.85); margin: 0 0 24px; }
.pdp-cta-actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.pdp-cta .btn-ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,.5); }
.pdp-cta .btn-ghost:hover { background: rgba(255,255,255,.12); }

/* ═══════════ จอแคบ ═══════════ */
@media (max-width: 980px) {
  .pdp { grid-template-columns: 1fr; gap: 28px; }
  .gallery, .config { position: static; }
  .pdp-title { font-size: 26px; }
  .pdp-section { padding-block: 44px; }
  .pdp-section-title { font-size: 24px; }
}
@media (max-width: 560px) {
  .gal-thumbs div { flex-basis: 60px; }   /* จอแคบลดขนาด thumbnail ลงหน่อย ยังเลื่อนแถวเดียวเหมือนเดิม */
  .spec-table th { width: 42%; }
  .spec-table th, .spec-table td { padding: 11px 12px; font-size: 14px; }
  .qty-row input[type=number] { width: 100%; }
  .qty-stepper { width: 100%; }
  .qty-stepper button { width: 56px; }
  .qty-row .qty-stepper input[type=number] { flex: 1; width: auto; }
  .pdp-lead { font-size: 15.5px; }
}


/* ═══════════ แถบสรุปยอดลอยด้านล่าง (buybar) ═══════════
   ทำไมต้องมี: แผงราคาอยู่ครึ่งบน พอเลื่อนลงมาอ่านรายละเอียดจะไม่เห็นยอดและปุ่มสั่ง
   แถบนี้ลอยติดล่างจอตลอด ทำให้กดสั่งได้ทุกจังหวะโดยไม่ต้องเลื่อนกลับขึ้นไป */

/* เว้นที่ท้ายหน้าไม่ให้แถบลอยไปทับเนื้อหา
   ★ ผูกกับ :has(.buybar) ไม่ใช่ body ลอยๆ — product.css ถูกโหลดในหน้าเตรียมไฟล์ด้วย
     ซึ่งไม่มี buybar ถ้าเว้นที่ไว้จะกลายเป็นช่องว่างเปล่าท้ายหน้า */
body:has(.buybar) { padding-bottom: 86px; }

/* ★ 2026-09-23 — เปลี่ยนจากพื้นขาวเป็นม่วงเข้มของธีม (มติเจ้าของ) ของเดิมพื้นขาวบนหน้าพื้นขาว
   กลืนกันจนแทบไม่รู้ว่ามีแถบอยู่ ทั้งที่เป็นจุดที่ต้องเห็นตลอด (ยอดเงิน + ปุ่มสั่งซื้อ) */
.buybar {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: 50;
  background: var(--purple);
  color: #fff;
  border-top: 1px solid var(--purple-dk);
  box-shadow: 0 -4px 20px rgba(36,27,43,.22);
}
.buybar-inner {
  max-width: var(--wrap); margin-inline: auto;
  padding: 12px 16px;
  display: flex; align-items: center; gap: 16px;
}
.buybar-info { min-width: 0; }
.buybar-name { font-weight: 700; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* ★ บนพื้นม่วงต้องใช้ขาวโปร่ง ไม่ใช่ --ink-mute (เทาเข้ม) ไม่งั้นอ่านแทบไม่ออก */
.buybar-opts { font-size: 13px; color: rgba(255,255,255,.72); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.buybar-total { margin-left: auto; text-align: right; white-space: nowrap; }
.buybar-total small { display: block; font-size: 12px; color: rgba(255,255,255,.72); }
.buybar-total b { font-size: 24px; color: var(--yellow); line-height: 1.1; }
.buybar .btn { flex: none; }
/* ปุ่มรองบนพื้นม่วง — btn-ghost เดิมเป็นตัวหนังสือม่วงบนพื้นขาว มองไม่เห็นบนพื้นม่วง */
.buybar .btn-ghost {
  color: #fff;
  border-color: rgba(255,255,255,.55);
  background: transparent;
}
.buybar .btn-ghost:hover { background: rgba(255,255,255,.12); }

@media (max-width: 560px) {
  .buybar-opts { display: none; }
  .buybar-inner { gap: 10px; padding: 10px 12px; }
  .buybar-total b { font-size: 19px; }
  .buybar .btn { padding: 12px 18px; font-size: 15px; }
  body:has(.buybar) { padding-bottom: 76px; }
}


/* ═══════════ ดูรูปเต็มจอ (lightbox) ═══════════
   สร้างโดย public/js/gallery.js แล้วแปะไว้ท้าย <body> */
body:has(.buybar) .line-fab { bottom: 92px; }   /* ยกปุ่มไลน์ให้พ้น buybar เฉพาะหน้าที่มีแถบจริง */

.lightbox {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(20,14,24,.92);
  display: flex; align-items: center; justify-content: center;
  padding: 40px;
}
.lightbox img {
  max-width: 100%; max-height: 100%;
  object-fit: contain;
  border-radius: var(--r-sm);
  background: #fff;
}
.lightbox-close {
  position: absolute; top: 18px; right: 22px;
  width: 44px; height: 44px;
  font-size: 30px; line-height: 1;
  background: rgba(255,255,255,.14); color: #fff;
  border: 0; border-radius: 999px; cursor: pointer;
}
.lightbox-close:hover { background: rgba(255,255,255,.28); }

.lightbox-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 52px; height: 52px;
  font-size: 34px; line-height: 1;
  background: rgba(255,255,255,.14); color: #fff;
  border: 0; border-radius: 999px; cursor: pointer;
}
.lightbox-nav:hover { background: rgba(255,255,255,.28); }
.lightbox-nav.prev { left: 20px; }
.lightbox-nav.next { right: 20px; }
/* ★ 2026-09-28 — เปิดรูปเดี่ยวจากปุ่มแว่นขยาย (ivStoreOpenLightbox) ไม่มีชุดรูปให้เลื่อน → ซ่อนลูกศร */
.lightbox.single .lightbox-nav { display: none; }

@media (max-width: 560px) {
  .lightbox { padding: 16px; }
  .lightbox-nav { width: 42px; height: 42px; font-size: 26px; }
  .lightbox-nav.prev { left: 8px; }
  .lightbox-nav.next { right: 8px; }
}

/* ═══════════ จุดขายสั้นๆ ═══════════ */
.selling-points {
  list-style: none; padding: 0; margin: 0 0 28px;
  display: grid; gap: 10px;
}
.selling-points li {
  position: relative; padding-left: 30px;
  font-size: 16px; color: var(--ink);
}
.selling-points li::before {
  content: "✓";
  position: absolute; left: 0; top: 1px;
  width: 20px; height: 20px;
  display: grid; place-items: center;
  background: var(--purple); color: #fff;
  border-radius: 999px; font-size: 12px; font-weight: 700;
}

/* ═══════════ มาตรฐานการผลิต — แถวสลับซ้าย-ขวา ═══════════
   ★ HTML เรียง "รูป → ข้อความ" เหมือนกันทุกแถวเสมอ
     การสลับข้างทำด้วย CSS ตรงนี้ที่เดียว (order: 2 ในแถวเลขคู่)
     เหตุผล: ลำดับ DOM คงที่ = โปรแกรมอ่านหน้าจอและปุ่ม Tab เดินถูกทุกแถว
     และถ้าวันหลังเพิ่มแถวที่ 4 มันจะสลับข้างเองโดยไม่ต้องแก้อะไร */

.pres .pres-head { max-width: 860px; margin-bottom: 40px; }

.pres-rows { display: grid; gap: 56px; }

.pres-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 40px;
  align-items: center;
}

.pres-fig { margin: 0; }
.pres-fig img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: #fff;
}

/* แถวเลขคู่ → ดันรูปไปอยู่ขวา ข้อความเลื่อนมาซ้ายเอง */
.pres-row:nth-child(even) .pres-fig { order: 2; }

.pres-eyebrow {
  display: inline-block;
  background: var(--purple-lt); color: var(--purple);
  border: 1px solid var(--purple-br);
  font-size: 12.5px; font-weight: 700;
  padding: 4px 12px; border-radius: 999px;
  margin-bottom: 12px;
}
.pres-text h3 { font-size: 23px; margin: 0 0 12px; line-height: 1.3; }
.pres-text p  { color: var(--ink-soft); font-size: 16px; line-height: 1.8; margin: 0; }

@media (max-width: 880px) {
  .pres-row { grid-template-columns: 1fr; gap: 20px; }
  .pres-row:nth-child(even) .pres-fig { order: 0; }   /* จอแคบ เรียงบน-ล่างเหมือนกันหมด */
  .pres-rows { gap: 44px; }
  .pres-text h3 { font-size: 20px; }
  .selling-points li { font-size: 15px; }
}


/* ═══════════════════════════════════════════════════════════
 * ขั้น ② หน้าเตรียมไฟล์งาน (.wrap-prep)
 *
 * layout: คอลัมน์เดียว กว้าง 880px สรุปราคาอยู่ล่างสุด
 *   มติเจ้าของ 2026-09-16 — ให้ลูกค้าอ่านวิธีทำไฟล์จนจบก่อนเห็นยอดเงิน
 *
 * ★ หน้านี้มีคลาสของตัวเอง (.sum-* .px-* .check-* .need-* .flow-*)
 *   ไม่ยืม .chips/.chip ของหน้าสินค้ามาใช้ เพราะที่นั่นเป็น grid ปุ่มเลือก
 *   ยืมมาแล้วป้ายอ่านอย่างเดียวจะกลายเป็นตาราง 2 คอลัมน์หน้าตาประหลาด
 * ═══════════════════════════════════════════════════════════ */

/* ───────── แถบบอกขั้นตอน (progress bar) ─────────
   ol เพราะลำดับมีความหมายจริง (โปรแกรมอ่านหน้าจอจะอ่านว่า "ข้อ 2 จาก 4")

   ★ 2026-09-23 — เปลี่ยนจากเม็ดยาเรียงกันเป็น progress bar วงกลม+เส้นเชื่อม ให้เห็นภาพ
     "เดินมาถึงไหนแล้ว" ชัดกว่า และใช้ภาษาภาพชุดเดียวกับแถบสถานะฝั่งแอดมิน
     ทุกขั้นที่กดได้จะพ่วงตัวเลือกที่เลือกไว้ไปด้วย (ดู components/customer-steps.blade.php) */
.stepper {
  display: flex; align-items: flex-start;
  list-style: none; margin: 0 0 26px; padding: 0;
  overflow-x: auto;
}
.stepper-step {
  flex: 1 0 84px; min-width: 84px; position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  text-align: center;
}
/* เส้นเชื่อมระหว่างวงกลม — วาดจากกึ่งกลางวงนี้ไปกึ่งกลางวงถัดไป */
.stepper-step:not(:last-child)::after {
  content: ""; position: absolute; top: 15px;
  left: calc(50% + 20px); right: calc(-50% + 20px);
  height: 2px; background: var(--line); z-index: 0;
}
.stepper-step.is-done:not(:last-child)::after { background: var(--purple); }

.stepper-step a { display: contents; text-decoration: none; }
.stepper-dot {
  width: 30px; height: 30px; flex: none; position: relative; z-index: 1;
  display: grid; place-items: center;
  border-radius: 50%; border: 2px solid var(--line);
  background: #fff; color: var(--ink-mute);
  font-size: 13px; font-weight: 800;
  transition: .12s;
}
.stepper-label { font-size: 12.5px; color: var(--ink-mute); line-height: 1.35; }

.stepper-step.is-done .stepper-dot { background: var(--purple); border-color: var(--purple); color: #fff; }
.stepper-step.is-done .stepper-label { color: var(--ink); font-weight: 700; }
.stepper-step.is-on .stepper-dot {
  border-color: var(--purple); color: var(--purple);
  box-shadow: 0 0 0 4px var(--purple-lt);
}
.stepper-step.is-on .stepper-label { color: var(--purple); font-weight: 800; }

/* ขั้นที่กดสลับไปได้ — ต้องรู้สึกกดได้จริง ไม่ใช่แค่ป้ายบอกสถานะ */
.stepper-step.is-clickable { cursor: pointer; }
.stepper-step.is-clickable:hover .stepper-dot { border-color: var(--purple); color: var(--purple); }
.stepper-step.is-clickable:hover .stepper-label { color: var(--purple); text-decoration: underline; }
/* ขั้นที่ยังไปไม่ถึง (เช่น ส่งไฟล์งาน ก่อนจ่ายเงิน) — จางลงให้รู้ว่ายังกดไม่ได้ ไม่ใช่ลิงก์เสีย */
.stepper-step.is-todo:not(.is-clickable) .stepper-dot,
.stepper-step.is-todo:not(.is-clickable) .stepper-label { opacity: .55; }

/* ───────── โครงหน้า ───────── */
.wrap-prep {
  max-width: 1400px;          /* 2026-09-28 (เจ้าของขอ) — ขยายให้เท่ากับ --wrap ทั้งเว็บ (เดิม 1200px)
                                 2026-09-24: ขยายจาก 880 → 960 เพราะรูปสอนเตรียมไฟล์ (.prep-guide-wrap)
                                 บีบแคบจนอ่านรายละเอียดในรูปไม่ออก */
  /* ★ 2026-09-25 — ระยะห่างบนต้องเป็นของ .wrap-prep เอง ห้ามพึ่ง .crumb (padding-block: 18px 0)
     เป็นตัวเว้นระยะแทน เพราะหน้า orders/show.blade.php ไม่มี .crumb (จ่ายเงินแล้ว ไม่มี "ย้อนกลับไปแก้"
     ให้กด) พอไม่มี .crumb เนื้อหาก็ไปติด header ทันที (บั๊กที่เจอจริง) — ใส่ระยะบนตรงนี้แทนให้ทุกหน้า
     ที่ใช้ .wrap-prep มีระยะเท่ากันเสมอ ไม่ว่าจะมี .crumb นำหน้าหรือไม่ */
  padding-block: 20px 64px;
}

/* หัวหน้า */
.prep-hero { margin-bottom: 22px; }
.prep-eyebrow {
  display: inline-block; margin: 0 0 8px;
  background: var(--purple-lt); color: var(--purple);
  border: 1px solid var(--purple-br);
  font-size: 12.5px; font-weight: 700;
  padding: 4px 12px; border-radius: 999px;
}
.prep-hero h1 { margin: 0; font-size: 30px; line-height: 1.25; letter-spacing: -.01em; }
.prep-hero-sub { margin: 8px 0 0; color: var(--ink-soft); font-size: 16px; }

/* ───────── การ์ดเนื้อหา ─────────
   แต่ละบล็อกเป็นการ์ดแยกกัน อ่านทีละเรื่อง */
.prep-block {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 24px 26px;
  margin-bottom: 18px;
}
.prep-block:last-child { margin-bottom: 0; }

/* หัวการ์ด — ขีดเหลืองสั้นๆ นำหน้า ให้กวาดตาเจอง่ายตอนเลื่อนยาวๆ */
.prep-block > h2 {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 16px; font-size: 19px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}
.prep-block > h2::before {
  content: ""; flex: none;
  width: 4px; height: 18px;
  background: var(--yellow); border-radius: 2px;
}

.prep-note { color: var(--ink-soft); font-size: 15.5px; line-height: 1.8; margin: 12px 0 0; }
.prep-note:first-of-type { margin-top: 0; }

/* รูปคู่มือ (เผื่อขอบ ฯลฯ) — ใช้ .gal-main/.gal-zoom ตัวเดียวกับหน้าสินค้า
   เพื่อให้กดดูเต็มจอได้ (data-gallery ใน blade) หน้าตาเลยเหมือนกันทั้งเว็บ
   ไม่ต้องคิดสไตล์ซูมใหม่ ต่างแค่ margin-top ห่างจากข้อความด้านบน */
.prep-guide-wrap { margin-top: 14px; }
.prep-guide-wrap .gal-main { aspect-ratio: 3/1;  max-width: none;}
/* 2026-09-24 — จอแคบ 3:1 จะเตี้ยเกินไป รายละเอียดในรูป (เผื่อขอบ ฯลฯ) อ่านไม่ออก
   ใช้อัตราส่วนเดียวกับ .pdp-hero (สูงขึ้นตอนจอแคบ) */
@media (max-width: 880px) {
  .prep-guide-wrap .gal-main { aspect-ratio: 16/9; }
}

/* ───────── การ์ดสรุปรายการที่สั่ง ─────────
   รูปทรงซ้าย + สเปคเป็นคู่ label/value ขวา
   อ่านง่ายกว่าป้ายลอยๆ ที่ไม่บอกว่าค่าไหนคืออะไร
   ★ คอลัมน์รูปกว้าง 460px — ให้เห็นรูปตัวอย่างสินค้าชัดๆ ใหญ่ๆ ไม่ย่อจนดูไม่ออก
   ★ รูปทรง/ขนาดสินค้าทุกไฟล์ (shape-*.jpg, size-*.jpg) เป็นสี่เหลี่ยมจัตุรัส 1:1
     จึงบังคับ aspect-ratio 1/1 ตรงนี้ ไม่ใช้ 3:2 ของ .gal-main เดิม (จะเกิดขอบขาวข้างรูป) */
.sum-grid { display: grid; grid-template-columns: 460px minmax(0, 1fr); gap: 28px; align-items: start; }
.sum-grid:has(> .sum-specs:only-child) { grid-template-columns: minmax(0, 1fr); }

.sum-fig { margin: 0; }
.sum-fig .gal-main { aspect-ratio: 1 / 1; }
.sum-fig figcaption {
  margin-top: 8px; text-align: center;
  font-size: 13.5px; color: var(--ink-mute);
}

.sum-specs { margin: 0; display: grid; gap: 0; }
.sum-specs > div {
  display: grid; grid-template-columns: 34% minmax(0, 1fr);
  gap: 12px; padding: 10px 0;
  border-bottom: 1px dashed var(--line);
}
.sum-specs > div:first-child { padding-top: 0; }
.sum-specs > div:last-child { border-bottom: 0; padding-bottom: 0; }
.sum-specs dt { color: var(--ink-mute); font-size: 14.5px; }
.sum-specs dd { margin: 0; font-size: 15.5px; font-weight: 600; overflow-wrap: anywhere; }

.sum-foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px;
  margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--line);
}
.sum-eta { font-size: 14.5px; color: var(--ink-soft); }
.sum-eta b { color: var(--ink); }
.sum-edit {
  margin-left: auto; font-size: 14px; font-weight: 600;
  color: var(--purple); text-decoration: none;
  border-bottom: 1px dotted var(--purple-br); padding-bottom: 1px;
}
.sum-edit:hover { border-bottom-style: solid; }

/* ───────── ความละเอียดไฟล์ ─────────
   รายการบรรทัดเดียวต่อแถว label ซ้าย ตัวเลขขวา — ไม่ต้องทำเป็นการ์ดใหญ่
   เน้นให้กวาดตาแล้วรู้เลยว่า "พอ / ไม่พอ" จากสี ไม่ใช่จากขนาดตัวอักษร */
.px-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.px-list li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface-2); padding: 10px 14px;
  font-size: 14.5px;
}
.px-label { color: var(--ink-soft); }
.px-val { margin-left: auto; font-weight: 700; }
.px-sub { font-weight: 500; color: var(--ink-mute); font-size: 13px; }
.px-list li.ok { border-color: #BFE3CE; background: #F3FAF5; }
.px-list li.ok .px-label { color: var(--ok); font-weight: 600; }
.px-list li.warn { border-color: #F0DBA8; background: var(--warn-bg); }
.px-list li.warn .px-label { color: var(--warn); font-weight: 600; }

/* ───────── รายการ Template ─────────
   ป้ายนามสกุลไฟล์อยู่หน้าสุด รู้ตั้งแต่ยังไม่โหลดว่าเปิดด้วยโปรแกรมอะไร */
.tpl-list { display: grid; gap: 8px; margin-top: 14px; }
.tpl-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px; border-radius: var(--r-sm);
  border: 1px solid var(--purple-br); background: var(--purple-lt);
  color: var(--purple); font-weight: 600; font-size: 15px;
  text-decoration: none; transition: .15s;
}
.tpl-item:hover { background: #fff; border-color: var(--purple); box-shadow: var(--shadow); }
.tpl-ext {
  flex: none; min-width: 46px; text-align: center;
  padding: 4px 8px; border-radius: 6px;
  background: var(--purple); color: #fff;
  font-size: 11.5px; font-weight: 700; letter-spacing: .04em;
}
.tpl-name { min-width: 0; overflow-wrap: anywhere; }
.tpl-ico {
  margin-left: auto; flex: none;
  width: 26px; height: 26px;
  display: grid; place-items: center; border-radius: 50%;
  background: #fff; border: 1px solid var(--purple-br);
  font-size: 14px;
}
.tpl-item:hover .tpl-ico { background: var(--purple); color: #fff; border-color: var(--purple); }

/* ───────── รายการ "เตรียมอะไรมาบ้าง" (เคสจ้างออกแบบ) ───────── */
.need-list { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 10px; }
.need-list li {
  position: relative; padding-left: 30px;
  font-size: 15.5px; line-height: 1.7; color: var(--ink-soft);
}
.need-list li b { color: var(--ink); }
.need-list li::before {
  content: "✓"; position: absolute; left: 0; top: 3px;
  width: 20px; height: 20px;
  display: grid; place-items: center;
  background: var(--purple); color: #fff;
  border-radius: 999px; font-size: 12px; font-weight: 700;
}

/* ───────── ลำดับขั้นหลังจากนี้ (เคสจ้างออกแบบ) ───────── */
.flow-list { list-style: none; margin: 0; padding: 0; counter-reset: flow; display: grid; gap: 14px; }
.flow-list li {
  counter-increment: flow;
  position: relative; padding-left: 40px;
  font-size: 15.5px; line-height: 1.7; color: var(--ink-soft);
}
.flow-list li b { color: var(--ink); }
.flow-list li::before {
  content: counter(flow);
  position: absolute; left: 0; top: 0;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--purple-lt); border: 1px solid var(--purple-br);
  color: var(--purple); font-size: 13px; font-weight: 700;
}

/* ───────── บล็อกสรุปราคา (ล่างสุด) ─────────
   ทำให้ต่างจากการ์ดอื่นชัดๆ เพราะเป็นปลายทางของหน้า */
.prep-summary { border-color: var(--purple-br); background: var(--purple-lt); }
.prep-summary > h2 { border-bottom-color: var(--purple-br); }
.prep-summary .pricebox {
  background: #fff; border: 0; border-radius: var(--r-sm);
  padding: 18px 20px;
}
.prep-summary .price-total { border-top-color: var(--line); }
.prep-summary .server-note { text-align: left; margin-top: 12px; }

/* ปุ่มท้ายหน้า — ปุ่มหลักอยู่ซ้าย */
.prep-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 18px; }
.prep-actions-note { margin: 12px 0 0; font-size: 13.5px; color: var(--ink-mute); }

/* ───────── จอแคบ ─────────
   ★ 2026-09-23 — แถบขั้นตอนเป็น progress bar แล้ว (ไม่ใช่เม็ดยา) บนจอแคบแค่ย่อวงกลม/ตัวอักษรลง
     ยังโชว์ครบทั้ง 4 ขั้นเหมือนเดิม เพราะจุดประสงค์คือให้เห็นว่าอยู่ตรงไหนของ 4 ขั้น */
@media (max-width: 880px) {
  .stepper-step { flex: 1 0 68px; min-width: 68px; }
  .stepper-dot { width: 26px; height: 26px; font-size: 12px; }
  .stepper-label { font-size: 11.5px; }
  .stepper-step:not(:last-child)::after { top: 13px; left: calc(50% + 18px); right: calc(-50% + 18px); }

  .prep-hero h1 { font-size: 25px; }
  .prep-block { padding: 18px 16px; }
  /* จอแคบเรียงบน-ล่าง — รูปเต็มความกว้างการ์ดเลย ไม่ย่อเล็ก */
  .sum-grid { grid-template-columns: 1fr; gap: 16px; }
  .prep-actions .btn { width: 100%; text-align: center; }
}
@media (max-width: 560px) {
  .sum-specs > div { grid-template-columns: 1fr; gap: 2px; padding: 9px 0; }
  .sum-specs dd { font-size: 15px; }
  .sum-edit { margin-left: 0; }
  .px-val { margin-left: 0; }
}


/* ══════════════════════════════════════════════════════════
   ขั้น ③ หน้ากรอกข้อมูลผู้สั่ง (.co-*) + หน้าออเดอร์
   ใช้ตัวแปรสี/รัศมีชุดเดียวกับทั้งเว็บ ไม่ตั้งค่าสีดิบใหม่
   ══════════════════════════════════════════════════════════ */

/* กล่องแจ้งเตือน — ใช้ทั้ง error จาก validate และ session('error') */
.alert {
  border-radius: var(--r-sm);
  padding: 14px 16px;
  margin-bottom: 18px;
  font-size: 15px;
  line-height: 1.7;
}
.alert ul { margin: 6px 0 0; padding-left: 20px; }
.alert-error {
  background: var(--warn-bg);
  border: 1px solid var(--warn);
  color: var(--ink);
}
/* ★ 2026-09-23 — "โอนเงินมาแล้ว ไม่ต้องโอนซ้ำ" เขียวไม่ใช่เหลือง เพราะเป็นข่าวดี ไม่ใช่คำเตือน
   ถ้าใช้สีเดียวกับ error ลูกค้าจะตกใจคิดว่ามีอะไรผิดพลาดทั้งที่ทุกอย่างเรียบร้อย */
.alert-paid,
.alert-success {
  background: #EAF7F0;
  border: 1px solid var(--ok);
  color: var(--ink);
}

/* TASK-012 — error ใต้ช่องที่กรอกผิด (<x-field>) ลูกค้าเห็นตรงจุด ไม่ต้องไล่อ่านจากกล่องบนสุด */
.co-field.has-error input,
.co-field.has-error select,
.co-field.has-error textarea { border-color: var(--danger); }
.co-field-error { margin: 6px 0 0; font-size: 13.5px; color: var(--danger); }

/* ดอกจันช่องบังคับ */
.req { color: var(--warn); font-weight: 700; }

/* ── ฟอร์ม ── */
.co-form > h2 { margin-top: 28px; }
.co-form > h2:first-of-type { margin-top: 0; }

.co-field { margin-top: 16px; }
.co-field > label {
  display: block;
  margin-bottom: 6px;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink-soft);
}
.co-field input[type="text"],
.co-field input[type="tel"],
.co-field input[type="email"],
.co-field input[type="date"],
.co-field input[type="time"],
.co-field input[type="number"],
.co-field input[type="url"],
.co-field select,
.co-field textarea {
  width: 100%;
  padding: 11px 13px;
  font: inherit;
  font-size: 15.5px;
  color: var(--ink);
  background: var(--bg);
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  transition: border-color .15s, opacity .15s;
  cursor: pointer;
}

/* ── select ── เอาลูกศร/กรอบเดิมของ OS ออก แล้ววาดลูกศรเองด้วย SVG
   เพื่อให้หน้าตาเหมือนกันทุกเบราว์เซอร์ เข้าธีมเดียวกับช่องอื่น */
.co-field select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 36px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%236b5b95' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 13px center;
}

/* select ที่ยังกดไม่ได้ (รอเลือกช่องก่อนหน้า) — จางลงให้รู้สึกว่า "ยังไม่พร้อม" */
.co-field select:disabled {
  opacity: .5;
  cursor: not-allowed;
  background-color: var(--surface);
}

/* ช่องรหัสไปรษณีย์ — readonly เพราะมาจากตำบลที่เลือกเท่านั้น ไม่ใช่ให้พิมพ์เอง
   ทำให้ดู "ปิด" ชัดเจน ต่างจากช่องที่พิมพ์ได้ปกติ */
.co-field input[readonly] {
  background: var(--surface);
  color: var(--ink-soft);
  cursor: default;
}

/* ไอคอนปฏิทิน/นาฬิกาฝั่งขวา — ของเบราว์เซอร์ (webkit) เท่านั้นที่แต่งได้
   Firefox ไม่มี pseudo-element นี้ ปล่อยเป็นค่าเริ่มต้นไป */
.co-field input[type="date"]::-webkit-calendar-picker-indicator,
.co-field input[type="time"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  padding: 4px;
  border-radius: var(--r-sm);
  transition: background .15s;
}
.co-field input[type="date"]::-webkit-calendar-picker-indicator:hover,
.co-field input[type="time"]::-webkit-calendar-picker-indicator:hover {
  background: var(--purple-lt);
}

.co-field input:focus,
.co-field select:focus,
.co-field textarea:focus {
  outline: none;
  border-color: var(--purple);
}
.co-field textarea { resize: vertical; line-height: 1.6; }

/* 2 ช่องเรียงข้างกันบนจอกว้าง */
.co-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }

/* 3 ช่อง (จังหวัด/อำเภอ/ตำบล) เรียงแถวเดียวกันบนจอกว้าง */
.co-row-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0 16px; }
@media (max-width: 720px) {
  .co-row-3 { grid-template-columns: 1fr; }
}

/* ── เวลาที่โอน (ชั่วโมง : นาที) ──
   บังคับ 24 ชม. เอง ไม่พึ่ง <input type="time"> ของเบราว์เซอร์
   select 2 ตัวสั้นๆ พอสำหรับตัวเลข 2 หลัก ไม่ต้องเต็มความกว้างเหมือนช่องอื่น */
.co-time { display: flex; align-items: center; gap: 6px; }
.co-time select {
  width: 72px;
  flex: none;
  text-align: center;
  padding-right: 30px; /* เผื่อลูกศร SVG ที่ยังใช้ร่วมกับ select ทั่วไป */
}
.co-time-sep { font-size: 18px; font-weight: 700; color: var(--ink-mute); }
.co-time-hint { font-size: 13.5px; color: var(--ink-mute); margin-left: 4px; }

/* ── PDPA — ติ๊กยอมรับเงื่อนไข ──
   วางไว้ล่างสุดของฟอร์ม (ใต้ปุ่มยืนยันสั่งซื้อ) ให้ลูกค้าเห็นทุกอย่างครบก่อนติ๊ก
   ★ ซ่อน <input type="checkbox"> จริงไว้ (แต่ยัง focus/tab ได้ตามปกติ ไม่ใช้ display:none)
     แล้ววาดกล่องเช็คเองด้วย .co-consent-box เพื่อคุมหน้าตาให้เหมือนกันทุกเบราว์เซอร์ */
.co-consent-wrap{
  margin-top: 5px;
  padding: 16px 18px;
     }
.co-consent {
  display: flex; align-items: flex-start; gap: 12px;
  margin-top: 10px;
  /* padding: 16px 18px; */
  /* background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r-md); */
  font-size: 15px;
  /* line-height: 1.65; */
  color: var(--ink-soft);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
/* .co-consent:hover { border-color: var(--purple-br); } */

.co-consent input {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}

.co-consent-box {
  flex: none;
  width: 22px; height: 22px;
  margin-top: 1px;
  border: 2px solid var(--line);
  border-radius: 6px;
  background: var(--bg);
  transition: border-color .15s, background .15s;
  position: relative;
}
/* เครื่องหมายถูก — วาดด้วย border เป็นตัว "L" หมุน 45 องศา ไม่ต้องพึ่งไอคอน/รูปภาพ */
.co-consent-box::after {
  content: "";
  position: absolute;
  left: 6px; top: 2px;
  width: 6px; height: 11px;
  border: solid #fff;
  border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg);
  opacity: 0;
  transition: opacity .1s;
}
.co-consent input:checked + .co-consent-box {
  background: var(--purple);
  border-color: var(--purple);
}
.co-consent input:checked + .co-consent-box::after { opacity: 1; }
.co-consent input:focus-visible + .co-consent-box { outline: 2px solid var(--yellow); outline-offset: 2px; }

/* ── ปุ่มเลือกแบบกลมเล็ก (radio) — ใช้กับ "LINE ID / เบอร์โทรที่ผูก LINE" (2026-09-24)
   ★ หลักเดียวกับ .co-consent: ซ่อน input จริง (ยัง focus/tab ได้) แล้ววาดวงกลมเอง
     เลือกแล้ว = วงนอกสีม่วง + จุดม่วงตรงกลาง */
.co-pick-row { display: flex; flex-wrap: wrap; gap: 8px 22px; margin-bottom: 10px; }
.co-pick {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 15px; color: var(--ink-soft);
  cursor: pointer; position: relative;
}
.co-pick input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.co-pick-dot {
  flex: none;
  width: 18px; height: 18px;
  border: 2px solid var(--line);
  border-radius: 50%;
  background: var(--bg);
  position: relative;
  transition: border-color .15s;
}
.co-pick-dot::after {
  content: "";
  position: absolute; inset: 3px;
  border-radius: 50%;
  background: var(--purple);
  transform: scale(0);
  transition: transform .12s;
}
.co-pick:hover .co-pick-dot { border-color: var(--purple-br); }
.co-pick input:checked + .co-pick-dot { border-color: var(--purple); }
.co-pick input:checked + .co-pick-dot::after { transform: scale(1); }
.co-pick input:checked ~ span:last-child { color: var(--ink); font-weight: 600; }
.co-pick input:focus-visible + .co-pick-dot { outline: 2px solid var(--yellow); outline-offset: 2px; }

/* ยังไม่ติ๊กแล้วพยายามกดสั่งซื้อ — เบราว์เซอร์ยิง 'invalid' มา (ดู script ท้ายหน้า) */
.co-consent.is-invalid {
  border-color: var(--danger);
  background: var(--danger-bg);
}
.co-consent.is-invalid .co-consent-box { border-color: var(--danger); }
.co-consent.is-invalid span:last-child { color: var(--danger); font-weight: 600; }

/* ── สรุปยอด ── */
.co-total {
  margin-top: 24px;
  padding: 18px 20px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.co-total dl { margin: 0; display: grid; gap: 0; }
.co-total dl > div {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 9px 0;
  border-bottom: 1px dashed var(--line);
}
.co-total dl > div:last-child { border-bottom: 0; padding-bottom: 0; }
.co-total dt { color: var(--ink-mute); font-size: 15px; }
.co-total dd { margin: 0; font-size: 15.5px; font-weight: 600; }

.co-grand { margin-top: 4px; padding-top: 14px !important; border-top: 2px solid var(--line); }
.co-grand dt { color: var(--ink) !important; font-size: 16.5px !important; font-weight: 700; }
.co-grand dd { font-size: 22px !important; font-weight: 800; color: var(--purple); }

/* ── กล่องบัญชีธนาคาร ──
   โลโก้วางบนสุด แล้วไล่ ธนาคาร / ชื่อบัญชี / เลขบัญชี ลงมา
   แถวเลขบัญชีเป็นพระเอก: ตัวใหญ่ สีม่วง ปุ่มคัดลอกชิดขวาสุด */
.co-bank {
  padding: 20px 22px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.co-bank-logo {
  display: block;
  width: 108px; height: auto;
  margin-bottom: 16px;
}
.co-bank .sum-specs > div { padding: 12px 0; }
.co-bank .sum-specs dd { font-size: 16px; }

/* ★ dd เป็น flex — span อยู่ซ้าย ปุ่มถูกดันไปขวาสุดด้วย space-between */
.co-bank-no dd {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  font-size: 19px; font-weight: 800;
  color: var(--purple);
  letter-spacing: .04em;
}
/* flex: none กันปุ่มถูกบีบจนตัวหนังสือตกบรรทัดตอนจอแคบ */
.co-copy { flex: none; padding: 8px 18px; font-size: 14px; font-weight: 700; }

@media (max-width: 560px) {
  .co-bank-no dd { font-size: 17px; }
  .co-copy { padding: 7px 14px; font-size: 13px; }
}


@media (max-width: 640px) {
  .co-row { grid-template-columns: 1fr; }
  .co-grand dd { font-size: 20px !important; }
}


/* ══════ กล่องแนบไฟล์ <x-file-drop> (2026-09-24) — ใช้ทั้งสลิปและไฟล์งาน ══════
   เส้นประ = สัญญะสากลว่า "วางของตรงนี้ได้" · <input type=file> โปร่งใสวางทับทั้งกล่อง
   (ลากมาวาง/กดตรงไหนก็เลือกไฟล์ได้ เบราว์เซอร์ทำให้เอง) · JS อยู่ใน public/js/file-drop.js */
.file-drop {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; text-align: center;
  padding: 32px 20px;
  background: var(--bg);
  border: 2px dashed var(--purple-br);
  border-radius: var(--r-md);
  transition: border-color .15s, background .15s;
}
.file-drop-input {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: 0; cursor: pointer;
}
.file-drop:hover,
.file-drop.is-dragover { border-color: var(--purple); background: var(--purple-lt); }
.file-drop.is-dragover { border-style: solid; }

.file-drop-icon { width: 36px; height: 36px; color: var(--purple); }
.file-drop-title { font-size: 16px; color: var(--purple); overflow-wrap: anywhere; }
.file-drop-hint { font-size: 14px; color: var(--ink-mute); }

/* เลือกไฟล์แล้ว — เส้นทึบสีเขียว + รายชื่อไฟล์ ให้เห็นชัดว่าแนบติดแล้ว */
.file-drop.is-filled { border-style: solid; border-color: var(--ok); background: var(--surface); }
.file-drop.is-filled .file-drop-title,
.file-drop.is-filled .file-drop-icon { color: var(--ok); }
.file-drop-list {
  list-style: none; margin: 6px 0 0; padding: 0;
  width: 100%; max-width: 460px;
  display: grid; gap: 4px; font-size: 13.5px;
}
.file-drop-list li {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 6px 10px; border-radius: var(--r-sm); background: var(--bg);
}
.file-drop-list li span:first-child { overflow-wrap: anywhere; text-align: left; }
.file-drop-list li span:last-child { flex: none; color: var(--ink-mute); }

/* ไฟล์ใหญ่เกิน / อัปไม่สำเร็จ */
.file-drop.is-error { border-style: solid; border-color: var(--danger); background: var(--danger-bg); }
.file-drop-error { margin: 4px 0 0; font-size: 13.5px; font-weight: 700; color: var(--danger); }

/* แถบ % ตอนอัปโหลด — ระหว่างอัปห้ามกดเปลี่ยนไฟล์ (input ถูกปิดด้วย pointer-events) */
.file-drop-progress { width: 100%; max-width: 460px; display: grid; gap: 6px; margin-top: 8px; }
.file-drop-bar { height: 10px; border-radius: 999px; background: var(--line); overflow: hidden; }
.file-drop-bar span { display: block; height: 100%; width: 0; background: var(--purple); transition: width .2s; }
.file-drop-percent { font-size: 13.5px; font-weight: 700; color: var(--purple); }
.is-uploading .file-drop-input { pointer-events: none; }

@media (max-width: 560px) {
  .file-drop { padding: 24px 16px; }
  .file-drop-title { font-size: 15px; }
  .file-drop-hint { font-size: 13px; }
}

/* ══════ EPIC-013 — กล่องบอกผลตรวจสลิป (checkout) ══════
   ใช้สีเดียวกับระบบ: เขียว = ผ่าน · เหลือง = ต้องกรอกเอง · แดง = สลิปใช้ไม่ได้ */
.slip-check {
  display: flex; align-items: center; gap: 8px;
  margin: 12px 0 4px;
  padding: 12px 16px;
  border: 1px solid var(--purple-br);
  border-radius: var(--r-md);
  font-size: 14.5px;
  line-height: 1.6;
}
.slip-check-text { font-weight: 600; overflow-wrap: anywhere; }

.slip-check.is-checking { background: var(--purple-lt); border-color: var(--purple-br); color: var(--purple); }
.slip-check.is-ok       { background: #E8F6EE; border-color: #A8DCBE; color: var(--ok); }
.slip-check.is-warn     { background: var(--warn-bg); border-color: #F0DBA8; color: var(--warn); }
.slip-check.is-error    { background: #FDECEC; border-color: #F3C2C2; color: #B42318; }

/* ★ ตัวหมุนบอกว่า "กำลังตรวจสอบอยู่" — ของเดิมมีแค่ข้อความนิ่งๆ ดูเหมือนค้าง (2026-09-22)
   โผล่เฉพาะตอน .is-checking เท่านั้น ตัวอื่นไม่ต้องมี (ตรวจเสร็จแล้วไม่ต้องหมุนต่อ) */
.slip-spinner {
  flex: none;
  width: 16px; height: 16px;
  border: 2px solid rgba(101, 47, 128, .25);
  border-top-color: var(--purple);
  border-radius: 50%;
  animation: slip-spin .7s linear infinite;
}
@keyframes slip-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .slip-spinner { animation: none; }
}

/* ★ ปุ่มยืนยันสั่งซื้อเด้งเรียกความสนใจตอนสลิปตรวจผ่านแล้ว (2026-09-22)
   เด้ง 3 รอบแล้วหยุดเอง (animation-iteration-count) ไม่รบกวนตลอดไป — แค่ชี้ว่า "ขั้นต่อไปคือปุ่มนี้" */
#co-submit.is-pulse { animation: co-submit-pulse .6s ease-in-out 3; }
@keyframes co-submit-pulse {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(253, 202, 0, .55); }
  50%      { transform: scale(1.045); box-shadow: 0 0 0 10px rgba(253, 202, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  #co-submit.is-pulse { animation: none; }
}

/* ช่องที่ระบบกรอกให้จากสลิป — กันแก้ แต่ยังส่งค่าไปกับฟอร์ม
   (ไม่ใช้ disabled เพราะ input/select ที่ disabled จะไม่ถูกส่งไปกับฟอร์มเลย) */
.co-form .is-locked {
  background: var(--bg);
  color: var(--ink-mute);
  border-color: var(--purple-br);
  pointer-events: none;
}

/* ── ป็อปอัพชำระเงิน — ยังเป็น <form> เดียวกับข้อมูลผู้สั่งทั้งหมด (2026-09-22)
   แค่ซ่อน/โชว์ด้วย CSS+JS ให้ดูเหมือนคนละขั้นตอน ไม่ใช่แยกหน้าจริง
   ★ ตั้งใจไม่ให้กดพื้นหลังเพื่อปิด (backdrop ไม่มี click listener) — มีแค่ปุ่ม "◀ ย้อนกลับ"
   ในป็อปอัพเท่านั้นที่ปิดได้ กันลูกค้ากดพลาดแล้วข้อมูลที่กรอกในป็อปอัพหาย */
.pay-modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(36, 27, 43, .6);
  z-index: 1000;
}
.pay-modal {
  position: fixed;
  top: 4%; bottom: 4%; left: 3%; right: 3%;
  z-index: 1001;
  background: var(--surface);
  border-radius: 20px;
  box-shadow: 0 24px 64px rgba(36, 27, 43, .4);
  display: flex;
  flex-direction: column;
  /* ★ overflow:hidden ตรงนี้ (ไม่ใช่ overflow-y:auto) — ตัวที่เลื่อนได้จริงคือ .pay-modal-scroll
  ข้างใน ไม่งั้น scrollbar ของเบราว์เซอร์ (แท่งเหลี่ยมตรงๆ) จะไปทับมุมโค้งขวาบน/ขวาล่างของกล่องนี้
  ทำให้ขอบดูไม่สมดุล (2026-09-22) */
  overflow: hidden;
}
.pay-modal-head {
  flex: none;
  display: flex; align-items: center; gap: 14px;
  padding: 16px 24px 12px;
  border-bottom: 1px solid var(--line);
}
.pay-modal-head h2 { margin: 0; font-size: 18px; }
.pay-modal-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 18px 24px 24px;
}
/* ★ ล็อกไม่ให้พื้นหลังเลื่อนตามตอนป็อปอัพเปิดอยู่ (ผูก class นี้ที่ <html> และ <body> ด้วย JS)
   ต้องใส่ทั้งคู่ — ตัวที่เบราว์เซอร์ใช้เลื่อนจริง (scrolling element) คือ <html> ไม่ใช่ <body>
   ถ้าใส่แค่ body พอเบราว์เซอร์เจอฟิลด์ required ที่ยังไม่กรอก (เช่น checkbox ยอมรับเงื่อนไข)
   แล้วพยายาม scrollIntoView ให้เห็น มันจะเลื่อน <html> แทน ทะลุ overflow:hidden ของ body ไปได้
   หน้าเว็บที่ซ่อนอยู่หลังป็อปอัพ (position:fixed) เลยเลื่อนเห็นพื้นที่ว่างขาวโล่งด้านล่าง */
html.pay-modal-open,
body.pay-modal-open { overflow: hidden; }

@media (max-width: 640px) {
  .pay-modal { top: 2%; bottom: 2%; left: 2%; right: 2%; }
  .pay-modal-head { padding: 14px 16px 10px; }
  .pay-modal-scroll { padding: 14px 16px 16px; }
}

/* ─────────────────────────────────────────────
   TASK-067 (2026-09-28) — แถบ "ออเดอร์นี้มีการอัปเดต" หน้าลูกค้า
   ไม่ auto-reload เอง (กันไฟล์ที่กำลังเลือกจะแนบหาย) — แค่บอกแล้วให้ลูกค้ากดเอง
   ───────────────────────────────────────────── */
.live-update-bar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: 18px; padding: 14px 18px;
  background: var(--purple-lt); border: 1.5px solid var(--purple-br); border-radius: var(--r-md);
}
.live-update-bar b { font-size: 15px; }
.live-update-bar .btn { margin-left: auto; }
.live-update-dot {
  width: 10px; height: 10px; border-radius: 50%; background: var(--purple); flex: none;
  animation: live-update-pulse 1.4s ease-in-out infinite;
}
@keyframes live-update-pulse {
  0%, 100% { opacity: .4; }
  50% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .live-update-dot { animation: none; }
}

/* ─────────────────────────────────────────────
   2026-09-28 — วิธีเลือกจำนวนแบบ "ทั้งสองแบบ" (ปุ่มขั้น + กรอกเอง)
   ───────────────────────────────────────────── */
.qty-row-both { margin-top: 10px; flex-wrap: wrap; }
.qty-tier-note { font-size: 13px; color: var(--ink-soft); }
.qty-next-tier {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 10px; padding: 10px 14px;
  background: var(--warn-bg); border: 1px solid #F0DFAF; border-radius: var(--r-sm);
  font-size: 14px; color: var(--warn);
}
.qty-next-tier .btn { padding: 7px 14px; font-size: 13.5px; margin-left: auto; }

/* ─────────────────────────────────────────────
   2026-09-28 — ช่องโค้ดส่วนลด (หน้าตาอย่างเดียว ยังไม่มีระบบหลังบ้าน)
   ───────────────────────────────────────────── */
.promo-row { display: flex; gap: 8px; }
.promo-row input {
  flex: 1; min-width: 0; font: inherit; padding: 11px 14px;
  border: 1.5px solid var(--line); border-radius: var(--r-sm); background: #fff;
}
.promo-row input:focus { border-color: var(--purple); outline: none; }
.promo-row .btn { padding: 11px 18px; border-radius: var(--r-sm); flex: none; }
.promo-msg { margin: 8px 0 0; font-size: 13px; color: var(--warn); }

/* ─────────────────────────────────────────────
   2026-09-28 — รูปตัวอย่างของตัวเลือกที่เลือก (1:1 เต็มความกว้างกลุ่ม · เหนือปุ่มตัวเลือก)
   พื้นเทาอ่อน + ขอบมน · รูปวางกลางแบบ contain (รูปไม่โดนตัด ถ้าแอดมินอัปมาไม่ใช่ 1:1)
   ───────────────────────────────────────────── */
.opt-preview {
  aspect-ratio: 1 / 1; width: 50%; margin-bottom: 10px;
  align-self: center; justify-self: center;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-md);
  overflow: hidden; display: grid; place-items: center;
  animation: opt-preview-in .2s ease;
}
.opt-preview[hidden] { display: none; }
.opt-preview img { width: 100%; height: 100%; object-fit: contain; }
@keyframes opt-preview-in {
  from { opacity: 0; transform: scale(.98); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .opt-preview { animation: none; } }

/* ─────────────────────────────────────────────
   2026-09-28 — การ์ดตัวเลือกมีรูป เลื่อนแนวนอนได้ (display_style = cards)
   ใช้กับกลุ่มที่มีรูปให้เทียบและอาจมีตัวเลือกเยอะในอนาคต (แอดมินสลับได้ต่อกลุ่ม ไม่ผูกกับชื่อกลุ่ม)
   ───────────────────────────────────────────── */
/* ★ 2026-09-28 (มติเจ้าของ รอบ 2) — ปิดไว้ก่อนเป็นกล่องสรุป กดแล้วค่อยขยายเป็นตาราง (ไม่ใช่โชว์ตลอด) */
.opt-picker-summary {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 12px; border: 1.5px solid var(--line); border-radius: var(--r-sm);
  background: #fff; font: inherit; font-size: 14.5px; font-weight: 600; color: var(--ink);
  cursor: pointer; text-align: left;
}
.opt-picker-summary:hover { border-color: var(--purple-br); }
.opt-picker-summary[aria-expanded="true"] { border-color: var(--purple); }
.opt-picker-thumb {
  width: 36px; height: 36px; flex: none; border-radius: var(--r-sm); overflow: hidden;
  background: var(--surface-2);
}
.opt-picker-thumb img { width: 100%; height: 100%; object-fit: cover; }
.opt-picker-label { flex: 1; }
.opt-picker-chevron {
  width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; color: var(--ink-mute); transition: transform .15s;
}
.opt-picker-summary[aria-expanded="true"] .opt-picker-chevron { transform: rotate(180deg); }

/* ตารางการ์ด — ขยายลงมาใต้กล่องสรุปตอนกด (grid ไม่ใช่เลื่อนแนวนอน) */
.opt-cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px;
  margin-top: 10px;
}
.opt-cards[hidden] { display: none; }
.opt-card { position: relative; }
.opt-card input { position: absolute; opacity: 0; inset: 0; cursor: pointer; margin: 0; }
.opt-card-body {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  height: 100%; padding: 8px; text-align: center;
  border: 1.5px solid var(--line); border-radius: var(--r-md); background: #fff;
}
/* ★ 2026-09-28 — ตัวเลือกไม่มีรูป: ไม่มี .opt-card-thumb ให้ยึดความสูง → จัดกลางแนวตั้งแทน
   กันการ์ดในแถวเดียวกันสูงไม่เท่ากันเวลาผสมกับใบที่มีรูป (grid แถวเดียวกันสูงเท่ากันอยู่แล้ว แค่เนื้อในไม่ล้นบน) */
.opt-card-body.no-thumb { justify-content: center; min-height: 72px; }
.opt-card-thumb {
  width: 100%; aspect-ratio: 1 / 1; border-radius: var(--r-sm); overflow: hidden;
  background: var(--surface-2);
}
.opt-card-thumb img { width: 100%; height: 100%; object-fit: cover; }
.opt-card-label { font-size: 13px; font-weight: 700; line-height: 1.3; }
.opt-card-note { display: block; color: var(--ink-mute); font-size: 11px; }
.opt-card-check {
  position: absolute; top: 6px; right: 6px; width: 20px; height: 20px; border-radius: 999px;
  background: var(--purple); color: #fff; font-size: 12px; line-height: 1;
  display: none; align-items: center; justify-content: center;
}
.opt-card input:checked + .opt-card-body {
  border-color: var(--purple); background: var(--purple-lt); box-shadow: inset 0 0 0 1px var(--purple);
}
.opt-card input:checked + .opt-card-body .opt-card-check { display: flex; }
.opt-card input:focus-visible + .opt-card-body { outline: 2px solid var(--yellow); outline-offset: 2px; }
.opt-card-body:hover { border-color: var(--purple-br); }

@media (max-width: 640px) {
  .opt-card { flex-basis: 92px; }
}

/* ─────────────────────────────────────────────
   2026-09-28 — ปุ่มแว่นขยายมุมขวาล่างบนรูปตัวเลือก (การ์ด + กล่องรูปใหญ่) → ดูรูปเต็มจอ
   พื้นมืดโปร่งแสง ให้เห็นชัดทั้งบนรูปสว่างและรูปมืด · อยู่เหนือรูปแต่ไม่บังรูปเยอะ
   ───────────────────────────────────────────── */
.opt-card-thumb, .opt-preview { position: relative; }
.opt-zoom-btn {
  position: absolute; right: 6px; bottom: 6px; z-index: 2;
  width: 28px; height: 28px; padding: 0; border: 0; border-radius: 999px;
  background: rgba(36, 27, 43, 0.067); color: #fff; cursor: zoom-in;
  display: grid; place-items: center;
  transition: background .15s, transform .15s;
}
.opt-zoom-btn:hover { background: var(--purple); transform: scale(1.08); }
.opt-zoom-btn:focus-visible { outline: 2px solid var(--yellow); outline-offset: 2px; }
.opt-zoom-btn svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}
/* กล่องรูปใหญ่ — ปุ่มใหญ่ขึ้นนิดตามขนาดกล่อง */
.opt-preview .opt-zoom-btn { width: 34px; height: 34px; right: 10px; bottom: 10px; }
.opt-preview .opt-zoom-btn svg { width: 18px; height: 18px; }
