/* ============================================================
   WOOCOMMERCE BRIDGE

   ไฟล์นี้ไม่ได้อยู่ใน design เดิม — สร้างขึ้นเพื่อเชื่อมส่วนประกอบ
   ที่ WooCommerce สร้างเองกับชุดสีของ design

   design ครอบคลุมเฉพาะ markup ที่วาดไว้ แต่ WooCommerce ยังออก
   ส่วนประกอบอื่นอีก (แจ้งเตือน, ตารางค่าจัดส่ง, ข้อความ error)
   ที่ต้องมีสีให้เข้ากับพื้นหลังเข้ม

   โหลดหลัง styles.css เสมอ (ดู inc/enqueue.php)
   ============================================================ */

/* ── ปิดกรอบสีฟ้าที่เด้งตอนแตะบนมือถือ (ผู้ใช้สั่ง 2026-09-13) ──
   Chrome บน Android ใส่ tap highlight สีฟ้าโปร่งให้ทุกลิงก์/ปุ่มเองตอนนิ้วแตะ
   บนพื้นเข้มของเว็บนี้เห็นชัดเป็นแถบสี่เหลี่ยมแว้บ ๆ ดูเหมือนหน้ากระพริบ
   ปุ่มของ design มีเอฟเฟกต์ตอนกดของตัวเองอยู่แล้ว จึงไม่ต้องพึ่งของเบราว์เซอร์

   ⚠️ ใส่ที่ `*` ไม่ใช่แค่ `html` — Chrome ไม่ได้สืบทอดค่านี้ให้ทุก element เสมอไป
      ปุ่มที่ปลั๊กอินวาดเองบางตัวยังเด้งอยู่ถ้าตั้งแค่ราก
   ⚠️ นี่ **ไม่เกี่ยวกับกรอบโฟกัสของคีย์บอร์ด** (`:focus-visible`) ซึ่งยังอยู่ครบ
      คนที่ใช้คีย์บอร์ด/โปรแกรมอ่านหน้าจอยังเห็นว่าอยู่ปุ่มไหน                  */
*,
*::before,
*::after {
  -webkit-tap-highlight-color: transparent;
}

/* ── ตัวแปรของ WooCommerce ──
   WooCommerce 8+ เปิดให้ปรับสีฟอร์มผ่าน custom property
   ใช้ทางนี้แทนการเขียนทับด้วย selector ที่ specificity สูง
   เพราะไม่พังเวลา WooCommerce อัปเดต                              */
:root {
  /* ⚠️ `transparent` ไม่ใช่ `--bg-input`
     design ตั้ง `.form-input { background: transparent }` (styles.css:586)
     และช่องกรอกทุกช่องในเว็บถูกบังคับเป็น transparent อยู่แล้วผ่านก้อน
     `.form-group .form-input { ... !important }` ด้านล่าง
     ตัวแปรนี้คือช่องทางที่ `.woocommerce form .form-row select` (0,2,1) ใช้
     ถ้าปล่อยเป็น `--bg-input` ช่องประเทศจะเป็น #0c0a1e อยู่ช่องเดียวในฟอร์ม */
  --wc-form-color-background: transparent;
  --wc-form-color-text: var(--text-primary);
  --wc-form-border-color: rgba(var(--text-secondary-rgb), 0.35);
  --wc-form-border-width: 1px;
  --wc-form-border-radius: var(--radius-btn, 8px);

  --wc-content-bg: var(--bg-primary);
  --wc-primary: var(--grad-2);
  --wc-primary-text: var(--text-primary);
  --wc-secondary: var(--bg-secondary);
  --wc-secondary-text: var(--text-primary);
  --wc-highlight: var(--grad-4);
  --wc-highligh-text: var(--text-primary);
  --wc-subtext: var(--text-secondary);
  --wc-red: var(--stat-danger, #ef4444);
  --wc-green: var(--stat-success, #22c55e);
}

/* ── textarea ที่ตัวแปรด้านบนยังไม่ครอบคลุม ──
   กฎของ Select2 ทั้งหมดรวมอยู่ท้ายไฟล์ (ค้นหา "Select2 / selectWoo")
   เคยกระจายอยู่ 3 ที่ในไฟล์นี้แล้วทับกันเองจนแก้จุดหนึ่งไปพังอีกจุด */
.woocommerce form .form-row textarea {
  background-color: transparent;
  color: var(--text-primary);
  border-color: rgba(var(--text-secondary-rgb), 0.35);
}

/* ============================================================
   แจ้งเตือนทั้งเว็บ — WordPress / WooCommerce / Dokan / Omise

   ใช้รูปทรงเดียวกับ .payment-timer ของ design (styles.css:2615)
   แถบเดียวจบ ไอคอนซ้าย ข้อความกลาง พื้นหลังโปร่งสีเดียวกับตัวอักษร
   เปลี่ยนแค่สีกับไอคอนตามประเภทของการแจ้งเตือน
   ============================================================ */

.woocommerce-message,
.woocommerce-info,
.woocommerce-error,
.woocommerce-noreviews,
.woocommerce-notice,
.coupon-error-notice,
.woocommerce p.no-comments,
.dokan-alert,
.dokan-info,
.dokan-error,
.dokan-message,
.es-notice {
  /*
   * grid ไม่ใช่ flex — ไอคอนต้องอยู่ซ้ายเสมอ แม้ข้อความจะยาวหลายบรรทัด
   * หรือมีหลายข้อ (error list) · ถ้าใช้ flex + wrap บรรทัดที่ 2 จะตกไป
   * อยู่ "ใต้ไอคอน" ไม่ใช่ข้างขวา
   * คอลัมน์ 1 = ไอคอน (auto) · คอลัมน์ 2 = ข้อความทั้งหมด (1fr)
   *
   * 🔴 **ไอคอนเสมอบรรทัดแรกของข้อความ ไม่ใช่กึ่งกลางกล่อง** (ผู้ใช้สั่ง 2026-09-13)
   * ของเดิมเป็น `center` ซึ่งดูดีเฉพาะกล่องบรรทัดเดียว พอข้อความยาว 3–4 บรรทัด
   * ไอคอนจะไปลอยกลางกล่อง ห่างจากคำแรกจนดูเหมือนคนละชิ้นกัน
   */
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;

  /*
   * ⚠️ ต้องเป็น column-gap ไม่ใช่ gap
   * `gap` ใน grid คุมทั้งแนวตั้งและแนวนอน ระยะ 8px จึงไปโผล่ใต้ข้อความด้วย
   * ดูเหมือนกล่องมี margin-bottom เกินมา — ที่จริงคือ row-gap
   * ระยะระหว่างข้อความหลายบรรทัดไปใช้ margin ที่ li แทน (ดูด้านล่าง)
   */
  column-gap: 8px;
  row-gap: 0;
  padding: 12px 16px;
  margin: 0 0 12px;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: 0.03em;
  border-radius: 12px;
  border: 0;
  list-style: none;

  /* ค่าเริ่มต้น = ข้อมูลทั่วไป */
  background: rgba(var(--grad-2-rgb, 0, 255, 255), 0.12);
  color: var(--grad-2);
}

/* ไอคอนนำหน้า — เขียนผ่าน ::before ให้ครอบคลุมแจ้งเตือนที่เราคุม markup ไม่ได้ */
.woocommerce-message::before,
.woocommerce-info::before,
.woocommerce-error::before,
.coupon-error-notice::before,
.dokan-alert::before,
.dokan-info::before,
.dokan-error::before,
.dokan-message::before,
.es-notice::before {
  font-family: 'Font Awesome 6 Free', 'Font Awesome 5 Free', sans-serif;
  font-weight: 900;
  font-size: 16px;

  /*
   * 🔴 **ต้องเป็น `inherit` ไม่ใช่ `1`** — กล่องของไอคอนจะได้สูงเท่ากับ
   * บรรทัดข้อความพอดี (14px × 1.45) แล้วตัวไอคอนจึงอยู่กึ่งกลาง **ของบรรทัดแรก**
   * ถ้าเป็น `1` กล่องไอคอนสูง 16px ชนขอบบนของบรรทัด ดูเหมือนไอคอนลอยสูงกว่าตัวหนังสือ
   */
  line-height: inherit;
  flex-shrink: 0;
  position: static;
  color: inherit;
  content: '\f05a'; /* circle-info */

  /* ยึดคอลัมน์ซ้าย **แถวแรกเท่านั้น** แล้วเสมอบรรทัดแรกของข้อความ */
  grid-column: 1;
  grid-row: 1;
  align-self: start;
}

/* ข้อความทุกชิ้นอยู่คอลัมน์ขวาเสมอ ไม่ว่าจะมากี่บรรทัด */
.woocommerce-message > *,
.woocommerce-info > *,
.woocommerce-error > *,
.dokan-alert > *,
.dokan-info > *,
.dokan-error > *,
.dokan-message > *,
.es-notice > * {
  grid-column: 2;
  min-width: 0;
  /* คำยาวที่ตัดบรรทัดเองไม่ได้ (อีเมล · URL · เลขพัสดุ) ต้องยอมให้หักกลางคำ
     ไม่งั้นมันดันคอลัมน์ขวาให้กว้างเกินกล่อง แล้วข้อความที่เหลือถูกบีบเป็น
     คอลัมน์ผอม ๆ อ่านไม่ได้ (เจอกับกล่อง "บัญชีไม่ตรง" ที่มีอีเมลเต็ม ๆ 2026-08-17) */
  overflow-wrap: anywhere;
}

/* ── สำเร็จ ── */
.woocommerce-message,
.woocommerce-notice--success,
.dokan-message {
  background: rgba(var(--stat-success-rgb), 0.12);
  color: var(--stat-success);
}

.woocommerce-message::before,
.dokan-message::before {
  content: '\f058'; /* circle-check */
}

/* ── ผิดพลาด ── */
.woocommerce-error,
.woocommerce-notice--error,
.coupon-error-notice,
.dokan-error {
  background: rgba(var(--stat-error-rgb), 0.12);
  color: var(--stat-error);
}

.woocommerce-error::before,
.coupon-error-notice::before,
.dokan-error::before {
  content: '\f06a'; /* circle-exclamation */
}

/* ── คำเตือน ── */
.es-notice--warning,
.woocommerce-info.woocommerce-no-products-found,
.dokan-alert {
  background: rgba(var(--stat-warning-rgb), 0.12);
  color: var(--stat-warning);
}

.es-notice--warning::before,
.dokan-alert::before {
  content: '\f071'; /* triangle-exclamation */
}

/* กล่องที่มีหลายย่อหน้า (เช่นแจ้งเตือนบัญชีทีมงานในหน้าโปรไฟล์)
   row-gap ของ grid เป็น 0 อยู่แล้ว ระยะจึงต้องมาจาก margin ของย่อหน้าเอง
   และเว้นเฉพาะ "ระหว่าง" ย่อหน้า ไม่ใช่ท้ายย่อหน้าสุดท้าย */
.woocommerce-message > p,
.woocommerce-info > p,
.woocommerce-error > p,
.es-notice > p {
  margin: 0;
}

.woocommerce-message > p + p,
.woocommerce-info > p + p,
.woocommerce-error > p + p,
.es-notice > p + p {
  margin-top: 5px;
  font-weight: 500;
  opacity: 0.85;
}

/* error ของ WooCommerce เป็น <ul> — แต่ละข้อเป็นแถวของ grid ในคอลัมน์ขวา */
.woocommerce-error li {
  grid-column: 2;
  margin: 0;
  min-width: 0;
  list-style: none;
}

/* เว้นระยะเฉพาะ "ระหว่าง" ข้อ ไม่ใช่ท้ายข้อสุดท้าย */
.woocommerce-error li + li {
  margin-top: 4px;
}

/*
 * ไม่เน้นกรอบตอนโฟกัส
 *
 * WooCommerce ใส่ tabindex ให้กล่องแจ้งเตือนแล้วสั่งโฟกัสเองเพื่อให้ screen reader อ่าน
 * เบราว์เซอร์จึงวาดกรอบขาวรอบกล่องทุกครั้งที่แจ้งเตือนโผล่ — ไม่ได้ตั้งใจให้เห็น
 */
.woocommerce-notices-wrapper:focus,
.woocommerce-notices-wrapper [tabindex]:focus,
.woocommerce-message:focus,
.woocommerce-info:focus,
.woocommerce-error:focus,
.dokan-alert:focus,
.dokan-info:focus,
.dokan-error:focus,
.dokan-message:focus,
.es-notice:focus {
  outline: none;
  box-shadow: none;
}

/* ลิงก์ในแจ้งเตือน เช่น "ดูตะกร้าสินค้า" */
.woocommerce-message a,
.woocommerce-info a,
.woocommerce-error a,
.es-notice a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.woocommerce-message a:hover,
.woocommerce-info a:hover,
.woocommerce-error a:hover,
.es-notice a:hover {
  color: inherit;
  opacity: 0.8;
  background: none;
  -webkit-text-fill-color: currentColor;
}

/* ปุ่มในแจ้งเตือน — ย้ายไปกำหนดเป็น "ลิงก์ตัวหนังสือ" ที่ท้ายไฟล์แล้ว
   (ผู้ใช้สั่งเปลี่ยนจากปุ่มแคปซูลเป็นลิงก์ขีดเส้นใต้) */

/* ── แจ้งเตือนของ Nextend Social Login (เข้าสู่ระบบด้วย Google) ──

   🔴 ผู้ใช้แจ้ง 2026-08-17: กล่องมุมขวาบน "สีขาว ๆ อ่านไม่ออก"
   ปลั๊กอินพิมพ์ CSS ของตัวเองลงท้ายหน้า (NextendSocialLogin::noticeStyles)
   ตั้ง `background: #fff` แต่ไม่ตั้งสีตัวอักษร ตัวหนังสือจึงสืบทอด
   `--text-primary` (ขาว) ของธีมมา = ขาวบนขาว

   ⚠️ ต้องนำหน้าด้วย `body` — CSS ของปลั๊กอินอยู่ท้ายเอกสาร ถ้า specificity
   เท่ากัน (`#nsl-notices-fallback > div` = 1,0,1) ของเขาชนะเพราะมาทีหลัง */
body #nsl-notices-fallback {
  right: 16px;
  top: 16px;
  left: 16px;
  z-index: 10000;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  pointer-events: none;
}

body #nsl-notices-fallback > div {
  pointer-events: auto;
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: 8px;
  /* ข้อความบางฉบับของ Nextend ยาวเป็นย่อหน้า — ถ้าปล่อย max-content
     กล่องจะลากยาวเกือบเต็มจอแล้วอ่านยาก */
  width: max-content;
  max-width: min(100%, 420px);
  margin: 0 0 8px;
  padding: 12px 40px 12px 16px;
  border: 0;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: 0.03em;
  background: var(--bg-card, #1a1a2e);
  color: var(--text-primary, #fff);
}

body #nsl-notices-fallback > div::before {
  font-family: 'Font Awesome 6 Free', 'Font Awesome 5 Free', sans-serif;
  font-weight: 900;
  font-size: 16px;
  line-height: 1;
  grid-column: 1;
  grid-row: 1 / -1;
  align-self: center;
  color: inherit;
  content: '\f05a'; /* circle-info */
}

/* ⚠️ ต้องประกาศ `display: grid` ซ้ำในสองบล็อกล่างนี้ด้วย
   ปลั๊กอินเขียน `#nsl-notices-fallback > div.error { display: block }` ซึ่ง
   specificity (1,1,1) สูงกว่ากฎรวมข้างบน (1,0,2) ถ้าไม่ย้ำ ไอคอนกับข้อความ
   จะหลุดออกจาก grid แล้วไอคอนไปกองอยู่บรรทัดบน */
body #nsl-notices-fallback > div.error {
  display: grid;
  border-left: 0;
  background: var(--bg-card, #1a1a2e);
  color: var(--stat-error, #ef4444);
}

body #nsl-notices-fallback > div.error::before {
  content: '\f06a'; /* circle-exclamation */
}

body #nsl-notices-fallback > div.updated {
  display: grid;
  border-left: 0;
  background: var(--bg-card, #1a1a2e);
  color: var(--stat-success, #22c55e);
}

body #nsl-notices-fallback > div.updated::before {
  content: '\f058'; /* circle-check */
}

body #nsl-notices-fallback p {
  grid-column: 2;
  min-width: 0;
  margin: 0;
  padding: 0;
  color: inherit;
  overflow-wrap: anywhere;
}

/* กากบาทปิด — ของเดิมเป็นตัว × สีตัวอักษรเดียวกับพื้น จึงมองไม่เห็น */
body #nsl-notices-fallback > div::after {
  top: 8px;
  right: 10px;
  color: inherit;
  opacity: 0.6;
}

/* ── ตัวเลือกวิธีจัดส่งในหน้าชำระเงิน ── */
.woocommerce-shipping-totals ul#shipping_method {
  list-style: none;
  margin: 0;
  padding: 0;
}

.woocommerce-shipping-totals ul#shipping_method li {
  margin: 0 0 6px;
  color: var(--text-primary);
}

/* ── ช่องที่กรอกไม่ครบ: กรอบแดง ──
 *
 * 🔴 **ต้องมี `!important`** — ก้อน `.form-group .form-input { border: … !important }`
 * (ค้นหา "ทวง .form-input คืนจาก dokan-tailwind") ประกาศ `border` ทั้งชุดแบบ
 * `!important` เพื่อสู้กับ `dokan-tailwind.css` กฎนี้ที่ไม่มี `!important`
 * จึงแพ้ตลอด — หัวข้อเป็นสีแดงแล้วแต่กรอบช่องไม่แดง (ผู้ใช้รายงาน 2026-08-10)
 *
 * `--stat-danger` **ไม่มีอยู่จริง** ในชุดตัวแปรของ design (ของจริงคือ `--stat-error`)
 * ของเดิมจึงตกไปใช้ค่า fallback มาตลอด — เปลี่ยนมาใช้ตัวที่มีจริง
 *
 * Select2 ต้องใส่ `:not(.select2-container--open)` ให้เท่ากับกฎของ WooCommerce
 * (0,6,1) ไม่งั้นแพ้เหมือนกรณีกรอบเขียว
 */
.woocommerce form .form-row.woocommerce-invalid .form-input,
.woocommerce form .form-row.woocommerce-invalid input.input-text,
.woocommerce form .form-row.woocommerce-invalid select,
.woocommerce form .form-row.woocommerce-invalid textarea,
.woocommerce form .form-row.woocommerce-invalid .select2-container:not(.select2-container--open) .select2-selection,
.woocommerce form .form-row.woocommerce-invalid .select2-container:not(.select2-container--open) .select2-selection--single {
  border-color: var(--stat-error, #ef4444) !important;
}

/* ตอนโฟกัสเข้าไปแก้ ยังคงกรอบแดงไว้ ไม่ต้องสลับเป็นขาว
   ไม่งั้นผู้ใช้กดเข้าไปแล้วสัญญาณ "ช่องนี้ผิด" หายไปทันที */
.woocommerce form .form-row.woocommerce-invalid .form-input:focus,
.woocommerce form .form-row.woocommerce-invalid input.input-text:focus,
.woocommerce form .form-row.woocommerce-invalid select:focus,
.woocommerce form .form-row.woocommerce-invalid textarea:focus {
  border-color: var(--stat-error, #ef4444) !important;
}

/* ⚠️ **ไม่ทำกรอบเขียวตอนกรอกผ่าน** — design ไม่มีสถานะนี้
   ผู้ใช้รายงานว่า "กรอบสีเขียวมาจากไหน" ตอนคลิกช่องจังหวัด
   คงไว้เฉพาะกรอบแดงตอนกรอกผิด ซึ่งจำเป็นต่อการบอกว่าต้องแก้ตรงไหน */
.woocommerce form .form-row.woocommerce-validated .form-input,
.woocommerce form .form-row.woocommerce-validated input.input-text,
.woocommerce form .form-row.woocommerce-validated select {
  border-color: rgba(var(--text-primary-rgb), 0.12);
}
/* ตัว Select2 ต้องใช้ `:not()` ถึงจะชนะ — อยู่ในก้อนรวมท้ายไฟล์ */

/* ── ตัวโหลดตอน checkout คำนวณยอดใหม่ ── */
.blockUI.blockOverlay {
  background: rgba(var(--bg-primary-rgb), 0.7) !important;
}

/* ── ลิงก์ "มีคูปองส่วนลด?" เหนือฟอร์ม ── */
.woocommerce-form-coupon-toggle .woocommerce-info {
  border-top-color: var(--grad-1);
}

/* ทรงของฟอร์มคูปองที่กางออกมาอยู่ท้ายไฟล์ (ค้นหา "ฟอร์มคูปองหน้าชำระเงิน") */

/* ============================================================
   ตัวเลขจำนวนสินค้าบนปุ่มตะกร้า
   design ไม่มีส่วนนี้ — เพิ่มให้กลืนกับปุ่มกลมเดิม (.btn-cart)
   ============================================================ */

.btn-cart {
  position: relative;
  overflow: visible;
}

.cart-count-badge {
  position: absolute;
  top: -2px;
  right: -2px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  /* พื้นแดง (ผู้ใช้สั่ง 2026-08-28) — ชุดสีเดียวกับตราแจ้งเตือนบนเมนูล่าง
     ตัวเลขบนตะกร้าเป็น "มีของค้างอยู่" เหมือนกัน ต้องอ่านเป็นภาษาเดียวกัน */
  color: #fff;
  background: var(--btn-danger);
  border-radius: 999px;
  border: 2px solid var(--bg-header);
  pointer-events: none;
  z-index: 2;
}

.cart-count-badge.is-empty {
  display: none;
}

/* ============================================================
   ลิงก์ "ดูตะกร้าสินค้า" ที่ WooCommerce เติมข้างปุ่ม +
   ทำเป็นบอลลูนลอยเหนือปุ่ม แล้วจางหายเองใน 10 วินาที
   (ค่าเริ่มต้นจะแทรกเป็นลิงก์ธรรมดาแล้วดันเลย์เอาต์การ์ดเสีย)
   ============================================================ */

.product-action {
  position: relative;
}

.product-action .added_to_cart {
  position: absolute;
  bottom: calc(100% + 10px);
  right: 0;
  z-index: 5;
  white-space: nowrap;
  padding: 7px 12px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  color: #1a1a1a;
  background: #ffffff;
  border-radius: 8px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
  text-decoration: none;

  /* โผล่มาแล้วค้างไว้ 10 วินาที ก่อนจางหาย */
  animation: es-balloon-in 0.25s ease-out both, es-balloon-out 0.4s ease-in 10s both;
}

.product-action .added_to_cart:hover {
  color: #1a1a1a;
  background: #ffffff;
  -webkit-text-fill-color: #1a1a1a;
}

/* หางบอลลูนชี้ลงหาปุ่ม */
.product-action .added_to_cart::after {
  content: '';
  position: absolute;
  top: 100%;
  right: 14px;
  border: 6px solid transparent;
  border-top-color: #ffffff;
}

@keyframes es-balloon-in {
  from { opacity: 0; transform: translateY(6px) scale(0.94); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes es-balloon-out {
  from { opacity: 1; visibility: visible; }
  to   { opacity: 0; visibility: hidden; }
}

@media (prefers-reduced-motion: reduce) {
  .product-action .added_to_cart {
    animation: es-balloon-out 0.4s ease-in 10s both;
  }
}

/* บนหน้าสินค้าเดี่ยว ปุ่มอยู่ในแถว .pruduct-buttons */
.pruduct-buttons {
  position: relative;
}

.pruduct-buttons .added_to_cart {
  position: absolute;
  bottom: calc(100% + 10px);
  right: 0;
  z-index: 5;
  white-space: nowrap;
  padding: 7px 12px;
  font-size: 12px;
  font-weight: 700;
  color: #1a1a1a;
  background: #ffffff;
  border-radius: 8px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
  animation: es-balloon-in 0.25s ease-out both, es-balloon-out 0.4s ease-in 10s both;
}

.pruduct-buttons .added_to_cart::after {
  content: '';
  position: absolute;
  top: 100%;
  right: 14px;
  border: 6px solid transparent;
  border-top-color: #ffffff;
}

/* ============================================================
   Gallery หน้าสินค้าเดี่ยว
   design เขียน CSS ไว้กับ .main-image ซึ่งเป็นคลาสของ prototype
   WooCommerce ออก .woocommerce-product-gallery__wrapper แทน
   และถ้าสินค้าไม่มีรูป gallery FlexSlider จะไม่สร้าง .flex-viewport
   ทำให้ไม่ได้มุมโค้งเลย — ผูกสไตล์เดียวกันให้ทั้งสองกรณี
   ============================================================ */

/*
 * ⚠️ **ห้ามใส่พื้นหลังทึบที่นี่**
 * เดิมเป็น `background: var(--bg-primary)` (ดำ) แล้วไปล้างทีหลังด้วย
 * `:has(.flex-viewport)` ซึ่งพังสองเคส:
 *   1. สินค้ามีรูปเดียว FlexSlider ไม่สร้าง .flex-viewport → พื้นดำโผล่
 *   2. Safari รุ่นเก่าบน iPad ไม่รองรับ `:has()` → กฎล้างไม่ทำงานเลย
 * รูปตั้ง aspect-ratio 1/1 + object-fit: cover อยู่แล้ว เต็มกรอบเสมอ
 * จึงไม่ต้องมีพื้นหลังรองอะไรทั้งนั้น
 */
/*
 * 🔴 **ห้ามเอา `border-radius` / `overflow` กลับมาไว้ที่ตัวนี้**
 * (ผู้ใช้แจ้ง 2026-08-29: สินค้ารูปเดียว "มุมโค้งด้านล่างซ้าย/ขวาไม่แสดง")
 *
 * ที่ ≥769px กล่องนี้เป็น **คอลัมน์ flex** (`flex: 0 0 45%` — single-product.css:564)
 * ซึ่ง **ยืดสูงตามคอลัมน์ขวา** เมื่อฝั่งขวาสูงกว่ารูป
 * วัดจริงที่จอ 768px: กล่อง 317×376 แต่รูป 317×317 — สูงเกินรูป 59px
 * มุมโค้งล่างจึงไปอยู่ **ใต้รูป บนพื้นที่ว่าง** มองไม่เห็น
 * (ที่ 390px กับ 933px บังเอิญสูงเท่ากันพอดี เลยดูเหมือนเป็นบั๊กเฉพาะบางจอ)
 *
 * `align-self: flex-start` = เลิกยืด กล่องสูงเท่ารูปเสมอ
 */
.woocommerce-product-gallery {
  align-self: flex-start;
  background: none;
}

/*
 * มุมโค้งของ **สินค้ารูปเดียว** — FlexSlider ไม่ทำงานเมื่อมีรูปเดียว
 * จึงไม่มี `.flex-viewport` มาถือมุมโค้งให้ ต้องผูกไว้ที่ wrapper แทน
 *
 * 🔴 **ตัวเลือกต้องเป็นลูกตรง (`>`) เท่านั้น** — นี่คือตัวแยกสองเคสให้เอง:
 * เมื่อมีหลายรูป FlexSlider จะย้าย wrapper เข้าไปอยู่ **ใน `.flex-viewport`**
 * มันจึงไม่ใช่ลูกตรงของ gallery อีกต่อไป กฎนี้เลยไม่ไปยุ่งกับเคสหลายรูปเลย
 * (ห้ามใช้ `:has()` แก้ — Safari เก่าบน iPad ไม่รองรับ ดูเหตุผลในคอมเมนต์ข้างบน)
 */
.woocommerce-product-gallery > .woocommerce-product-gallery__wrapper {
  border-radius: 12px;
  overflow: hidden;
}

/* ⚠ ห้ามใส่ border-radius ที่นี่ — design ตั้ง .flex-viewport เป็น 12px
   แล้วขยายเป็น 20px ที่ ≥768px (single-product.css:597)
   กฎนี้เป็น (0,2,0) ชนะ .flex-viewport (0,1,0) ของ design ทุกความกว้าง
   ถ้าใส่ไว้ มุมโค้งจะค้างที่ 12px บนแท็บเล็ต/เดสก์ท็อป */
.woocommerce-product-gallery .flex-viewport {
  overflow: hidden;
}

/* สินค้ารูปเดียวต้องโค้งเท่าสินค้าหลายรูปทุกความกว้าง — design ขยาย
   `.flex-viewport` เป็น 20px ที่ **≥768px** (single-product.css:555)
   ตัวนี้จึงต้องใช้จุดตัดเดียวกันเป๊ะ ไม่งั้นที่ 768px พอดีจะได้คนละค่า
   ⚠️ ที่นี่คือ 768 ไม่ใช่ 782 แบบฝั่งหลังบ้าน — คนละชุดจุดตัดกัน */
@media (min-width: 768px) {
  .woocommerce-product-gallery > .woocommerce-product-gallery__wrapper {
    border-radius: 20px;
  }
}

.woocommerce-product-gallery__wrapper,
.woocommerce-product-gallery__image {
  width: 100%;
  display: block;
}

.woocommerce-product-gallery__image img,
.woocommerce-product-gallery__wrapper img {
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
}

/* มี .flex-viewport แล้วไม่ต้องโค้งซ้อนอีกชั้น
   (ไม่พึ่ง :has() ในการล้างพื้นหลังแล้ว — ดูหมายเหตุด้านบน) */
.woocommerce-product-gallery:has(.flex-viewport) {
  border-radius: 0;
  overflow: visible;
}

/* ============================================================
   กันรูปกระพริบ / หน้ากระโดด ตอนเปิดหน้าสินค้า (2026-09-21)
   ============================================================

   อาการที่ผู้ใช้แจ้ง: "เข้าไปแล้วรูปมันกระพริบบัค ๆ เหมือนขนาดมันเพี้ยน
   ก่อนจะโหลดหน้าเสร็จ"

   ต้นเหตุ: HTML ที่ส่งมามีรูปแกลเลอรี **ทุกใบเรียงต่อกันลงมา** ยังไม่มี
   `.flex-viewport` จนกว่า FlexSlider จะทำงาน ปกติ `woocommerce.css` มีกฎ
   `.woocommerce-product-gallery__image:nth-child(n+2){width:25%}` กันไว้
   แต่ไฟล์นั้น (`woocommerce-general`) **ถูก dequeue ตั้งแต่รอบ PageSpeed
   5 ก.ย.** (`inc/performance.php`) และเราตั้งทับเป็น `width:100%` ข้างบน
   → สินค้า 3 รูป = กล่องสูง 3 เท่า แล้วยุบลงตอน init = ทั้งหน้ากระโดด

   🔴 **ตัวเลือกต้องเป็นลูกตรง (`>`) ทั้งเส้น** — นี่คือสวิตช์ปิดตัวเอง:
   FlexSlider ย้าย `__wrapper` เข้าไปใน `.flex-viewport` (jquery.flexslider.js
   บรรทัด 838) ทุกกฎในหัวข้อนี้จึงหยุดเองทันทีที่ init เสร็จ
   ไม่ต้องใช้ JS ไม่ต้องใช้ `:has()` (Safari เก่าบน iPad ไม่รองรับ)

   🔴 **ห้ามเอา `opacity:0` ของ template ต้นฉบับกลับมา** — เหตุผลเต็ม ๆ
   อยู่หัวไฟล์ `woocommerce/single-product/product-image.php`
   ============================================================ */

/* 1) รูปที่ 2 เป็นต้นไปไม่ต้องโผล่ก่อน — FlexSlider จะพาไปเป็นสไลด์อยู่แล้ว */
.woocommerce-product-gallery > .woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image:nth-child(n+2) {
  display: none;
}

/* 2) มุมโค้งของสินค้า **หลายรูป** ต้องอยู่ที่ตัวรูป ไม่ใช่ที่ wrapper
      เพราะ wrapper ต้องอุ้มที่ว่างของแถวธัมบ์ (ข้อ 3) ไว้ด้วย
      ถ้าโค้งที่ wrapper มุมล่างจะไปอยู่ใต้ที่ว่าง มองไม่เห็น
      (เคสรูปเดียวยังใช้กฎ wrapper เดิมข้างบนเหมือนเดิม) */
.woocommerce-product-gallery.es-gallery-multi > .woocommerce-product-gallery__wrapper {
  border-radius: 0;
  overflow: visible;
}

.woocommerce-product-gallery.es-gallery-multi > .woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image:first-child img {
  border-radius: 12px;
}

/* 3) จองที่ของแถวธัมบ์ที่ FlexSlider จะ append ทีหลัง
      `data-es-thumbs` = จำนวนธัมบ์ (6 ขึ้นไปส่งมาเป็น 6) จาก product-image.php

      🔴 **ตัวเลขต้องตรงกับ `.flex-control-thumbs li` ใน single-product.css เป๊ะ**
      แก้ขนาดธัมบ์ที่นั่นเมื่อไร ต้องมาแก้ที่นี่ด้วย ไม่งั้นหน้าจะกระโดดอีก:

        | ธัมบ์ | <768px              | ≥768px               |
        |------|---------------------|----------------------|
        | 2, 4 | (100%−24px)/4 ≤90   | (100%−36px)/4 ≤110   |
        | 3    | (100%−16px)/3 ≤90   | (100%−24px)/3 ≤110   |
        | 5    | (100%−32px)/5 ≤70   | (100%−48px)/5 ≤90    |
        | 6+   | 68px                | 68px                 |

      ⚠️ ใช้ `width` + `aspect-ratio` ไม่ใช่ `height` — % ของ height อ้างอิง
      ความสูงพ่อ (ซึ่งยังไม่รู้) แต่ % ของ width อ้างอิงความกว้าง */
.woocommerce-product-gallery.es-gallery-multi > .woocommerce-product-gallery__wrapper::after {
  content: '';
  display: block;
  width: min(90px, calc((100% - 24px) / 4));
  aspect-ratio: 1 / 1;
  margin-top: 12px;
}

.woocommerce-product-gallery.es-gallery-multi[data-es-thumbs="3"] > .woocommerce-product-gallery__wrapper::after {
  width: min(90px, calc((100% - 16px) / 3));
}

.woocommerce-product-gallery.es-gallery-multi[data-es-thumbs="5"] > .woocommerce-product-gallery__wrapper::after {
  width: min(70px, calc((100% - 32px) / 5));
}

.woocommerce-product-gallery.es-gallery-multi[data-es-thumbs="6"] > .woocommerce-product-gallery__wrapper::after {
  width: 68px;
}

/* ≥768px: ช่องไฟ 12px · ระยะห่างจากรูป 16px · เพดานธัมบ์ใหญ่ขึ้น
   (single-product.css บล็อก @media (min-width:768px)) */
@media (min-width: 768px) {
  .woocommerce-product-gallery.es-gallery-multi > .woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image:first-child img {
    border-radius: 20px;
  }

  .woocommerce-product-gallery.es-gallery-multi > .woocommerce-product-gallery__wrapper::after {
    width: min(110px, calc((100% - 36px) / 4));
    margin-top: 16px;
  }

  .woocommerce-product-gallery.es-gallery-multi[data-es-thumbs="3"] > .woocommerce-product-gallery__wrapper::after {
    width: min(110px, calc((100% - 24px) / 3));
  }

  .woocommerce-product-gallery.es-gallery-multi[data-es-thumbs="5"] > .woocommerce-product-gallery__wrapper::after {
    width: min(90px, calc((100% - 48px) / 5));
  }

  .woocommerce-product-gallery.es-gallery-multi[data-es-thumbs="6"] > .woocommerce-product-gallery__wrapper::after {
    width: 68px;
  }
}

/* ============================================================
   คำบรรยายสินค้า — บังคับชิดซ้าย
   บาง wrapper ของ WooCommerce จัดกึ่งกลางมาให้ ทับไว้ให้ตรง design
   ============================================================ */

.product-description,
.product-description p,
.product-description ul,
.product-description ol,
.product-description li,
.product-description h1,
.product-description h2,
.product-description h4,
.product-description h5,
.product-description h6,
.product-description .description-header {
  text-align: left;
}

/*
 * ⚠️ หัวข้อ Information ต้องอยู่ซ้าย ปุ่มเปิดเสียงอ่านอยู่ขวา **เสมอ**
 * แม้คำบรรยายจะสั้นแค่บรรทัดเดียว
 * design ตั้ง flex + space-between ไว้แล้ว (single-product.css:370)
 * แต่ `text-align: left` ที่เราทับไว้ด้านบนไปกวน justify-content ในบางเบราว์เซอร์
 * ตอกย้ำอีกชั้นตรงนี้ให้แน่ใจ
 */
.product-description .description-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.product-description .description-header h2,
.product-description .description-header h3 {
  margin: 0;
  text-align: left;
}

/*
 * 🔴 **ปุ่มอ่านต้องไม่ขยับตอนกด** (ผู้ใช้แจ้ง 2026-08-29)
 *
 * ของเดิม: h3 ซ้าย · ปุ่มอ่านดันไปขวาด้วย `margin-left: auto` · ปุ่มหยุดต่อท้าย
 * พอกดอ่าน ปุ่มหยุดโผล่ขึ้นมา **ต่อท้าย** ปุ่มอ่านจึงถูกดันไปทางซ้าย 50px
 * เห็นเป็นการกระตุกทุกครั้งที่กด
 *
 * แก้ด้วย `order` ไม่ต้องแตะ HTML: ให้ h3 เป็นตัวดันช่องว่าง (`margin-right:auto`)
 * แล้วสลับให้ **ปุ่มหยุดอยู่ก่อนปุ่มอ่าน** ปุ่มหยุดจึงโผล่เข้าไปในช่องว่างตรงกลาง
 * ที่ว่างอยู่แล้ว ส่วนปุ่มอ่านยึดขอบขวาไว้ตลอด ไม่ขยับสักพิกเซล
 */
.product-description .description-header h2,
.product-description .description-header h3 {
  margin-right: auto;
  /* 🔴 ต้องยอมให้หดได้ ไม่งั้นจอแคบจะไม่พอที่แล้วปุ่มตกไปบรรทัดใหม่
     วัดที่ 390px: หัวข้อ 180 + ปุ่มหยุด 38 + ปุ่มอ่าน 138 + ช่องไฟ = เกินความกว้าง
     `min-width: 0` คือตัวปลดล็อก — ลูกของ flex มี `min-width: auto` เป็นค่าตั้งต้น
     ซึ่งห้ามหดต่ำกว่าความกว้างของข้อความ ทำให้หดไม่ได้เลยแม้สั่ง flex-shrink */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ข้อความเตือน (เครื่องไม่มีเสียงไทย) ต้องลงบรรทัดของตัวเองเสมอ
   ไม่ใช่ไปเบียดแถวปุ่มจนปุ่มตกบรรทัด — มันมี `order: 9` อยู่แล้ว
   เติม flex-basis เต็มแถวให้ชัด จะได้ไม่ต้องพึ่งว่าที่เหลือพอดีหรือเปล่า */
.product-description .btn-read-aloud__note {
  flex: 0 0 100%;
}

/* ปุ่มหยุดสูงกว่าปุ่มอ่าน 1px (มีขอบ 1px รอบด้าน ส่วนปุ่มอ่านใช้ padding ล้วน)
   พอโผล่ขึ้นมาแถวจึงสูงขึ้น 1px แล้วดันเนื้อหาข้างล่างขยับตาม
   จองความสูงไว้ที่ค่าสูงสุดตั้งแต่แรก ทั้งสองสถานะจึงสูงเท่ากันเป๊ะ
   ⚠️ ถ้าแก้ padding/ขอบของปุ่มสองอันนี้ ต้องกลับมาวัดเลขนี้ใหม่ */
.product-description .description-header {
  min-height: 38px;
}

.product-description .btn-read-aloud {
  flex-shrink: 0;
  margin-left: 0;
  order: 2;
}

.product-description .btn-read-stop {
  order: 1;
}

.product-description .btn-read-aloud[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ============================================================
   ปุ่มเปิดเสียงอ่าน — สถานะ "กำลังอ่าน"

   ผู้ใช้สั่ง 2026-08-21: กดอ่านแล้วต้องค้างเป็น active ตลอดเวลาที่อ่านอยู่
   ไม่ใช่ติดแวบเดียวตอนเมาส์อยู่บนปุ่ม

   ใช้ **กฎชุดเดียวกับ :hover เป๊ะ ๆ** (single-product.css:444) ไม่ได้วาดใหม่
   เอฟเฟกต์จึงเหมือนกันแน่นอน ต่อให้วันหลังมีคนไปแก้สีไล่ระดับที่ต้นทาง
   ============================================================ */
.product-description .btn-read-aloud.is-preparing::before,
.product-description .btn-read-aloud.is-speaking::before {
  background: linear-gradient(90deg,
    var(--grad-1) 0%,
    var(--grad-2) 12.5%,
    var(--grad-3) 25%,
    var(--grad-4) 37.5%,
    var(--grad-1) 50%,
    var(--grad-2) 62.5%,
    var(--grad-3) 75%,
    var(--grad-4) 87.5%,
    var(--grad-1) 100%
  );
  background-size: 200% 100%;
  animation: gradient-slide 1s linear infinite;
}

/* ไอคอนลำโพงเต้นเบา ๆ ให้รู้ว่าเสียงยังเดินอยู่ แม้ปิดเสียงลำโพงไว้ */
.product-description .btn-read-aloud.is-speaking i {
  animation: es-speak-pulse 1.1s ease-in-out infinite;
}

@keyframes es-speak-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.55; transform: scale(0.86); }
}

/* กำลังอ่านอยู่ห้ามกดซ้ำ — JS กันไว้อีกชั้นแล้ว ตรงนี้บอกด้วยเคอร์เซอร์ */
.product-description .btn-read-aloud.is-preparing,
.product-description .btn-read-aloud.is-speaking {
  cursor: default;
}

/* ------------------------------------------------------------
   🔴 มือถือ: อ่านจบแล้วขอบไล่สียังวิ่งค้าง (ผู้ใช้แจ้ง 2026-09-16)
   ต้นเหตุคือ `:hover` (single-product.css:458) — จอสัมผัสจำว่า "ชี้อยู่" ที่ปุ่มที่เพิ่งแตะ
   จนกว่าจะแตะที่อื่น พอ JS ถอด `.is-speaking` ตอนอ่านจบ กฎ `:hover` ก็ยังวิ่งต่อ
   เครื่องที่ชี้ไม่ได้ (`hover: none`) → ปิดเอฟเฟกต์ hover ของปุ่มนี้ เหลือแต่ตอนเตรียม/กำลังอ่าน
   ------------------------------------------------------------ */
@media (hover: none) {
  .product-description .btn-read-aloud:not(.is-speaking):not(.is-preparing):hover::before {
    background: var(--gradient);
    background-size: auto;
    animation: none;
  }
}

/* ------------------------------------------------------------
   ม่านตอนเตรียมเสียง — คลุมคำบรรยายทั้งกล่อง + วงหมุนตรงกลาง ไม่มีตัวหนังสือ (ผู้ใช้สั่ง 2026-09-16)
   JS: `preparing()` ใน assets/js/read-aloud.js · วงหมุนหน้าตาเดียวกับ `.es-loading__spinner` (หน้าเปลี่ยนหน้า)
   จาง 0.25 วิ ทั้งเข้าและออก · `pointer-events` ปิดตอนซ่อน ไม่งั้นม่านใสบังการเลือกข้อความ
   ------------------------------------------------------------ */
.product-description__body.es-speech-host {
  position: relative;
}

.es-speech-wait {
  position: absolute;
  /* บน-ล่างเผื่อ 8px — คำบรรยายบรรทัดเดียว (สูง ~37px) วงหมุน 32px ไม่ล้นม่าน */
  inset: -8px -6px;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  /* บาง ๆ (ผู้ใช้สั่ง 2026-09-16 "มันดำไป เอาเหลือแบบบาง ๆ") — เดิม 0.72 + เบลอ 2px · ตัวหนังสือยังอ่านออกผ่านม่าน */
  background: rgba(var(--bg-primary-rgb), 0.35);
  backdrop-filter: blur(1px);
  -webkit-backdrop-filter: blur(1px);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.25s ease, visibility 0s linear 0.25s;
}

.es-speech-wait.is-on {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 0.25s ease, visibility 0s linear 0s;
}

/* เล็กลง 30% จากเดิม 46px (ผู้ใช้สั่ง 2026-09-18) */
.es-speech-wait__spinner {
  width: 32px;
  height: 32px;
  border: 2px solid rgba(var(--text-primary-rgb), 0.15);
  border-top-color: var(--grad-1);
  border-radius: 50%;
  animation: es-loading-spin 0.7s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .es-speech-wait__spinner {
    animation-duration: 2.4s;
  }
}

/* ⚠️ **กฎจอแคบของปุ่มเปิดเสียงอ่านไม่ได้อยู่ตรงนี้** — อยู่ท้ายไฟล์
   (ค้นคำว่า "จอแคบ — ปุ่มเปิดเสียงอ่านเหลือแต่ไอคอน")
   เพราะ `.product-description .description-header` ถูกประกาศซ้ำหลายที่ในไฟล์นี้
   ความเฉพาะเจาะจงเท่ากันหมด **ตัวท้ายไฟล์เป็นตัวชนะ** เขียนไว้ตรงนี้แล้วไม่มีผล */

/* ------------------------------------------------------------
   ปุ่มหยุด — อยู่ขวามือของปุ่มอ่าน โผล่เฉพาะตอนกำลังอ่าน

   `hidden` ของ HTML ถูก `display: flex` ทับได้ง่าย ๆ จึงตอกด้วย
   [hidden] { display: none } อีกชั้น ไม่งั้นปุ่มค้างอยู่ตลอดเวลา
   ------------------------------------------------------------ */
.product-description .btn-read-stop {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid rgba(var(--text-secondary-rgb), 0.4);
  border-radius: var(--radius-btn);
  background: transparent;
  color: var(--text-primary);
  font-size: 13px;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}

.product-description .btn-read-stop[hidden] {
  display: none;
}

.product-description .btn-read-stop:hover,
.product-description .btn-read-stop:focus-visible {
  border-color: var(--grad-4);
  color: var(--grad-4);
  background: rgba(var(--grad-4-rgb), 0.1);
}

/* ── ⛔ กฎชุดนี้ไม่ได้ใช้แล้ว เก็บไว้เป็นบันทึกเท่านั้น (2026-09-03) ──
   `.btn-read-aloud__note` เคยเป็นกล่องข้อความ `flex-basis: 100%` ในแถว
   เดียวกับปุ่ม พอโผล่ขึ้นมาคำบรรยายทั้งก้อนเลื่อนลง **63.8px** (วัดจริง
   ที่จอ 900px) ตอนนี้ข้อความไปอยู่ในกล่องซ้อนแล้ว (`read-aloud.js` → `say()`)

   🔴 **ห้ามเอากลไกนี้กลับมา** ไม่ว่ารูปแบบไหน — ทุกอย่างที่กินที่ใน
   `.description-header` จะดันคำบรรยายลงทันที
   ------------------------------------------------------------------ */
.product-description .btn-read-aloud__note {
  flex-basis: 100%;
  order: 9;
  margin-top: 10px;
  padding: 10px 14px;
  border-radius: 10px;
  border: 1px solid rgba(var(--text-secondary-rgb), 0.35);
  background: rgba(var(--text-secondary-rgb), 0.08);
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-secondary);
  text-align: left;
}

.product-description .btn-read-aloud__note:empty,
.product-description .btn-read-aloud__note[hidden] {
  display: none;
}

.product-description .btn-read-aloud__note--error {
  border-color: rgba(220, 76, 100, 0.55);
  background: rgba(220, 76, 100, 0.12);
  color: #ffb4c0;
}

/* ============================================================
   ไฮไลต์คำที่กำลังอ่าน (ผู้ใช้สั่ง 2026-08-21)

   คำที่เสียงอ่านถึงเปลี่ยนเป็นขาวล้วน #ffffff เพื่อให้ตาไล่ตามได้
   กดหยุดหรืออ่านจบ คลาสถูกถอดออก สีกลับเป็นเดิมเอง

   ⚠️ `.es-read-word` ถูก JS ห่อรอบทุกคำในคำบรรยาย **ต้องไม่มีสไตล์ใด ๆ
   ตอนปกติ** ไม่งั้นหน้าตาเพี้ยนทั้งย่อหน้าแม้ยังไม่ได้กดอ่านเลย
   ============================================================ */
/*
 * ⚠️ **เปลี่ยนแค่ `color` ห้ามแตะ `font-weight` หรืออะไรที่กินที่**
 * ตัวหนาทำให้คำกว้างขึ้น ตัวหนังสือรอบ ๆ ขยับตามทุกครั้งที่เสียงเลื่อนคำ
 * ทั้งย่อหน้าเลยเด้งไปมาตลอดเวลาที่อ่าน (ผู้ใช้แจ้ง 2026-08-21)
 */
.product-description .es-read-word.is-reading {
  color: #ffffff;
}

/* ตัดคำแบบไทยยังทำงานเหมือนเดิม — span ต้องไม่กลายเป็นกล่องที่ห้ามตัดบรรทัด */
.product-description .es-read-word {
  display: inline;
}

/* ⚠️ **ห้ามใส่ `transition` ให้สีของคำ** — เสียงเดินคำละ ~0.3 วินาที
   ถ้าสีค่อย ๆ ไล่ ตอนที่คำถัดไปสว่างขึ้น คำก่อนหน้ายังจางไม่ทัน
   จะเห็นเป็นแถบสว่างสองสามคำพร้อมกัน แทนที่จะรู้ชัดว่าอ่านอยู่คำไหน
   (และทำให้ค่าที่อ่านได้จาก getComputedStyle เป็นสีระหว่างทาง ตรวจยากด้วย) */

/* ============================================================
   กล่องอธิบายเมื่อเครื่องผู้อ่านไม่มีเสียงภาษาไทย

   ⚠️ **ต้องดูเป็นกล่องแจ้งเตือน ไม่ใช่ข้อความลอย ๆ** (ผู้ใช้สั่ง 2026-08-21)
   ของเดิมเป็นตัวหนังสือบรรทัดเดียวใต้ปุ่ม อ่านแล้วไม่รู้ว่าเป็นคำเตือน
   และไม่บอกว่าต้องทำอะไรต่อ

   ใช้โทนสีเหลืองชุดเดียวกับกล่องเตือน XXL ในหน้าสินค้า เพื่อให้ทั้งเว็บ
   สื่อ "เรื่องที่ต้องอ่าน แต่ไม่ใช่ความผิดพลาด" ด้วยหน้าตาเดียวกัน

   ── 🔴 ทำไมกฎชุดนี้ไม่มี `.product-description` นำหน้า (2026-09-03) ──
   กล่องนี้ไม่ได้กางในหน้าอีกแล้ว — `read-aloud.js` ก๊อปมันไปแสดงใน
   **กล่องซ้อน** เพราะกางในแถวของปุ่มแล้วมันดันคำบรรยายลง 155.2px
   (ผู้ใช้แจ้ง: *"กดปุ่มแต่ไปทำเนื้อหาข้างล่างขยับ"*)
   ตัวที่อยู่ใน markup กลายเป็น **แม่แบบที่ซ่อนไว้ตลอด** ส่วนตัวที่คนเห็น
   เป็นสำเนาที่อยู่ใน `.es-confirm__text` ซึ่งไม่ได้อยู่ใต้ `.product-description`
   → ถ้าใส่ scope กลับไป กล่องในกล่องซ้อนจะไม่มีสไตล์เลย
   ============================================================ */
.es-speech-help {
  flex-basis: 100%;
  order: 10;
  margin-top: 12px;
  padding: 14px 16px;
  border: 1px solid rgba(240, 180, 41, 0.5);
  border-left-width: 4px;
  border-radius: 10px;
  background: rgba(240, 180, 41, 0.1);
  text-align: left;
}

.es-speech-help[hidden] {
  display: none;
}

.es-speech-help__title {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 6px;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.5;
  color: #f0b429;
}

.es-speech-help__body {
  margin: 0;
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-secondary);
}

.es-speech-help__how {
  margin-top: 10px;
  font-size: 13px;
}

.es-speech-help__how summary {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  color: var(--text-primary);
  font-weight: 600;
  list-style: none;
}

/* ลูกศรของ <details> ต่างกันทุกเบราว์เซอร์ — วาดเองให้เหมือนกันทุกที่ */
.es-speech-help__how summary::-webkit-details-marker {
  display: none;
}

/* ลูกศรหมุนได้ต้องมีกล่องของตัวเอง ไม่งั้นตอน rotate มันเบียดตัวหนังสือ */
.es-speech-help__how summary::before {
  content: "\f105";
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
  flex: 0 0 auto;
  width: 10px;
  text-align: center;
  transition: transform 0.2s;
}

.es-speech-help__how[open] summary::before {
  transform: rotate(90deg);
}

.es-speech-help__how dl {
  margin: 10px 0 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 14px;
}

.es-speech-help__how dt {
  font-weight: 700;
  color: var(--text-primary);
  white-space: nowrap;
}

.es-speech-help__how dd {
  margin: 0;
  color: var(--text-secondary);
  line-height: 1.7;
}

@media (max-width: 560px) {
  .es-speech-help__how dl {
    grid-template-columns: 1fr;
    gap: 2px;
  }

  .es-speech-help__how dd {
    margin-bottom: 8px;
  }
}

/* หัวข้อต้องยอมให้ตัดบรรทัดได้ ไม่งั้นข้อความบอกเหตุไปเบียดปุ่มจนล้น */
.product-description .description-header {
  flex-wrap: wrap;
}

/* ============================================================
   หน้า 404
   design ไม่ได้วาดไว้ — ประกอบจากโทนสีและรูปทรงเดียวกับหน้าอื่น
   ============================================================ */

/* หน้านี้ไม่มี app header และไม่มีแถบล่าง (ผู้ใช้สั่ง 2026-08-09)
   เนื้อหาจึงต้องจัดกลางแนวตั้งเอง ไม่งั้นจะไปกองอยู่ชิดขอบบนของจอ

   หน้านี้ **ไม่มีท้ายเว็บด้วย** (`es_marketplace_show_app_footer()`) `.site-main`
   จึงเป็นลูกตัวเดียวของ wrapper และสูงเท่าจอพอดีจาก `flex: 1 0 auto`
   + `body { min-height: 100dvh }` ของ design → `justify-content: center` ก็ตรงกลางจอเป๊ะ
   และความสูงรวมของหน้าเท่ากับจอ **ไม่เกิด scrollbar**

   ⚠️ **เคยแก้ผิดมาแล้วสองรอบ อย่าวนกลับไป:**
   1. `justify-content: center` เฉย ๆ ตอนที่ยังมีท้ายเว็บ — กล่องสูงแค่
      (จอ − ท้ายเว็บ) กึ่งกลางจึงลอยสูงกว่ากึ่งกลางจอครึ่งหนึ่งของความสูงท้ายเว็บ
   2. `min-height: 100dvh` ตอนที่ยังมีท้ายเว็บ — กลางจอตรง แต่หน้าสูงเป็น
      100dvh + ท้ายเว็บ = **มี scrollbar ทั้งที่เนื้อหาไม่ล้น**

   padding บนล่างของ `.error-404` ต้องเท่ากัน ไม่งั้นกึ่งกลางเยื้องตามส่วนต่าง
   (ตอนอยู่กลางจอมันไม่มีผลอยู่แล้ว แต่ตอนจอเตี้ยกว่าเนื้อหาแล้วต้องเลื่อน
   มันคือกันชนไม่ให้ตัวหนังสือชนขอบจอ)

   **ไม่ใส่ padding แนวนอน** — `.page-fixs-wrapper` ใส่ `0 var(--side-padding)`
   ให้ทุกหน้าอยู่แล้ว (20px / 32px เมื่อจอ ≥480) ถ้าใส่ซ้ำจะกลายเป็น 36/48px
   และ **ไม่ใส่ `padding-top` ที่ `.site-main`** — เคยมีไว้ชดเชยความสูงท้ายเว็บ
   พอเอาท้ายเว็บออกแล้วก็ไม่ต้องชดเชยอะไรอีก */
.error-404 {
  width: 100%;
  padding: 40px 0;
  text-align: center;
}

body.error404 .site-main {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.error-404__code {
  font-size: 110px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.08em;
  margin: 0 0 10px;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.error-404__title {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--text-primary);
  margin: 0 0 10px;
}

.error-404__text {
  font-size: 14px;
  line-height: 1.75;
  color: var(--text-secondary);
  max-width: 460px;
  margin: 0 auto 24px;
}

/* ── ช่องค้นหา ──
   ใช้คลาส `.header-search-wrapper` ตัวเดียวกับหน้า shop แล้ว (ผู้ใช้สั่ง 2026-09-16)
   ขอบเทา · ไล่สีวิ่งตอนชี้/พิมพ์ · ปุ่มแว่นขยาย มาจากกฎของช่องค้นหาหน้า shop ทั้งหมด
   (หัวข้อ "ขอบช่องค้นหา" + "ปุ่มแว่นขยายในช่องค้นหาบน header")
   ที่นี่คุมแค่ความกว้างให้เท่าปุ่มข้างล่าง กับระยะห่าง

   ⚠️ design ตั้ง `.header-search-wrapper { flex: 1; max-width: 500px }` ไว้สำหรับแถบหัวเว็บ
   หน้านี้อยู่ใน `.error-404` (ไม่ใช่ flex) จึงต้องบอกความกว้างเอง */
.error-404__search {
  width: 100%;
  max-width: 420px;
  margin: 0 auto 20px;
  text-align: left;
}

/* ── ปุ่ม ── */
.error-404__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin-bottom: 48px;
}

/* ปุ่ม BACK TO HOME = ปุ่มหลักของธีม `.btn-gradient` (ผู้ใช้สั่ง 2026-09-16 "เหมือน ADD NEW PRODUCT · OPEN STORE")
   ขอบไล่สี · พื้นดำ · hover สีวิ่ง · ขนาดตัวอักษร 15px มาจาก styles.css ทั้งหมด — ที่นี่คุมแค่ความกว้างกับจัดข้อความกลาง
   ⛔ เดิมเป็นชุด `.error-404__btn--primary` ที่มี `::before` ไล่สีแต่**ไม่มี `::after` ปิดพื้น** ปุ่มจึงกลายเป็นพื้นไล่สีทั้งปุ่ม
   ⚠️ เป็น <a> — ต้องสั่ง flex/กลางเอง (`.btn-gradient` ทำไว้สำหรับ <button>) · สีตัวอักษรตอน hover มีกฎกลาง `a[class*='btn']:hover` คุมอยู่แล้ว */
.btn-gradient.error-404__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 420px;
  box-sizing: border-box;
  text-decoration: none;
}

.error-404__suggest-title {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-primary);
  margin: 0 0 16px;
}

.error-404 .product-list {
  text-align: left;
}

@media (max-width: 480px) {
  .error-404__code { font-size: 84px; }
}

/* ============================================================
   กล่องฟอร์มของวิธีชำระเงิน (.payment_box)

   ค่าเริ่มต้นของ WooCommerce เป็นพื้นหลังสีม่วงอ่อน #dcd7e2 พร้อมสามเหลี่ยมชี้ขึ้น
   ซึ่งสว่างจ้าบนธีมเข้ม design เตรียม .omise-card-form ไว้ (checkout.css:364)
   จึงใช้ค่าชุดเดียวกันกับกล่องนี้
   ============================================================ */

/* WooCommerce ใช้ .woocommerce-checkout #payment div.payment_box (มี id)
   ต้องเทียบ specificity ให้ถึง ไม่งั้นพื้นหลัง #dcd7e2 ของมันชนะ           */
.woocommerce-checkout #payment div.payment_box,
.woocommerce-checkout #payment .payment-method .payment_box {
  width: 100%;
  background: var(--bg-secondary);
  background-color: var(--bg-secondary);
  color: var(--text-primary);
  border-radius: 12px;
  padding: 14px;
  margin: 10px 0 0;
  font-size: 13px;
  line-height: 1.6;
}

/* เอาสามเหลี่ยมชี้ขึ้นของ WooCommerce ออก */
.woocommerce-checkout #payment div.payment_box::before {
  display: none;
}

.woocommerce-checkout #payment div.payment_box p {
  margin: 0 0 8px;
  color: var(--text-secondary);
}

.woocommerce-checkout #payment div.payment_box p:last-child {
  margin-bottom: 0;
}

/* .payment-method ของ design เป็น flex แนวนอน (ไอคอน + ชื่อ)
   กล่องฟอร์มเป็นลูกอีกตัวจึงถูกดันไปอยู่ข้าง ๆ — บังคับให้ตกลงบรรทัดใหม่เต็มความกว้าง

   ⚠️ **ห้าม scope ด้วย `.payment-methods`** เหตุผลเดียวกับกฎ label ข้างล่าง
   หน้า order-pay ใช้ <ul class="wc_payment_methods payment_methods methods">
   ที่ไม่มีคลาสนั้น กฎเลยไม่ติด → ชื่อวิธีชำระเงินกับฟอร์มบัตรไปเรียงเป็น
   สองคอลัมน์ ไม่เหมือนหน้า checkout (ผู้ใช้ทัก 2026-08-13)
   ยึดที่ <li> เองเหมือนกัน จะได้มีผลทั้งสองหน้า */
.payment-method.wc_payment_method {
  flex-wrap: wrap;
}

/* ⚠ ห้าม scope ด้วย .payment-methods
   หน้า checkout ใช้ payment.php ของเราซึ่งใส่คลาสนั้นให้ <ul>
   แต่หน้า order-pay เรียก markup ของ WooCommerce ตรง ๆ ได้
   <ul class="wc_payment_methods payment_methods methods"> ที่ไม่มีคลาสนั้น
   → กฎไม่ติด label เหลือกว้าง 86px จากกล่อง 896px
   กดตรงไหนของการ์ดก็ไม่เลือกวิธีชำระเงิน แล้วไปติด validation ของฟอร์มบัตร
   ยึดที่ตัว <li> เองแทน จะได้มีผลทุกหน้า */
.payment-method.wc_payment_method > label {
  display: flex;
  align-items: center;
  align-self: stretch;
  gap: 12px;
  flex: 1 1 auto;
  cursor: pointer;
  margin: 0;
}

.payment-method.wc_payment_method .payment_box {
  flex: 1 1 100%;
}

/* ฟอร์มบัตรของ Omise ฝังมาเป็น iframe ที่ธีมสีของมันเองแล้ว
   ที่นี่แค่จัดพื้นที่รอบ ๆ ให้ไม่มีขอบขาว                        */
#omise_cc_form,
.omise-new-card-form {
  width: 100%;
}

#omise-card {
  width: 100% !important;
  max-width: none !important;
}

/* 🔴 iframe ของ Omise ต้องประกาศชุดสีสว่างเอง
   หน้าบ้านประกาศ <meta name="color-scheme" content="dark"> (inc/webapp.php)
   เบราว์เซอร์จะปูพื้นขาวทึบใต้ iframe คนละโดเมนที่ชุดสีไม่ตรงกับหน้าแม่
   (pay.html ของ Omise ไม่ประกาศ = สว่าง) → ฟอร์มบัตรกลายเป็นกล่องขาว
   ตั้ง light ที่ตัว iframe ให้ตรงกับเอกสารข้างใน พื้นจะกลับมาโปร่งใส
   ครอบ #payment ทั้งก้อน (ผ่อนชำระ/Google Pay) + หน้าบัตรที่บันทึกไว้ในบัญชี
   ฟอนต์ข้างใน iframe คุมจาก CSS นี้ไม่ได้ — ตั้งที่หลังบ้าน Omise
   (Card form customization → Font "Other" → Anuphan)                    */
#payment iframe,
#omise-card iframe {
  color-scheme: light;
}

.omise-banks-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.omise-banks-list li {
  margin: 0;
}

/* รายการวิธีชำระเงินที่ยังไม่ถูกเลือก ให้ดูจางลงเล็กน้อย */
.payment-methods {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
}

/* ============================================================
   Gallery thumbnail — เชื่อม design เข้ากับ FlexSlider

   design เขียนไว้ตอนที่ยังไม่มี FlexSlider จึงมีสองจุดที่ไม่ตรงกัน:

   1) design ตั้ง .flex-control-thumbs li img { pointer-events: none }
      เพราะ prototype ผูก click ไว้ที่ <li>
      แต่ FlexSlider ผูก click ไว้ที่ <img> — รูปจึงกดไม่ได้เลย

   2) design ใช้ .flex-control-thumbs li.active วาดขอบไล่สี
      แต่ FlexSlider ใส่คลาส .flex-active ไว้ที่ <img> ไม่ใช่ <li>
      thumbnail ที่เลือกอยู่จึงไม่เคยถูกไฮไลต์
   ============================================================ */

.flex-control-thumbs li img {
  pointer-events: auto;
  cursor: pointer;
}

/* ให้ li ที่มีรูป .flex-active หน้าตาเหมือน li.active ของ design */
.flex-control-thumbs li:has(img.flex-active) {
  opacity: 1;
  border-color: transparent;
  isolation: isolate;
}

.flex-control-thumbs li:has(img.flex-active)::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 9px;
  background: var(--gradient);
  z-index: -1;
}

.flex-control-thumbs li:has(img.flex-active)::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 7px;
  background: var(--bg-primary);
  z-index: -1;
}

/* ============================================================
   PhotoSwipe — ปุ่มขยายรูปและหน้าต่างดูรูปเต็มจอ
   ============================================================ */

.woocommerce-product-gallery__trigger {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 3;
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(var(--bg-primary-rgb), 0.72);
  color: var(--text-primary);
  font-size: 0;
  text-decoration: none;
  backdrop-filter: blur(6px);
  transition: background 0.25s ease;
}

.woocommerce-product-gallery__trigger:hover {
  background: rgba(var(--bg-primary-rgb), 0.9);
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
}

/* ไอคอนแว่นขยาย — WooCommerce ส่งมาเป็นข้อความล้วน จึงวาดเองด้วย Font Awesome */
.woocommerce-product-gallery__trigger::before {
  content: '\f00e';
  font-family: 'Font Awesome 6 Free', 'Font Awesome 5 Free', sans-serif;
  font-weight: 900;
  font-size: 15px;
  line-height: 1;
}

/* หน้าต่างดูรูปเต็มจอต้องอยู่เหนือ header และ bottom nav ที่ fixed ไว้
   🔴 และต้องอยู่ **เหนือกล่องซ้อนของธีม** (`.avatar-cropper` 100001) — ผู้ใช้แจ้ง 2026-10-02:
   หน้าการเงิน กดดูสลิปในกล่องรายละเอียดรายการถอน แล้วรูปเต็มจอไปเปิดอยู่ข้างหลังกล่อง (เดิม 100000)
   รูปที่กดจากในกล่อง (สลิป · รูปแนบทิกเก็ต) จึงต้องทับกล่องได้ · ยังอยู่ใต้ตัวหมุนโหลดหน้า (100003) */
.pswp {
  z-index: 100002;
}

.pswp__bg {
  background: rgba(var(--bg-header-rgb), 0.96);
}

.pswp__caption__center {
  text-align: center;
  font-family: var(--font);
}

/* ── ลากแถบ thumbnail ── */
.flex-control-thumbs {
  cursor: grab;
  scroll-behavior: smooth;
  user-select: none;
  -webkit-user-select: none;
}

.flex-control-thumbs.is-dragging {
  cursor: grabbing;
  scroll-behavior: auto; /* ตอนลากต้องตามนิ้วทันที ไม่ต้อง smooth */
}

/* ระหว่างลากไม่ให้ hover ทำให้ opacity กระพริบ */
.flex-control-thumbs.is-dragging li:hover {
  opacity: 0.5;
}

.flex-control-thumbs.is-dragging li:has(img.flex-active):hover {
  opacity: 1;
}

.flex-control-thumbs img {
  -webkit-user-drag: none;
  user-select: none;
}

/* ============================================================
   ฟอร์มเพิ่ม/แก้ไขสินค้า บนมือถือ: รูปปกกับตารางแกลเลอรีอยู่บนกริดเดียวกัน
   (ผู้ใช้สั่ง 2026-09-20 — "จัด layout RWD รูปสินค้าและรูปแกลเลอรี ตาม grid ที่สมควรเป็น")

   เดิม (add-new-product.css `@media (max-width: 768px)`): กล่องรูปปกกว้าง 200px ตายตัว
   แล้ว `margin: 0 auto` ดันไปกึ่งกลาง ส่วนตารางแกลเลอรีเป็น 3 ช่องเต็มความกว้างชิดซ้าย
   → สองก้อนไม่ตรงกริดกัน และเหลือที่ว่างข้างรูปปกข้างละ ~80px

   ใหม่: รูปปก = 2 ช่องของตารางแกลเลอรีพอดี (2 ช่อง + ช่องไฟ 1 ช่อง) ชิดซ้ายตรงกัน
   ผู้ใช้เลือกแล้ว: ตารางแกลเลอรีคง 3 ช่อง × 2 แถวเหมือนเดิม
   🔴 ต้องคิดจากสูตรเดียวกับ `.gall-grid` (3 คอลัมน์ · ช่องไฟ 8px) ถ้าวันไหนเปลี่ยนจำนวน
      คอลัมน์หรือช่องไฟของตาราง ต้องมาแก้บรรทัดนี้ด้วย ไม่งั้นขอบซ้ายจะไม่ตรงกันอีก
   ============================================================ */
@media (max-width: 768px) {
  .trade-item-cover-box-wrap .trade-item-cover-box {
    /* 2 ช่อง + ช่องไฟ 1 ช่อง ของตาราง 3 คอลัมน์ */
    width: calc((100% - 16px) / 3 * 2 + 8px);
    max-width: none;
    margin: 0;
  }
}

/* ── แถบแบ่งหน้าของหน้าร้าน ──
   markup มาจาก es_marketplace_store_pagination() (inc/dokan.php)
   ที่เขียนแทน dokan_content_nav() — คลาสเดิมของ Dokan ทั้งหมด

   ที่ต้องเขียนทับ:
   1. `a { color: var(--grad-4) }` ของ design ทำให้ตัวเลขเป็นสีฟ้า
      และ `a:hover` (styles.css:197) ทำตัวอักษรโปร่งใสแล้วไล่สีทับ (กับดักข้อ 6)
      ผู้ใช้สั่งให้ hover เป็นสีขาวเรียบ ๆ แทน
   2. หน้าที่ยืนอยู่ต้อง **ไม่มี effect ตอน hover** เพราะกดไปก็ไม่ไปไหน */
/* ============================================================
   แถบแบ่งหน้า — ชุดเดียวใช้ทั้งเว็บ

   markup มาจาก `es_marketplace_pagination()` (inc/template-functions.php)
   ที่ใช้แทน `dokan_content_nav()`, `woocommerce_pagination()` และ
   `paginate_links()` ทั้งหมด **ถ้าเห็นหน้าไหนแบ่งหน้าคนละทรง แปลว่าหน้านั้น
   ยังเรียกของเดิมอยู่ ไม่ใช่ CSS ไม่ครอบคลุม**

   ที่ต้องเขียนทับ CSS ของ design:
   1. `a { color: var(--grad-4) }` ทำให้ตัวเลขเป็นสีฟ้า
   2. `a:hover` (styles.css:197) ทำตัวอักษรโปร่งใสแล้วไล่สีทับ (กับดักข้อ 6)
      ผู้ใช้สั่งให้ hover เป็นสีขาวเรียบ ๆ แทน
   ============================================================ */

.es-pagination {
  margin: 20px 0 8px;
}

/* หน้ากลาง ๆ ของร้านที่สินค้าเยอะได้ 11 ช่อง (ลูกศร 4 + ตัวเลข 5 + จุดไข่ปลา 2)
   พอดีจอ 390px — ถ้าเกิน (เลขหลายหลัก) ให้ตัดบรรทัดด้วย gap ไม่ใช่ margin
   ของ Dokan ที่ทำให้ระยะบรรทัดสองเบี้ยว */
.es-pagination__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.es-pagination__list li {
  display: block;
  margin: 0;
}

.es-pagination__list a,
.es-pagination__list li.is-current span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* กว้างเท่ากันทุกช่อง ไม่งั้นช่องลูกศรแคบกว่าช่องตัวเลขจนแถบดูเบี้ยว */
  min-width: 34px;
  min-height: 30px;
  padding: 0 8px;
  border: 1px solid rgba(var(--text-secondary-rgb), 0.35);
  border-radius: 8px;
  background: rgba(var(--bg-input-rgb), 0.7);
  color: var(--text-secondary);
  font-size: 13px;
  line-height: 1;
  text-decoration: none;
  transition: color 0.2s, background 0.2s, border-color 0.2s;
}

/* ไอคอนลูกศร (Font Awesome) — เล็กกว่าตัวเลขนิดหนึ่งถึงจะดูเท่ากัน
   เพราะ glyph ของไอคอนเต็มความสูงบรรทัด ส่วนตัวเลขมีช่องว่างบนล่างในตัว */
.es-pagination__list a i {
  font-size: 12px;
  line-height: 1;
}

.es-pagination__list a:hover {
  color: #fff;
  -webkit-text-fill-color: #fff;
  background: rgba(var(--text-primary-rgb), 0.14);
  border-color: rgba(var(--text-primary-rgb), 0.45);
  /* ล้างไล่สีของ a:hover ที่ design ตั้งไว้ทั้งเว็บ */
  background-clip: border-box;
  animation: none;
}

/* หน้าปัจจุบันเป็น <span> ไม่ใช่ <a> จึงไม่มี hover ให้ต้องปิดตั้งแต่แรก
   ⚠️ **ห้ามใช้ `background: var(--gradient)`** — เคยเผลอหยิบมาจากชุดเดิมของ
   vendor dashboard ตอนรวม CSS แล้วแถบไล่สีเด่นจนแย่งสายตาไปจากสินค้า
   ทรงที่ใช้จริงคือพื้นขาวจาง ๆ กับกรอบ แค่บอกว่า "อยู่หน้านี้" ไม่ใช่ปุ่มเรียกร้องให้กด */
.es-pagination__list li.is-current span {
  background: rgba(var(--text-primary-rgb), 0.12);
  border-color: rgba(var(--text-primary-rgb), 0.45);
  color: var(--text-primary);
  font-weight: 600;
  cursor: default;
}

/* จุดไข่ปลาไม่ใช่ปุ่ม ไม่ต้องมีกรอบ */
.es-pagination__list li.is-dots span {
  padding: 0 4px;
  color: var(--text-muted);
  font-size: 13px;
}

/* ซ่อนเมื่อ JS โหลดต่อเนื่องทำงานแล้ว — ห้ามซ่อนตั้งแต่แรก
   ไม่งั้น JS พัง = ไปหน้า 2 ไม่ได้เลย และ search engine ต้องเห็นลิงก์นี้เสมอ */
body.js-infinite .es-pagination {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ============================================================
   ปุ่มเปิดร้านในหน้าบัญชี + ฟอร์มขอเปิดร้าน
   ============================================================ */

#createStoreBtn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  margin: 20px 0 0;
  text-decoration: none;
}

/* สถานะรออนุมัติ — เป็น span กดไม่ได้ ทำให้ดูจางลงและเปลี่ยน cursor */
#createStoreBtn.is-pending {
  opacity: 0.65;
  cursor: not-allowed;
}

.create-store-wrapper {
  width: 100%;
}

.create-store-wrapper .form-hint {
  margin: 6px 0 0;
  font-size: 12px;
  color: var(--text-secondary);
}

/* หมายเหตุใต้ชื่อ-นามสกุลผู้ยื่นขอ (2026-09-11) — อยู่นอก .form-group
   ถ้าใช้ margin ของ .form-hint ตรง ๆ จะชิดป้าย "ลิงก์ร้าน" ข้างล่างจนอ่านเป็นก้อนเดียวกัน */
.create-store-wrapper .es-applicant-note {
  margin: 0 0 18px;
}

.create-store-wrapper .form-hint code {
  background: rgba(var(--text-primary-rgb), 0.08);
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 11px;
}

.create-store-wrapper .tab-fields[hidden] {
  display: none;
}

.create-store-wrapper .form-group--checkbox .form-label {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

.create-store-wrapper .form-group--checkbox input {
  width: auto;
  margin: 0;
}

.create-store-actions {
  margin-top: 24px;
}

.create-store-actions .btn-gradient {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
}

/* ช่องที่จำเป็นแต่ยังซ่อนอยู่ ต้องไม่โดน :invalid วาดขอบแดง */
.create-store-wrapper .tab-fields[hidden] .form-input {
  border-color: transparent;
}

/* ============================================================
   หน้าบัญชีผู้ใช้
   ============================================================ */

/* WooCommerce จัดหน้าบัญชีเป็นสองคอลัมน์ลอย (nav 30% / content 68%)
   design เป็นคอลัมน์เดียวเรียงลงมา จึงต้องยกเลิก float ทั้งคู่          */
.woocommerce-account .woocommerce-MyAccount-navigation,
.woocommerce-account .woocommerce-MyAccount-content {
  float: none;
  width: 100%;
}

/* เมนูของ WooCommerce ท้ายหน้า — design ไม่มีเมนูข้าง
   ทำเป็นแถวลิงก์แทน list ธรรมดา                                    */
.woocommerce-MyAccount-navigation {
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid rgba(var(--text-secondary-rgb), 0.2);
}

.woocommerce-MyAccount-navigation ul {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.woocommerce-MyAccount-navigation li {
  margin: 0;
}

.woocommerce-MyAccount-navigation a {
  display: inline-flex;
  align-items: center;
  padding: 9px 18px;
  border-radius: 999px;
  border: 1px solid rgba(var(--text-secondary-rgb), 0.35);
  background: rgba(var(--text-primary-rgb), 0.04);
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  transition: border-color 0.25s ease, color 0.25s ease;
}

.woocommerce-MyAccount-navigation a:hover,
.woocommerce-MyAccount-navigation li.is-active a {
  color: var(--text-primary);
  border-color: var(--grad-2);
  -webkit-text-fill-color: var(--text-primary);
}

/* ปุ่มออกจากระบบให้เด่นกว่าเมนูอื่น */
.woocommerce-MyAccount-navigation li.woocommerce-MyAccount-navigation-link--customer-logout a {
  border-color: rgba(var(--stat-error-rgb), 0.5);
  color: var(--stat-error);
}

/* ── รูปโปรไฟล์ + ปุ่มเปลี่ยนรูป ── */
.profile-picture {
  position: relative;
}

.profile-picture img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  display: block;
}

/* ปุ่มเปลี่ยนรูปโปรไฟล์ — มุมขวาล่างของรูป
   design วางไว้ซ้าย (.profile-picture-icon) แต่ผู้ใช้เลือกให้อยู่ขวา   */
.profile-picture__edit {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 2px solid var(--bg-header);
  border-radius: 50%;
  background: var(--grad-4);
  color: var(--bg-primary);
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  transition: transform 0.2s ease;
}

.profile-picture__edit:hover {
  transform: scale(1.08);
}

/* ── การ์ดคำสั่งซื้อ: ปุ่มท้ายการ์ด (design ไม่มี ผู้ใช้ต้องมีทางไปต่อ) ── */
.order-card__actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  margin-top: 10px;
}

.order-card__action-link {
  padding: 7px 16px;
  border-radius: 999px;
  border: 1px solid rgba(var(--text-secondary-rgb), 0.35);
  color: var(--text-secondary);
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
}

.order-card__action-link--primary {
  border-color: var(--grad-2);
  color: var(--grad-2);
}

.order-card__action-link:hover {
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
}

/* ── กันหน้าพังเมื่อปลั๊กอินอื่นเพิ่ม endpoint เข้ามาในหน้าบัญชี ──
   บังคับให้ตาราง/ฟอร์มที่ไม่รู้จักอยู่ในกรอบและใช้สีของธีม        */
.woocommerce-MyAccount-content table {
  width: 100%;
  max-width: 100%;
  border-collapse: collapse;
  color: var(--text-primary);
}

.woocommerce-MyAccount-content table th,
.woocommerce-MyAccount-content table td {
  padding: 10px;
  border-bottom: 1px solid rgba(var(--text-secondary-rgb), 0.18);
  text-align: left;
}

/* ให้เฉพาะตารางเลื่อนแนวนอนได้ ไม่ใช่ทั้งกล่องเนื้อหา
   ไม่งั้นแค่มีข้อความสั้น ๆ ก็ขึ้น scrollbar ครอบทั้งบล็อก      */
.woocommerce-MyAccount-content table {
  display: block;
  overflow-x: auto;
  white-space: nowrap;
}

.woocommerce-MyAccount-content h2,
.woocommerce-MyAccount-content h3,
.woocommerce-MyAccount-content legend {
  color: var(--text-primary);
}

/* ⚠ ยกเว้นหัวข้อย่อยในฟอร์มแก้ไขโปรไฟล์
   design ตั้ง .profile-section-title เป็นสีจาง (--text-secondary)
   แต่กฎด้านบน (0,2,1) ชนะกฎของ design (0,1,0) ทำให้กลายเป็นสีขาว
   หัวข้อ "ข้อมูลส่วนตัว" / "ที่อยู่จัดส่ง" จึงเด่นเท่าตัวเนื้อหา */
.woocommerce-MyAccount-content h3.profile-section-title,
.woocommerce-MyAccount-content h2.profile-section-title {
  color: var(--text-secondary);
}

.woocommerce-MyAccount-content fieldset {
  border: 1px solid rgba(var(--text-secondary-rgb), 0.25);
  border-radius: 12px;
  padding: 16px;
  margin: 20px 0;
}

/* ── หัวโปรไฟล์ ──
   ค่าทั้งหมดตาม design (profile.css:5-44) — เคยขยายรูปเป็น 84px และย่อชื่อ
   เป็น 18px เพื่อกันปุ่มกล้องทับชื่อ แต่ทำให้ผิด design ทั้งบล็อก
   ปุ่มกล้องอยู่ได้เพราะ .profile-picture img มี border-radius ของตัวเอง
   จึงไม่ต้องพึ่ง overflow: hidden ของกล่องแม่ในการตัดรูปให้กลม */
.profile-picture {
  overflow: visible;
}

.profile-name {
  word-break: break-word;
}

/* .btn-edit-profile เป็น <a> ไม่ใช่ <button> จึงต้องจัดกึ่งกลางเอง */
a.btn-edit-profile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}

/* ============================================================
   ปุ่มที่เราแปลงจาก <button> ของ design เป็น <a>

   design ตั้ง a:hover ให้ตัวอักษรโปร่งใสแล้วไล่สีผ่าน background-clip
   (styles.css:197) ปุ่มที่มีพื้นหลังของตัวเองจึงกลายเป็นตัวหนังสือหาย
   design เองก็ยกเว้นให้ .bnav-item / .product-card a / .category-list__item a
   ที่นี่ยกเว้นให้ปุ่มทั้งหมดที่เราทำเป็น <a> ด้วยเหตุผลเชิงโครงสร้าง
   (ลิงก์ต้องเป็น <a> เพื่อให้กดขวาเปิดแท็บใหม่ได้และ crawler เดินตามได้)
   ============================================================ */

/*
 * 🔴 **เลิกไล่ใส่ทีละปุ่ม — ใช้แพตเทิร์นคลุมทั้งหมด (2026-08-13)**
 *
 * เดิมบรรทัดนี้เป็นรายชื่อปุ่มที่ต้องมาเติมเองทุกครั้งที่ทำปุ่มใหม่
 * ผลคือมีปุ่มหลุดเรื่อย ๆ แล้วผู้ใช้ต้องมาทักซ้ำ ๆ ("แก้แล้วไม่หายขาด")
 *
 * `[class*="btn"]` / `[class*="button"]` ครอบทุกคลาสปุ่มของ design ที่เป็น `<a>`
 * ทั้งที่มีอยู่และที่จะทำเพิ่มในอนาคต — ปุ่มใหม่ไม่ต้องมาเติมที่นี่อีก
 * ที่เหลือด้านล่างคือลิงก์ที่ทำหน้าที่เป็นปุ่มแต่ชื่อคลาสไม่มีคำว่า btn/button
 */
a[class*='btn']:hover,
a[class*='btn']:focus,
a[class*='button']:hover,
a[class*='button']:focus,
a[class*='btn']:hover i,
a[class*='button']:hover i,
a.error-404__btn:hover,
a.product-load-more:hover,
a.order-card__action-link:hover,
a.product-item:hover,
a.product-item:hover .product-badge,
a.woocommerce-MyAccount-navigation a:hover,
.woocommerce-MyAccount-navigation a:hover,
.order-card__product-info h4 a:hover,
.cart-item-name a:hover,
a.vendor-action-btn:hover,
a.order-tracking-link:hover {
  color: var(--text-primary);
  /*
   * ตัวที่ทำให้ตัวหนังสือหายคือ `-webkit-text-fill-color: transparent`
   * ของ `a:hover` (styles.css:197) — มัน **สืบทอดลงไปถึงลูกทุกตัว** ด้วย
   * ป้าย sold ที่อยู่ข้างใน `<a class="product-item">` จึงหายไปทั้งที่
   * ตัวมันเองตั้งสีไว้แล้ว ต้องสั่งคืนที่ลูกด้วย ไม่ใช่แค่ที่ <a>
   */
  -webkit-text-fill-color: var(--text-primary);
  /* ตัดเฉพาะผืนไล่สี ไม่แตะ background-color ที่ปุ่มแต่ละตัวตั้งไว้เอง */
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

/*
 * ⚠️ **ห้ามยกเว้น a:hover ให้ลิงก์ผู้ขาย**
 * เคยเข้าใจผิดว่าต้องคืนสีให้เหมือนตอนไม่ hover แล้วไปตัดเอฟเฟกต์ทิ้ง
 * ตรวจ design แล้ว — `styles.css:197` ไล่สีให้ลิงก์ทุกตัว และยกเว้นไว้แค่
 * `.bnav-item`, `.nav-tabs-item a`, `.product-card a` ฯลฯ
 * **ไม่มี `.vendor-info a` อยู่ในรายการยกเว้น** = ตั้งใจให้ไล่สีตอน hover
 */

/*
 * ลิงก์ผู้ขายต้องกว้างเท่าเนื้อหา ไม่ใช่เต็มบรรทัด
 *
 * design ตั้ง `.vendor-info a { display: flex }` ซึ่งทำให้ `<a>` เป็น block
 * กินความกว้าง 100% → เอาเมาส์ไปชี้ตรงพื้นที่ว่างข้าง ๆ ก็ติด hover
 * ทั้งที่ควรติดเฉพาะตรงรูปกับชื่อร้าน
 *
 * `inline-flex` + `width: fit-content` ทำให้กล่องหดเท่าเนื้อหาจริง
 * ส่วน `.vendor-info` ยังเป็น block เต็มบรรทัดเหมือนเดิม เลย์เอาต์ไม่ขยับ
 */
.vendor-info a.vendor-link {
  display: inline-flex;
  width: fit-content;
  max-width: 100%;
}

/*
 * "(ออนไลน์ล่าสุดเมื่อ …)" ต่อท้ายชื่อร้าน
 *
 * เป็นข้อมูลประกอบ ไม่ใช่ตัวเอก จึงเล็กและจางกว่าชื่อร้าน
 * ร้านที่เงียบเกินเกณฑ์ (ดู es_marketplace_vendor_is_stale) เปลี่ยนเป็นสีเตือน
 * เพื่อให้สะดุดตาตั้งแต่หน้าสินค้า ก่อนจะไปเจอกล่องแดงในตะกร้า
 *
 * **หน้าสินค้าอยู่บรรทัดเดียวกับชื่อร้าน** — `.vendor-info` ของ design
 * (single-product.css:154) เป็น block เปล่า ๆ ทำให้ `<span>` ตกลงบรรทัดใหม่
 * เปลี่ยนเป็น flex แถวเดียว จัดกึ่งกลางตามแนวตั้งให้ตรงกับรูปร้าน
 * `flex-wrap` ไว้กันข้อความยาวล้นจอแคบ
 *
 * **หน้าร้านอยู่คนละบรรทัด** ตามที่ design วางไว้ (ใต้ชื่อร้าน)
 */
.vendor-info {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.vendor-last-seen {
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-secondary);
}

/*
 * หน้าร้าน — เวลาออนไลน์อยู่ใต้รูปร้าน (ผู้ใช้สั่ง 2026-08-10)
 *
 * `.store-header` ของ design เป็น flex แถวเดียว จัดกึ่งกลางตามแนวตั้ง
 * (store-profile.css:มีอยู่แล้ว) จึงห่อรูปกับข้อความไว้ในคอลัมน์เดียว
 * ไม่งั้นข้อความจะไปแทรกเป็นคอลัมน์ที่สามข้าง ๆ รูป
 *
 * รูปกว้าง 72px คงที่ — ข้อความยาวกว่านั้นได้ จึงไม่ล็อกความกว้าง
 * แต่ `text-align: center` ให้อยู่กึ่งกลางใต้รูป
 */
.store-picture-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

.store-picture-col .store-last-seen {
  margin: 0;
  font-size: 11px;
  line-height: 1.4;
  text-align: center;
  white-space: nowrap;
  color: var(--text-secondary);
}

.vendor-last-seen--stale,
.store-picture-col .store-last-seen--stale {
  color: #e5484d;
}

/*
 * แท็บเล็ตลงมา: "ออนไลน์ล่าสุด" ย้ายขึ้นไปอยู่เหนือลิงก์ร้าน (ผู้ใช้สั่ง 2026-08-11)
 *
 * ต่ำกว่า 769px `.store-header` เป็นแถว — รูปซ้าย ข้อมูลร้านขวา
 * ข้อความจึงไปห้อยใต้รูปในคอลัมน์ซ้ายซึ่งแคบและอ่านยาก
 *
 * ใช้ grid + `display: contents` ที่ตัวห่อ เพื่อดึงรูปกับข้อความออกมาเป็น
 * grid item คนละช่องโดย **ไม่ต้องย้าย markup** — จอ ≥769px ที่เป็นคอลัมน์
 * และหัวร้านฝั่ง dashboard จะไม่ได้รับผลกระทบเลย
 * (จำกัดด้วย `.dokan-store` = หน้าร้านสาธารณะเท่านั้น)
 */
@media (max-width: 768px) {
  .dokan-store .store-header {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "pic info";
    align-items: center;
    column-gap: 16px;
  }

  .dokan-store .store-picture-col {
    display: contents;
  }

  .dokan-store .store-header .store-picture {
    grid-area: pic;
    align-self: baseline;
  }

  .dokan-store .store-header .store-info {
    grid-area: info;
  }
}

/*
 * บัญชีรับเงินคืนในหน้าแก้ไขโปรไฟล์
 *
 * design ไม่มีหน้าตาของส่วนนี้ (เพิ่งมามีตอนทำระบบยกเลิกอัตโนมัติ)
 * ทำเป็นการ์ดใบละบัญชี หัวการ์ดมีชื่อกับปุ่มลบ ตัวฟอร์มใช้คลาสเดิมของหน้านี้
 * ปุ่ม "เพิ่มบัญชี" โคลนการ์ดเปล่าออกมาทันที (assets/js/bank-accounts.js)
 */

.es-bank-accounts {
  width: 100%;
}

.es-bank-accounts__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

/* หัวข้อในกล่องนี้อยู่แถวเดียวกับปุ่ม จึงไม่ต้องมีระยะล่างของตัวเอง */
.es-bank-accounts__head .profile-section-title {
  margin-bottom: 0;
}

.es-bank-add {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  padding: 7px 14px;
  border-radius: var(--radius-btn, 50px);
  border: 1px solid rgba(var(--grad-2-rgb), 0.55);
  background: rgba(var(--grad-2-rgb), 0.12);
  color: var(--grad-2);
  font-family: var(--font);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.2s ease;
}

.es-bank-add:hover {
  background: rgba(var(--grad-2-rgb), 0.22);
}

/* คำอธิบายใต้หัวข้อ — เล็กลงและถอยห่างจากแถวหัวข้อ+ปุ่มอีกหน่อย
   (`.form-hint` ของ store.css เป็น 12px / margin-top 6px ซึ่งชิดเกินไปตรงนี้) */
.es-bank-accounts > .form-hint {
  margin-top: 12px;
  font-size: 11px;
  line-height: 1.7;
}

.es-bank-list {
  display: grid;
  gap: 12px;
  margin-top: 14px;
}

.es-bank-card {
  padding: 14px;
  border: 1px solid rgba(var(--text-secondary-rgb), 0.22);
  border-radius: 14px;
  background: rgba(var(--text-primary-rgb), 0.03);
}

/* ติ๊กลบไว้แล้วแต่ยังไม่ได้กดบันทึก — ยังเห็นอยู่แต่บอกให้รู้ว่ากำลังจะหาย */
.es-bank-card.is-removing {
  opacity: 0.45;
  border-style: dashed;
}

.es-bank-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}

.es-bank-card__title {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.es-bank-card__delete {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(var(--stat-error-rgb), 0.12);
  color: var(--stat-error);
  font-size: 13px;
  cursor: pointer;
  transition: background 0.2s ease;
}

.es-bank-card__delete:hover {
  background: rgba(var(--stat-error-rgb), 0.24);
}

/* ช่องกรอกในการ์ดไม่ต้องเว้นล่างเท่าฟอร์มหลัก ระยะมาจาก gap ของกริดแทน */
.es-bank-card__grid {
  display: grid;
  gap: 0 14px;
}

.es-bank-card__grid > .form-group {
  margin-bottom: 12px;
}

.es-bank-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding-top: 10px;
  border-top: 1px dashed rgba(var(--text-secondary-rgb), 0.18);
}

.es-bank-card__primary,
.es-bank-card__remove {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-secondary);
  cursor: pointer;
}

.es-bank-card__primary input,
.es-bank-card__remove input {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  margin: 0;
  accent-color: var(--grad-2);
  cursor: pointer;
}

/*
 * ปุ่มถังขยะกับช่องติ๊ก "ลบบัญชีนี้ตอนบันทึก" ทำงานแทนกัน
 * มี JS → ใช้ปุ่ม (ช่องติ๊กถูกซ่อนแต่ยังส่งค่าไปกับฟอร์ม)
 * ไม่มี JS → ปุ่มไม่มีประโยชน์ ซ่อนปุ่มแล้วโชว์ช่องติ๊กแทน
 */
.es-bank-accounts.has-js .es-bank-card__remove {
  display: none;
}

.es-bank-accounts:not(.has-js) .es-bank-card__delete {
  display: none;
}

/* จอกว้างพอ: ธนาคารกับเลขบัญชีอยู่บรรทัดเดียวกัน ชื่อบัญชีเต็มความกว้าง */
@media (min-width: 560px) {
  .es-bank-card {
    padding: 16px 18px;
  }

  .es-bank-card__grid {
    grid-template-columns: 1fr 1fr;
  }

  .es-bank-card__wide {
    grid-column: 1 / -1;
  }
}

/* ============================================================
   รายการคำสั่งซื้อในหน้าบัญชี — ปรับตามที่ผู้ใช้สั่ง (2026-08-11)
   ============================================================ */

/*
 * ⚠️ `.order-card-list` **ไม่เคยมี CSS เลย** การ์ดจึงติดกันสนิททุกแท็บ
 *
 * design ไม่ได้ใช้ชื่อคลาสนี้ — ของ design คือ `.profile-order-list` ที่ตั้ง
 * `gap: 12px` ไว้ (styles.css:2336) แต่ตอนแปลงเป็น PHP เปลี่ยนชื่อคลาส
 * แล้วไม่ได้ย้าย CSS ตาม ระยะห่างเลยหายไปทั้งหมดโดยไม่มีอะไรฟ้อง
 *
 * ฝั่งผู้ขายไม่มีปัญหานี้ — `.store-tab-panel` ตั้ง gap ไว้แล้ว (store.css:514)
 */
.order-card-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-bottom: 60px;
}

/*
 * กดที่การ์ดเพื่อดูรายละเอียด + บอกให้รู้ว่ากำลังชี้อยู่
 * design ใช้ `onclick` ฝังใน HTML (profile.html:246) ซึ่งเอามาใช้ตรง ๆ ไม่ได้
 * ตัวจัดการอยู่ใน vendor-dashboard-ui.js อ่านจาก `data-order-href`
 */
.order-card[data-order-href] {
  cursor: pointer;
  transition: box-shadow 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.order-card[data-order-href]:hover {
  border-color: rgba(var(--grad-2-rgb), 0.55);
  box-shadow: 0 6px 20px rgba(var(--grad-1-rgb), 0.18);
  transform: translateY(-2px);
}

/* สลิปการโอนเงินคืนในหน้าคำขอคืนของผู้ซื้อ */
.return-refund-slip {
  display: block;
  max-width: 240px;
  height: auto;
  margin: 8px 0;
  border-radius: 8px;
}

/* ปุ่มที่มีสีเฉพาะของตัวเอง ให้คงสีเดิมไว้ */
a.order-card__action-link--primary:hover {
  color: var(--grad-2);
  -webkit-text-fill-color: var(--grad-2);
}

.woocommerce-MyAccount-navigation-link--customer-logout a:hover {
  color: var(--stat-error);
  -webkit-text-fill-color: var(--stat-error);
}

/* ============================================================
   หน้าแก้ไขโปรไฟล์
   ============================================================ */

.edit-profile-avatar {
  display: flex;
  justify-content: center;
}

.edit-profile-avatar .profile-picture {
  width: 104px;
  height: 104px;
  flex: 0 0 104px;
}

.edit-profile-wrapper .profile-name {
  text-align: center;
  margin: 0 0 24px;
}

/* ⚠ design วางชื่อไว้ใน .edit-profile-wrapper จึงได้ขนาดจาก
   styles.css `.edit-profile-wrapper .profile-name { font-size: 22px }`
   ของเราชื่ออยู่ในฟอร์มเหมือนกัน แต่กฎอื่นของ profile.css (0,1,0) ชนกัน
   ระบุค่าให้ชัดตามหน้า เพื่อให้ตรงทั้งมือถือและ ≥769px */
.woocommerce-edit-account .profile-name {
  font-size: 22px;
  letter-spacing: 0.08em;
}

.woocommerce-edit-account .profile-info {
  gap: 4px;
}

@media (min-width: 769px) {
  .woocommerce-edit-account .profile-name {
    font-size: 26px;
  }
}

/* ส่วนเปลี่ยนรหัสผ่านแบบพับได้ */
/* ⚠ ส่วนนี้ไม่มีใน design (edit-profile.html ไม่มีช่องรหัสผ่านเลย)
   เป็นของที่เพิ่มเข้ามาเพราะฟอร์มบัญชีของ WooCommerce มีให้เปลี่ยนรหัสผ่าน
   เดิมทำเป็นกล่องมีขอบ+padding 16px ทำให้ช่องกรอกข้างในเหลือ 268px
   ทั้งที่ช่องอื่นทั้งหน้ากว้าง 302px — ตัดขอบกล่องออก ใช้เส้นคั่นด้านบนแทน
   ช่องกรอกจึงเรียงตรงกับส่วนอื่นของหน้า */
.edit-profile-password {
  margin: 18px 0;
  padding: 14px 0 0;
  border-top: 1px solid rgba(var(--text-secondary-rgb), 0.25);
}

.edit-profile-password > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  list-style: none;
}

.edit-profile-password > summary::-webkit-details-marker {
  display: none;
}

.edit-profile-password > summary::before {
  content: '\f107'; /* chevron-down */
  font-family: 'Font Awesome 6 Free', 'Font Awesome 5 Free', sans-serif;
  font-weight: 900;
  margin-right: 8px;
  display: inline-block;
  transition: transform 0.2s ease;
}

.edit-profile-password[open] > summary::before {
  transform: rotate(180deg);
}

.edit-profile-password[open] > summary {
  margin-bottom: 14px;
  color: var(--text-primary);
}

/* ปุ่มบันทึกในแถบล่างเต็มความกว้าง */
.bottom-nav-container > .btn-gradient {
  width: 100%;
}

/* แถบสถานะคำสั่งซื้อ — ลากได้เหมือนแถบ thumbnail */
#profileOrderScroll {
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
}

#profileOrderScroll.is-dragging {
  cursor: grabbing;
}

/* ============================================================
   หน้าเข้าสู่ระบบ / สมัครสมาชิก
   ============================================================ */

/* design มีแค่ลิงก์ "ลืมรหัสผ่าน" จัดกึ่งกลาง
   ผู้ใช้สั่งเพิ่ม "จดจำในระบบ" ชิดซ้าย ลิงก์ชิดขวา จึงเป็นสองฝั่ง */
.login-form .forgot-wrapper {
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.login-remember {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  color: var(--text-secondary);
  cursor: pointer;
  user-select: none;
}

.login-remember input {
  width: auto;
  margin: 0;
  accent-color: var(--grad-2);
  cursor: pointer;
}

/* ⚠ WooCommerce ใส่ margin/padding ให้ form.login กับ form.register เอง
   (woocommerce.css: .woocommerce form.login, .woocommerce form.register
    { border:1px solid; padding:20px; margin:2em 0 })
   ทำให้ฟอร์มแคบลง 40px และเนื้อหาไม่ตรงกับ design ทั้งหน้า
   เทียบ computed style กับ signin-signup.html แล้วต่างกันเกือบทุก element
   เพราะข้อนี้ข้อเดียว */
/* ต้องใส่ `form` ในตัวเลือกด้วยให้ specificity เท่ากับของ WooCommerce (0,2,1)
   แล้วชนะด้วยลำดับการโหลด — เขียนเป็น `.woocommerce .login-form` เฉย ๆ
   ได้แค่ (0,2,0) ซึ่งแพ้เงียบ ๆ */
.woocommerce form.login-form,
.woocommerce form.signup-form,
.woocommerce form.forgot-password-form,
.woocommerce-account form.login-form,
.woocommerce-account form.signup-form,
.woocommerce-account form.forgot-password-form {
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  text-align: start;
}

/* design ใช้ .form-row เป็นแถวสองช่อง (รหัสผ่าน + ยืนยันรหัสผ่าน)
   แต่ WooCommerce มีคลาสชื่อเดียวกันที่หมายถึง "หนึ่งแถวหนึ่งช่อง"
   และ specificity สูงกว่า — จำกัดขอบเขตให้ทับเฉพาะสองฟอร์มนี้เท่านั้น
   ห้ามเขียนกว้างกว่านี้ ไม่งั้นหน้าชำระเงินกับหน้าแก้ไขโปรไฟล์จะพัง */
.woocommerce form.signup-form .form-row,
.woocommerce form.forgot-password-form .form-row,
.woocommerce-account form.signup-form .form-row,
.woocommerce-account form.forgot-password-form .form-row {
  display: flex;
  gap: 12px;
  margin: 0 0 18px;
  padding: 0;
}

/* ⚠ WooCommerce ใส่ clearfix ::before/::after ให้ .form-row ทุกอัน
   (woocommerce.css: .woocommerce form .form-row::after,::before
    { content:" "; display:table })
   พอ .form-row เป็น flex เจ้าสองตัวนี้กลายเป็น flex item เปล่า ๆ
   ทำให้ gap ถูกนับ 3 ช่วงแทนที่จะเป็น 1 ช่องครึ่งแถวจึงแคบไป 12px ต่อช่อง
   หาสาเหตุยากมากเพราะ padding/margin/border ของทุก element เป็น 0 หมด */
.woocommerce form.signup-form .form-row::before,
.woocommerce form.signup-form .form-row::after,
.woocommerce form.forgot-password-form .form-row::before,
.woocommerce form.forgot-password-form .form-row::after,
.woocommerce-account form.signup-form .form-row::before,
.woocommerce-account form.signup-form .form-row::after,
.woocommerce-account form.forgot-password-form .form-row::before,
.woocommerce-account form.forgot-password-form .form-row::after {
  content: none;
}

/* ไม่ตั้ง margin-bottom ที่นี่โดยตั้งใจ — design ประกาศ .form-group--half
   ไว้ "ก่อน" .form-group (styles.css:551 กับ 562) กฎหลังจึงชนะ
   ช่องครึ่งแถวของ design จึงได้ margin-bottom 18px เหมือนช่องเต็มแถว */
.woocommerce form.signup-form .form-group--half,
.woocommerce form.forgot-password-form .form-group--half,
.woocommerce-account form.signup-form .form-group--half,
.woocommerce-account form.forgot-password-form .form-group--half {
  flex: 1;
  min-width: 0;
}


/* ฟอร์มที่ไม่ได้เปิดอยู่ต้องซ่อนจริง ไม่ใช่แค่จาง
   (design ใช้ .form--active / .form--inactive) */
.woocommerce-form.form--inactive {
  display: none;
}

/* แจ้งเตือนของ WooCommerce ต้องอยู่เหนือฟอร์ม ไม่ใช่ลอยข้าง ๆ */
.woocommerce-account:not(.logged-in) .woocommerce-notices-wrapper {
  max-width: var(--max-width);
  margin: 0 auto 16px;
}

/* ข้อความนโยบายความเป็นส่วนตัวใต้ฟอร์มสมัคร — WooCommerce ไม่ได้กำหนดขนาดไว้ */
.woocommerce-privacy-policy-text {
  margin: 14px 0 18px;
}

.woocommerce-privacy-policy-text p {
  font-size: 12px;
  line-height: 1.7;
  color: var(--text-secondary);
  margin: 0;
}

.woocommerce-privacy-policy-text a {
  color: var(--grad-2);
}

/* ============================================================
   VENDOR DASHBOARD

   Dokan โหลด CSS ของตัวเอง 4 ไฟล์บนหน้า dashboard
   (frontend.css, style.css, components.css, dokan-tailwind.css)
   ซึ่งวางโครงไว้สำหรับ sidebar สีม่วง + เนื้อหาพื้นขาว

   ที่นี่ปิดทับเฉพาะกฎที่ขวาง design ไม่ได้ dequeue ทิ้ง เพราะ Dokan
   ใช้คลาสของตัวเองคุมการแสดงผลเชิงพฤติกรรมด้วย (.dokan-hide, .show_if_*,
   .dokan-section-toggle) ถ้าเอา CSS ออกหมดฟอร์มจะโชว์ทุกอย่างพร้อมกัน

   markup ที่คงคลาส Dokan ไว้เพราะ JS ผูกอยู่:
     .dokan-feat-image-upload / .dokan-feat-image-btn  รูปปกสินค้า
     .product_images / .add-product-images             แกลเลอรีสินค้า
     .dokan-banner / .dokan-gravatar                   รูปร้าน
     .product_tag_search                               select2 แท็ก
   ============================================================ */

/* โครงหลัก — Dokan ตั้ง width 83% กับ padding ซ้ายไว้เผื่อ sidebar ที่ถอดออกแล้ว */
.dokan-dashboard .dokan-dashboard-wrap,
.dokan-dashboard-wrap {
  display: block;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
}

.dokan-dashboard .dokan-dashboard-content,
.dokan-dashboard-content {
  width: 100%;
  max-width: none;
  flex: none;
  float: none;
  padding: 0;
  margin: 0;
  background: none;
  border: 0;
  box-shadow: none;
  overflow: visible;
}

/* article ของแต่ละหน้า — Dokan ตั้ง padding/width ด้วย selector 2 ชั้น
   (เช่น .dokan-product-listing .dokan-product-listing-area { padding: 0 15px })
   ซึ่งชนะการ reset ที่ตัว article ลอย ๆ ต้องไล่ระบุให้ครบทุกหน้า */
.dokan-dashboard-wrap article,
.dokan-dashboard-content article,
.dokan-product-listing .dokan-product-listing-area,
.dokan-orders-content .dokan-orders-area,
.dokan-withdraw-content .dokan-withdraw-area,
.dokan-settings-content .dokan-settings-area,
.dokan-dashboard-content .dokan-new-product-area {
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  width: auto;
  float: none;
}

/* 🔴 Dokan style.css ตั้ง `article { overflow: scroll }` ที่จอ ≤ 430px
   (.dokan-dashboard .dokan-dashboard-content article) → ทุกหน้าในแดชบอร์ดร้าน
   กลายเป็นกล่องเลื่อนซ้อน: นิ้วเลื่อนข้างในก่อน + ตัดเงาปุ่ม/ปุ่มที่ล้นขอบ
   ให้เหลือแถบเลื่อนของเบราว์เซอร์อย่างเดียว (ผู้ใช้แจ้ง 2026-09-18) */
.dokan-dashboard .dokan-dash-sidebar article,
.dokan-dashboard .dokan-dashboard-content article {
  overflow: visible;
}

/* .dokan-withdraw-area ul li ถูกตั้งเป็น inline-block + padding 0 5px
   ทำให้รายการในแท็บการเงินเรียงเป็นแนวนอน */
.dokan-withdraw-content .dokan-withdraw-area ul li,
.dokan-dashboard .dokan-dashboard-content ul li {
  display: list-item;
  padding: 0;
  margin: 0;
}

/* แถบแท็บของเราเป็น <ul><li> เหมือนกัน ต้องไม่โดนกฎด้านบน */
.dokan-dashboard-wrap .nav-tabs-list li {
  display: list-item;
}

/* หัวข้อ/ปุ่มที่ Dokan ใส่มาเองแต่ design ไม่มี */
.dokan-dashboard-header,
.dokan-store-settign-header-wrap,
.dokan-update-setting-top,
.dokan-dash-sidebar {
  display: none;
}

/* เส้นคั่น — ตั้งแค่ระยะห่าง ตัวเส้นให้กฎ hr ใน styles.css:1202 เป็นคนวาด
   (height 1px + background var(--border-inactive)) เหมือนที่ design ได้
   store.html ใช้ <hr style="margin:10px 0"> กับ
   <hr style="margin-top:0;margin-bottom:10px"> ใต้แท็บย่อย */
.store-header-divider,
.store-tabs-divider {
  margin: 10px 0;
}

.store-subtabs-divider {
  margin-top: 0;
  margin-bottom: 10px;
}

/* ------------------------------------------------------------
   สถานะว่าง
   ------------------------------------------------------------ */

.es-vendor-empty {
  text-align: center;
  padding: 48px 16px;
  color: var(--text-secondary);
}

.es-vendor-empty i {
  font-size: 34px;
  display: block;
  margin-bottom: 12px;
  color: var(--text-muted);
}

.es-vendor-empty p {
  margin: 0;
  font-size: 14px;
}

/* ปุ่มกลับในหน้าที่เข้าไม่ได้ — .btn-edit-store เกิดมาเป็นปุ่มในหัวร้าน
   ถ้าไม่บังคับ inline-flex มันจะกางเต็มความกว้างแล้วข้อความตกบรรทัด */
.es-vendor-empty .btn-edit-store {
  display: inline-flex;
  align-items: center;
  width: auto;
  margin-top: 18px;
  white-space: nowrap;
}

/* ------------------------------------------------------------
   แถบแบ่งหน้าของ vendor dashboard เคยอยู่ตรงนี้ (.pagination-wrap > ul.pagination)
   ย้ายไปใช้ชุดกลาง `.es-pagination` ที่ใช้ทั้งเว็บแล้ว — ดูหัวข้อ "แถบแบ่งหน้า"
   ------------------------------------------------------------ */

/* ------------------------------------------------------------
   ฟอร์มของ Dokan ที่ยังหลงเหลืออยู่ในหน้า (inventory / other options)
   ------------------------------------------------------------ */

.dokan-dashboard-content .dokan-edit-row {
  background: rgba(var(--bg-card-rgb), 0.55);
  border: 1px solid var(--border-input);
  border-radius: 14px;
  padding: 14px 16px;
  margin: 0 0 16px;
}

.dokan-dashboard-content .dokan-section-heading {
  border: 0;
  padding: 0 0 8px;
  margin: 0;
  background: none;
}

.dokan-dashboard-content .dokan-section-heading h2 {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
  margin: 0;
}

.dokan-dashboard-content .dokan-section-heading p {
  font-size: 12px;
  color: var(--text-secondary);
  margin: 4px 0 0;
}

.dokan-dashboard-content .dokan-section-heading i {
  color: var(--grad-2);
}

.dokan-dashboard-content .dokan-form-group {
  margin-bottom: 14px;
}

/* จำกัดไว้เฉพาะ label ที่อยู่ในฟอร์มของ Dokan (inventory / other options)
   ห้ามใช้ .dokan-dashboard-content .form-label ลอย ๆ เพราะทั้งหน้าอยู่ใน
   .dokan-dashboard-content — จะไปทับ .form-label ของ design ที่อยู่ในฟอร์ม
   ของเราเองด้วย (design ตั้ง margin-bottom: 0 และสีขาว) */
.dokan-dashboard-content .dokan-form-group > .form-label,
.dokan-dashboard-content .dokan-edit-row .form-label,
.dokan-dashboard-content .dokan-control-label {
  display: block;
  font-size: 13px;
  color: var(--text-secondary);
  margin-bottom: 6px;
  width: auto;
  text-align: left;
  float: none;
}

.dokan-dashboard-content .dokan-form-control,
.dokan-dashboard-content input[type="text"],
.dokan-dashboard-content input[type="number"],
.dokan-dashboard-content input[type="email"],
.dokan-dashboard-content input[type="url"],
.dokan-dashboard-content select,
.dokan-dashboard-content textarea {
  width: 100%;
  background: var(--bg-input);
  border: 1px solid var(--border-input);
  border-radius: 12px;
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 14px;
  padding: 11px 14px;
  height: auto;
  box-shadow: none;
}

.dokan-dashboard-content .dokan-form-control:focus,
.dokan-dashboard-content input:focus,
.dokan-dashboard-content select:focus,
.dokan-dashboard-content textarea:focus {
  border-color: var(--border-active);
  outline: none;
}

/* คอลัมน์ครึ่งของ Dokan ใช้ float — เปลี่ยนเป็น grid ให้เท่ากับ .form-row-2col */
.dokan-dashboard-content .content-half-part {
  float: none;
  width: 100%;
  padding: 0;
}

@media (min-width: 480px) {
  .dokan-dashboard-content .dokan-section-content {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 14px;
  }

  .dokan-dashboard-content .dokan-section-content > .dokan-form-group:not(.content-half-part),
  .dokan-dashboard-content .dokan-section-content > .dokan-stock-management-wrapper {
    grid-column: 1 / -1;
  }
}

.dokan-dashboard-content .dokan-btn {
  background: var(--gradient);
  border: 0;
  border-radius: var(--radius-btn);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 13px;
  padding: 10px 18px;
  text-shadow: none;
  box-shadow: none;
}

/* ------------------------------------------------------------
   ต่างจาก store.html เพราะเหตุผลเชิงโครงสร้าง

   design เป็น prototype ที่ไม่ต้องกดได้จริง เลยใช้ <div>/<button> ตามสะดวก
   ของจริงต้องเป็น <a> เมื่อเป็นลิงก์ (กดขวาเปิดแท็บใหม่ได้ crawler เดินตามได้)
   และเป็น <button> เมื่อกดแล้วเกิดการกระทำ — สามกฎนี้ลบส่วนต่างทางสายตาออก
   ------------------------------------------------------------ */

/* design: <div class="store-profile-link"> — ของเราเป็น <button> เพราะกดคัดลอกได้
   เหลือแค่ล้าง chrome ของปุ่มที่ store.css ไม่ได้ครอบคลุม (ขอบ outset 2px
   กับฟอนต์ของ UA) — ห้ามใช้ shorthand `font: inherit` เพราะจะไปล้าง
   font-size: 11px ที่ store.css ตั้งไว้ด้วย กลายเป็น 16px */
.store-profile-link {
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  font-family: inherit;
  /* UA ตั้ง text-align: center ให้ <button> ส่วน design เป็น <div> ที่ได้ start */
  text-align: start;
}

/* design: <button class="btn-edit-store"> — ของเราเป็น <a> เพราะพาไปอีกหน้า
   ปุ่มของ design computed เป็น display:block จัดข้อความกลางด้วย text-align */
a.btn-edit-store {
  display: block;
  text-align: center;
  text-decoration: none;
}

/* ปุ่มของ design ที่เราทำเป็น <a> เพราะพาไปอีกหน้า
   <button> จัดข้อความกึ่งกลางให้เอง ส่วน <a> ไม่ทำ ข้อความจะเยื้องซ้าย
   ต้องสั่ง text-align: center ให้ครบทุกตัวที่แปลง */
a.vendor-action-btn,
a.order-tracking-btn,
a.btn-add-new-product,
a.btn-update-store {
  text-decoration: none;
  text-align: center;
}

/* design ใส่ style="margin-top:0" ไว้ที่ .vendor-action-row ในการ์ดสินค้า */
.store-tab-panel .order-card__footer .vendor-action-row {
  margin-top: 0;
}

/* ชื่อสินค้าในการ์ดของเราเป็นลิงก์ไปหน้าแก้ไข design เป็นข้อความเปล่า */
.order-card__product-info h4 a,
.order-card__product-info-left h4 a {
  color: inherit;
  font: inherit;
  text-decoration: none;
}

/* ------------------------------------------------------------
   แท็บการเงิน
   ------------------------------------------------------------ */

.store-finance-card__value--good {
  color: var(--stat-confirmed);
}

/* ยอดติดลบ (เช่น "พร้อมถอน" หลังถูกหักคืนเงิน) — ผู้ใช้สั่ง 2026-09-18 */
.store-finance-card__value--bad {
  color: var(--stat-error);
}

.es-withdraw-message {
  font-size: 13px;
  margin: 10px 0 0;
  color: var(--text-secondary);
}

.es-withdraw-message.is-error {
  color: var(--stat-error);
}

/* wc_price ออก <span class="woocommerce-Price-amount"> — อย่าให้ไปทับขนาด/สีของ design */
.store-finance-card__value .woocommerce-Price-amount,
.finance-chart__value .woocommerce-Price-amount,
.order-card__total-amount .woocommerce-Price-amount,
.order-item__price .woocommerce-Price-amount,
.payment-product__price .woocommerce-Price-amount {
  color: inherit;
  font-size: inherit;
  font-weight: inherit;
}

/* ------------------------------------------------------------
   ฟอร์มตั้งค่าร้าน + ฟอร์มสินค้า
   ------------------------------------------------------------ */

/* ปุ่มจริงอยู่ในฟอร์มเพื่อให้ field ถูกส่งครบ ตัวที่ผู้ใช้กดอยู่ในแถบล่าง */
.es-store-submit,
.es-product-submit {
  position: absolute;
  width: 1px !important;
  height: 1px !important;
  min-height: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.es-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-secondary);
  cursor: pointer;
}

/*
 * ⚠️ วงแหวนขาวหนา ๆ รอบ checkbox/radio ตอน focus — เอาออกทั้งเว็บ
 *
 * `dokan-tailwind.css` ตั้ง
 *   [type=checkbox]:focus { --tw-ring-offset-width: 2px; --tw-ring-offset-color: #fff; box-shadow: <ring> }
 * = วงขาว 2px แล้วตามด้วยวงน้ำเงินอีกชั้น บนพื้นดำของธีมจึงเด่นจนดูเหมือนบัค
 * specificity (0,2,0) — ต้องระบุ element เพิ่มเป็น (0,2,1) ถึงจะทับได้
 *
 * ยังเหลือเส้นบาง ๆ ตอนใช้คีย์บอร์ด (`:focus-visible`) ไว้ให้คนที่ไม่ได้ใช้เมาส์
 * ยังรู้ว่าตอนนี้อยู่ช่องไหน — เมาส์คลิกจะไม่เห็น
 */
input[type="checkbox"]:focus,
input[type="radio"]:focus {
  outline: none;
  box-shadow: none;
  --tw-ring-shadow: 0 0 #0000;
  --tw-ring-offset-shadow: 0 0 #0000;
  --tw-ring-offset-width: 0px;
}

input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible {
  outline: 1px solid rgba(var(--grad-2-rgb), 0.7);
  outline-offset: 2px;
}

/* คำอธิบายสั้นใต้ checkbox — เยื้องให้ตรงกับข้อความของป้าย (กล่อง 16px + gap 8px) */
.es-checkbox__hint {
  margin: 2px 0 0;
  padding-left: 24px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-secondary);
  opacity: 0.8;
}

.es-checkbox input {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  margin: 0;
  accent-color: var(--grad-2);
  cursor: pointer;
}

/* รูปร้านในหน้าตั้งค่า

   คงคลาส .dokan-gravatar ไว้เพราะ Dokan ใช้เป็นจุดอ้างอิงหลายที่
   ส่วนตัวอัปโหลดเปลี่ยนมาใช้กล่องตัดรูปของธีมแล้ว (ดู dokan/settings/store-form.php)

   Dokan ตั้งขนาดของตัวเองด้วย
     .dokan-settings-content .dokan-settings-area .dokan-gravatar   (0,3,0)
   ซึ่งชนะ .edit-store-avatar .store-picture (0,2,0) ของ store.css
   กรอบรูปเลยยืดเต็มความกว้างกลายเป็นวงรี — ต้องทวงคืนที่นี่ */
.edit-store-avatar .store-picture.dokan-gravatar {
  width: 104px;
  height: 104px;
  flex: 0 0 104px;
  border-radius: 50%;
  overflow: visible;
  flex-shrink: 0;
  background: var(--bg-card);
  position: relative;
  float: none;
  margin: 0;
  padding: 0;
  cursor: pointer;
}

/* ⚠️ **ห้ามใส่ media query ขยายเป็น 150px**
   รูปโปรไฟล์ฝั่งผู้ซื้อถูกตรึงไว้ที่ 104px ทุกขนาดจอโดยกฎในไฟล์นี้
   (`.edit-profile-avatar .profile-picture { width: 104px }` — ทับ 120/150px
   ของ styles.css เพราะ specificity เท่ากันแต่ไฟล์นี้โหลดทีหลัง)
   ถ้าฝั่งร้านยังเดินตาม store.css เดิม รูปร้านจะใหญ่กว่ารูปโปรไฟล์บนจอกว้าง
   ผู้ใช้ทักเรื่องนี้มาแล้วรอบหนึ่ง (2026-08-11) */

.edit-store-avatar .gravatar-wrap {
  position: static;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  float: none;
}

/* Dokan บังคับ height: 80px !important ด้วย selector 5 ชั้น
     .dokan-settings-content .dokan-settings-area .dokan-gravatar
     .gravatar-wrap .dokan-gravatar-img
   ต้องเทียบ specificity ให้เท่ากัน (5 คลาส) ไฟล์นี้โหลดทีหลังจึงชนะ */
.edit-store-avatar .store-picture.dokan-gravatar .gravatar-wrap .dokan-gravatar-img {
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
  object-fit: cover;
  border-radius: 50%;
  display: block;
}

/* ไอคอนกล้องใช้ตัวเดียวกับหน้าแก้ไขโปรไฟล์ (.profile-picture__edit — สีฟ้า มุมขวาล่าง)
   ผู้ใช้สั่งให้สองหน้านี้เหมือนกันทุกอย่าง (2026-08-11) */
.edit-store-avatar .profile-picture__edit {
  pointer-events: none;
}

.edit-store-avatar .store-picture:hover .profile-picture__edit {
  transform: scale(1.08);
}

/* ── แบนเนอร์ร้าน ──
   น้ำหนักกรอบเท่ากับกล่องอัปโหลดรูปในหน้าคืนสินค้า (.image-upload-box)
   และหน้าเพิ่มสินค้า (.trade-item-cover-box) — 2px dashed */
/* ── ตารางเวลาเปิด-ปิดร้าน (dokan/settings/store-time.php) ──

   ของ Dokan เป็นตารางที่พึ่งกริด .dokan-w3/.dokan-w6 ซึ่งธีมนี้ถอดออกไปแล้ว
   วาดใหม่เป็นการ์ดรายวัน: ชื่อวัน | เปิด/ปิด | ช่วงเวลา */

.es-store-hours {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 18px;
}

/* ช่อง "กำหนดเวลาเปิด-ปิดร้าน" ยังไม่ติ๊ก = ไม่ต้องแสดงตาราง
   (vendor-store-settings.js สลับคลาสนี้ให้) */
.es-store-hours.is-hidden {
  display: none;
}

/* มือถือ: ชื่อวันซ้าย เปิด/ปิดชิดขวา แล้วช่วงเวลาเต็มบรรทัดข้างล่าง
   จอกว้างค่อยยุบเป็นบรรทัดเดียว (ดู media query ท้ายบล็อก) */
.es-store-hours__row {
  display: grid;
  grid-template-columns: 1fr 128px;
  align-items: center;
  gap: 10px;
  padding: 12px;
  border: 1px solid rgba(var(--text-secondary-rgb), 0.22);
  border-radius: 12px;
  background: rgba(var(--text-primary-rgb), 0.03);
}

.es-store-hours__day {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: 0.03em;
}

/* ช่องเปิด/ปิดกับช่องเวลาต้องเตี้ยกว่าช่องกรอกปกติ ไม่งั้นการ์ดสูงเกินไป */
.es-store-hours .form-input {
  padding: 9px 12px;
  font-size: 12px;
  letter-spacing: 0.04em;
}

.es-store-hours__time {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 8px;
  padding-top: 10px;
  border-top: 1px dashed rgba(var(--text-secondary-rgb), 0.18);
}

.es-store-hours__time .form-input {
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
}

.es-store-hours__dash {
  color: var(--text-secondary);
  flex-shrink: 0;
}

/* วันที่ตั้งเป็น "ปิด" ซ่อนช่วงเวลาไปเลย ไม่ใช่แค่ visibility:hidden
   ของเดิมเว้นที่ว่างค้างไว้ทั้งแถวทั้งที่ไม่มีอะไรให้กรอก */
.es-store-hours__row.is-closed .es-store-hours__time {
  display: none;
}

.es-store-hours__row.is-closed {
  background: none;
  border-style: dashed;
}

@media (min-width: 520px) {
  .es-store-hours__row {
    grid-template-columns: 88px 128px 1fr;
  }

  .es-store-hours__time {
    grid-column: auto;
    padding-top: 0;
    border-top: 0;
  }
}

/* รายการเวลาของ timepicker (jQuery plugin ที่ Dokan โหลดมา) เป็นพื้นขาว
   ตัวอักษรดำ — ต้องเป็นพื้นดำเข้าชุดกับ dropdown อื่นในหน้า */
/* 🔴 รายการเวลาสูงทะลุจอ เลือกบนมือถือยาก (ผู้ใช้แจ้ง 2026-09-18) — CSS ของปลั๊กอินที่จำกัดความสูง
   ไม่ได้ถูกโหลดในหน้านี้ รายการ 48 ช่วงเวลาจึงยาวเต็มความสูงหน้า → จำกัดเองให้เลื่อนในกล่อง
   แถวสูงขึ้นให้นิ้วแตะง่าย */
.ui-timepicker-wrapper {
  z-index: 100010;
  box-sizing: border-box;
  width: 8.5em;
  max-height: min(264px, 45vh);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  outline: none;
}

.ui-timepicker-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.ui-timepicker-list li {
  cursor: pointer;
  white-space: nowrap;
}

@media (hover: none) {
  .ui-timepicker-list li {
    padding: 11px 12px;
    font-size: 15px;
  }
}

.ui-timepicker-wrapper {
  background: var(--bg-primary);
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
  padding: 6px;
}

.ui-timepicker-list li {
  display: block;
  padding: 7px 10px;
  border-radius: 8px;
  color: var(--text-primary);
  font-size: 13px;
}

.ui-timepicker-list li:hover,
.ui-timepicker-list .ui-timepicker-selected,
.ui-timepicker-list li.ui-timepicker-selected:hover,
.ui-timepicker-list li:hover.ui-timepicker-selected {
  background: rgba(var(--grad-2-rgb), 0.22);
  color: var(--text-primary);
}

/* ── สวิตช์ "ซ่อนสินค้า" อยู่บรรทัดเดียวกับหัวข้อ "ชื่อสินค้า" ชิดขวา (ผู้ใช้สั่ง 2026-09-14) ──
   เดิม (2026-08-16) สวิตช์อยู่ขวาของช่องกรอก กินความกว้างช่องชื่อไป 210px
   และต้องมีจุดตัด 900px ให้ตกลงใต้ชื่อบนจอแคบ — ตอนนี้ช่องชื่อเต็มความกว้างทุกจอ จึงไม่มีจุดตัดแล้ว
   ระยะหัวข้อ → ช่องกรอก 8px เท่ากับ `.form-group` ช่องอื่น (วัดจริง: ช่องเทคนิค 8px) */
.es-title-row__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}

.es-title-row__head .form-label {
  min-width: 0;
  margin: 0;
}

.es-title-row__side {
  flex: 0 0 auto;
}

/* ============================================================
   เปลือกกล่องซ้อน (modal) ที่ใช้ร่วมกันทั้งหน้าบ้าน

   🔴 **ต้องอยู่ในไฟล์นี้ ไม่ใช่แค่ใน image-cropper.css**
   คลาสชุด `.avatar-cropper*` ไม่ได้ใช้แค่กล่องตัดรูป — ตอนนี้มี 4 ที่:
     • กล่องตัดรูป (avatar-crop.js)
     • **กล่องแจ้งเลขพัสดุ** (vendor-dashboard-ui.js → buildShipModal)
     • **กล่องตั้งค่าบัญชีรับเงิน** (หน้าการเงินของผู้ขาย)
     • กล่องยืนยัน (confirm-modal.js — ใช้ได้ทุกหน้าของเว็บ)

   ⚠️ **เคยพังมาแล้ว** ตอนแยก image-cropper.css ออกไปเมื่อ 2026-08-16
   เพื่อให้หลังบ้านใช้ได้ — ผลข้างเคียงคือหน้า dashboard ของผู้ขายที่ไม่ได้
   โหลดไฟล์นั้น (หน้าออเดอร์ · หน้าการเงิน) เหลือ overlay แบบ `position:static`
   พื้นหลังใส กลายเป็นก้อน markup ท้ายหน้าที่มองไม่เห็น = "กดแล้วไม่เด้ง"
   (ผู้ใช้แจ้ง 2026-08-17)

   image-cropper.css ยังต้องมีชุดนี้ต่อไปสำหรับ **wp-admin** ซึ่งไม่โหลดไฟล์นี้
   → แก้ค่าที่ไหนต้องแก้อีกที่ให้ตรงกันด้วย
   ============================================================ */

.avatar-cropper {
  position: fixed;
  inset: 0;
  z-index: 100001;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(var(--bg-header-rgb, 12, 8, 22), 0.9);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.avatar-cropper__box {
  width: 100%;
  max-width: 380px;
  padding: 22px;
  border-radius: var(--radius-card, 12px);
  background: var(--bg-primary, #14101f);
  text-align: center;
}

.avatar-cropper__title {
  margin: 0 0 16px;
  font-size: 16px;
  font-weight: 700;
  color: var(--text-primary, #ffffff);
}

.avatar-cropper__actions {
  display: flex;
  gap: 10px;
  margin-top: 18px;
}

.avatar-cropper__actions > button {
  /* ไอคอน + ข้อความ (ตรงกับ image-cropper.css — หน้าที่ไม่โหลดไฟล์นั้นก็ต้องได้ทรงนี้ · 2026-09-22) */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex: 1 1 0;
  min-width: 0;
  padding: 16px 10px;
  border-radius: var(--radius-btn, 50px);
  font-family: var(--font, inherit);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.2;
  cursor: pointer;
}

.avatar-cropper__actions > button i {
  flex: 0 0 auto;
  font-size: 0.9em;
}

.avatar-cropper__cancel {
  border: 1px solid rgba(var(--text-secondary-rgb, 123, 115, 153), 0.4);
  background: none;
  color: var(--text-secondary, #7b7399);
}

.avatar-cropper__save[disabled] {
  opacity: 0.6;
  cursor: wait;
}

/* ── กล่องยืนยัน (confirm-modal.js) — ต่อยอดจากเปลือกข้างบน ── */

.es-confirm .es-confirm__box {
  padding: 24px 22px;
}

.es-confirm .avatar-cropper__title {
  margin: 0 0 10px;
}

.es-confirm__text {
  margin: 0;
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-secondary);
  /* ⚠️ `pre-line` เพื่อให้ข้อความหลายย่อหน้าที่ส่งมาทาง `text` (textContent)
     ยังขึ้นบรรทัดตามที่เขียนไว้ — กล่องเตือน "กดรับสินค้าเร็วผิดปกติ"
     มี 3 ย่อหน้า (เวลาที่ส่ง · คำเตือน · ผลที่จะเกิด) ถ้าไม่มีบรรทัดนี้
     ทั้งสามจะติดกันเป็นพืดอ่านไม่ออก (ผู้ใช้สั่ง 2026-09-03)
     ตัวที่ส่ง HTML มาทาง `html` ไม่ได้รับผล เพราะมี <p> ของตัวเองอยู่แล้ว */
  white-space: pre-line;
}

/* กล่องที่ใส่ HTML มาเอง (เช่นกล่อง "เครื่องไม่มีเสียงไทย") ไม่ต้องขึ้นบรรทัด
   ตามช่องว่างใน markup — ไม่งั้นการเว้นบรรทัดใน PHP จะกลายเป็นบรรทัดว่าง */
.es-confirm__text > * {
  white-space: normal;
}

.es-confirm .avatar-cropper__actions {
  margin-top: 20px;
}

/* ปุ่มในกล่องยืนยันสั้นกว่าปุ่มในกล่องตัดรูป และไม่ต้องเป็นตัวพิมพ์ใหญ่ */
.es-confirm .avatar-cropper__actions > button {
  padding: 14px 10px;
  border: 0;
  font-size: 14px;
  letter-spacing: 0.06em;
  text-transform: none;
}

.es-confirm .avatar-cropper__cancel {
  background: transparent;
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.18);
  color: var(--text-secondary);
}

.es-confirm .avatar-cropper__cancel:hover {
  border-color: rgba(var(--text-primary-rgb), 0.4);
  color: var(--text-primary);
}

/* งานที่ย้อนกลับไม่ได้ (ลบสินค้า) ใช้ปุ่มแดง ไม่ใช่ไล่สีของปุ่มยืนยันทั่วไป */
.es-confirm .es-confirm__ok--danger {
  background: var(--stat-error);
  color: #fff;
}

.es-confirm .es-confirm__ok--danger:hover {
  filter: brightness(1.1);
}

/* ============================================================
   ตัวหมุนบอกว่ากำลังโหลด — ทับทั้งหน้า (ผู้ใช้สั่ง 2026-08-17)
   สคริปต์อยู่ที่ assets/js/loading.js
   ============================================================ */

.es-loading {
  position: fixed;
  inset: 0;
  /*
   * 🔴 **ต้องสูงกว่าชั้นของ modal (100001)** — ผู้ใช้แจ้ง 2026-08-30 ว่า
   * กด SEND ในกล่องแล้ว "หน้าโหลดไม่แสดง" ของเดิมเป็น 99999 ตัวหมุนจึงถูก
   * สร้างขึ้นจริงและทำงานถูกต้องทุกอย่าง **แต่ไปนอนอยู่ใต้กล่อง** เลยมองไม่เห็น
   *
   * ⚠️ ตัวหมุนนี้แปลว่า "หน้ากำลังจะเปลี่ยน" จึงต้องอยู่บนสุดของทุกอย่างเสมอ
   * เพิ่มชั้นอะไรใหม่ที่สูงกว่า 100003 เมื่อไร ต้องกลับมาขยับตัวนี้ตาม
   * (ชั้นที่ใช้อยู่ตอนนี้: `.avatar-cropper` 100001 · `.pswp` 100002 — กล่องดูรูปต้องทับกล่องซ้อนได้ 2026-10-02)
   */
  z-index: 100003;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  background: rgba(var(--bg-primary-rgb), 0.78);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

/* `[hidden]` อย่างเดียวแพ้ `display:flex` ข้างบน ต้องเขียนกฎซ่อนเอง */
.es-loading[hidden] {
  display: none;
}

/*
 * ไม่กะพริบ (ผู้ใช้สั่ง 2026-10-12): ชั้นนี้ขึ้นทันที (กันกดซ้ำ) แต่โปร่งใส 0.3 วิแรก แล้วจางเข้า 0.2 วิ
 * หน้าที่มาเร็วกว่า 0.3 วิจึงไม่เห็นอะไรเลย · ทุกครั้งที่ถอด [hidden] แอนิเมชันเริ่มนับใหม่เอง
 * `.es-loading--now` = ขึ้นทันที (iPhone/iPad ที่ต้องรอเซิร์ฟเวอร์ · ดู show() ใน loading.js)
 */
@keyframes es-loading-in {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.es-loading {
  animation: es-loading-in 0.2s ease-out 0.3s both;
}

.es-loading.es-loading--now {
  animation-duration: 0.12s;
  animation-delay: 0s;
}

/*
 * วงแหวนหมุน — ขอบจาง ๆ รอบวง แล้วให้ด้านบนเป็นสีแบรนด์ พอหมุนจึงเห็นเป็น
 * เส้นวิ่ง ไม่ใช้ GIF/SVG เพื่อให้เปลี่ยนสีตามธีมได้เอง
 */
.es-loading__spinner {
  width: 46px;
  height: 46px;
  border: 3px solid rgba(var(--text-primary-rgb), 0.15);
  border-top-color: var(--grad-1);
  border-radius: 50%;
  animation: es-loading-spin 0.7s linear infinite;
}

.es-loading__text {
  color: var(--text-secondary);
  font-size: 12px;
  letter-spacing: 0.1em;
}

@keyframes es-loading-spin {
  to {
    transform: rotate(360deg);
  }
}

/* คนที่ตั้งค่าเครื่องว่าไม่เอา animation — คงวงแหวนไว้เฉย ๆ ไม่ต้องหมุน */
@media (prefers-reduced-motion: reduce) {
  .es-loading__spinner {
    animation-duration: 2.4s;
  }
}

/* กันกดอะไรซ้ำระหว่างรอ */
body.es-is-loading {
  overflow: hidden;
}

/* ── ปุ่มแก้ไขบนหน้ารายละเอียดสินค้าของตัวเอง (ผู้ใช้สั่ง 2026-08-17) ──
   บรรทัดเดียวกับชื่อสินค้า ชิดขวา · ปกติเห็นแต่ไอคอน · hover แล้วคำว่า EDIT
   คลี่ออกมาต่อท้าย

   ⚠️ ใช้ `max-width` + `opacity` กับตัวหนังสือ ไม่ใช่ `display:none`
   เพราะ display เปลี่ยนไม่ได้แบบมี transition — จะกระตุกเป็นช็อต ๆ
   และต้อง `white-space: nowrap` ไม่งั้นตอนกำลังคลี่ตัวอักษรจะตกบรรทัด */
.product-name-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
}

.product-name-row .product-name {
  flex: 1 1 auto;
  min-width: 0;
}

.product-edit-btn {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 0;
  margin-top: 4px;
  padding: 8px 10px;
  border: 1px solid rgba(var(--text-primary-rgb), 0.18);
  border-radius: 999px;
  color: var(--text-secondary);
  font-size: 12px;
  line-height: 1;
  text-decoration: none;
  transition: border-color 0.22s, color 0.22s, gap 0.22s;
}

.product-edit-btn:hover,
.product-edit-btn:focus-visible {
  border-color: var(--grad-1);
  color: var(--grad-1);
  gap: 7px;
}

/* `line-height: 1` ด้วยเหตุผลเดียวกับปุ่มแชร์ที่อยู่ข้างกัน (ผู้ใช้ทัก 2026-09-13)
   — ปุ่มตั้ง line-height ไว้ แต่ inline-block ลูกในนั้นคิดความสูงจากค่าของตัวเอง
   ตัวอักษรจึงเยื้องลงต่ำกว่าไอคอน ต้องคุมที่ตัวหนังสือเอง */
.product-edit-btn__text {
  display: inline-block;
  max-width: 0;
  overflow: hidden;
  opacity: 0;
  white-space: nowrap;
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.1em;
  transition: max-width 0.22s, opacity 0.22s;
}

/* 70px เท่าปุ่มแชร์ที่อยู่ข้างกัน — สองปุ่มนี้ต้องคลี่ข้อความด้วยจังหวะเดียวกัน
   (ผู้ใช้ทัก 2026-09-13 ว่าเอฟเฟกต์ไม่เหมือนกัน) · ค่านี้เป็นเพดาน ไม่ใช่ความกว้างจริง */
.product-edit-btn:hover .product-edit-btn__text,
.product-edit-btn:focus-visible .product-edit-btn__text {
  max-width: 70px;
  opacity: 1;
}

/* จอเล็กไม่มี hover ให้ใช้ — โชว์คำว่า EDIT ค้างไว้เลย */
@media (hover: none) {
  .product-edit-btn {
    gap: 7px;
  }

  .product-edit-btn__text {
    max-width: 60px;
    opacity: 1;
  }
}

/* ── ลิงก์สาธารณะใต้ชื่อสินค้า (ผู้ใช้สั่ง 2026-08-16) ──
   แถวเดียว: ไอคอน + URL + ปุ่มคัดลอก + ปุ่ม VIEW
   URL ต้องตัดด้วย ellipsis ไม่ใช่ตัดบรรทัด — slug ไทยยาวมากจนดันฟอร์มพัง */
.es-permalink {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 0 0;
  padding: 0 4px 0 2px;
  min-width: 0;
  /* 🔴 ตรึงความสูงไว้ ไม่งั้นกดแก้ลิงก์แล้วทั้งฟอร์มขยับลง (ผู้ใช้แจ้ง 2026-08-29)
     โหมดอ่านสูง 21px โหมดแก้สูง 27px (ปุ่ม "ตกลง" เป็นตัวที่สูงสุด ไม่ใช่ช่องกรอก)
     จองพื้นเท่าโหมดที่สูงกว่าไว้ตั้งแต่แรก ทั้งสองโหมดจึงสูงเท่ากัน
     ⚠ ถ้าแก้ padding/font ของ `.es-permalink__btn` ต้องมาวัดค่านี้ใหม่ */
  min-height: 27px;
}

.es-permalink__icon {
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--text-muted);
}

.es-permalink__url {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 11.5px;
  color: var(--text-secondary);
  text-decoration: none;
}

.es-permalink__url:hover {
  color: var(--grad-1);
  text-decoration: underline;
}

.es-permalink__btn {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  border: 1px solid rgba(var(--text-primary-rgb), 0.16);
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  line-height: 1.6;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}

.es-permalink__btn:hover {
  border-color: var(--grad-1);
  color: var(--grad-1);
}

/* ปุ่มคัดลอกใช้สถานะ `is-copied` ชุดเดียวกับปุ่มคัดลอกเลขพัสดุทั้งเว็บ */
.es-permalink__btn.is-copied,
.es-permalink__btn.is-copied:hover {
  border-color: #10b981;
  color: #10b981;
}

/* สินค้าที่ซ่อนอยู่ — ลิงก์ยังเปิดไม่ได้ ทำให้จางลงเพื่อไม่ให้เข้าใจผิด */
.es-permalink.is-hidden-product .es-permalink__url {
  opacity: 0.55;
  text-decoration: line-through;
}

/* ── กดที่ URL แล้วแก้ slug ได้ (ผู้ใช้สั่ง 2026-08-29) ──
   โหมดอ่านเปลี่ยนจาก <a> เป็น <button> จึงต้องล้างทรงปุ่มของเบราว์เซอร์ทิ้ง
   ก่อน ไม่งั้นได้พื้นเทา ขอบนูน และตัวอักษรจัดกึ่งกลาง */
button.es-permalink__url {
  padding: 0;
  border: 0;
  background: transparent;
  font-family: var(--font);
  text-align: left;
  cursor: pointer;
}

/* ท่อนที่แก้ได้ต้องดูออกว่าแก้ได้ — ขีดประใต้เฉพาะ slug ไม่ใช่ทั้ง URL
   ส่วนฐาน (โดเมน + /product/) แก้ไม่ได้ จึงจางกว่าและไม่มีขีด */
.es-permalink__base {
  opacity: 0.75;
}

.es-permalink__slug {
  color: var(--text-primary);
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}

button.es-permalink__url:hover .es-permalink__slug {
  color: var(--grad-1);
  text-decoration-style: solid;
}

/* 🔴 ต้องมีกฎนี้ ไม่งั้นสองโหมดโผล่พร้อมกัน
   `[hidden]` ของเบราว์เซอร์คือ `display: none` ที่ระดับ user-agent
   กฎ `display: flex` / `inline-flex` ของเราชนะมันเสมอ — ตัวสลับโหมดใน JS
   จึงเหมือนไม่ทำงานเลย (เจอตอนตรวจจริง 2026-08-29)
   `.es-permalink [hidden]` = (0,2,0) ชนะทั้ง `.es-permalink__edit` และ
   `.es-permalink__btn` ที่เป็น (0,1,0) โดยไม่ต้องใช้ !important */
.es-permalink [hidden] {
  display: none;
}

/* โหมดแก้ — ฐาน URL เป็นข้อความ ตามด้วยช่องกรอกเฉพาะ slug */
.es-permalink__edit {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  min-width: 0;
  font-size: 11.5px;
  color: var(--text-secondary);
}

/* ฐาน URL ในโหมดแก้ห้ามหด ไม่งั้นช่องกรอกดันจนอ่านไม่ออกว่าลิงก์ขึ้นต้นยังไง
   แต่บนจอแคบต้องยอมตัดด้วย ellipsis */
.es-permalink__edit .es-permalink__base {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* ⚠️ ต้องเจาะ `.dokan-dashboard-content` มาด้วย — กฎรวมของช่องกรอกในแดชบอร์ด
   (`.dokan-dashboard-content input[type="text"]` บรรทัด ~2579) เป็น (0,2,1)
   ชนะ `.es-permalink__input` เปล่า ๆ ช่องเลยกลายเป็นกล่องสูง 45px
   ตัวอักษร 14px คร่อมทั้งแถว ทั้งที่ทั้งแถวสูงแค่ ~20px

   🔴 ต้องมี `input` นำหน้าคลาสด้วย — `.dokan-dashboard-content .es-permalink__input`
   เป็น (0,2,0) **ยังแพ้** (0,2,1) อยู่ดี เพราะฝั่งโน้นมี `input[type="text"]`
   ที่นับ element เข้าไปอีกหนึ่ง (พลาดข้อนี้มารอบหนึ่งแล้ว) */
.dokan-dashboard-content input.es-permalink__input {
  flex: 1 1 auto;
  width: auto;
  min-width: 60px;
  margin-left: 2px;
  padding: 2px 7px;
  border: 1px solid rgba(var(--grad-1-rgb), 0.55);
  border-radius: 5px;
  background: rgba(var(--text-primary-rgb), 0.06);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 11.5px;
  line-height: 1.6;
}

.dokan-dashboard-content input.es-permalink__input:focus {
  outline: none;
  border-color: var(--grad-1);
}



/* 🔴 บรรทัดข้อความใต้ลิงก์ — **จองที่ไว้เสมอ** (ผู้ใช้สั่ง 2026-08-29)
   ของเดิมเป็น `[hidden]` โผล่มาแล้วดันฟอร์มทั้งก้อนลง 22px
   ตอนนี้ที่ว่างอยู่ตลอด ซ่อนแค่ตัวหนังสือ — เปลี่ยนสถานะกี่ครั้งก็ไม่มีอะไรขยับ
   ⚠ ต้องมี `min-height` ด้วย เพราะตอนไม่มีข้อความ textContent ว่าง
   `visibility: hidden` อย่างเดียวจะได้กล่องสูง 0 กลับมาเด้งเหมือนเดิม */
.es-permalink__note {
  margin: 5px 0 0;
  padding-left: 2px;
  min-height: 17px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--stat-error);
}

.es-permalink__note.is-quiet {
  visibility: hidden;
}

/* "ลิงก์ใหม่จะใช้ได้หลังกดบันทึก" — เตือน ไม่ใช่ผิดพลาด จึงเป็นสีเหลือง */
.es-permalink__note--warn {
  color: var(--stat-warning);
}

.es-switch {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  cursor: pointer;
  user-select: none;
}

/* ซ่อน checkbox จริงแบบยังโฟกัสด้วยคีย์บอร์ดได้ — `display:none` จะกด Tab ไม่ถึง */
.es-switch__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.es-switch__track {
  position: relative;
  flex: 0 0 auto;
  width: 42px;
  height: 24px;
  border-radius: 999px;
  background: rgba(var(--text-primary-rgb), 0.16);
  transition: background 0.22s;
}

.es-switch__dot {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.22s;
}

.es-switch__input:checked + .es-switch__track {
  background: var(--grad-1);
}

.es-switch__input:checked + .es-switch__track .es-switch__dot {
  transform: translateX(18px);
}

.es-switch__input:focus-visible + .es-switch__track {
  outline: 2px solid var(--grad-1);
  outline-offset: 2px;
}

.es-switch__label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-primary);
  white-space: nowrap;
}

.es-switch__input:checked ~ .es-switch__label {
  color: var(--grad-1);
}

/* ── ช่องแท็ก / แบรนด์ แบบพิมพ์เพิ่มเองได้ ──
   🔴 **ค่าทุกตัวต้องตรงกับ `.form-input` ใน styles.css เป๊ะ ๆ**
   ของเดิมลอกมาแบบเดา ๆ (เส้น 1px แทน 1.5px · โปร่งใสน้อยกว่า · มุม 12px แทน
   ทรงแคปซูล · พื้น `--bg-input` ทึบ) ผลคือช่องนี้จมหายไปกับพื้นเมื่อวางข้าง
   ช่องอื่น และตอนโฟกัสขึ้นเส้นชมพูคนละสีกับทั้งฟอร์ม (ผู้ใช้แจ้ง 2026-08-16
   ว่า "ดูซ่อน ๆ กัน แล้วก็ focus สีไม่เหมือนกับ input ทั่วไป")
   ถ้าจะแก้หน้าตาช่องกรอกทั้งเว็บ ต้องมาแก้ที่นี่ด้วยเสมอ */
.es-terms {
  position: relative;
}

.es-terms__box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-height: 49px;
  padding: 8px 18px;
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  border-radius: var(--radius-input);
  background: transparent;
  transition: border-color 0.25s, box-shadow 0.25s;
  cursor: text;
}

.es-terms__box:focus-within {
  border-color: var(--border-active);
  background-clip: padding-box;
}

.es-terms__chips {
  display: contents;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* 🔴 ต้องมี `.dokan-dashboard .dokan-dashboard-content` นำหน้า — กฎรวม
   `.dokan-dashboard .dokan-dashboard-content ul li { display:list-item; padding:0 }` (0,2,2)
   ชนะ `.es-terms__chip` (0,1,0) เงียบ ๆ → ชิปชิดขอบ · × แบรนด์ไม่ไปขวาสุด (ผู้ใช้แจ้ง 2026-09-18) */
.dokan-dashboard .dokan-dashboard-content .es-terms__chip,
.es-terms__chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 4px 8px 4px 14px;
  border-radius: 20px;
  background: rgba(var(--grad-2-rgb), 0.25);
  color: var(--text-primary);
  font-size: 13px;
  line-height: 1.6;
  list-style: none;
}

.es-terms__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.25);
  color: inherit;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}

.es-terms__remove:hover {
  background: rgba(0, 0, 0, 0.45);
}

/* ── ช่องที่รับได้ค่าเดียว (แบรนด์) ──
   เลือกแล้วต้องอ่านออกทันทีว่า "นี่คือค่าที่เลือกไว้ ไม่ใช่แท็กใบแรกของหลายใบ"
   ชิปจึงกินเต็มความกว้าง พื้นใส และดัน × ไปชิดขวาเหมือนช่อง select ที่ล้างค่าได้
   (ผู้ใช้แจ้ง 2026-08-16 ว่าแบรนด์ยังดูเหมือนช่องแท็ก) */
.dokan-dashboard .dokan-dashboard-content .es-terms.is-single .es-terms__chip,
.es-terms.is-single .es-terms__chip {
  flex: 1 1 auto;
  justify-content: space-between;
  padding: 0;
  background: transparent;
  font-size: 13px;
  letter-spacing: 0.08em;
}

/* × ของแบรนด์ = ปุ่มล้างค่า หน้าตาเดียวกับ `.es-clear-btn` ของช่องวันที่ลดราคา
   (ผู้ใช้สั่ง 2026-09-18 ให้เหมือนกันและเห็นชัด) — แก้ที่หนึ่งต้องแก้อีกที่ด้วย */
.es-terms.is-single .es-terms__remove,
.es-clear-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  margin: 0;
  padding: 0;
  border: 1px solid rgba(var(--text-primary-rgb), 0.22);
  border-radius: 50%;
  background: rgba(var(--text-primary-rgb), 0.06);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s;
}

.es-terms.is-single .es-terms__remove:hover,
.es-terms.is-single .es-terms__remove:focus-visible,
.es-clear-btn:hover,
.es-clear-btn:focus-visible {
  background: rgba(var(--text-primary-rgb), 0.18);
  border-color: rgba(var(--text-primary-rgb), 0.45);
  outline: none;
}

.es-clear-btn[hidden] {
  display: none;
}

/* ช่องวันที่ที่มีปุ่มล้าง — ปุ่มลอยชิดขวาในกรอบ ตำแหน่งเดียวกับ × ของแบรนด์ */
.input-wrapper.has-clear {
  position: relative;
}

.input-wrapper.has-clear .form-input {
  padding-right: 52px;
}

.es-clear-btn--input {
  position: absolute;
  top: 50%;
  right: 18px;
  transform: translateY(-50%);
}

/* ── ปฏิทินเลือกวัน (jQuery UI datepicker ของ Dokan) ──
   ธีมไม่เคยมี CSS ให้ตัวนี้เลย ปฏิทินจึงออกมาเป็นตัวหนังสือลอยทับฟอร์ม
   (ผู้ใช้แจ้ง 2026-09-18) · ตัวกล่องต่อท้าย <body> อยู่นอก .dokan-dashboard-content
   ต้องขึ้นต้นด้วย #ui-datepicker-div ให้ชนะกฎ table/td/a ทั่วไปของธีม */
#ui-datepicker-div.ui-datepicker {
  display: none;
  z-index: 100050 !important;
  width: 296px;
  margin-top: 6px;
  padding: 12px;
  border: 1px solid rgba(var(--text-primary-rgb), 0.14);
  border-radius: 16px;
  background: var(--bg-card);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 13px;
}

#ui-datepicker-div .ui-datepicker-header {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 36px;
  margin-bottom: 8px;
}

#ui-datepicker-div .ui-datepicker-title {
  font-weight: 600;
  letter-spacing: 0.04em;
}

#ui-datepicker-div .ui-datepicker-title span + span {
  margin-left: 6px;
}

#ui-datepicker-div .ui-datepicker-prev,
#ui-datepicker-div .ui-datepicker-next {
  position: absolute;
  top: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(var(--text-primary-rgb), 0.06);
  color: transparent;
  font-size: 0;
  text-decoration: none;
  cursor: pointer;
  -webkit-text-fill-color: currentColor;
}

#ui-datepicker-div .ui-datepicker-prev { left: 0; }
#ui-datepicker-div .ui-datepicker-next { right: 0; }

#ui-datepicker-div .ui-datepicker-prev:hover,
#ui-datepicker-div .ui-datepicker-next:hover {
  background: rgba(var(--text-primary-rgb), 0.16);
}

#ui-datepicker-div .ui-datepicker-prev.ui-state-disabled,
#ui-datepicker-div .ui-datepicker-next.ui-state-disabled {
  opacity: 0.3;
  cursor: default;
}

/* ลูกศรวาดด้วยขอบ — ไม่พึ่งภาพไอคอนของ jQuery UI ที่ธีมไม่มี */
#ui-datepicker-div .ui-datepicker-prev .ui-icon,
#ui-datepicker-div .ui-datepicker-next .ui-icon {
  display: block;
  width: 8px;
  height: 8px;
  border-top: 2px solid var(--text-primary);
  border-left: 2px solid var(--text-primary);
  font-size: 0;
  text-indent: -9999px;
  overflow: hidden;
}

#ui-datepicker-div .ui-datepicker-prev .ui-icon { transform: translateX(2px) rotate(-45deg); }
#ui-datepicker-div .ui-datepicker-next .ui-icon { transform: translateX(-2px) rotate(135deg); }

#ui-datepicker-div table.ui-datepicker-calendar {
  display: table;
  width: 100%;
  margin: 0;
  border: 0;
  border-collapse: collapse;
  table-layout: fixed;
  white-space: normal;
  background: none;
}

#ui-datepicker-div .ui-datepicker-calendar th,
#ui-datepicker-div .ui-datepicker-calendar td {
  padding: 2px;
  border: 0;
  background: none;
  text-align: center;
}

#ui-datepicker-div .ui-datepicker-calendar th {
  padding-bottom: 6px;
  color: var(--text-secondary);
  font-size: 11px;
  font-weight: 600;
}

#ui-datepicker-div .ui-datepicker-calendar td a,
#ui-datepicker-div .ui-datepicker-calendar td span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin: 0 auto;
  border-radius: 50%;
  background: none;
  color: var(--text-primary);
  font-size: 13px;
  text-decoration: none;
  -webkit-text-fill-color: currentColor;
}

#ui-datepicker-div .ui-datepicker-calendar td a:hover {
  background: rgba(var(--text-primary-rgb), 0.14);
}

#ui-datepicker-div .ui-datepicker-calendar td.ui-datepicker-today a {
  box-shadow: inset 0 0 0 1px var(--grad-4);
}

#ui-datepicker-div .ui-datepicker-calendar td a.ui-state-active,
#ui-datepicker-div .ui-datepicker-calendar td.ui-datepicker-current-day a {
  background: var(--gradient-diag);
  color: #fff;
  font-weight: 700;
}

#ui-datepicker-div .ui-datepicker-calendar td.ui-state-disabled span,
#ui-datepicker-div .ui-datepicker-calendar td.ui-datepicker-other-month span {
  color: var(--text-muted);
  cursor: default;
}

#ui-datepicker-div .ui-datepicker-buttonpane {
  display: none;
}

/* เต็มโควตาแล้วไม่มีอะไรให้พิมพ์ เคอร์เซอร์ text จะหลอกว่ายังพิมพ์ได้ */
.es-terms.is-full .es-terms__box {
  cursor: default;
}

/* ตัวอักษรต้องเท่ากับ `.form-input` (13px / letter-spacing 0.08em)
   ไม่งั้นพิมพ์ในช่องนี้แล้วตัวหนังสือใหญ่กว่าช่องข้าง ๆ เห็นชัด

   ⚠️ ต้องเขียน `.dokan-dashboard-content input.…` ให้ครบ — กฎรวมของ dashboard
   (`.dokan-dashboard-content input[type="text"]` บรรทัด ~2203) เป็น 0,2,1
   ถ้าเขียนแค่ `.es-terms__input` (0,1,0) จะแพ้แล้วได้ 14px กลับมา */
.dokan-dashboard-content input.es-terms__input,
.es-terms__input {
  flex: 1 1 120px;
  width: auto;
  min-width: 120px;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.08em;
  outline: none;
}

.dokan-dashboard-content input.es-terms__input::placeholder,
.es-terms__input::placeholder {
  color: var(--text-placeholder);
  letter-spacing: 0.12em;
  font-size: 12px;
}

/* กล่องคำแนะนำลอยทับเนื้อหาข้างล่าง ไม่ดันฟอร์มให้ขยับตอนพิมพ์ */
.es-terms__suggest {
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 220px;
  overflow-y: auto;
  margin: 0;
  padding: 4px;
  list-style: none;
  /* พื้นดำ + เส้นขอบชุดเดียวกับ `.icon-select__list` — ผู้ใช้สั่งให้ dropdown
     ทุกตัวในเว็บหน้าตาเหมือนกัน (2026-08-17) รวมช่องแนะนำแท็กกับแบรนด์ด้วย */
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  border-radius: 12px;
  background: var(--bg-primary);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
}

/* แถวสูงขึ้นและเว้นห่างจากตัวเลขมากขึ้น (ผู้ใช้แจ้ง 2026-08-17 ว่าบีบและชิดเกิน)
   🔴 ต้องมี selector ยาวของ dashboard นำหน้า (ผู้ใช้แจ้งซ้ำ 2026-09-14 ว่ายังบีบ) — Dokan มีกฎ
   `.dokan-dashboard .dokan-dashboard-content ul li { display: list-item; padding: 0 }` (0,2,2)
   ชนะ `.es-terms__option` (0,1,0) เงียบ ๆ วัดจริงได้ padding 0 · display list-item · แถวสูง 20px
   ชื่อกับ "ใช้อยู่ N ชิ้น" ติดกัน — แบบ 0,3,0 ข้างล่างชนะกฎนั้น */
.dokan-dashboard .dokan-dashboard-content .es-terms__option,
.es-terms__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin: 0;
  padding: 11px 14px;
  border-radius: 8px;
  list-style: none;
  cursor: pointer;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-primary);
}

.dokan-dashboard .dokan-dashboard-content .es-terms__option:hover,
.es-terms__option:hover {
  background: rgba(var(--grad-1-rgb), 0.22);
  color: var(--text-primary);
}

.es-terms__count {
  flex: 0 0 auto;
  font-size: 11px;
  font-style: normal;
  color: var(--text-muted);
}

.es-terms__hint {
  margin: 6px 0 0;
  padding-left: 2px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-muted);
}

/* ── หมายเหตุใต้หัวข้อในฟอร์มสินค้า ── */
.es-vendor-product-form .es-form-note {
  display: flex;
  align-items: flex-start;
  gap: 2px;
  margin: 0 0 14px;
  padding: 10px 12px;
  border-radius: 10px;
  background: rgba(var(--grad-1-rgb), 0.07);
  border: 1px solid rgba(var(--grad-1-rgb), 0.18);
  font-size: 12px;
  line-height: 1.65;
  color: var(--text-secondary);
}

.es-vendor-product-form .es-form-note .es-field-icon {
  margin-top: 2px;
  flex: 0 0 auto;
}

/* ── ป้ายไซส์ที่คำนวณสด ──
   ผู้ใช้สั่ง 2026-08-16 ให้ "ซ่อนไว้ก่อน แล้วเวลาแสดงให้เน้นหน่อยว่าไซส์อะไร
   ใส่ icon ด้วย" — ไม่ใช่หมายเหตุตัวเล็กเหมือนก่อนแล้ว แต่เป็นการ์ดที่มี
   ตัวอักษรไซส์ตัวใหญ่อยู่ในวงกลม ให้กวาดตาแล้วเห็นทันทีว่าตกไซส์ไหน
   การซ่อน/แสดงคุมด้วย attribute `hidden` จาก JS (ดู initSizePreview) */
.es-vendor-product-form .es-ship-size {
  display: flex;
  /* เกาะบน ไม่ใช่กลาง — การ์ดสูงขึ้นมากหลังมีตารางค่าส่ง (2026-09-09)
     ถ้าเป็น center วงกลมไซส์จะลอยอยู่กลางตารางแทนที่จะอยู่คู่กับหัวข้อ */
  align-items: flex-start;
  gap: 14px;
  /* `.add-new-product-wrapper` เป็น flex column + align-items:center — ลูกทุกตัว
     ต้องประกาศ width เอง ไม่งั้นจะหดเหลือเท่าเนื้อหาแล้วลอยอยู่กลางฟอร์ม */
  width: 100%;
  margin: 0 0 14px;
  padding: 14px 16px;
  border: 1px solid rgba(var(--grad-2-rgb), 0.35);
  border-radius: 12px;
  background: rgba(var(--grad-2-rgb), 0.10);
  color: var(--text-primary);
}

.es-vendor-product-form .es-ship-size[hidden] {
  display: none;
}

/* วงกลมตัวอักษรไซส์ — ตัวเลขความกว้างคงที่ไว้ กัน S กับ XXL ทำกล่องขยับ */
.es-ship-size__badge {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: rgba(var(--grad-2-rgb), 0.22);
  border: 1.5px solid rgba(var(--grad-2-rgb), 0.55);
  color: var(--grad-2);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
}

.es-ship-size__body {
  min-width: 0;
}

.es-ship-size__title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 3px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
}

.es-ship-size__title i {
  color: var(--grad-2);
}

.es-ship-size__meta {
  margin: 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-secondary);
}

/* ── ตารางค่าจัดส่งใต้ป้ายไซส์ (ผู้ใช้สั่ง 2026-09-09) ──
   ผู้ขายกรอกขนาดพัสดุแล้วต้องเห็นเลยว่าผู้ซื้อจะโดนเก็บกี่บาท
   ทั้งในพื้นที่เดียวกับร้านและส่งข้ามภาค — ตัวเลขวาดด้วย JS (renderRates)

   ⚠️ ใช้ <ul> ไม่ใช่ <table> ตั้งใจ — ตารางสองคอลัมน์ในกล่องแคบ ๆ บนมือถือ
   จะดันกล่องจนล้น ส่วน flex row ยุบบรรทัดได้เอง */
.es-ship-rates {
  margin: 12px 0 0;
  padding: 12px 0 0;
  border-top: 1px dashed rgba(var(--text-primary-rgb), 0.14);
}

.es-ship-rates__head {
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary);
}

.es-ship-rates__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* 🔴 **ต้องใช้ 3 คลาสขึ้นไป** — กฎ reset ของเราเองที่ช่วง "โครงหลัก"
   `.dokan-dashboard .dokan-dashboard-content ul li { display:list-item; padding:0 }`
   (0,2,2) ชนะคลาสเดี่ยว ถ้าเขียนแค่ `.es-ship-rates__list li` ราคาจะตกไป
   อยู่บรรทัดใหม่ใต้ชื่อภาค (กับดักเดียวกับ `.icon-select__option` ท้ายไฟล์) */
.es-ship-size .es-ship-rates .es-ship-rates__list li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 5px 0;
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-secondary);
}

.es-ship-size .es-ship-rates .es-ship-rates__list li + li {
  border-top: 1px solid rgba(var(--text-primary-rgb), 0.07);
}

/* แถวปลายทางเดียวกับที่ตั้งร้าน — เรตถูกที่สุดเสมอ ทำให้เห็นชัดว่าอันไหน */
.es-ship-size .es-ship-rates__list li.is-home .es-ship-rates__zone,
.es-ship-size .es-ship-rates__list li.is-home .es-ship-rates__price {
  color: var(--text-primary);
  font-weight: 600;
}

.es-ship-rates__zone {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}

.es-ship-rates__tag {
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(var(--grad-2-rgb), 0.18);
  color: var(--grad-2);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.es-ship-rates__price {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* XXL เรตเป็น 0 ทุกช่อง — ห้ามโชว์ "฿0" เพราะอ่านเป็น "ส่งฟรี" ซึ่งตรงข้ามความจริง */
.es-ship-rates__price.is-none {
  color: var(--stat-warning, #f59e0b);
  font-weight: 600;
}

/* ส่งด่วนในพื้นที่ — ข้อความใต้ตัวเลือกในหน้าชำระเงิน (ผู้ใช้สั่ง 2026-09-15) */
.vendor-shipping-option.is-express .vendor-shipping-option-info {
  flex-wrap: wrap;
}

.vendor-shipping-option-note {
  flex: 0 0 100%;
  display: block;
  margin-top: 4px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--text-secondary);
}

/* ส่งด่วนในพื้นที่ — กล่องย่อยต่อจากตารางค่าส่งปกติ (ผู้ใช้สั่ง 2026-09-15)
   แถวใช้ .es-ship-rates__list li ชุดเดิม (อยู่ใน .es-ship-size .es-ship-rates อยู่แล้ว) */
.es-ship-rates__express {
  margin: 12px 0 0;
  padding: 10px 0 0;
  border-top: 1px dashed rgba(var(--text-primary-rgb), 0.14);
}

.es-ship-rates__note {
  margin: 10px 0 0;
  font-size: 11px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.es-ship-rates__note.is-warn {
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid rgba(245, 158, 11, 0.35);
  background: rgba(245, 158, 11, 0.1);
  color: var(--stat-warning, #f59e0b);
}

/* ------------------------------------------------------------
   ฟองข้อความ "กรอกไม่ครบ" ต้องไม่ถูกหัวเว็บบัง

   🔴 เบราว์เซอร์เลื่อนช่องที่กรอกไม่ครบขึ้นมาให้เอง แต่มันไม่รู้จัก
   `.app-header` ที่เป็น `position: sticky` สูง 102px — ช่องจึงไปหยุด
   *ใต้* หัวเว็บพอดี ฟองข้อความที่วาดเหนือช่องเลยโดนบังจนอ่านไม่ออก
   (เจอตอนไล่ตรวจ F3 2026-08-18 · ผู้ขายเห็นแค่เงาสีส้มโผล่ครึ่งเดียว)

   `scroll-margin-top` เป็นค่าที่เบราว์เซอร์ใช้ตอนเลื่อนอัตโนมัติ
   ทั้ง validation, `:target` และ `scrollIntoView()` — ใส่ที่เดียวคุมได้หมด
   ------------------------------------------------------------ */

.form-input,
.form-select,
.form-textarea,
.add-new-product-wrapper select,
.add-new-product-wrapper textarea {
  scroll-margin-top: 120px;
  scroll-margin-bottom: 120px;
}

/* คำเตือน XXL — ระบบไม่คิดค่าส่งให้ ผู้ขายต้องเก็บเอง */
.es-ship-size__warn {
  display: flex;
  gap: 8px;
  margin: 10px 0 0;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid rgba(245, 158, 11, 0.35);
  background: rgba(245, 158, 11, 0.1);
  font-size: 12px;
  line-height: 1.6;
  color: var(--stat-warning, #f59e0b);
}

.es-ship-size__warn i {
  flex: 0 0 auto;
  margin-top: 2px;
}

/* ── หมายเหตุใต้ "รายได้ของร้าน" ในหน้ารายละเอียดออเดอร์ ──
   ใบที่ติดเรื่องคืนเงิน ตัวเลขรายได้ยังไม่ใช่เงินของร้านจริง
   ทรงเดียวกับกล่องเตือนไซส์ XXL เพื่อให้ผู้ขายอ่านออกว่าเป็นคำเตือนแบบเดียวกัน */
.payment-summary__note {
  display: flex;
  gap: 8px;
  margin: 10px 0 0;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid rgba(245, 158, 11, 0.35);
  background: rgba(245, 158, 11, 0.1);
  font-size: 12px;
  line-height: 1.6;
  color: var(--stat-warning, #f59e0b);
}

.payment-summary__note i {
  flex: 0 0 auto;
  margin-top: 2px;
}

/* ราคาใน `wc_price()` มาพร้อม <bdi> ที่ธีมตั้งสีอื่นไว้ — ในกล่องนี้ต้องสีเดียวกับข้อความ */
.payment-summary__note .woocommerce-Price-amount,
.payment-summary__note bdi {
  color: inherit;
  font-weight: 600;
}

@media (max-width: 480px) {
  .es-ship-size__badge {
    width: 46px;
    height: 46px;
    font-size: 14px;
  }
}

/* ── ไอคอนในฟอร์มสินค้า ──
   ใช้ `--grad-1` (ชมพู) ตัวเดียวกับปุ่มอัปโหลดและเส้นเน้นอื่น ๆ ทั้งฟอร์ม
   ห้ามใส่สีตายตัว — ธีมเปลี่ยนชุดสีเมื่อไรไอคอนต้องเปลี่ยนตาม

   `.es-field-icon` เหลือที่เดียวคือไอคอนหน้าข้อความหมายเหตุ (`.es-form-note`)
   ป้ายช่องกรอกไม่มีไอคอนแล้ว — ดูเหตุผลที่บล็อก `.product-section-title` */
.es-vendor-product-form .es-section-icon,
.es-vendor-product-form .es-field-icon {
  color: var(--grad-1);
  margin-right: 7px;
}

.es-vendor-product-form .es-section-icon {
  font-size: 0.95em;
}

.es-vendor-product-form .es-field-icon {
  font-size: 0.9em;
  margin-right: 6px;
}

/* 🔴 **ป้ายของกล่องรูปต้องเป็น `.form-label` เหมือนช่องอื่นทั้งฟอร์ม**
   ของเดิม "Product Gallery (Max 6 photos)" เป็น <label> เปล่า ๆ ที่ไม่มีกฎ
   ไหนจับเลย (add-new-product.css จับ `> div:first-child` ซึ่งเป็น <div>)
   จึงตกไปใช้ขนาดตัวอักษรพื้นฐานของธีม ใหญ่กว่าป้ายข้าง ๆ เห็นได้ชัด
   ผู้ใช้แจ้งว่า "ตัวหนังสือใหญ่แปลก ๆ" */
.trade-item-cover-box-wrap > .form-label,
.trade-item-gall-box-wrap > .form-label {
  display: flex;
  align-items: center;
  font-size: 13px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--text-primary);
  letter-spacing: 0.03em;
  padding-left: 2px;
  margin: 0;
  text-transform: none;
}

/* กล่องรูปปกสินค้า + แกลเลอรี — markup ของ Dokan ในกรอบของ design */
.trade-item-cover-box .instruction-inside {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 100%;
}

/* 🔴 **ต้องมีบรรทัดนี้ ไม่งั้นอัปโหลดปกเสร็จแล้วกล่องเปล่ายังค้างทับรูป**
   `.dokan-hide` ของ Dokan เป็น `display:none` เฉย ๆ (0,1,0) ส่วนกฎบนนี้
   เป็น `.trade-item-cover-box .instruction-inside` (0,2,0) จึงชนะ
   กล่อง "ยังไม่มีรูป" เลยซ่อนไม่ลง — ไอคอนเมฆกับกากบาทซ้อนกันมั่วไปหมด
   และรูปจริงถูกบีบเหลือ 0px เพราะกล่องเปล่ายังกินความสูงอยู่
   (เจอตอนทดสอบอัปโหลดจริง 2026-08-16) */
.trade-item-cover-box .instruction-inside.dokan-hide {
  display: none;
}

/* ปุ่มเลือกไฟล์ต้องกินเต็มกล่อง ไม่ใช่แค่ตรงไอคอน — กล่องเป็นกรอบประ
   ขนาดใหญ่ ผู้ใช้เล็งกดตรงไหนก็ควรติด ไม่ต้องจิ้มไอคอนเป๊ะ ๆ */
.trade-item-cover-box .es-cover-pick {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}

.trade-item-cover-box .instruction-inside i,
.trade-item-cover-box .es-cover-pick i {
  font-size: 32px;
  color: var(--grad-1);
  transition: transform 0.25s, color 0.25s;
}

.trade-item-cover-box:hover .es-cover-pick i {
  transform: scale(1.08);
}

.trade-item-cover-box .es-cover-pick:focus-visible {
  outline: 2px solid var(--grad-1);
  outline-offset: -4px;
  border-radius: 10px;
}

/* 🔴 **ต้องเป็น `absolute; inset:0` ไม่ใช่ `relative; height:100%`**
   กล่องปกเป็น flex คอลัมน์ที่ `align-items:center` — ลูกที่เป็น flex item
   จะกว้างเท่าเนื้อหาข้างในเท่านั้น พอรูปข้างในตั้ง `width:100%` ของพ่อที่
   กว้าง 0 ก็ได้ 0 กลับมา รูปสูงแต่ไม่มีความกว้าง มองไม่เห็นอะไรเลย
   (วัดได้ 0×162px ตอนทดสอบจริง 2026-08-16) — design เองก็วางรูปเป็น
   absolute เต็มกล่องเหมือนกัน (add-new-product.css `.trade-item-cover-box img`) */
.trade-item-cover-box .image-wrap {
  position: absolute;
  inset: 0;
}

/* 🔴 **ต้องประกาศ `display` ด้วย ห้ามใส่แค่ขนาด**
   add-new-product.css ของ design ตั้ง `.trade-item-cover-box img { display:none }`
   ไว้ แล้วโชว์ด้วยคลาส `.has-image` บนกล่อง — markup ของเราเป็นคนละทรง
   ถ้าไม่ย้ำตรงนี้ รูปปกที่อัปเสร็จแล้วจะโหลดมาจริงแต่สูง 0px มองไม่เห็นอะไรเลย
   (ตัวคลาส `.has-image` เองมี vendor-product-images.js คอยติด/ถอดให้ด้วย
   เพื่อให้กรอบเปลี่ยนจากเส้นประเป็นเส้นทึบตาม design) */
.trade-item-cover-box .image-wrap img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 10px;
}

/* แกลเลอรีสินค้า — markup เป็น <ul class="product_images"> ของ Dokan
   แต่หน้าตาต้องเป็นตะแกรง 3x2 ของ design (.gall-grid .img-item / .add-slot)

   Dokan ต่อรูปใหม่ท้าย <ul> เสมอ ส่วน design วางปุ่มอัปโหลดไว้หลังรูป
   แล้วตามด้วยช่องว่าง — เรียงด้วย order แทนการยุ่งกับลำดับใน DOM */
.trade-item-gall-box .gall-grid {
  list-style: none;
  margin: 0;
  padding: 0;
}

.trade-item-gall-box .gall-grid > li {
  position: relative;
  margin: 0;
  padding: 0;
  list-style: none;
  aspect-ratio: 1 / 1;
}

.trade-item-gall-box .gall-grid > li.image {
  order: 1;
  border-radius: 10px;
  overflow: hidden;
  background: rgba(var(--text-primary-rgb), 0.06);
  border: 2px solid rgba(var(--text-primary-rgb), 0.10);
}

.trade-item-gall-box .gall-grid > li.add-image {
  order: 2;
}

/* 🔴 **ต้องเขียนกฎซ่อนเอง** — `.gall-grid > li` ข้างบนตั้ง `aspect-ratio` กับ
   `position` ไว้ ซึ่ง**ไม่ทับ** `display:none` ของ `[hidden]` ก็จริง แต่ตอน
   ครบ 6 รูปแล้วปุ่มยังโผล่อยู่ (ผู้ใช้แจ้ง 2026-08-16) จึงย้ำด้วยกฎที่มี
   specificity สูงกว่า UA เพื่อไม่ต้องไล่ว่าใครทับใครอีก */
.trade-item-gall-box .gall-grid > li.add-image[hidden] {
  display: none;
}

/* รูปที่เลือกไว้แต่ยังไม่ได้ส่งขึ้น server — จางกว่ารูปที่อัปแล้วนิดหน่อย
   พร้อมป้ายมุมล่างบอกว่า "รออัปโหลด" (ดู vendor-product-images.js) */
.trade-item-gall-box .gall-grid > li.image.is-pending {
  border-style: dashed;
  border-color: rgba(var(--grad-1-rgb), 0.55);
}

.trade-item-gall-box .gall-grid > li.image.is-pending img {
  opacity: 0.75;
}

.es-gall-pending {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 2px 0;
  background: rgba(var(--bg-primary-rgb), 0.78);
  color: var(--grad-1);
  font-size: 9px;
  letter-spacing: 0.06em;
  text-align: center;
  text-transform: uppercase;
  pointer-events: none;
}

/* ระหว่างส่งรูปตอนกดบันทึก — ทั้งฟอร์มกดอะไรไม่ได้ กันกดซ้ำแล้วได้สองใบ */
.es-vendor-product-form.is-flushing {
  opacity: 0.6;
  pointer-events: none;
}

.trade-item-gall-box .gall-grid > li.gall-placeholder {
  order: 3;
  border: 1px solid rgba(var(--text-primary-rgb), 0.12);
  border-radius: 10px;
  background: transparent;
}

.trade-item-gall-box .gall-grid > li.image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ปุ่มลบรูป — เป็น <button> ไม่ใช่ <a> แล้ว (ไม่งั้น dokan.js ผูก wp.media ทับ)
   ต้องรีเซ็ต border/padding ของปุ่มเอง ไม่งั้นได้กรอบปุ่มมาตรฐานของเบราว์เซอร์ */
.trade-item-gall-box .gall-grid .action-delete,
.trade-item-cover-box .image-wrap .close {
  padding: 0;
  border: 0;
  cursor: pointer;
  font-family: inherit;
}

/* ── ปุ่มลบรูป — ชุดเดียวกับฟอร์มคืนสินค้า (`.image-remove-btn` ใน styles.css) ──
   ผู้ใช้สั่ง 2026-08-16 ให้ใช้หน้าตาเดียวกัน: สี่เหลี่ยมแดงมุมมน 2px
   ไอคอน fa-times สีขาว ไม่ใช่วงกลมโปร่งเหมือนเดิม
   ถ้าจะแก้ที่นี่ ให้ไปแก้ `.image-remove-btn` ให้ตรงกันด้วย

   ⚠️ `z-index` ห้ามตัดออก — รูปปกสืบ `position:absolute` มาจากกฎของ design
   (`.trade-item-cover-box img`) และอยู่หลังปุ่มใน DOM จึงวาดทับปุ่มลบจนกดไม่ได้ */
.trade-item-gall-box .gall-grid .action-delete,
.trade-item-cover-box .image-wrap .close {
  position: absolute;
  top: 4px;
  right: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 2px;
  background: var(--stat-error);
  color: var(--text-primary);
  font-size: 10px;
  line-height: 1;
  text-decoration: none;
  opacity: 1;
  text-shadow: none;
  z-index: 2;
}

/* ปุ่มอัปโหลด = .add-slot ของ design (กรอบประชมพู ไอคอนเมฆ) */
.trade-item-gall-box .gall-grid > li.add-image > .es-gallery-add {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 2px dashed rgba(var(--grad-1-rgb), 0.4);
  border-radius: 10px;
  background: rgba(var(--grad-1-rgb), 0.08);
  color: var(--grad-1);
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.25s, background 0.25s;
}

.trade-item-gall-box .gall-grid > li.add-image > .es-gallery-add:hover {
  border-color: var(--grad-1);
  background: rgba(var(--grad-1-rgb), 0.15);
}

/* 🔴 **ต้องย้ำสีไอคอนตอน hover ด้วย**
   ธีมมี `a:hover { color: … }` ทั่วเว็บ ซึ่งกินไอคอนที่สืบสีจากพ่อไปด้วย
   ตอนเอาเมาส์ไปวางไอคอนเมฆเลยจางหายไปกับพื้น (ผู้ใช้แจ้ง 2026-08-16)
   ตั้งสีให้ทั้งสถานะปกติและ hover ตรง ๆ จะได้ไม่ต้องพึ่งการสืบสี */
.trade-item-gall-box .gall-grid > li.add-image i,
.trade-item-gall-box .gall-grid > li.add-image > .es-gallery-add:hover i,
.trade-item-gall-box .gall-grid > li.add-image > .es-gallery-add:focus i {
  font-size: 32px;
  color: var(--grad-1);
  opacity: 1;
  transition: transform 0.25s;
}

.trade-item-gall-box .gall-grid > li.add-image > .es-gallery-add:hover i {
  transform: scale(1.08);
}

.trade-item-gall-box .gall-grid > li.add-image > .es-gallery-add:focus-visible {
  outline: 2px solid var(--grad-1);
  outline-offset: 2px;
}

/* ── รูปปกเป็นช่องบังคับ (ผู้ใช้สั่ง 2026-08-17) ──
   `required` ใช้กับ `<input type="hidden">` ไม่ได้ เบราว์เซอร์ข้ามช่องที่ซ่อนอยู่
   ตอนตรวจ constraint validation จึงต้องเช็คเองแล้ววาดข้อความเตือนเอง
   (ดู vendor-product-images.js) */
.trade-item-cover-box-wrap.has-error .trade-item-cover-box {
  border-color: var(--stat-error);
  background: rgba(var(--stat-error-rgb), 0.08);
}

.es-cover-error {
  margin: 8px 0 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--stat-error);
}

/* ระหว่างอัปโหลด — กันกดซ้ำแล้วได้รูปซ้ำ */
.trade-item-gall-box.is-uploading .es-gallery-add {
  opacity: 0.55;
  cursor: progress;
}

/* select2 ของแท็ก — Dokan โหลดธีมสว่างมา */
.dokan-dashboard-content .select2-container--default .select2-selection--multiple {
  background: var(--bg-input);
  border: 1px solid var(--border-input);
  border-radius: 12px;
  min-height: 44px;
}

.dokan-dashboard-content .select2-container--default .select2-selection--multiple .select2-selection__choice {
  background: rgba(var(--grad-2-rgb), 0.25);
  border: 0;
  border-radius: 20px;
  color: var(--text-primary);
  padding: 2px 10px;
}

/* หมวดหมู่สินค้า — UI แยกของ Dokan (dokan-product-category-ui.css) */
.es-product-category .dokan-category-selection,
.es-product-category .dokan-single-category-select {
  background: var(--bg-input);
  border: 1px solid var(--border-input);
  border-radius: 12px;
  color: var(--text-primary);
}

/* templates/products/dokan-category-header-ui.php:23 ใส่ <label>Category</label>
   ของตัวเองมาอีกอัน ทำให้กล่องหมวดหมู่มีหัวข้อซ้อนสองชั้น
   ใช้ label ของ design ที่อยู่นอกกล่องอันเดียวพอ */
.es-product-category label[for="chosen_product_cat"] {
  display: none;
}

/* ============================================================
   ปลด .form-input ที่ dokan-tailwind.css ยึดไว้ด้วย !important

   Dokan โหลด dokan-tailwind.css บนหน้าที่มี UI ของตัวเอง ซึ่งประกาศ

     .form-input { background-color:#fff !important; border-radius:0 !important;
                   padding:.5rem .75rem !important; font-size:1rem !important;
                   border-color:oklch(...) !important; appearance:none !important }

   .form-input เป็นคลาสหลักของ design ที่ใช้กับทุกช่องกรอก — ช่องทั้งหมด
   ในหน้าที่ Dokan แตะจึงกลายเป็นพื้นขาวขอบเหลี่ยม
   กระทบ: ฟอร์มขอเปิดร้าน, ตั้งค่าร้าน, ฟอร์มสินค้า, หน้ารายละเอียดออเดอร์

   ทางเดียวที่ชนะ !important คือ !important — จำกัดขอบเขตไว้เฉพาะ
   ช่องกรอกที่อยู่ในโครงของ design เท่านั้น ไม่ไปแตะ UI ของ Dokan เอง
   (อย่า dequeue dokan-tailwind.css ทิ้ง — ตัวเลือกหมวดหมู่สินค้าใช้ utility
   class จากไฟล์นี้ ถ้าเอาออกกล่องเลือกหมวดจะพัง)
   ============================================================ */

.input-wrapper .form-input,
.form-group .form-input,
.form-bank-info .form-input,
.trade-item-bg-gray .form-input {
  width: 100% !important;
  padding: 14px 20px !important;
  background-color: transparent !important;
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.12) !important;
  border-radius: var(--radius-input) !important;
  color: var(--text-primary) !important;
  font-family: var(--font) !important;
  font-size: 13px !important;
  font-weight: 400 !important;
  letter-spacing: 0.08em !important;
  line-height: normal !important;
  appearance: none !important;
  -webkit-appearance: none !important;
}

.input-wrapper .form-input::placeholder,
.form-group .form-input::placeholder {
  color: var(--text-placeholder) !important;
  letter-spacing: 0.12em;
  font-size: 12px;
  opacity: 1;
}

.input-wrapper .form-input:focus,
.form-group .form-input:focus {
  border-color: var(--border-active) !important;
  outline: none !important;
}

/* textarea ของ design มุมมน 20px และสูงอย่างน้อย 100px (styles.css:628) */
.input-wrapper .form-input.form-textarea,
.form-group .form-input.form-textarea {
  border-radius: 20px !important;
  min-height: 100px !important;
  resize: vertical !important;
}

/* select ของ design ใช้ลูกศร SVG ของตัวเอง (styles.css:611)
   จึงต้องคง appearance: none ไว้ ห้ามคืนลูกศรของเบราว์เซอร์
   และต้องกัน background-image ไม่ให้โดน tailwind ล้าง */
.input-wrapper select.form-input,
.form-group select.form-input {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%237b7399' d='M1.41 0L6 4.58 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: right 16px center !important;
  padding-right: 40px !important;
  cursor: pointer;
}

.input-wrapper select.form-input option,
.form-group select.form-input option {
  background: var(--bg-card);
  color: var(--text-primary);
}

/* ============================================================
   กราฟแท่งรายได้ — แก้บั๊กที่ติดมาจาก design

   store.css:1171 เขียน .finance-chart__bar::before { height: var(--height) }
   โดย --height เป็นเปอร์เซ็นต์ แต่ .finance-chart__bar เป็น flex item ที่
   ความสูงเป็น auto — เปอร์เซ็นต์จึงแก้ไม่ออกและกลายเป็น 0 แท่งไม่ขึ้นเลย

   ตรวจกับ frontend-backup/store.html ตัวจริงบนเบราว์เซอร์แล้ว: หน้า design
   เองก็ได้ ::before สูง 0px เหมือนกัน ไม่ใช่เพราะการแปลงเป็น PHP

   แก้โดยให้แท่งสูงเต็มกรอบแล้วดันเนื้อหาชิดล่าง ส่วน ::before ใช้ flex-basis
   แทน height — ได้ผลตามที่ design ตั้งใจ (ฐานแท่งเรียงกัน ยอดต่างกันตามสัดส่วน
   ตัวเลขกับชื่อเดือนอยู่ใต้แท่ง)
   ============================================================ */

.finance-chart__bar {
  height: 100%;
  justify-content: flex-end;
}

.finance-chart__bar::before {
  flex: 0 0 var(--height, 50%);
}

/* ============================================================
   ระบบคืนสินค้า (STEP 4)

   styles.css ของ design มีคลาสของหน้าคืนสินค้าเกือบครบแล้ว
   (.return-status-box / .return-evidence-grid / .return-reason-item /
    .step-indicator--return / .image-upload-* / .btn-shipping-option ฯลฯ)
   ที่นี่เติมเฉพาะสองอย่าง: คลาสที่ design ใช้แต่ไม่เคยเขียนกฎให้
   กับคลาสที่เราตั้งขึ้นแทน inline style ของ prototype
   ============================================================ */

/* ── .alert-box ── design ใช้ในสถานะ seller_rejected แต่ไม่มีกฎในไฟล์ไหนเลย
   (profile-order-returns.html:658) กล่องจึงไม่มีหน้าตา
   ใช้ทรงเดียวกับ .return-status-box.danger เพื่อให้อยู่ในภาษาเดียวกัน */
.alert-box {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 12px;
  border-radius: 8px;
  margin-bottom: 12px;
  font-size: 14px;
  line-height: 1.5;
  background: rgba(var(--text-primary-rgb), 0.06);
  color: var(--text-primary);
}

.alert-box i {
  margin-top: 2px;
}

.alert-box.danger {
  background: rgba(239, 68, 68, 0.08);
  border: 1px solid rgba(239, 68, 68, 0.2);
}

/* สถานะ seller_rejected = ผู้ดูแลระบบตัดสินให้ผู้ซื้อ ไม่ใช่ข่าวร้าย จึงใช้โทน info
   ค่าสีชุดเดียวกับ .return-status-box.info (styles.css:3750) */
.alert-box.info {
  background: rgba(59, 130, 246, 0.08);
  border: 1px solid rgba(59, 130, 246, 0.2);
}

/* ── หน้าการเงินของร้าน ──
   design มีแค่การ์ด 4 ใบเรียงลงมา (store.css:702) ที่นี่เติมสองอย่างที่เพิ่มเข้ามา:
   คำอธิบายใต้ชื่อการ์ด กับกลุ่มย่อยที่บอกว่าเงินสุทธิไปค้างอยู่ตรงไหน */
.store-finance-card__label {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.store-finance-card__hint {
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-secondary);
  font-weight: 400;
}

.store-finance-breakdown,
.store-finance-locked,
.store-finance-refunded {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* หัวข้อของกล่องที่เพิ่มเข้ามาต้องเท่ากับหัวข้อเดิมของ design เป๊ะ
   (.store-finance-withdraw-form h3 — store.css:973) ไม่งั้นดูเป็นคนละหน้า */
.store-finance-breakdown h3,
.store-finance-locked h3,
.store-finance-refunded h3 {
  font-size: 16px;
  font-weight: 700;
  color: var(--text-primary);
  margin: 0 0 8px 0;
  display: flex;
  align-items: center;
  gap: 8px;
  letter-spacing: 0.04em;
}

/* ไอคอนหัวข้อในหน้าการเงินทั้งหมดเป็นชมพูชุดเดียวกัน (ผู้ใช้สั่ง 2026-08-15)
   ของเดิม design ใช้ --text-secondary ซึ่งจมไปกับตัวหนังสือ */
.store-finance-withdraw-form h3 i,
.store-finance-history h3 i,
.store-finance-report h3 i,
.store-finance-breakdown h3 i,
.store-finance-locked h3 i,
.store-finance-refunded h3 i {
  color: var(--grad-1);
  font-size: 16px;
}

/* การ์ดกลุ่มย่อยเบากว่าการ์ดหลัก จะได้ไม่แย่งสายตากับตัวเลขสำคัญ */
.store-finance-card--sub {
  padding: 12px 16px;
  background: rgba(var(--text-primary-rgb), 0.04);
}

.store-finance-card--sub .store-finance-card__value {
  font-size: 16px;
}

/* ── ฟอร์มบัญชีรับเงินของร้าน ──
   ทรงเดียวกับ dropdown ธนาคารของบัญชีผู้ซื้อ (inc/bank-accounts.php)
   ไอคอนวางทับด้านซ้ายของ select แล้วเว้น padding ให้ตัวหนังสือไม่ทับกัน */
.form-bank-select {
  position: relative;
}

.es-bank-select__icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 20px;
  pointer-events: none;
}

.form-bank-select:has(.es-bank-select__icon) .form-input {
  padding-left: 42px;
}

.es-bank-settings .form-group {
  margin-bottom: 16px;
}

.es-bank-settings__actions {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 20px;
}

/* ── กราฟรายได้แบบรายปี ──
   design ทำกราฟไว้สำหรับ 2–6 แท่ง (store.css:1154 — gap 20px + flex:1)
   โหมดรายปีมี 12 แท่งเสมอ บนจอ 375px จะเหลือแท่งละ ~10px อ่านไม่ออก
   จึงล็อกความกว้างขั้นต่ำต่อแท่งแล้วให้เลื่อนแนวนอนแทน */
/* 🔴 โครงกราฟรายปีต่างจาก design ตรงที่ **ต้องล็อกความสูงของพื้นที่แท่ง**
 *
 * ของ design (store.css:1154) เป็น flex column: แท่ง → ตัวเลข → ชื่อเดือน
 * แล้วให้ `::before` สูงเป็น % ซึ่งอ้างอิงกับกล่องที่สูงตามเนื้อหา — พอมี 12 แท่ง
 * ที่ตัวเลขยาวไม่เท่ากัน (บางเดือนไม่มีตัวเลขเลย) จะเกิดสองปัญหา:
 *   1. ชื่อเดือนไม่อยู่แนวเดียวกัน เพราะแถวตัวเลขของบางแท่งสูง 0
 *   2. แท่งที่สูง 100% ทะลุกรอบ 200px ออกไป ยอดบนเลยโดนตัด
 *
 * เปลี่ยนเป็น grid 3 แถว: [พื้นที่แท่ง 1fr] [ตัวเลข] [ชื่อเดือน]
 * แถวแรกมีความสูงแน่นอน `%` ของแท่งจึงคำนวณถูก และอีกสองแถวเรียงตรงกันทุกแท่ง
 */
/* ── เส้นค่าเฉลี่ยต่อเดือน ──
 *
 * ต้องรู้ตำแหน่งพื้นที่กราฟเป็น "พิกเซลที่คำนวณได้" จึงเปลี่ยนแถวแรกของ grid
 * จาก `1fr` (เบราว์เซอร์คิดให้) เป็น `var(--plot-h)` ค่าคงที่
 * เส้นจึงวางด้วย calc ได้ตรงเป๊ะ: บนสุดของกราฟ + (1 - สัดส่วน) × ความสูงกราฟ
 *
 * `--avg-ratio` มาจาก PHP เป็นตัวเลข 0–1 ไม่มีหน่วย จะได้คูณกับ px ใน calc ได้
 */
.finance-chart-wrap {
  position: relative;
}

.finance-chart__avg {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(10px + (1 - var(--avg-ratio, 0)) * var(--plot-h, 160px));
  border-top: 1px dashed rgba(var(--grad-1-rgb), 0.55);
  pointer-events: none;
  z-index: 2;
}

.finance-chart__avg-label {
  position: absolute;
  right: 0;
  top: -9px;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--bg-primary);
  font-size: 10px;
  line-height: 1.6;
  letter-spacing: 0.04em;
  color: var(--grad-1);
  white-space: nowrap;
}

.finance-chart--year {
  --plot-h: 160px;
  gap: 8px;
  align-items: stretch;
  padding: 10px 0 8px;
  overflow-x: auto;
  overflow-y: hidden;
  /* จอกว้างพอ 12 แท่ง = ยืดเต็ม 100% / จอแคบ = เลื่อนแนวนอน
     (flex-basis 44px คือความกว้างขั้นต่ำที่ตัวเลขยังอ่านออก) */
  scroll-snap-type: x proximity;
  cursor: grab;
}

.finance-chart--year.is-grabbing {
  cursor: grabbing;
  user-select: none;
}

/* 🔴 `min-width: 0` ขาดไม่ได้
 *
 * flex item มี `min-width: auto` โดยปริยาย = ย่อเล็กกว่าเนื้อหาข้างในไม่ได้
 * แท่งจึงกว้างตาม**ความยาวตัวเลข**ที่อยู่ในนั้น — เดือนที่ขายได้เยอะเลขยาวกว่า
 * เลยกว้างกว่า ส่วนเดือนที่ไม่มีตัวเลขแคบสุด ทั้งที่ควรกว้างเท่ากันหมด
 */
.finance-chart--year .finance-chart__bar {
  flex: 1 0 52px;
  min-width: 0;
  scroll-snap-align: center;
  display: grid;
  /*
   * 🔴 **ต้องประกาศคอลัมน์เอง** ห้ามปล่อยให้ grid สร้าง implicit column
   *
   * ถ้าไม่ประกาศ คอลัมน์จะเป็น `auto` = กว้างเท่าเนื้อหาที่กว้างที่สุด
   * (ชื่อเดือน / ตัวเลขยอด) แล้ว `width: 100%` ของแท่งใน store.css
   * ก็อ้างอิงกับคอลัมน์นั้น → **แท่งสีกว้างตามความยาวตัวหนังสือ**
   * เดือนที่ยอดเลขยาวได้แท่งอ้วน เดือนที่ไม่มีตัวเลขได้แท่งผอม
   * (วัดจริงบนเบราว์เซอร์ 2026-08-15: 24.4px ถึง 40.6px ทั้งที่คอลัมน์ 62.9px เท่ากันหมด)
   *
   * `minmax(0, 1fr)` = เต็มความกว้างเสมอ และยอมให้เนื้อหาย่อได้ (มี ellipsis รองรับ)
   */
  grid-template-columns: minmax(0, 1fr);
  /* แถวแรกเป็นความสูงคงที่ ไม่ใช่ 1fr — เส้นค่าเฉลี่ยจะได้คำนวณตำแหน่งตรงกัน */
  grid-template-rows: var(--plot-h) auto auto;
  align-items: end;
  gap: 6px;
}

.finance-chart--year .finance-chart__bar::before {
  align-self: end;
  height: var(--height, 0%);
  /* เดือนที่ขายได้น้อยมากยังต้องเห็นว่ามีแท่งอยู่ */
  min-height: 3px;
  /* ต้องอยู่เหนือรางพื้นหลัง (::after) ที่วางทับช่องเดียวกัน */
  grid-row: 1;
  grid-column: 1;
  z-index: 1;
}

/* ── รางพื้นหลังของแต่ละเดือน ──
 *
 * วางเป็น grid item ในช่องเดียวกับแท่งจริง (`grid-row/column: 1`) แล้วซ้อนกัน
 * **ไม่ใช้ position: absolute** เพราะจะหลุดออกจาก grid แล้วต้องมานั่งคำนวณ
 * ความสูงของแถวตัวเลขกับชื่อเดือนเอง ซึ่งพังทันทีที่ขนาดฟอนต์เปลี่ยน
 *
 * เส้นแนวนอนวาดด้วย repeating gradient บนรางเลย จะได้อยู่ในกรอบพื้นที่กราฟพอดี
 * ไม่ล้ำไปทับแถวตัวเลข/ชื่อเดือนเหมือนตอนวาดบนกล่องกราฟทั้งใบ
 */
.finance-chart--year .finance-chart__bar::after {
  content: '';
  grid-row: 1;
  grid-column: 1;
  align-self: stretch;
  width: 100%;
  border-radius: 8px 8px 0 0;
  background-color: rgba(var(--text-primary-rgb), 0.04);
  background-image: repeating-linear-gradient(
    to top,
    rgba(var(--text-primary-rgb), 0.09) 0 1px,
    transparent 1px 25%
  );
  z-index: 0;
}

/* ล็อกความสูงหนึ่งบรรทัดไว้เสมอ แม้เดือนนั้นไม่มีตัวเลข
   (เป็น grid item แล้ว min-height จึงมีผล — ตอนเป็น inline span ไม่มีผล)
   ตัวเลขยาวเกินช่องให้ตัดด้วย … แทนที่จะไปดันแท่งให้กว้างขึ้น */
.finance-chart--year .finance-chart__value {
  font-size: 11px;
  line-height: 1.3;
  min-height: 1.3em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
}

/* ⚠ จุดของเดือนปัจจุบันต้องเป็น absolute
   ถ้าปล่อยเป็น block ธรรมดา ชื่อเดือนนั้นจะสูงกว่าเพื่อน 7px
   แล้วทั้งแท่งขยับตาม (align-items: end) ระดับเดือนเลยไม่อยู่ระนาบเดียวกัน */
.finance-chart--year .finance-chart__label {
  position: relative;
  line-height: 1.3;
  min-height: 1.3em;
  padding-bottom: 8px;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.finance-chart--year .finance-chart__bar--now .finance-chart__label::after {
  position: absolute;
  left: 50%;
  bottom: 0;
  margin: 0;
  transform: translateX(-50%);
}

/* ── แท่งเดือนปัจจุบัน วิ้งไล่เฉียงจากล่างซ้ายไปบนขวา ──
 *
 * ใช้แนวเดียวกับป้าย SOLD บนการ์ดสินค้า (store-profile.css:186) แต่ทำด้วย
 * **การเลื่อน background-position** แทนการวาง element ซ้อน
 * เพราะตัวแท่งคือ `::before` อยู่แล้ว และ `::after` ของแท่งจะกลายเป็น
 * grid item ตัวที่ 4 ไปดันแถวของกราฟเสีย
 *
 * ชั้นบน = แถบแสงเฉียง (45deg = แกนล่างซ้าย→บนขวา)
 * ชั้นล่าง = ไล่สีเดิมของ design ไม่แตะ
 */
.finance-chart--year .finance-chart__bar--now::before {
  background-image:
    linear-gradient(
      45deg,
      transparent 35%,
      rgba(255, 255, 255, 0.55) 50%,
      transparent 65%
    ),
    linear-gradient(180deg, #ec4899, #d946ef, #8b5cf6);
  background-size: 300% 300%, 100% 100%;
  background-repeat: no-repeat;
  animation: esFinanceBarShimmer 2.4s ease-in-out infinite;
}

/* 🔴 **ทิศกลับหัวกับที่คิดเอาไว้ ตรวจให้ดีก่อนแก้**
 *
 * `background-size: 300%` ทำให้ภาพใหญ่กว่ากรอบ การขยับ `background-position`
 * จึงเป็นการ **เลื่อนกรอบไปบนภาพ** ไม่ใช่เลื่อนภาพในกรอบ
 * → กรอบวิ่งไปทางขวาบน = ลายที่ตาเห็นวิ่งสวนไปทางซ้ายล่าง
 *
 * อยากให้ลายวิ่ง **ล่างซ้าย → บนขวา** กรอบจึงต้องวิ่งสวนไปทางซ้ายล่าง
 * เริ่มที่มุมขวาบนของภาพ (100% 0%) แล้วไปจบมุมซ้ายล่าง (0% 100%)
 */
@keyframes esFinanceBarShimmer {
  0% {
    background-position: 100% 0%, 0 0;
  }

  60%,
  100% {
    background-position: 0% 100%, 0 0;
  }
}

/* เคารพการตั้งค่าลดการเคลื่อนไหวของเครื่องผู้ใช้ */
@media (prefers-reduced-motion: reduce) {
  .finance-chart--year .finance-chart__bar--now::before {
    animation: none;
  }
}


/* เดือนที่ยังมาไม่ถึง — เทาจาง ๆ พอให้เห็นว่าเป็นช่องที่ยังว่างอยู่
   (ความสูงคุมด้วย min-height ของ .finance-chart--year ที่ specificity สูงกว่า) */
.finance-chart__bar--future::before {
  background: rgba(var(--text-primary-rgb), 0.08);
}

.finance-chart__bar--future .finance-chart__label {
  opacity: 0.45;
}

/* เดือนที่ผ่านไปแล้วแต่ไม่มียอดขาย — เหลือแค่ขีดบาง ๆ ให้รู้ว่ามีเดือนนี้อยู่ */
.finance-chart__bar--empty::before {
  background: rgba(var(--text-primary-rgb), 0.14);
}

/* เดือนปัจจุบัน — ยอดยังเดินอยู่ ไม่ใช่ตัวเลขปิดยอด
   ⚠️ ตั้งใจไม่ลด opacity ให้เดือน/ปีเก่า ยอดขายจริงเมื่อวานกับปีที่แล้วจริงเท่ากัน
   การทำให้จางลงจะสื่อผิดว่าตัวเลขเก่าเชื่อถือได้น้อยกว่า */
.finance-chart__bar--now .finance-chart__label {
  font-weight: 700;
  color: var(--text-primary);
}

.finance-chart__bar--now .finance-chart__label::after {
  content: '';
  display: block;
  width: 4px;
  height: 4px;
  margin: 3px auto 0;
  border-radius: 50%;
  background: var(--grad-1);
}

/* ปุ่มตั้งค่าบัญชี / ขอถอนเงิน — เต็มความกว้างแต่เตี้ยกว่าปุ่มหลักของ design
   (.btn-gradient กับ .btn-add-new-product เหมือนกันเป๊ะ: padding 16px + font 15px
    + letter-spacing .14em ซึ่งสูงเกินไปสำหรับปุ่มที่อยู่ในการ์ด ไม่ใช่แถบล่าง) */
.es-bank-trigger,
.es-finance-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 11px 10px;
  font-size: 13px;
  letter-spacing: 0.1em;
  text-decoration: none;
  box-sizing: border-box;
}

.es-bank-trigger i,
.es-finance-btn i {
  font-size: 13px;
}

/* เว้นจากบรรทัด "ยังไม่ได้ตั้งค่าบัญชีรับเงิน..." ที่อยู่เหนือปุ่ม — เดิมชิดกันเกินไป */
.store-finance-withdraw-form .form-hint + .es-bank-trigger {
  margin-top: 14px;
}

/* เปลี่ยนปี / เปลี่ยนหน้าประวัติ — จางออกแล้วจางกลับ ไม่กระพริบทั้งหน้า
   ล็อกความสูงขั้นต่ำไว้ระหว่างสลับ กันหน้ากระโดดตอนเนื้อหาใหม่สั้นกว่าเดิม */
.store-tab-content-wrapper {
  transition: opacity 0.16s ease;
}

.store-tab-content-wrapper.is-swapping {
  opacity: 0.35;
  pointer-events: none;
}

/* ── สัดส่วนตารางบนจอใหญ่ ──
 *
 * วัดจากหน้าจริง (2026-08-15): ทุกคอลัมน์กว้างกว่าเนื้อหา 2–7 เท่า
 * (คอลัมน์ "คำสั่งซื้อ" เนื้อหา 25px แต่กว้าง 175px) แล้วทุกช่องชิดซ้าย
 * ตัวเลขเงินจึงลอยห่างกันเป็นหย่อม ๆ อ่านเทียบกันไม่ได้และดูแหว่ง
 *
 * แก้สองทาง:
 *   1. ให้คอลัมน์ "ข้อความ" ดูดพื้นที่ว่างไปไว้ที่เดียว (`width: 100%`)
 *      คอลัมน์ตัวเลขจะหดพอดีเนื้อหา (`width: 1%` + nowrap)
 *   2. ตัวเลขเงินและคอลัมน์สุดท้ายชิดขวา — หลักเลขตรงกันทุกแถว
 *
 * ทั้งหมดอยู่ใน min-width: 601px เท่านั้น มือถือยังเป็นการ์ดเหมือนเดิม
 */
@media (min-width: 601px) {
  .store-finance-locked .finance-report-table th,
  .store-finance-locked .finance-report-table td,
  .store-finance-report .finance-report-table th,
  .store-finance-report .finance-report-table td,
  .store-finance-history .finance-history-table th,
  .store-finance-history .finance-history-table td {
    white-space: nowrap;
  }

  /* ── รายงานรายได้ + ประวัติถอนเงิน: แบ่งความกว้างเท่ากันทุกคอลัมน์ ──
     (ผู้ใช้สั่ง 2026-08-15) `table-layout: fixed` บังคับให้ยึดตาม width ที่กำหนด
     ไม่ไปคิดตามเนื้อหาเอง

     ⚠️ **ไม่รวมตาราง "เงินที่รอปลดล็อก"** — ผู้ใช้สั่งให้คงแบบเดิมไว้
     (คอลัมน์คำสั่งซื้อยืดรับพื้นที่ว่าง ที่เหลือหดพอดีเนื้อหา) */
  .store-finance-report .finance-report-table,
  .store-finance-history .finance-history-table {
    table-layout: fixed;
    width: 100%;
  }

  .store-finance-report .finance-report-table th,
  .store-finance-history .finance-history-table th {
    width: 25%;
  }

  /* เงินที่รอปลดล็อก — คงพฤติกรรมเดิม */
  .store-finance-locked .finance-report-table th:first-child,
  .store-finance-locked .finance-report-table td:first-child {
    width: 100%;
    white-space: normal;
  }

  .store-finance-locked .finance-report-table th:not(:first-child),
  .store-finance-locked .finance-report-table td:not(:first-child) {
    width: 1%;
    padding-left: 28px;
  }

  /* ตัวเลขเงินกับคอลัมน์สุดท้ายชิดขวา — หลักเลขตรงกันทุกแถว เทียบยอดได้ด้วยตา */
  .store-finance-locked .finance-report-table th:not(:first-child),
  .store-finance-locked .finance-report-table td:not(:first-child),
  .store-finance-report .finance-report-table th:not(:first-child),
  .store-finance-report .finance-report-table td:not(:first-child),
  /* ⚠ ต้องระบุ nth-child(4) ไม่ใช่ :last-child
     เพราะมี <td> ซ่อนตัวที่ 5 เก็บรายละเอียดไว้ให้ modal — `:last-child`
     จะไปตกที่ช่องซ่อนนั้น แล้วคอลัมน์สถานะหลุดจากการชิดขวา */
  .store-finance-history .finance-history-table th:nth-child(2),
  .store-finance-history .finance-history-table td:nth-child(2),
  .store-finance-history .finance-history-table th:nth-child(4),
  .store-finance-history .finance-history-table td:nth-child(4) {
    text-align: right;
  }

  /* คอลัมน์บัญชียาวกว่าเพื่อน — ตัดด้วย … ไม่ให้ดันตารางบาน */
  .store-finance-history .finance-history-table td:nth-child(3) {
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* ── กล่องตั้งค่าบัญชีรับเงิน ── ยืมโครง .avatar-cropper เหมือนกล่องแจ้งเลขพัสดุ
 *
 * 🔴 **ต้องมีบรรทัดนี้** — `.avatar-cropper` ตั้ง `display: flex` ไว้ ซึ่งชนะ
 * `[hidden] { display: none }` ของเบราว์เซอร์ (class specificity สูงกว่า UA stylesheet)
 * ถ้าไม่ประกาศทับ กล่องจะกางค้างทับทั้งหน้าตั้งแต่โหลด กดอะไรไม่ได้เลย
 *
 * กล่องแจ้งเลขพัสดุไม่เจอปัญหานี้เพราะ JS สร้าง element ตอนเปิดแล้วลบทิ้งตอนปิด
 * ส่วนกล่องนี้เป็น markup ที่ server วาดมาตั้งแต่แรก (จะได้ใช้ได้ตอน JS ยังไม่ทำงาน)
 */
/* ครอบคลุม **ทุกกล่อง** ที่ใช้โครง .avatar-cropper ไม่ใช่เฉพาะกล่องบัญชี
   เพิ่มกล่องใหม่เมื่อไรก็ไม่ต้องมานั่งเติมกฎนี้ซ้ำ (พลาดมาแล้วสองรอบ) */
.avatar-cropper[hidden] {
  display: none !important;
}

.es-bank-modal__box {
  max-width: 420px;
  max-height: 88vh;
  overflow-y: auto;
  text-align: left;
}

.es-bank-modal__box .form-group:last-of-type {
  margin-bottom: 12px;
}

.es-bank-modal__box .form-hint i {
  color: var(--grad-2);
  margin-right: 4px;
}

/* จำนวนรายการทั้งหมดในหัวข้อ — บอกว่าที่เห็นเป็นแค่หน้าแรก */
.store-finance-count {
  margin-left: auto;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--text-secondary);
}

/* ── ตัวแบ่งหน้า ── ปุ่มเล็กชิดซ้าย-ขวา เลขหน้าอยู่กลางบรรทัดเดียวกัน
   ไม่ใช้ .btn-return-plain เพราะนั่นเป็นปุ่มเต็มความกว้าง ดันเลขหน้าตกบรรทัด */
.finance-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 14px;
  flex-wrap: nowrap;
}

.finance-pager__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid rgba(var(--text-primary-rgb), 0.18);
  background: transparent;
  color: var(--text-primary);
  font-size: 12px;
  letter-spacing: 0.04em;
  text-decoration: none;
  white-space: nowrap;
  transition: border-color 0.2s, color 0.2s;
}

.finance-pager__btn:hover {
  border-color: var(--grad-1);
  color: var(--grad-1);
}

/* หน้าแรก/หน้าสุดท้าย — คงปุ่มไว้เป็นที่ว่าง เลขหน้าจะได้ไม่ขยับไปมา */
.finance-pager__btn.is-disabled {
  opacity: 0.3;
  pointer-events: none;
}

.finance-pager__pos {
  flex: 1 1 auto;
  text-align: center;
  font-size: 12px;
  color: var(--text-secondary);
  letter-spacing: 0.04em;
  white-space: nowrap;
}

/* ไอคอนธนาคารในตารางประวัติ */
.es-bank-cell {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.es-bank-cell i {
  font-size: 16px;
  flex: 0 0 auto;
}

/* ป้ายสถานะแบบไอคอน + ตัวหนังสือ */
.finance-history-row__status .status-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}

/* เวลาเป็นข้อมูลรอง — จางกว่าวันที่ เพื่อให้กวาดตาหาวันได้ก่อน
   แต่ยังอ่านได้เมื่อต้องแยกรายการในวันเดียวกัน */
.finance-history-row__time {
  margin-left: 6px;
  font-size: 0.86em;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

/* ── แถวกดได้ + กล่องรายละเอียด ──
   ตารางกลับมาเป็น 4 คอลัมน์เหมือนเดิม รายละเอียดเต็มไปอยู่ในกล่องเด้งแทน
   (ผู้ใช้สั่ง 2026-08-15) */
.finance-history-row {
  cursor: pointer;
  transition: background 0.18s, box-shadow 0.18s;
}

/* hover ให้เห็นชัดว่าแถวนี้กดได้ — พื้นเข้มขึ้นพร้อมขีดชมพูด้านซ้าย
   ใช้ box-shadow วาดขีดแทน border เพราะ border บน <tr> ทำให้ตารางขยับ */
.finance-history-row:hover,
.finance-history-row:focus-visible {
  background: rgba(var(--grad-1-rgb), 0.1);
  box-shadow: inset 3px 0 0 var(--grad-1);
  outline: none;
}

/* บนเดสก์ท็อปเป็น <tr> — ขีดอยู่ขอบตาราง ห่างตัวหนังสืออยู่แล้ว
   บนมือถือแถวเป็นการ์ด ต้องเว้น padding-left ให้ขีด (ดูใน media query) */
@media (max-width: 600px) {
  .store-finance-history .finance-history-row:hover,
  .store-finance-history .finance-history-row:focus-visible {
    box-shadow: inset 3px 0 0 var(--grad-1);
  }
}

.finance-history-row:hover .finance-history-row__time,
.finance-history-row:hover .finance-history-row__date {
  color: var(--text-primary);
}

/* ช่องเก็บรายละเอียดเต็ม — ซ่อนไว้ให้ JS โคลนไปใส่กล่อง
   ต้องซ่อนแบบไม่กินที่ทั้งใน table และ grid (มือถือ) */
.finance-history-detail[hidden] {
  display: none !important;
}

.es-detail-modal__box {
  max-width: 420px;
  max-height: 88vh;
  overflow-y: auto;
  text-align: left;
}

.finance-detail {
  margin: 0 0 4px;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px 14px;
  align-items: baseline;
}

.finance-detail dt {
  font-size: 12px;
  color: var(--text-secondary);
  white-space: nowrap;
}

.finance-detail dd {
  margin: 0;
  font-size: 13px;
  overflow-wrap: anywhere;
}

.finance-detail__amount {
  font-weight: 700;
  font-size: 15px;
}

.finance-detail dd i {
  margin-right: 4px;
}

/* ── ค่าบริการการถอนเงิน (2026-09-09) ────────────────────────────────
   ผู้ขายต้องอ่านออกใน 1 วินาทีว่า "ขอถอนเท่าไร โดนหักเท่าไร ได้จริงเท่าไร"
   ตัวหักใช้สีเตือน ตัวสุทธิใช้สีเดียวกับยอดที่เป็นบวกในการ์ดการเงิน */

.finance-detail__fee {
  color: var(--color-danger, #d64545);
}

.finance-detail__net {
  font-size: 15px;
}

/* ยอดสุทธิใต้ยอดเต็มในตารางประวัติ — บรรทัดที่สองตัวเล็กกว่า ไม่แย่งสายตา */
.finance-history-row__net {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-secondary);
  white-space: nowrap;
}

/* ตารางสรุปก่อนกดยื่นคำขอ */
.es-withdraw-fee {
  margin: 0 0 18px;
}

.es-withdraw-fee__table {
  margin: 0 0 8px;
  padding: 12px 14px;
  border: 1px solid var(--border-color, rgba(0, 0, 0, 0.08));
  border-radius: 10px;
  background: var(--surface-2, rgba(0, 0, 0, 0.02));
}

.es-withdraw-fee__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
}

.es-withdraw-fee__row + .es-withdraw-fee__row {
  margin-top: 6px;
}

.es-withdraw-fee__row dt {
  font-size: 12px;
  color: var(--text-secondary);
}

.es-withdraw-fee__row dd {
  margin: 0;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.es-withdraw-fee__row--minus dd {
  color: var(--color-danger, #d64545);
}

/* เส้นคั่นเหนือบรรทัดสุทธิ — บอกว่าเป็นผลลัพธ์ ไม่ใช่รายการที่สาม */
.es-withdraw-fee__row--total {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border-color, rgba(0, 0, 0, 0.08));
}

.es-withdraw-fee__row--total dt {
  font-weight: 700;
  color: var(--text-primary, inherit);
}

.es-withdraw-fee__row--total dd {
  font-size: 16px;
  font-weight: 700;
}

/* หมายเหตุก่อนกด WITHDRAW — ต้องรอแอดมิน · มีคำขอค้างได้ครั้งละ 1 (2026-10-03) */
.es-withdraw-note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 0 0 16px;
  padding: 12px 14px;
  border: 1px solid rgba(var(--text-primary-rgb), .1);
  border-radius: 10px;
  background: rgba(var(--text-primary-rgb), .04);
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.es-withdraw-note > i {
  flex: 0 0 auto;
  margin-top: 3px;
  font-size: 14px;
  color: var(--grad-1);
}

/* จุดนำหน้าแต่ละข้อ — สองข้อติดกันไม่มีจุดอ่านเป็นย่อหน้าเดียว */
.es-withdraw-note__item {
  position: relative;
  margin: 0;
  padding-left: 12px;
}

.es-withdraw-note__item::before {
  content: '';
  position: absolute;
  top: .7em;
  left: 0;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  opacity: .6;
}

.es-withdraw-note__item + .es-withdraw-note__item {
  margin-top: 6px;
}

/* สลิป — โชว์รูปย่อกดขยายได้ ไม่ต้องเดาว่าลิงก์พาไปไหน */
.finance-detail__slip {
  display: block;
  margin-top: 14px;
  text-decoration: none;
}

.finance-detail__slip img {
  width: 100%;
  border-radius: 8px;
  display: block;
}

.finance-detail__slip span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--grad-1);
}

/* ── ประวัติถอนเงินบนมือถือ ──
   4 คอลัมน์ในจอ 375px บีบจนอ่านไม่ออก (วันที่ตกบรรทัด เลขบัญชีถูกตัด)
   เปลี่ยนเป็นการ์ดสองบรรทัดต่อรายการ ใช้ grid + order สลับตำแหน่งเอา
   โดยไม่ต้องแก้ลำดับ <td> ใน HTML (desktop ยังเป็นตารางปกติ)

     บรรทัด 1:  [ไอคอน] ธนาคาร ••••1234        ฿500.00
     บรรทัด 2:  15 ส.ค. 2026                   [✓ โอนแล้ว]
   ============================================================ */
@media (max-width: 600px) {
  .store-finance-history .finance-history-table,
  .store-finance-history .finance-history-table tbody,
  .store-finance-history .finance-history-row,
  .store-finance-history .finance-history-row td {
    display: block;
    width: auto;
  }

  .store-finance-history .finance-history-table thead {
    /* หัวตารางไม่มีความหมายแล้วเมื่อเป็นการ์ด แต่ยังต้องอยู่ให้ screen reader อ่าน */
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .store-finance-history .finance-history-row {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 2px 10px;
    /* เว้นซ้ายไว้ให้ขีด hover — ไม่งั้นขีดจะแนบติดตัวหนังสือกับไอคอน */
    padding: 12px 0 12px 12px;
    margin-left: -12px;
    border-radius: 8px;
    border-bottom: 1px solid rgba(var(--text-primary-rgb), 0.08);
  }

  .store-finance-history .finance-history-row:last-child {
    border-bottom: none;
  }

  .store-finance-history .finance-history-row td {
    padding: 0;
    border: none;
  }

  .store-finance-history .finance-history-row__bank {
    order: 1;
    min-width: 0;
    font-size: 13px;
  }

  .store-finance-history .finance-history-row__amount {
    order: 2;
    text-align: right;
    font-weight: 700;
    white-space: nowrap;
  }

  .store-finance-history .finance-history-row__date {
    order: 3;
    font-size: 12px;
    color: var(--text-secondary);
  }

  .store-finance-history .finance-history-row__status {
    order: 4;
    text-align: right;
  }

  /* เลขบัญชียาวเกินช่อง — ตัดด้วย … ไม่ให้ดันการ์ดกว้างเกินจอ */
  .store-finance-history .es-bank-cell {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* จอแคบมาก — เหลือแต่ไอคอนสถานะ ตัวหนังสือไปอยู่ใน title/screen reader */
@media (max-width: 380px) {
  .finance-history-row__status .status-badge__text {
    display: none;
  }

  .finance-history-row__status .status-badge {
    padding: 4px 8px;
  }
}

/* ── รายงานรายได้ + เงินรอปลดล็อกบนมือถือ ──
   ทั้งสองตารางมี 4 คอลัมน์เหมือนกัน บีบในจอ 375px แล้วตัวเลขเงินตกบรรทัดกันหมด
   ใช้แนวเดียวกับประวัติถอนเงิน: การ์ดสองบรรทัด ตัวเลขสำคัญอยู่ขวาบน

     รายงานรายได้           เงินรอปลดล็อก
     ส.ค. 2569    ฿1,049,382    #573        ฿33,140
     ขาย ฿1.2M · ค่าคอม ฿185K   ถอนได้ 30 ส.ค.  [⏳ 16 วัน]
   ============================================================ */
@media (max-width: 600px) {
  .store-finance-report .finance-report-table,
  .store-finance-report .finance-report-table tbody,
  .store-finance-locked .finance-report-table,
  .store-finance-locked .finance-report-table tbody,
  .finance-report-row,
  .finance-locked-row,
  .finance-report-row td,
  .finance-locked-row td {
    display: block;
    width: auto;
  }

  .store-finance-report .finance-report-table thead,
  .store-finance-locked .finance-report-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .finance-report-row,
  .finance-locked-row {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 2px 10px;
    padding: 12px 0;
    border-bottom: 1px solid rgba(var(--text-primary-rgb), 0.08);
  }

  .finance-report-row:last-child,
  .finance-locked-row:last-child {
    border-bottom: none;
  }

  .finance-report-row td,
  .finance-locked-row td {
    padding: 0;
    border: none;
  }

  /* บรรทัดบน — ชื่อเดือน / เลขที่ออเดอร์ กับตัวเลขสำคัญ */
  .finance-report-row__label,
  .finance-locked-row__order {
    order: 1;
    min-width: 0;
    font-weight: 700;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .finance-report-row__net,
  .finance-locked-row__amount {
    order: 2;
    text-align: right;
    font-weight: 700;
    white-space: nowrap;
  }

  /* บรรทัดล่าง — รายละเอียดรอง ตัวเล็กและจางกว่า */
  .finance-report-row__gross,
  .finance-locked-row__date {
    order: 3;
    font-size: 12px;
    color: var(--text-secondary);
    white-space: nowrap;
  }

  .finance-report-row__fee {
    order: 4;
    text-align: right;
    font-size: 12px;
    color: var(--text-secondary);
    white-space: nowrap;
  }

  .finance-locked-row__left {
    order: 4;
    text-align: right;
  }

  /* หัวตารางถูกซ่อนแล้ว — เติมคำนำหน้าจาก data-label แทน ไม่งั้นเดาไม่ออกว่าเลขไหนคืออะไร */
  .finance-report-row__gross::before,
  .finance-report-row__fee::before,
  .finance-locked-row__date::before {
    content: attr(data-label) ' ';
  }

  /* แถวรวมทั้งปี — คั่นให้เห็นว่าไม่ใช่เดือนหนึ่ง */
  .finance-report-table .table-total-row {
    border-top: 1px solid rgba(var(--text-primary-rgb), 0.18);
    border-bottom: none;
    margin-top: 4px;
    padding-top: 14px;
  }
}

@media (max-width: 380px) {
  /* ตัวเลขหลักล้านยาวมาก — ย่อขนาดลงหน่อยกันตกบรรทัด */
  .finance-report-row__gross,
  .finance-report-row__fee {
    font-size: 11px;
  }
}

.store-finance-report__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.store-finance-report__head h3 {
  margin: 0;
}

.finance-year-picker select {
  padding: 6px 10px;
  border-radius: 8px;
}

/* design ใส่ class="text-error" กับยอดที่ถูกปฏิเสธ แต่ไม่มีกฎรองรับ */
.text-error {
  color: var(--stat-error);
}

.text-success {
  color: var(--stat-success);
}

/* ── รายการสินค้าในฟอร์มขอคืน ──
   design ให้ profile-return-form.js วาดด้วย inline style ทั้งก้อน (บรรทัด 80–128)
   เมื่อย้ายมาวาดฝั่ง PHP จึงต้องมีคลาสจริง ค่าทุกตัวยกมาจาก inline style เดิม */
.return-product-list {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.return-product-item {
  border: 1px solid rgba(var(--text-primary-rgb), 0.12);
  border-radius: 8px;
  padding: 12px;
}

.return-product-item__select {
  display: flex;
  align-items: center;
  gap: 12px;
}

.return-product-item__select input[type="checkbox"] {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  cursor: pointer;
}

.return-product-item__label {
  display: flex;
  gap: 10px;
  align-items: center;
  flex: 1;
  min-width: 0;
  cursor: pointer;
}

.return-product-item__label img {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  object-fit: cover;
  flex-shrink: 0;
}

.return-product-item__info {
  flex: 1;
  min-width: 0;
}

.return-product-item__info h4 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
}

.return-product-item__info p {
  margin: 4px 0 0 0;
  font-size: 12px;
  color: var(--text-secondary);
}

.return-product-item__price {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 2px 0 0 0;
}

.return-product-item__price span:first-child {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
}

.return-product-item__price span:last-child {
  font-size: 12px;
  color: var(--text-secondary);
}

.return-product-item__problem {
  border-top: 1px solid rgba(var(--text-primary-rgb), 0.08);
  padding-top: 12px;
  margin-top: 12px;
}

/* ── ปุ่ม RETURN / RECEIVED บนการ์ดในหน้าบัญชี ──
   design วางไว้ในการ์ดที่มีร้านเดียว ของเราอยู่ในบล็อกของร้านซึ่งชิดสินค้า */
.order-card__vendor > .order-action-row {
  margin-top: 12px;
}

/* ปุ่ม RECEIVED ต้องมีฟอร์มของตัวเอง (แนบ nonce) แต่ .order-action-row เป็น flex
   ที่แจกความกว้างให้ลูกโดยตรง ฟอร์มจึงต้องส่งความกว้างต่อลงไปให้ปุ่ม */
.order-action-row__form {
  flex: 1;
  min-width: 0;
  display: flex;
}

.order-action-row__form .order-tracking-btn {
  width: 100%;
}

/* <button> จัดข้อความกึ่งกลางให้เอง แต่ <a> ไม่ทำ (กับดักข้อ 18 ใน PROGRESS.md)
   ปุ่มคืนสินค้าหลายตัวเป็นลิงก์เพราะพาไปอีกหน้า */
a.btn-return-plain,
a.order-tracking-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  text-decoration: none;
}

/* ============================================================
   หน้าเข้าสู่ระบบ / ลืมรหัสผ่าน — ส่วนที่เพิ่มตอน STEP 5
   ============================================================ */

/* design เป็น <button class="btn-google"> แต่ของจริงต้องพาไปหน้า OAuth
   จึงเป็น <a> — <a> ไม่จัดกึ่งกลางให้เอง (กับดักข้อ 18) */
a.btn-google {
  text-align: center;
  text-decoration: none;
}

/* ⚠ กับดักข้อ 6 — design ตั้ง a:hover ให้ตัวอักษรโปร่งใสแล้วไล่สีผ่าน
   background-clip: text (styles.css:197) ปุ่มที่แปลงจาก <button> เป็น <a>
   ตัวหนังสือจึงหายตอนเอาเมาส์ไปชี้ ต้องยกเว้นให้ทุกครั้งที่ทำปุ่มเป็นลิงก์ */
a.btn-google:hover,
a.btn-google:focus,
a.btn-google:hover .btn-google__text,
a.btn-google:focus .btn-google__text {
  color: var(--btn-google-text);
  -webkit-text-fill-color: var(--btn-google-text);
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

/* พื้นหลังตอน hover ตาม design (.btn-google:hover ใน styles.css) */
a.btn-google:hover,
a.btn-google:focus {
  background-color: var(--btn-google-hover);
}

/* ============================================================
   ปุ่มเข้าสู่ระบบด้วยโซเชียลตัวอื่นที่ไม่ใช่ Google (เพิ่ม 2026-09-07)

   design วาดไว้ปุ่มเดียวคือ Google — พอผู้ใช้เปิด **X** เพิ่มในหลังบ้าน
   Nextend ธีมก็ต้องมีทรงปุ่มให้ ใช้ขนาด/ระยะ/มุมโค้งชุดเดียวกับ .btn-google
   เป๊ะ ๆ (styles.css:541) ต่างกันแค่สีพื้นกับสีตัวอักษรตามแบรนด์

   🔴 ห้ามแตะ .btn-google — ปุ่ม Google ยังใช้กฎเดิมทั้งหมด
   ============================================================ */

/* หลายปุ่มเรียงกันต้องมีระยะห่าง — ฟอร์มเข้าสู่ระบบเป็น flex column gap:0 */
.social-buttons {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ⚠️ ปุ่ม "Sign in with Eyestyle Scan" ของ mu-plugin `eyestyle-sso.php`
   ถูก **แทรกด้วย JS** ไว้ก่อนปุ่ม Google ซึ่งตอนนี้อยู่ในกล่องนี้แล้ว
   มันจึงกลายมาเป็นลูกของ .social-buttons ไปด้วย และพก `margin-bottom:15px`
   ของตัวเองมา ทำให้ช่องไฟไม่เท่ากับปุ่มอื่น — ล้างทิ้งแล้วใช้ gap ของกล่องแทน
   (แก้ที่นี่ ไม่ไปแตะ mu-plugin)

   🔴 **`order:-1` = ปุ่ม Scan อยู่บนสุดเสมอ** (ผู้ใช้สั่ง 2026-09-07)
   JS ของ mu-plugin แทรกปุ่มไว้ "ก่อนปุ่ม Google" ซึ่งเคยแปลว่าบนสุดเพราะ
   Google เป็นปุ่มเดียว — พอเปิด Facebook/X เพิ่มแล้วเรียงลำดับตามหลังบ้าน
   (เช่น Facebook → Google → X) ปุ่ม Scan จะไปโผล่กลางกอง
   ใช้ `order` ของ flex จับขึ้นบนสุดแทน **ไม่ต้องแก้ mu-plugin และไม่ต้องพึ่ง
   ว่า JS จะแทรกตรงไหน** — ปุ่มอื่นเป็น order:0 ตามค่าเริ่มต้นอยู่แล้ว

   ⚠️ ถ้าวันไหน **ปิด Google** ทั้งตัว JS ของ mu-plugin จะหาจุดแทรกไม่เจอ
   (มันมองหา `a[href*="google"]`) แล้วถอยไปแทรกนอกกล่องนี้ กฎนี้จะไม่มีผล
   — ตอนนั้นต้องไปแก้ที่ `eyestyle-sso.php` ให้เล็ง `.social-buttons` แทน */
.social-buttons > .eyestyle-scan-wrapper {
  margin: 0;
  order: -1;
}

a.btn-social {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: 100%;
  padding: 14px 10px;
  border: 1px solid rgba(var(--text-primary-rgb), 0.22);
  border-radius: var(--radius-btn);
  background-color: #1c1c26;
  color: #fff;
  font-family: var(--font);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.03em;
  text-align: center;
  text-decoration: none;
  transition: box-shadow 0.25s, filter 0.25s, transform 0.15s;
}

a.btn-social:active {
  transform: scale(0.98);
}

a.btn-social:hover,
a.btn-social:focus {
  filter: brightness(1.25);
  box-shadow: 0 2px 8px rgba(var(--bg-primary-rgb), 0.18);
}

/* ⚠ กับดักข้อ 6 อีกรอบ — design ตั้ง a:hover ให้ตัวอักษรโปร่งใสแล้วไล่สีผ่าน
   background-clip:text ตัวหนังสือในปุ่มลิงก์จึงหายตอนเอาเมาส์ไปชี้
   ต้องยกเว้นให้เหมือนที่ทำกับ a.btn-google */
a.btn-social:hover,
a.btn-social:focus,
a.btn-social:hover .btn-social__text,
a.btn-social:focus .btn-social__text {
  color: #fff;
  -webkit-text-fill-color: #fff;
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

.btn-social__icon {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  font-size: 18px;
  line-height: 1;
}

.btn-social__text {
  line-height: 1;
}

/* สีตามแบรนด์ — ตัวที่ไม่ได้ระบุใช้พื้นเข้มกลาง ๆ ข้างบน */
a.btn-social--twitter  { background-color: #000000; }
a.btn-social--facebook { background-color: #1877f2; border-color: transparent; }
a.btn-social--line     { background-color: #06c755; border-color: transparent; }
a.btn-social--apple    { background-color: #000000; }
a.btn-social--microsoft{ background-color: #2f2f2f; }
a.btn-social--linkedin { background-color: #0a66c2; border-color: transparent; }
a.btn-social--tiktok   { background-color: #010101; }

/* ปุ่ม CONFIRM / BACK TO SIGN IN ที่เป็นลิงก์ก็โดนกฎเดียวกัน
   ตัวหนังสือเป็นสีขาวบนพื้น gradient ของ .btn-submit เอง */
a.btn-submit:hover,
a.btn-submit:focus {
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

/* ปุ่ม "กลับไปเข้าสู่ระบบ" ในหน้ายืนยันการส่งอีเมลก็เป็น <a> เหมือนกัน */
a.btn-submit {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  text-decoration: none;
}

/* ตั้งใจไม่ทำ .forgot-password-form ให้เป็น flex
   forgot-password.html ของ design ปล่อยฟอร์มนี้เป็น block ธรรมดา
   (styles.css จัด flex ให้เฉพาะ .login-form / .signup-form)
   ถ้าทำเป็น flex ปุ่ม CONFIRM จะถูก blockify แล้วระยะห่างเพี้ยนจาก design */

/* ⚠ ต้องอยู่ "หลัง" ก้อนที่สู้ dokan-tailwind ด้านบน
   ก้อนนั้นใช้ `padding: 14px 20px !important` กับ .form-input ทุกช่อง
   ซึ่งไปล้าง padding-right 52px ที่ design เว้นไว้ให้ปุ่มตา (styles.css:558)
   specificity เท่ากันและ !important เหมือนกัน ตัวที่มาทีหลังจึงชนะ
   ถ้าย้ายกฎนี้ขึ้นไปข้างบนช่องรหัสผ่านจะกลับไปทับปุ่มตาอีก */
.input-wrapper .form-input--password,
.form-group .form-input--password {
  padding-right: 52px !important;
}

/* ============================================================
   หน้ารายละเอียดคำสั่งซื้อฝั่งผู้ซื้อ (STEP 6)
   view-order + order-pay — design: frontend-backup/profile-order-*.html
   ============================================================ */

/* ⚠ design ตั้งชื่อ .payment-method ซ้ำกันสองความหมาย
     profile-order-payment.css:268 = กล่องครอบตัวเลือก (flex column)
     checkout.css:301              = หนึ่งตัวเลือก (flex row)
   สองไฟล์นี้โหลดพร้อมกันในหน้า order-pay และ checkout.css มาทีหลังจึงชนะ
   กล่องครอบจึงต้องใช้ชื่อคลาสของตัวเอง แล้วยกค่าจาก design มาไว้ที่นี่ */
.order-detail-payment-method {
  background: var(--bg-primary);
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.order-detail-payment-method h3 {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: 0.03em;
  margin: 0 0 6px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.order-detail-payment-method h3 i {
  color: var(--text-secondary);
  font-size: 14px;
}

/* รายการตัวเลือกวิธีจ่ายเงินเป็น <ul> — ตัด bullet กับระยะของเบราว์เซอร์ออก */
.order-detail-payment-method .wc_payment_methods {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* แถวปุ่มท้ายหน้า — สั่งข้ามร้านจะมีหลายแถว จึงต้องมีระยะคั่น */
.order-detail-actions {
  margin: 16px 0;
}

.order-detail-actions__label,
.order-card__action-label {
  display: block;
  font-size: 12px;
  color: var(--text-secondary);
  margin-bottom: 6px;
}

/* ป้ายชื่อร้านเหนือปุ่ม RETURN/RECEIVED ในการ์ด — ขึ้นเฉพาะออเดอร์ข้ามร้าน
   ที่มีปุ่มมากกว่าหนึ่งชุด ต้องเว้นจากกล่องสถานะจัดส่งด้านบน */
.order-card__footer .order-card__action-label {
  margin-top: 10px;
}

/* ปุ่ม Pay Now ในหน้า view-order เป็นลิงก์ไปหน้า order-pay
   (<a> ไม่จัดกึ่งกลางให้เอง และโดน a:hover ทำตัวหนังสือหาย — กับดักข้อ 6/18) */
a.payment-pay-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-align: center;
  text-decoration: none;
}

a.payment-pay-btn:hover,
a.payment-pay-btn:focus {
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

/* ⚠ WooCommerce ตั้ง `float: right` ให้ปุ่ม #place_order (woocommerce.css)
   ปุ่มกว้างเต็ม 960px แล้วลอย ทำให้ <p class="payment-note"> ที่ตามมา
   (เป็น flex จึงสร้าง BFC) ถูกบีบเหลือ **กว้าง 0** ข้อความเลยตกบรรทัดละคำ
   และไปซ้อนใต้ปุ่ม — หายากเพราะไม่มีกฎ width ไหน match เลย */
/* ต้องมี #payment ในตัวเลือกด้วย — กฎของ WooCommerce คือ
   `.woocommerce #payment #place_order` ซึ่งมีสอง id (2,1,0)
   เขียนแค่ `.order-detail-actions #place_order` (1,1,0) จะแพ้เงียบ ๆ */
#payment .order-detail-actions #place_order,
.order-detail-actions .payment-pay-btn {
  float: none;
}

/* กันไว้อีกชั้น เผื่อปลั๊กอินอื่นทำให้ปุ่มลอยอีก */
.payment-note {
  clear: both;
}

/* ============================================================
   Responsive (STEP 7)
   ============================================================ */

/* ⚠ design เขียนกฎตัดข้อความของ .header-title ไว้ใน store-profile.css เท่านั้น
   เพราะหน้าร้านเป็นหน้าเดียวใน design ที่หัวข้อยาว (ตั้งใจทดสอบไว้ด้วย)
   ของจริงหัวข้อยาวได้ทุกหน้า — ชื่อเพจ ชื่อร้าน ชื่อสินค้า
   ถ้าไม่ตัด บนมือถือ 390px หัวข้อจะตกสามบรรทัดและดัน header สูงขึ้น 50px
   ยกกฎเดิมมาไว้ที่นี่ให้มีผลทุกหน้า (ค่าเหมือน store-profile.css:6-13 เป๊ะ) */
.header-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
  text-align: center;
}

/* หัวข้อหน้าที่ยาว (CUSTOMER PROFILE · STORE PROFILE · ADD NEW PRODUCT) — 2026-09-11
   ย่อตัวอักษรตามความกว้างจอแทนการตัดเป็น "STORE PRO…" (เจอหลังเปลี่ยนชื่อหัวข้อตามที่ผู้ใช้สั่ง)

   วัดของจริงบนเบราว์เซอร์ (2026-09-11):
     "CUSTOMER PROFILE" (16 ตัว) ที่ 22px กว้าง 262px = 0.745 × ขนาดตัวอักษร ต่อหนึ่งตัว
     "STORE PROFILE"    (13 ตัว) ที่ 20px กว้าง 184px = 0.708 × ขนาดตัวอักษร ต่อหนึ่งตัว
   ช่องของหัวข้อ = ความกว้างจอ − 162px ทุกหน้า (อัปเดต 2026-09-11 หลังถอดปุ่ม .btn-shop)
     ปุ่มย้อนกลับ 42 + ปุ่มตะกร้า/ตัวเว้นช่อง 42 + gap 15×2 + padding 24×2
   (เดิมใช้ 206 เพราะฝั่งซ้ายเป็นปุ่มสองตัว 66px และหน้าแดชบอร์ดมีตัวเว้นช่อง 66px)
   → ขนาดที่พอดี = (100vw − 162px) / (จำนวนตัว × 0.78)  ← 0.78 เผื่อตัวกว้างอย่าง M/W
   header.php ส่งจำนวนตัวมาใน `--es-title-len` — หัวข้อสั้นจึงย่อน้อยกว่าหัวข้อยาว
   และเต็ม 22px เมื่อจอกว้างพอ

   คลาสนี้ใส่ให้เฉพาะหัวข้ออังกฤษตั้งแต่ 10 ตัวขึ้นไป (header.php)
   ชื่อสินค้า/ชื่อร้านภาษาไทยยังตัดด้วย … ตามเดิม
   ⚠️ ถ้าแถบหัวเว็บเพิ่มปุ่มจนช่องหัวข้อแคบลง ต้องวัดเลข 162 ใหม่ */
/* ขั้นต่ำ 11px (เดิม 14px) — 2026-09-16 ถอดปุ่ม Market ออกจากหัวเว็บหน้าโปรไฟล์ แล้วจอ 320
   ได้ "CUSTOMER PROF…" (สูตรให้ 12.7px แต่โดนดันขึ้น 14px จนล้น) · ตอนมีปุ่ม Market ขั้นต่ำเป็น 11px อยู่แล้ว */
.header-title--long {
  font-size: clamp(11px, calc((100vw - 162px) / (var(--es-title-len, 16) * 0.78)), 22px);
}

/* ⚠ WooCommerce ตั้งขนาดปุ่มไปชำระเงินด้วย
     .wc-proceed-to-checkout a.checkout-button { font-size:1.25em; padding:1em }
   ซึ่งเป็น (0,2,1) ชนะ .btn-checkout (0,1,0) ของ design
   → ปุ่มสูง 83px ตัวอักษร 20px แทนที่จะเป็น 48px / 15px ตาม design
   เขียนทับด้วย specificity เท่ากันแล้วชนะด้วยลำดับการโหลด */
.wc-proceed-to-checkout a.btn-checkout {
  font-size: 15px;
  padding: 16px 10px;
  margin-bottom: 0;
}

/* ============================================================
   หน้าขอบคุณ — สาขา "รอชำระเงิน" และ QR ของ Omise

   design (thankyou.html) วาดไว้แค่กรณีสำเร็จ ไอคอนจึงเป็นสีเขียวตายตัว
   ของจริงมี 3 กรณี: สำเร็จ / ชำระเงินไม่สำเร็จ / รอสแกน QR
   ============================================================ */

.thankyou-icon--failed {
  color: var(--stat-error);
}

.thankyou-icon--pending {
  color: var(--stat-warning);
}

.thankyou-timer {
  width: 100%;
  margin-bottom: 24px;
}

/* คำเตือน "อย่าสแกนจ่ายหลังหมดเวลา" — วางใต้ QR ของ Omise
   ต้องอ่านออกแน่ ๆ แต่ไม่แย่งความสนใจไปจาก QR จึงใช้พื้นจาง ไม่ใช่สีทึบ */
.thankyou-warning {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  width: 100%;
  margin: 0 0 20px;
  padding: 12px 14px;
  border-radius: var(--radius-card, 12px);
  border: 1px solid rgba(var(--stat-warning-rgb), 0.45);
  background: rgba(var(--stat-warning-rgb), 0.1);
  font-size: 12px;
  line-height: 1.75;
  color: var(--text-primary);
  text-align: start;
}

.thankyou-warning i {
  flex-shrink: 0;
  margin-top: 3px;
  font-size: 13px;
  color: var(--stat-warning);
}

/* ── กล่อง QR PromptPay ──
   markup มาจากปลั๊กอิน (class-omise-payment-promptpay.php:167)
   design ไม่เคยเห็นบล็อกนี้ ต้องจัดเองทั้งหมด */
#omise-offline-additional-details,
#omise-offline-payment-result {
  width: 100%;
  background: var(--bg-secondary);
  border-radius: 16px;
  padding: 20px;
  margin-bottom: 24px;
  text-align: center;
  font-size: 14px;
  color: var(--text-primary);
}

#omise-offline-additional-details p {
  margin: 0 0 12px;
}

/* ⚠ QR ของ Omise เป็น SVG เส้นสีดำบนพื้นโปร่งใส
   เว็บนี้พื้นหลังดำ ถ้าไม่ใส่กรอบขาวให้ QR จะมองไม่เห็นและสแกนไม่ได้เลย */
.omise-promptpay-qrcode {
  display: inline-block;
  width: 260px;
  max-width: 100%;
  background: #ffffff;
  border-radius: 12px;
  padding: 12px;
  margin-bottom: 16px;
}

/* ⚠ SVG ที่ Omise ส่งมาเป็นใบสลิปเต็ม (viewBox 740×1050) ไม่ใช่จัตุรัส
   ถ้าบังคับ height จะบี้จน QR สแกนไม่ผ่าน — ให้ความสูงคิดจาก viewBox เอง
   (omise-css.css:146 ตั้ง max-width: 300px !important ไว้ที่จอ ≥768px
   จึงคุมความกว้างที่กล่องครอบแทน) */
.omise-qr-image {
  width: 100%;
}

.omise-qr-image svg,
#omise-promptpay-qrcode-svg {
  display: block;
  width: 100%;
  height: auto;
}

/* ปุ่มดาวน์โหลด QR — ให้เข้าชุดปุ่มรองของ design (.btn-continue-shopping)
   เป็น <a> อยู่แล้ว จึงต้องยกเว้น a:hover ด้วย (กับดักข้อ 6) */
a.omise-download-promptpay-qr,
#omise-offline-payment-refresh-status {
  display: block;
  width: 100%;
  padding: 14px 10px;
  margin: 0 auto 16px;
  background: transparent;
  border: 1px solid var(--border-inactive);
  border-radius: var(--radius-btn);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

a.omise-download-promptpay-qr:hover,
#omise-offline-payment-refresh-status:hover {
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  background: rgba(var(--text-primary-rgb), 0.06);
  border-color: var(--border-active);
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

/* นับถอยหลังหมดอายุ QR ที่ปลั๊กอินใส่มาเอง (#countdown) */
#omise-offline-additional-details #countdown {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--stat-warning);
}

/* ── ขั้นตอนการชำระเงิน ──
   .qr-alert-box กับ .align-left เป็นคลาสของปลั๊กอินที่ไม่มี CSS มาด้วย
   (เจอแบบเดียวกับ .alert-box ของ design ในกับดักข้อ 24) */
.qr-alert-box {
  margin-top: 16px;
  padding: 16px;
  background: rgba(var(--text-primary-rgb), 0.04);
  border-radius: 12px;
  text-align: left;
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.7;
}

.qr-alert-box strong {
  color: var(--text-primary);
}

.qr-alert-box ol.align-left {
  margin: 0;
  padding-left: 18px;
  text-align: left;
}

.qr-alert-box ol.align-left li {
  margin-bottom: 6px;
}

/* ============================================================
   ปุ่มย้อนกลับบนหัวเว็บ — วงกลมขอบไล่สีแบบปุ่มตะกร้า (ผู้ใช้สั่ง 2026-09-11)

   design เดิมเป็นลูกศรลอย ๆ 30px (styles.css:310) ผู้ใช้ส่งรูปให้ทำเป็นวงกลม
   ขอบไล่สีแบบเดียวกับ .btn-cart (styles.css:1041) ทุกหน้า
   *"effect เวลา hover ไม่ต้อง"* → ไม่ใส่ button-pulse ที่ปุ่มตะกร้ามี

   ขนาด 42px เท่าปุ่มตะกร้า ฝั่งซ้าย–ขวาของหัวเว็บจึงหนักเท่ากัน หัวข้ออยู่กลางพอดี
   (.header-spacer ขยายเป็น 42px ตามด้วย — ดูท้ายไฟล์ "ถ่วงน้ำหนัก header")

   ปุ่มไปหน้า Market (.btn-shop) ถอดออกจากทุกหน้าในรอบเดียวกัน แล้ว**เอากลับมา
   เฉพาะหน้าบัญชี (CUSTOMER PROFILE) กับแดชบอร์ดร้าน (STORE PROFILE) และหน้าย่อย**
   (ผู้ใช้สั่ง 2026-09-11 รอบถัดมา — สองกลุ่มนี้ใช้แถบปุ่มเฉพาะหน้าแทนแถบเมนูล่าง
   จึงไม่มีเมนู Market ให้กด) · ทรงเดียวกับปุ่มย้อนกลับ · ไอคอนเดียวกับเมนู Market
   ============================================================ */

.btn-back,
.btn-shop {
  position: relative;
  isolation: isolate;
  width: 42px;
  height: 42px;
  padding: 0;
  margin-top: 0;
  border-radius: 50%;
  background: var(--bg-primary);
  opacity: 1;
  transition: none;
}

/* ส่วนที่ .btn-back ได้จาก styles.css:310 แต่ .btn-shop เป็น <a> ไม่มี */
.btn-shop {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--text-primary);
  text-decoration: none;
}

.btn-shop .es-market-icon .fa-shop {
  font-size: 15px;
}

.btn-shop .es-market-icon .fa-location-dot {
  right: -5px;
  bottom: -3px;
  font-size: 8px;
}

/* ปุ่มย้อนกลับ + ปุ่ม Market จับคู่ในกล่องเดียว — .header-inner เป็น space-between
   ถ้าใส่เป็นลูกตัวที่สี่ ระยะจะกระจายผิด */
.header-nav {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

/* ── หน้าที่มีปุ่ม Market: หัวข้อต้องอยู่กลางจอพอดี และไม่ทับปุ่มทุกขนาดจอ ──
   (ผู้ใช้สั่ง 2026-09-11 — รอบก่อนหัวข้อเยื้องขวา ~25px เพราะซ้ายมีสองปุ่ม ขวามีปุ่มเดียว)

   ใช้ grid สามคอลัมน์ ซ้าย–ขวากว้างเท่ากัน 92px (ปุ่มย้อนกลับ 42 + ช่อง 8 + ปุ่ม Market 42)
   → ช่องกลางอยู่กึ่งกลางจอเสมอ และกล่องหัวข้อไม่มีทางล้นไปทับปุ่ม (ล้นได้แค่ในช่องตัวเอง)
   ปุ่มตะกร้า (หน้าบัญชี) ชิดขวาของคอลัมน์ขวา · หน้าแดชบอร์ดคอลัมน์ขวาเป็น .header-spacer ว่าง

   ช่องหัวข้อ = 100vw − padding − 92×2 − 8×2
     จอ < 480: padding 24×2 → 100vw − 248px · จอ ≥ 480: padding 32×2 → 100vw − 264px
     สูตรใช้ 264 ตัวที่แคบกว่า (ถ้าใช้ 248 จอ 480–520px หัวข้อจะเกินช่อง 16px)

   ขนาดตัวอักษร = ค่าที่ใหญ่กว่าระหว่าง
     ① บรรทัดเดียวพอดีช่อง   (ช่อง ÷ (จำนวนตัว × 0.78))
     ② สองบรรทัด ไม่เกิน 17px (ช่อง ÷ (คำที่ยาวที่สุด × 0.8))
   ① ใหญ่กว่า = บรรทัดเดียวพอดี · ② ใหญ่กว่า = ตัวหนังสือล้นบรรทัดเดียวจึงตัดคำลงบรรทัดสอง
   จอ 360px: CUSTOMER PROFILE ≈ 15px สองบรรทัด · STORE PROFILE ≈ 17px สองบรรทัด
   จอกว้าง ~440px ขึ้นไปกลับเป็นบรรทัดเดียว · 2 บรรทัดสูง ~38px ไม่เกินปุ่ม 42px หัวเว็บไม่สูงขึ้น
   header.php ส่ง `--es-title-len` / `--es-title-word` ให้ทุกหัวข้อในหน้ากลุ่มนี้ */
.header-inner--shop {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr) 92px;
  align-items: center;
  gap: 0 8px;
}

.header-inner--shop > :last-child {
  justify-self: end;
}

.header-inner--shop .header-title {
  /* ขั้นต่ำ 11px — จอ 320px ที่ 12px "CUSTOMER" กว้างเกินช่อง ~3px ตัวท้ายโดนตัด (วัดจริง) */
  font-size: clamp(
    11px,
    max(
      calc((100vw - 264px) / (var(--es-title-len, 16) * 0.78)),
      min(calc((100vw - 264px) / (var(--es-title-word, 8) * 0.8)), 17px)
    ),
    22px
  );
  line-height: 1.12;
  white-space: normal;
  text-wrap: balance;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

/* จอเล็กกว่า 360px (เช่น 320px) — แม้ 11px "CUSTOMER" ยังกว้างเกินช่อง ~5px (วัดจริง
   ตัวอักษร C/U/O/M กว้างกว่าค่าเฉลี่ยในสูตร) → บีบช่องไฟระหว่างปุ่มจาก 8 เหลือ 4
   คอลัมน์ข้างละ 88px ช่องหัวข้อกว้างขึ้น 16px · จอ 360px ขึ้นไปไม่โดนกฎนี้ */
@media (max-width: 359px) {
  .header-inner--shop {
    grid-template-columns: 88px minmax(0, 1fr) 88px;
    gap: 0 4px;
  }

  .header-inner--shop .header-nav {
    gap: 4px;
  }
}

/* ⚠ กับดักข้อ 6 — design ตั้ง a:hover ให้ตัวอักษรโปร่งใสแล้วไล่สีผ่าน
   background-clip: text (styles.css:244) ไอคอนเป็นตัวอักษร ถ้าไม่ยกเว้นจะหายตอนชี้
   (a[class*='btn']:hover คลุมอยู่แล้ว เขียนซ้ำไว้กันคนมาเปลี่ยนชื่อคลาส) */
.btn-shop:hover,
.btn-shop:focus-visible {
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

.btn-back::before,
.btn-shop::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--grad-1) 0%, var(--grad-2) 33%, var(--grad-3) 66%, var(--grad-4) 100%);
  z-index: -1;
}

.btn-back::after,
.btn-shop::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--bg-primary);
  z-index: -1;
}

.btn-back:hover {
  opacity: 1;
  animation: none;
}

/* ============================================================
   STEP 7 — หน้าสินค้าเดี่ยว: ล้างระยะที่ WooCommerce แถมมา

   ตรวจด้วยการเทียบ computed style กับ single-product.html พบว่า
   WooCommerce ใส่ margin-bottom: 2em (32px) ให้ 3 บล็อกหลัก
   design เป็น 0 ทั้งหมด (ระยะห่างมาจาก gap ของ .single-product-content)
   → หน้าจริงสูงกว่า design 96px และช่องไฟระหว่างบล็อกไม่ตรง

   selector ของ WooCommerce เป็น (0,2,2) เขียนทับด้วยค่าเท่ากันแล้วชนะ
   ด้วยลำดับการโหลด (bridge อยู่ท้ายสุดเสมอ — กับดักข้อ 15)
   ============================================================ */

.woocommerce div.product div.images,
.woocommerce div.product div.summary,
.woocommerce div.product form.cart {
  margin-bottom: 0;
}

/* ⚠ WooCommerce ตั้ง overflow: hidden ให้แถบ thumbnail (0,3,2)
   ทับ overflow-x: auto ของ design → เลื่อนดูรูปที่เกินจอด้วยนิ้วไม่ได้
   design ซ่อน scrollbar ไว้แล้วทั้ง webkit / firefox / edge จึงไม่มีแถบโผล่ */
.woocommerce div.product div.images .flex-control-thumbs {
  overflow-x: auto;
  overflow-y: hidden;
}

/* ============================================================
   STEP 7 — ตะกร้า: ทวงคืนปุ่มลบและปุ่มไปชำระเงินจาก WooCommerce

   ⚠ นับ specificity ให้ครบ (กับดักข้อ 17 ซ้ำรอย)
   ของเดิมในไฟล์นี้เขียน .wc-proceed-to-checkout a.btn-checkout (0,2,1)
   แต่ WooCommerce ใช้
   .woocommerce-cart .wc-proceed-to-checkout a.checkout-button (0,3,1)
   → ปุ่มยังสูง 20px ตัวอักษร 20px แทนที่จะเป็น 15px ตาม design
   ============================================================ */

#add_payment_method .wc-proceed-to-checkout a.btn-checkout,
.woocommerce-cart .wc-proceed-to-checkout a.btn-checkout,
.woocommerce-checkout .wc-proceed-to-checkout a.btn-checkout {
  font-size: 15px;
  letter-spacing: 0.14em;
  padding: 16px 10px;
  margin-bottom: 0;
}

/* ⚠ ปุ่มลบสินค้า — WooCommerce ตั้ง .woocommerce a.remove (0,2,1)
   เป็นกากบาทแดงตัวหนา 24px ทับวงกลมเทา 28px ของ design จนหมด
   และใช้ color: !important จึงต้องทวงคืนด้วย !important เหมือนกัน */
.woocommerce a.cart-item-remove {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  font-size: 12px;
  font-weight: 400;
  line-height: normal;
  border-radius: 50%;
  background: rgba(var(--text-primary-rgb), 0.06);
  color: var(--text-secondary) !important;
  transition: background 0.2s, color 0.2s;
}

.woocommerce a.cart-item-remove:hover {
  background: rgba(var(--grad-1-rgb), 0.2);
  color: var(--grad-1) !important;
}

/* ============================================================
   STEP 7 — คืนสภาพ "ซ่อน" ให้ <select> ตัวจริงที่ Select2 ครอบไว้

   ⚠ บั๊กจริงที่เจอตอนวัดความกว้างหน้าชำระเงินบนมือถือ
   select2.css ซ่อน <select> เดิมด้วย .select2-hidden-accessible
   { width: 1px !important } แต่ก้อน !important ที่ทวง .form-input
   คืนจาก dokan-tailwind (บรรทัด ~2139) โหลดทีหลังจึงชนะ
   → <select> จังหวัดกลับมากว้างเต็มจอ ทับหน้าและ **ดันหน้าให้เลื่อนซ้ายขวาได้**
   (วัดที่ 500px: documentElement.scrollWidth = 552px)

   กระทบทุกหน้าที่มี Select2: ชำระเงิน, ที่อยู่ในโปรไฟล์,
   ตั้งค่าร้าน, ฟอร์มสินค้า — ยกเว้นให้ตรงนี้ทีเดียว
   ============================================================ */

.input-wrapper .form-input.select2-hidden-accessible,
.form-group .form-input.select2-hidden-accessible,
.form-bank-info .form-input.select2-hidden-accessible,
.trade-item-bg-gray .form-input.select2-hidden-accessible,
select.select2-hidden-accessible {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  border: 0 !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  white-space: nowrap !important;
}

/* ============================================================
   STEP 7 — กล่องเลือกวิธีจัดส่งรายร้าน

   คลาส .vendor-shipping* ทั้งชุดมีสไตล์อยู่แล้วใน checkout.css ของ design
   ที่นี่เพิ่มเฉพาะสิ่งที่ design ไม่ได้วาด (เพราะตัวจำลองสมมติว่ามีวิธีส่งเสมอ)
   กับกฎที่ต้องทวงคืนจาก WooCommerce
   ============================================================ */

/* กรณีที่อยู่ปลายทางไม่มีวิธีจัดส่งรองรับ — design ไม่มีเคสนี้ */
.vendor-shipping-empty {
  margin: 0;
  padding: 10px 12px;
  background: rgba(var(--stat-warning-rgb), 0.10);
  border-radius: 10px;
  color: var(--stat-warning);
  font-size: 12px;
  letter-spacing: 0.03em;
}

/* WooCommerce ตั้ง .woocommerce form .form-row label { line-height: 2 }
   ตัวเลือกวิธีจัดส่งเป็น <label> จึงสูงเกินและตัวหนังสือลอย */
.woocommerce-checkout label.vendor-shipping-option {
  line-height: normal;
}

/* ปุ่ม radio ของ design โผล่จริง (ไม่ได้ซ่อนแบบ .payment-method)
   แต่ WooCommerce ตั้ง .form-row input[type=radio] ทับขนาดไว้ */
.vendor-shipping-option input[type="radio"] {
  width: 16px;
  height: 16px;
  margin: 0;
  flex-shrink: 0;
}

/* ============================================================
   STEP 7 — ฟอร์มทั้งเว็บ: ทวงระยะและตัวอักษรคืนจาก WooCommerce

   ⚠ ช่องกรอกของเราได้ "สองคลาสพร้อมกัน" — form-row ของ WooCommerce
   กับ form-group ของ design (es_marketplace_form_field_args เติมให้)
   ผลคือกฎของทั้งสองฝั่งชนกันหมด วัดที่หน้าชำระเงินพบว่าเพี้ยนทุกค่า:

     gap            8px  → 10px   (.checkout-form .form-row ชนะ .form-group)
     margin-bottom  14px →  6px   (.woocommerce form .form-row)
     padding          0  →  3px   (.woocommerce form .form-row)
     label ความสูง normal → 26px  (.woocommerce form .form-row label { line-height:2 })
     ดอกจัน         ปกติ → ตัวหนา + คนละสี

   กระทบทุกฟอร์มในเว็บ ไม่ใช่แค่หน้าชำระเงิน
   ============================================================ */

/* ── โครงแถว ──
   design วางช่องครึ่งแถวด้วย flex + gap
   WooCommerce ใช้ float:left/right width:47% ซึ่งได้ช่องไฟ 6% (24px ที่ 400px)
   ไม่ใช่ 10px ตาม design และช่องที่ไม่มี form-row-first/last จะไม่จับคู่เลย */
.woocommerce form .woocommerce-billing-fields__field-wrapper,
.woocommerce form .woocommerce-shipping-fields__field-wrapper,
.woocommerce form .woocommerce-additional-fields__field-wrapper,
.woocommerce form .es-field-grid {
  display: flex;
  flex-wrap: wrap;
  column-gap: 10px;
}

.woocommerce form .form-row.form-group {
  flex: 1 1 100%;
  float: none;
  width: auto;
  padding: 0;
  margin: 0 0 18px;
  gap: 8px;
}

/* หน้าชำระเงินใช้ระยะแคบกว่าหน้าอื่น (checkout.css:45) */
.woocommerce form.checkout-form .form-row.form-group {
  margin-bottom: 14px;
}

.woocommerce form .form-row.form-group--half {
  flex: 1 1 calc(50% - 5px);
  max-width: calc(50% - 5px);
}

/* ── ป้ายกำกับและดอกจัน ── */
.woocommerce form .form-row label.form-label {
  line-height: normal;
}

.woocommerce form .form-row .required {
  color: var(--stat-error-bright);
  font-weight: 400;
  line-height: normal;
  text-decoration: none;
}

/* ── จอแคบ: ช่องครึ่งแถวเรียงลงมาเป็นแถวเดียว ──
   design ไม่ได้เขียนไว้เพราะออกแบบที่ 390px เป็นหลัก
   แต่ชื่อจังหวัด/รหัสไปรษณีย์ภาษาไทยยาวกว่าอังกฤษ พอแคบกว่า 360px
   ช่องครึ่งแถวจะเหลือ ~165px แล้ว placeholder ถูกตัด */
@media (max-width: 359px) {
  .woocommerce form .form-row.form-group--half {
    flex-basis: 100%;
    max-width: 100%;
  }
}

/* ============================================================
   STEP 7 — จับคู่โครงที่ design กับ WooCommerce เรียกคนละชื่อ
   ============================================================ */

/* design ครอบช่องกรอกด้วย .input-wrapper — WooCommerce ใช้
   .woocommerce-input-wrapper ซึ่งเป็น <span> ธรรมดาไม่มีสไตล์เลย
   ปุ่มตา/ไอคอนที่วางแบบ absolute จึงไม่มีจุดอ้างอิง
   ยกกฎของ design (styles.css:577) มาให้คลาสของ WooCommerce ด้วย */
.woocommerce-input-wrapper {
  position: relative;
  display: flex;
  align-items: center;
}

.woocommerce-input-wrapper > .form-input,
.woocommerce-input-wrapper > .input-text {
  width: 100%;
}

/* ── สวิตช์ "ส่งที่อยู่อื่น" ──
   design: <label class="shipping-toggle"> (checkout.css:56)
   WooCommerce: <h3 id="ship-to-different-address"><label class="checkbox">
   ที่เป็นหัวข้อ h3 จึงตัวใหญ่หนาและมี margin ของหัวข้อติดมา */
#ship-to-different-address {
  margin: 4px 0;
  font-size: inherit;
  font-weight: inherit;
}

#ship-to-different-address label {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  cursor: pointer;
  line-height: normal;
}

#ship-to-different-address input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin: 0;
  cursor: pointer;
  flex-shrink: 0;
}

#ship-to-different-address label span {
  font-size: 13px;
  font-weight: 400;
  color: var(--text-secondary);
  letter-spacing: 0.03em;
  cursor: pointer;
}

/* ============================================================
   STEP 7 — หน้าร้านสาธารณะ
   ============================================================ */

/* ⚠ Dokan บีบเนื้อหาหน้าร้านเข้ามาข้างละ 3% เฉพาะจอ ≤767px
   (style.css @media(max-width:767px) .dokan-store-sidebar, .dokan-single-store)
   ที่ 390px = ข้างละ 10.26px → ทุกอย่างในหน้าร้านแคบกว่า design 20.5px
   ตะแกรงสินค้าจึงได้ช่องละ 99px แทนที่จะเป็น 106px ตาม design
   design ให้ระยะขอบมาจาก .page-fixs-wrapper อยู่แล้ว ไม่ต้องซ้อนอีกชั้น */
.dokan-store-wrap .dokan-single-store,
.dokan-store-wrap .dokan-store-sidebar {
  margin-left: 0;
  margin-right: 0;
}

/* ⚠ การ์ดสินค้าในหน้าร้านเป็น <a> จึงกินสีลิงก์ (--grad-4 ฟ้าอมเขียว)
   design เป็น <div> ตัวหนังสือจึงเป็นสีขาว — ป้าย SOLD ที่ทับบนรูปเพี้ยนตาม */
a.product-item {
  color: var(--text-primary);
}

/* ⚠ Dokan บีบด้วย width: 94% **!important** ใน @media (max-width:767px)
   (style.css — .dokan-store-sidebar, .dokan-single-store)
   342px × 94% = 321.5px ทางเดียวที่ชนะคือ !important เหมือนกัน
   ถ้าไม่แก้ ตะแกรงสินค้าในหน้าร้านจะได้ช่องละ 99px แทน 106px ตาม design */
.dokan-store-wrap .dokan-single-store,
.dokan-store-wrap .dokan-store-sidebar {
  width: 100% !important;
}

/* ⚠ ปุ่มคัดลอกลิงก์ร้าน — design ใส่ข้อความไว้ในตัว element เลย
   ellipsis จึงทำงาน ของเราครอบด้วย <span> เพิ่มอีกชั้นเพื่อแยกไอคอนออก
   text-overflow ของแม่ไม่มีผลกับลูกที่เป็น flex item
   → URL ยาวทะลุขอบจอออกไป 15px ที่ความกว้าง 390px */
/* ตัดข้อความ URL ที่ยาวเกินปุ่มด้วย ellipsis
   `:not()` กัน `.store-copy-toast` ที่เป็น <span> ลูกอีกตัวของปุ่มโดนกฎนี้ไปด้วย
   (มันต้องลอยพ้นขอบปุ่มขึ้นไป ถ้าโดน overflow: hidden จะหายทั้งก้อน) */
.store-profile-link > span:not(.store-copy-toast) {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── สถานะ "คัดลอกแล้ว" ของปุ่มลิงก์ร้าน ──
   ปุ่มนี้ `border: 0` อยู่แล้ว (บรรทัด 1937) ถ้าใส่ border จริงตอนกด
   ความกว้าง/สูงจะขยับ 2px เห็นเป็นอาการกระตุก → ใช้ `box-shadow: inset`
   วาดกรอบแทน ไม่กินพื้นที่ layout เลย */
.store-profile-link {
  position: relative;
  /* ต้องมองเห็นข้อความที่ลอยอยู่เหนือปุ่ม — store-profile.css:63 ตั้ง hidden ไว้
     สำหรับตัดข้อความยาว แต่งานนั้นย้ายไปอยู่ที่ `> span` แล้ว (บรรทัด 3269) */
  overflow: visible;
  transition: background 0.2s, box-shadow 0.2s;

  /* ── ความกว้างเท่าเนื้อหา ไม่ใช่ค่าคงที่ (ผู้ใช้สั่ง 2026-08-16) ──
     design ตั้ง max-width: 220px (400px ที่ ≥769px) ไว้ตายตัว ปุ่มจึงลากยาว
     เป็นแถบเทาว่าง ๆ ทุกร้านที่ลิงก์สั้นกว่านั้น

     ⚠ ต้องเป็น `width` ไม่ใช่ `max-width` — `.store-info` เป็น flex คอลัมน์
     ที่ align-items เป็น stretch (ค่าเริ่มต้น) ลูกที่ width: auto จะถูกยืด
     เต็มความกว้างเสมอ การกำหนด width ชัด ๆ ปิด stretch ไปในตัว

     max-width: 100% คือด่านที่ทำให้ ellipsis ของ `> span` ได้ทำงานเมื่อจอแคบ */
  width: max-content;
  max-width: 100%;
}

.store-profile-link.is-copied {
  box-shadow: inset 0 0 0 1px var(--stat-success, #22c55e);
  background: rgba(var(--stat-success-rgb, 34, 197, 94), 0.12);
}

.store-profile-link.is-copied i {
  color: var(--stat-success, #22c55e);
}

/* ============================================================
   ป้ายประเภทร้าน หน้าลิงก์ร้าน (ผู้ใช้สั่ง 2026-09-11)

   ใช้ทั้งหัวร้านในแดชบอร์ด (template-parts/vendor/dashboard-store-header.php)
   และหน้าร้านสาธารณะ (dokan/store-header.php) — ทรงเดียวกับป้ายลิงก์ร้าน
   ตัวสร้าง HTML: es_marketplace_store_type_badge() (inc/vendor-onboarding.php)

   ⚠️ แถวต้อง `min-width: 0` ทั้งตัวแถวและลิงก์ ไม่งั้น ellipsis ของลิงก์ร้าน
   ไม่ทำงาน แล้วป้ายดันลิงก์ทะลุขอบจอที่ 390px
   ============================================================ */
.store-link-row {
  display: flex;
  align-items: stretch;
  gap: 6px;
  min-width: 0;
  max-width: 100%;
}

.store-link-row .store-profile-link {
  min-width: 0;
}

/* หน้าร้านสาธารณะ: บรรทัด "ออนไลน์ล่าสุดเมื่อ…" มาแทนที่ลิงก์ร้านในแถวนี้
   (ผู้ใช้สั่ง 2026-09-13) — ของเดิมห้อยอยู่ใต้รูปร้าน
   หัวร้านฝั่งแดชบอร์ดยังเป็นปุ่มคัดลอกลิงก์เหมือนเดิม */
.store-link-row .store-last-seen {
  display: inline-flex;
  align-items: center;
  min-width: 0;
  margin: 0;
  font-size: 11px;
  line-height: 1.5;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text-secondary);
}

.store-link-row .store-last-seen--stale {
  color: #e5484d;
}

/* มือถือ: ปุ่มแชร์ชิดขอบขวาของจอ (ผู้ใช้สั่ง 2026-09-13)
   แถวนี้กว้างเท่าเนื้อหาโดยปริยาย — ต้องยืดเต็มก่อน แล้วดันปุ่มด้วย
   `margin-left: auto` ป้ายประเภทร้านกับบรรทัดออนไลน์ล่าสุดจึงอยู่ซ้ายตามเดิม */
@media (max-width: 768px) {
  .dokan-store .store-link-row {
    width: 100%;
  }

  .dokan-store .store-link-row .es-share {
    margin-left: auto;
  }
}

/* ============================================================
   ปุ่มแชร์ (ผู้ใช้สั่ง 2026-09-13)

   ใช้สองที่: บรรทัดชื่อสินค้า (`.product-name-row`) และแถวลิงก์ร้าน
   (`.store-link-row`) — ทรงเดียวกับปุ่มแก้ไขสินค้าเพื่อให้อยู่ด้วยกันแล้วเข้าชุด
   HTML มาจาก es_marketplace_share_button() (inc/social-meta.php)

   ⚠️ กล่องนอกต้อง `position: relative` เพราะเมนูลอยเกาะมัน และ `flex: 0 0 auto`
   ไม่งั้นโดนบีบในแถวที่เป็น flex
   ============================================================ */
.es-share {
  position: relative;
  flex: 0 0 auto;
}

.es-share__btn {
  display: inline-flex;
  align-items: center;
  gap: 0;
  padding: 8px 10px;
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 1px solid rgba(var(--text-primary-rgb), 0.18);
  border-radius: 999px;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.22s, color 0.22s, gap 0.22s;
}

.es-share__btn:hover,
.es-share__btn:focus-visible,
.es-share__btn[aria-expanded='true'] {
  border-color: var(--grad-1);
  color: var(--grad-1);
  gap: 7px;
}

/* คำว่า SHARE คลี่ออกตอน hover — หลักเดียวกับปุ่ม EDIT ข้างกัน
   (ใช้ max-width/opacity ไม่ใช่ display เพราะ display ทำ transition ไม่ได้) */
/* 🔴 ต้องตั้ง `line-height` เองที่ตัวหนังสือ (ผู้ใช้ทัก 2026-09-13 — "ตัวหนังสือจม")
   ปุ่มตั้ง `line-height: 1` ไว้ แต่ค่านั้นไม่ตกทอดเป็นความสูงของ inline-block
   ลูกในนั้นคิดความสูงจาก line-height ของตัวเอง (normal ≈ 1.2 ของฟอนต์ไทย
   ซึ่งมีระยะใต้เส้นฐานเยอะ) กล่องข้อความจึงสูงกว่าไอคอนแล้วถูกจัดกึ่งกลาง
   ทำให้ตัวอักษร "จม" ต่ำกว่าไอคอนที่อยู่ข้างกัน */
.es-share__btn-text {
  display: inline-block;
  max-width: 0;
  overflow: hidden;
  opacity: 0;
  white-space: nowrap;
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.1em;
  transition: max-width 0.22s, opacity 0.22s;
}

.es-share__btn:hover .es-share__btn-text,
.es-share__btn:focus-visible .es-share__btn-text,
.es-share__btn[aria-expanded='true'] .es-share__btn-text {
  max-width: 70px;
  opacity: 1;
}

@media (hover: none) {
  .es-share__btn {
    gap: 7px;
  }

  .es-share__btn-text {
    max-width: 70px;
    opacity: 1;
  }
}

/* 🔴 **ต้องเยื้องลงเท่าปุ่ม EDIT ที่อยู่ข้างกัน** (ผู้ใช้ทัก 2026-09-13 — "ระดับไม่ตรงกัน")
   แถวชื่อสินค้าเป็น `align-items: flex-start` ปุ่มจึงเกาะขอบบนของแถว ส่วนปุ่ม EDIT
   ตั้ง `margin-top: 4px` ไว้ให้ตรงกับบรรทัดแรกของชื่อสินค้า — ถ้าปุ่มแชร์ไม่ตั้งด้วย
   มันจะลอยสูงกว่าพอดี 4px (วัดจริงได้ topDelta = -4)
   ⚠️ เฉพาะแถวชื่อสินค้า — แถวลิงก์ร้านไม่มีปุ่ม EDIT จึงไม่ต้องเยื้อง */
.product-name-row .es-share__btn {
  margin-top: 4px;
}

/* ── EDIT กับ SHARE ต้องเป็นปุ่มพี่น้องกัน (ผู้ใช้ทัก 2026-09-13) ──
   สองปุ่มนี้อยู่ติดกันในบรรทัดชื่อสินค้า จึงต้อง hover เหมือนกันเป๊ะ

   🔴 **ต้นเหตุที่เคยไม่เหมือน: EDIT เป็น `<a>` ส่วน SHARE เป็น `<button>`**
   ธีมมีกฎกลาง `a[class*="btn"]:hover` (น้ำหนัก 0,2,1) ตั้งตัวอักษรเป็นสีขาว
   ทั้ง `color` และ `-webkit-text-fill-color` — มันชนะ `.product-edit-btn:hover`
   (0,2,0) ที่เขียนไว้ ตัวหนังสือ EDIT จึงเป็นขาวตอน hover ส่วน SHARE เป็นชมพู
   (วัดจริง: EDIT `fill: rgb(255,255,255)` · SHARE `rgb(232,78,155)`)

   กฎนี้จึงต้องมีน้ำหนักมากกว่า 0,2,1 — `.product-name-row a.product-edit-btn:hover`
   คือ (0,3,1) · เขียนปุ่มทั้งสองไว้ในกฎเดียวกันเพื่อไม่ให้หลุดจากกันอีก
   ⚠️ เพิ่ม/แก้สไตล์ hover ของปุ่มไหนในบรรทัดนี้ ต้องแก้ที่กฎนี้ที่เดียว */
/* 🔴 **ไอคอนต้องมีกฎของตัวเอง — สืบทอดสีจากปุ่มไม่พอ** (ผู้ใช้ทักซ้ำ 2026-09-13)
   กฎกลางของธีมมีอีกบรรทัดที่เจาะไอคอนโดยตรง: `a[class*='btn']:hover i`
   (บรรทัด ~1886 ของไฟล์นี้) ตั้งทั้ง `color` และ `-webkit-text-fill-color`
   เป็น `--text-primary` — น้ำหนัก (0,2,2) · **สีที่สืบทอดมาจากปุ่มแม่ไม่มีทาง
   ชนะกฎที่เจาะตัวไอคอนเอง** ไอคอน EDIT จึงยังขาวทั้งที่ตัวปุ่มเป็นชมพูแล้ว
   (ไอคอนปุ่มแชร์ไม่โดน เพราะเป็น `<button>` ไม่ใช่ `<a>` — แต่เขียนคู่กันไว้
   ให้สองปุ่มมีที่มาของสีชุดเดียวกัน จะได้ไม่หลุดจากกันอีก)
   น้ำหนักกฎนี้ = (0,3,2) จึงชนะ */
.product-name-row a.product-edit-btn:hover i,
.product-name-row a.product-edit-btn:focus-visible i,
.product-name-row .es-share__btn:hover i,
.product-name-row .es-share__btn:focus-visible i,
.product-name-row .es-share__btn[aria-expanded='true'] i {
  color: var(--grad-1);
  -webkit-text-fill-color: var(--grad-1);
}

.product-name-row a.product-edit-btn:hover,
.product-name-row a.product-edit-btn:focus-visible,
.product-name-row .es-share__btn:hover,
.product-name-row .es-share__btn:focus-visible,
.product-name-row .es-share__btn[aria-expanded='true'] {
  gap: 7px;
  border-color: var(--grad-1);
  background: transparent;
  color: var(--grad-1);
  -webkit-text-fill-color: var(--grad-1);
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

/* ปุ่มในแถวลิงก์ร้านเตี้ยกว่า — แถวนั้นเป็นป้ายเล็ก ๆ ทั้งแถว
   `align-items: stretch` ของแถวจะยืดปุ่มให้สูงเท่าลิงก์ร้านเอง */
.store-link-row .es-share__btn {
  height: 100%;
  padding: 4px 10px;
}

/* 🔴 **z-index ต้องเหนือปุ่มแชตลอยกับแถบเมนูล่าง** (เจอตอนตรวจ 2026-09-13)
   ของเดิม 60 — ในหน้าร้าน เมนูกางลงมาชนปุ่มแชตพอดี `elementFromPoint` ตรงแถว
   "คัดลอกลิงก์" ได้ไอคอนของปุ่มแชต แปลว่า**ผู้ใช้กดรายการนั้นไม่ได้เลย** กดแล้ว
   ไปโดนปุ่มแชตแทน · 1200 = เหนือแถบล่าง/แชต (~999–1001) แต่ยังใต้บอลลูนแนะนำ
   (9000) และแถบคุกกี้ (9500) ตามลำดับชั้นที่ใช้กันทั้งเว็บ */
.es-share__menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 1200;
  display: flex;
  flex-direction: column;
  min-width: 178px;
  padding: 6px;
  border-radius: 12px;
  border: 1px solid rgba(var(--text-primary-rgb), 0.12);
  background: var(--bg-card);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
}

/* 🔴 **ต้องเขียนเอง — `hidden` อย่างเดียวไม่พอ** (ผู้ใช้ทัก 2026-09-13 "มันค้าง")
   กฎ `[hidden] { display: none }` มาจาก stylesheet ของเบราว์เซอร์ ซึ่ง**แพ้สไตล์
   ของผู้เขียนเสมอ** ไม่ว่า specificity จะต่ำแค่ไหน — `.es-share__menu { display: flex }`
   ข้างบนจึงลบล้างมันทิ้ง เมนูเลยกางค้างอยู่ตลอดเวลาทั้งที่ JS ตั้ง `hidden = true` แล้ว
   (ตอนตรวจอ่านค่า `menu.hidden` ได้ `true` จึงไม่เห็นอาการ — ต้องดูด้วยตาถึงจะเจอ) */
.es-share__menu[hidden] {
  display: none;
}

.es-share__item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 11px;
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  border-radius: 8px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 13px;
  line-height: 1.4;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.18s, color 0.18s;
}

/* 🔴 **ต้องปิดเอฟเฟกต์ `a:hover` ของธีมด้วย** (ผู้ใช้ทัก 2026-09-13 — "ตัวหนังสือจม")
   styles.css:244 ใส่ `-webkit-text-fill-color: transparent` + `background-clip: text`
   + `animation: gradient-slide` ให้ลิงก์ทุกตัวในเว็บ กฎนี้ชนะแค่ `color`/`background`
   ส่วนสองตัวแรกยังอยู่ → พื้นจาง ๆ ของเราถูกตัดให้เหลือเฉพาะในรูปตัวอักษร
   ตัวหนังสือจึงจางลงจนดูเหมือน "จม" และแถบพื้นตอน hover ก็หายไปด้วย
   (อาการเดียวกับลิงก์ในตะกร้าว่าง — ดู `.es-empty-cart__link:hover` ท้ายไฟล์) */
.es-share__item:hover,
.es-share__item:focus-visible {
  background: rgba(var(--text-primary-rgb), 0.07);
  color: var(--grad-1);
  -webkit-text-fill-color: var(--grad-1);
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

/* ไอคอนกว้างเท่ากันทุกตัว รายการจะได้เรียงตรงกันเป็นคอลัมน์ */
.es-share__item i {
  width: 16px;
  font-size: 14px;
  text-align: center;
}

/* "คัดลอกลิงก์แล้ว" — แจ้งในบรรทัดของปุ่มคัดลอกเอง (ผู้ใช้สั่ง 2026-09-13)
   ของเดิมเป็นป้ายลอยใต้ปุ่มแชร์ ซึ่งไปบังรายการอื่นในเมนู และดูเหมือน
   เป็นคนละเรื่องกับปุ่มที่เพิ่งกด — ตอนนี้สลับข้อความ+ไอคอนของรายการนั้นแทน
   (ตัวสลับอยู่ใน assets/js/share.js) */
/* 🔴 ต้องประกาศ `-webkit-text-fill-color` ตรงนี้ด้วย (ผู้ใช้ทัก 2026-09-13)
   กฎ hover ข้างบนตั้งค่านั้นเป็นสีชมพูไว้ (เพื่อกัน `a:hover` ของธีม) — ถ้าเขียว
   ประกาศแต่ `color` เมาส์ที่ยังค้างอยู่บนปุ่มตอนกดจะทำให้ตัวหนังสือเป็นชมพูทับเขียว
   เพราะ `-webkit-text-fill-color` ชนะ `color` เสมอไม่ว่า specificity จะเป็นอย่างไร */
.es-share__item.is-copied,
.es-share__item.is-copied:hover {
  color: var(--stat-success, #22c55e);
  -webkit-text-fill-color: var(--stat-success, #22c55e);
  background: rgba(var(--stat-success-rgb, 34, 197, 94), 0.12);
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

.es-store-type {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 11px;
  line-height: 1.5;
  white-space: nowrap;
  color: var(--text-primary);
  background: rgba(var(--text-primary-rgb), 0.06);
  /* ไม่มี box-shadow (ผู้ใช้สั่งเอาออก 2026-09-11) — กฎนี้ตัวเดียวคุมป้ายทุกจุด
     (หัวร้านแดชบอร์ด + หน้าร้านสาธารณะ) */
  cursor: default;
}

.es-store-type i {
  font-size: 11px;
}

/* หัวข้อที่อยู่ร้านถูกพามาด้วย #es-store-address — เว้นที่ให้แถบหัวเว็บที่ลอยอยู่ */
#es-store-address {
  scroll-margin-top: 96px;
}

/* จอแคบ: เหลือแต่ไอคอน (ผู้ใช้สั่ง) — ซ่อนแบบที่โปรแกรมอ่านหน้าจอยังอ่านชื่อได้
   ใช้เลข 700px ตัวเดียวกับปุ่มหัวโปรไฟล์ที่ย่อเหลือไอคอน (`.profile-actions__side`) */
@media (max-width: 700px) {
  .es-store-type {
    padding: 4px 8px;
  }

  .es-store-type__label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* ── ข้อความ "คัดลอกลิงก์แล้ว" ──
   ผู้ใช้สั่งย้ายมาลอยเหนือปุ่ม (2026-08-09) ของเดิมยกมาจาก store.css:673
   ที่เป็น `position: fixed; bottom: 100px` — ไปโผล่แถวท้ายเว็บ ไกลจากปุ่ม
   ที่เพิ่งกดจนไม่รู้ว่าเกี่ยวกัน

   เกาะกับตัวปุ่มโดยตรง ไม่ใช่ `.store-info` เพราะที่ ≥768px design จัด
   กล่องนั้นเป็น `align-items: center` ตำแหน่งจะเยื้องเวลาจอแคบ */
.store-copy-toast {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(6px);
  background: rgba(var(--bg-primary-rgb), 0.92);
  box-shadow: inset 0 0 0 1px rgba(var(--stat-success-rgb, 34, 197, 94), 0.5);
  color: var(--text-primary);
  padding: 6px 14px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  font-family: var(--font);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.3s ease;
  z-index: 9999;
  white-space: nowrap;
}

.store-copy-toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ── ถ่วงน้ำหนัก header ให้หัวข้อ/step อยู่กึ่งกลาง ──
   ปุ่มย้อนกลับกว้าง 42px แล้ว (2026-09-11) แต่ .header-spacer ฝั่งขวาของ design
   กว้าง 30px (เท่าลูกศรเดิม) → ขยายให้เท่ากัน
   ⚠ ต้องยอมให้หดได้ — .step-indicator มี min-content ~209px หดต่อไม่ได้
   จอ 360px ช่องเหลือไม่พอ ถ้าตรึง 42px ตายตัว spacer จะทะลุขอบจอ */
.header-spacer {
  flex: 0 1 42px;
  width: auto;
  min-width: 0;
}

/* ⚠ ข้อความใต้หัวข้อในหน้าขอบคุณไม่ใช่ "แจ้งเตือน"
   WooCommerce ติดคลาส .woocommerce-notice มาให้ ทำให้โดนทรงกล่องแจ้งเตือน
   ของเราครอบ กลายเป็นแถบสีม่วงมีขอบมน ทั้งที่ design เป็นข้อความเปล่า
   (thankyou.css:39 — สีจาง 14px จัดกึ่งกลาง max-width 320px) */
.thankyou-subtitle.woocommerce-notice {
  display: block;
  align-items: normal;
  gap: normal;
  padding: 0;
  margin: 0 0 32px;
  background: none;
  border-radius: 0;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: 0.03em;
  color: var(--text-secondary);
  max-width: 320px;
}

.thankyou-subtitle.woocommerce-notice::before {
  content: none;
}

/* ⚠ WooCommerce ห่อปุ่มสั่งซื้อไว้ใน <div class="form-row place-order">
   ซึ่งกินกฎ .form-row { display: flex; gap: 12px } ของ design ไปด้วย
   ปุ่มจึงกลายเป็น flex item ที่หดได้ — วัดที่ 390px ได้ 66×135px
   (ข้อความ "สั่งซื้อ" ตกบรรทัดละตัวอักษร) แทนที่จะเป็น 342×48px ตาม design
   .place-order ไม่ใช่ "แถวสองช่อง" ของ design จึงต้องล้างกฎนั้นทิ้ง

   🔴 `.woocommerce-checkout #payment .form-row.place-order` = **(1,3,0)**
   คือกฎที่ specificity สูงที่สุดของกล่องนี้ทั้งไฟล์
   เคยเขียน `display: block` ไว้ตรงนี้ แล้วไปตั้ง `gap` ในกฎ (1,2,0)
   ที่ท้ายไฟล์ — ระยะระหว่างข้อความเงื่อนไขกับปุ่มจึงไม่เคยขยับเลย
   **ระยะของกล่องนี้ต้องแก้ที่นี่ที่เดียว** */
.woocommerce form .form-row.place-order {
  display: block;
  padding: 0;
  margin: 0;
}

.woocommerce-checkout #payment .form-row.place-order {
  display: flex;
  flex-direction: column;

  /* ระยะเดียวกับปุ่มในหน้าตะกร้า (ผู้ใช้สั่ง 2026-08-10)
     `.btn-checkout { margin-top: 8px }` (cart.css:360) */
  gap: 8px;
  padding: 0;
  margin: 0;
  background: none;
}

/* ⚠ ปุ่มสั่งซื้อในหน้าชำระเงินปกติ (ไม่ใช่ order-pay)
   WooCommerce ตั้ง `.woocommerce #payment #place_order` เป็น (2,1,0)
   ให้ display:inline-block และ margin ข้างละ 15px
   วัดที่ 390px ได้กว้าง 274px แทน 342px และสูง 56px แทน 48px
   design ให้ปุ่มเต็มความกว้างเป็น block และไม่มี margin ซ้ายขวา */
.woocommerce #payment #place_order.btn-place-order,
.woocommerce-page #payment #place_order.btn-place-order {
  /* 🔴 `flex` ไม่ใช่ `block`
     กฎนี้ specificity (2,2,0) สูงที่สุดในบรรดากฎของปุ่มนี้ ถ้าปล่อยเป็น
     `block` ไว้ `gap` ที่ตั้งไว้ในกฎอื่นจะไม่มีผลเลย ไอคอนกับข้อความจะเหลือ
     แค่ช่องว่างของ inline (~4px) = อาการ "ไอคอนชิดตัวหนังสือ" ที่แก้ไม่หาย */
  display: flex;
  align-items: center;
  justify-content: center;

  /* ระยะเดียวกับปุ่มในหน้าตะกร้า — `.btn-checkout { gap: 10px }` */
  gap: 10px;
  width: 100%;
  margin: 4px 0;
  padding: 16px 10px;
  float: none;
}

/* ── ไอคอนบริษัทขนส่ง ──
   ⚠ wp_get_attachment_image() ออกรูปขนาด thumbnail (150×150) มาให้
   ถ้าไม่คุมขนาด โลโก้ขนส่งจะใหญ่เท่ารูปสินค้าและดันบรรทัดจนเลย์เอาต์เพี้ยน
   ตั้งให้สูงเท่าไอคอน FontAwesome ที่มันมาแทน (~18px) */
.carrier-icon {
  display: inline-block;
  width: auto;
  height: 18px;
  max-width: 64px;
  object-fit: contain;
  vertical-align: middle;
  border-radius: 3px;
}

/* ── กล่องเลือกวิธีส่งของคืน ──
 *
 * ⚠️ styles.css ตั้ง `.btn-shipping-option label strong { display: block }` ไว้
 * ชื่อบริษัทจึงตกไปอยู่บรรทัดใหม่ เหลือโลโก้ลอยอยู่บรรทัดบนตัวเดียว
 * ทำ label เป็น flex แล้วดึง strong กลับเป็น inline โลโก้กับชื่อจะอยู่บรรทัดเดียวกัน
 */
.btn-shipping-option label {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.btn-shipping-option label strong {
  display: inline;
  min-width: 0;
  overflow-wrap: anywhere;
}

.btn-shipping-option label .carrier-icon {
  height: 20px;
  max-width: 72px;
  margin-right: 0; /* ระยะห่างมาจาก gap ของ flex แล้ว */
  flex: 0 0 auto;
}

/* ไอคอนรถบรรทุกที่ใช้แทนโลโก้เมื่อบริษัทนั้นยังไม่ได้อัปโหลดรูป */
/* ขนส่งที่รับขนาด/น้ำหนักของที่คืนไม่ได้ (2026-09-14 · เช่น LINE MAN) — เห็นแต่เลือกไม่ได้ */
.btn-shipping-option.is-disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.btn-shipping-option.is-disabled label {
  pointer-events: none;
}

.btn-shipping-option label > i {
  flex: 0 0 auto;
  color: var(--text-secondary);
}

/* หมายเหตุใต้หัวข้อในกล่องสถานะ — เช่น เรื่องค่าส่งของคืนที่ผู้ขายรับผิดชอบ */
.return-status-box__note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 12px;
  padding: 10px 12px;
  border-radius: 8px;
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.2);
  font-size: 12px;
  line-height: 1.65;
  color: var(--text-secondary);
}

.return-status-box__note i {
  flex: 0 0 auto;
  margin-top: 2px;
  color: rgb(245, 158, 11);
}

/* บรรทัดชื่อบริษัทขนส่งในรายการสินค้า */
.payment-product__shipping {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--text-secondary);
  margin: 2px 0 0;
}

.payment-product__shipping .carrier-icon {
  height: 16px;
  max-width: 58px;
  object-fit: contain;
  border-radius: 3px;
}

/* ══════════════════════════════════════════════════════════════
   ชื่อสินค้าเป็นลิงก์ — ต้องเปลี่ยนสีตอนเอาเมาส์ชี้

   ⚠️ **ต้องถอน gradient hover ของ `a:hover` ออกก่อน**
   styles.css:197 ทำ `a:hover` เป็นตัวอักษรไล่สีด้วย background-clip:text
   + `-webkit-text-fill-color: transparent` ซึ่งบนตัวหนังสือสั้น ๆ ในการ์ด
   แทบมองไม่ออกว่าเปลี่ยนอะไร ผู้ใช้จึงรายงานว่า "hover แล้วไม่เปลี่ยนสี"

   วิธีถอนใช้ชุดเดียวกับที่ธีมทำไว้แล้วกับ `a.bnav-item:hover` (styles.css:219)
   ถ้าตั้งแค่ `color` เฉย ๆ จะไม่มีผล เพราะ `-webkit-text-fill-color` ชนะ color เสมอ

   ครอบทั้งการ์ดหน้ารายการ (order-card) และหน้ารายละเอียด (payment-product)
   ทั้งฝั่งผู้ซื้อและผู้ขาย เพราะใช้คลาสชุดเดียวกันหมด
   ══════════════════════════════════════════════════════════════ */
.order-card__product-info h4 a,
.payment-product__info h4 a {
  color: inherit;
  text-decoration: none;
  transition: color 0.15s ease;
}

.order-card__product-info h4 a:hover,
.order-card__product-info h4 a:focus-visible,
.payment-product__info h4 a:hover,
.payment-product__info h4 a:focus-visible {
  color: var(--grad-1);
  background: none;
  -webkit-background-clip: unset;
  background-clip: unset;
  -webkit-text-fill-color: var(--grad-1);
  animation: none;
  text-decoration: none;
}

/* จุดอ้างอิงให้ JS ของ Dokan เท่านั้น ไม่ต้องเห็น */
.es-dokan-anchor {
  height: 0;
  overflow: hidden;
}

/* กล่องข้อความผลลัพธ์ตอนบันทึกตั้งค่าร้าน — ว่างอยู่ก็ไม่ต้องกินที่

   ⚠️ ใช้ `:empty` อย่างเดียวไม่พอ — Dokan พิมพ์ช่องว่างกับขึ้นบรรทัดใหม่ไว้ข้างใน
   ซึ่งนับเป็น text node กล่องจึงไม่เคยเข้าเงื่อนไข `:empty` เลย
   ผลคือหน้า EDIT STORE เว้นด้านบนมากกว่า EDIT PROFILE อยู่ 12px ตลอด
   ย้ายระยะห่างไปไว้ที่ลูกแทน จะได้มีที่ว่างเฉพาะตอนมีข้อความจริง */
.dokan-ajax-response {
  margin: 0;
}

.dokan-ajax-response > * {
  margin-bottom: 12px;
}

/* ข้อความ "บันทึกสำเร็จ" ของ Dokan — ให้เป็นโทนสำเร็จ ไม่ใช่โทนเตือน
   (ทรงกล่องมาจากชุดแจ้งเตือนกลางที่ต้นไฟล์แล้ว เปลี่ยนแค่สีกับไอคอน) */
.dokan-alert-success {
  background: rgba(var(--stat-confirmed-rgb), 0.12);
  color: var(--stat-confirmed);
}

.dokan-alert-success::before {
  content: '\f058'; /* check-circle */
}

.dokan-alert-danger {
  background: rgba(var(--stat-error-rgb), 0.12);
  color: var(--stat-error);
}

.dokan-alert-danger::before {
  content: '\f06a'; /* circle-exclamation */
}

.dokan-alert p {
  margin: 0;
}

/* ============================================================
   ไม่เน้นกรอบตอนโฟกัส — ทั้งเว็บ

   ผู้ใช้สั่งให้เอากรอบขาวที่เด้งขึ้นตอนกด/ตอนแจ้งเตือนโผล่ออกทุกจุด
   กรอบนั้นคือ focus ring มาตรฐานของเบราว์เซอร์ ไม่ได้มาจาก CSS ของ design

   ⚠️ ตัดทิ้งหมดไม่ได้ — คนที่ใช้ปุ่ม Tab แทนเมาส์จะหาไม่เจอว่าตอนนี้อยู่ช่องไหน
   จึงตัดเฉพาะ :focus (เมาส์ + โฟกัสที่สคริปต์สั่ง) แล้วคืนให้ :focus-visible
   ซึ่งเบราว์เซอร์จะยิงเฉพาะตอนใช้คีย์บอร์ด และเปลี่ยนเป็นสีแบรนด์แทนสีขาว
   ============================================================ */

:focus {
  outline: none;
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--grad-2);
  outline-offset: 2px;
}

/* กล่องแจ้งเตือนไม่ต้องมีกรอบแม้แต่ตอนใช้คีย์บอร์ด — มันไม่ใช่สิ่งที่กดได้ */
.woocommerce-notices-wrapper:focus-visible,
.woocommerce-notices-wrapper > [tabindex]:focus-visible,
.woocommerce-message:focus-visible,
.woocommerce-info:focus-visible,
.woocommerce-error:focus-visible,
.dokan-alert:focus-visible,
.dokan-info:focus-visible,
.dokan-error:focus-visible,
.dokan-message:focus-visible,
.es-notice:focus-visible {
  outline: none;
}

/* ============================================================
   กล่องวัดความแข็งแรงของรหัสผ่าน (ฟอร์มสมัคร / แก้ไขโปรไฟล์ / ตั้งรหัสใหม่)

   markup มาจาก password-strength-meter.js ของ WooCommerce
   ตำแหน่งถูกจัดไว้แล้วที่ form-login.php (วาง div เปล่าไว้ก่อนแถวสองช่อง)
   ที่นี่คุมแค่หน้าตา
   ============================================================ */

.woocommerce-password-strength,
.woocommerce-password-hint {
  display: block;
  width: 100%;
  margin: 0 0 10px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.45;
  text-align: start;
  border: 0;
  border-radius: 10px;
  background: rgba(var(--text-primary-rgb), 0.06);
  color: var(--text-secondary);
}

.woocommerce-password-strength.short,
.woocommerce-password-strength.bad {
  background: rgba(var(--stat-error-rgb), 0.12);
  color: var(--stat-error);
}

.woocommerce-password-strength.good {
  background: rgba(var(--stat-warning-rgb), 0.12);
  color: var(--stat-warning);
}

.woocommerce-password-strength.strong {
  background: rgba(var(--stat-success-rgb), 0.12);
  color: var(--stat-success);
}

/* ข้อความแนะนำต่อท้ายกล่องวัด — ให้ดูเป็นก้อนเดียวกัน ไม่ใช่สองกล่องซ้อน */
.woocommerce-password-hint {
  margin-top: -6px;
  background: none;
  padding-top: 0;
  font-weight: 400;
}

/* ============================================================
   หัวโปรไฟล์ รอบปรับตามที่ผู้ใช้สั่ง (กลุ่ม A)
   - รูปกดได้ทั้งรูป ไม่ใช่แค่ไอคอนกล้อง
   - ไอคอนกล้องขึ้นเฉพาะหน้าแก้ไขโปรไฟล์
   - ออกจากระบบอยู่บรรทัดเดียวกับปุ่มแก้ไขโปรไฟล์ ชิดขวาสุด
   ============================================================ */

/* หน้าแก้ไขโปรไฟล์ — กดที่รูปทั้งรูปเพื่อเปลี่ยนรูป ไม่ใช่แค่ไอคอนกล้อง
   (หน้า my-account รูปกดไม่ได้ ไม่มีคลาสนี้) */
.profile-picture--editable {
  cursor: pointer;
}

.profile-picture--editable:hover .profile-picture__edit {
  transform: scale(1.08);
}

/* ไอคอนกล้องเป็น <span> แล้ว ไม่ใช่ <button> — ต้องไม่กินคลิกแทนกรอบรูป */
.profile-picture--editable .profile-picture__edit {
  pointer-events: none;
}

/* แถวปุ่มใต้ชื่อ — แก้ไขโปรไฟล์ซ้าย / ออกจากระบบขวาสุด
   ค่าทุกตัวตรงกับ `.store-header-actions` (บรรทัด ~8451) รวม flex-wrap
   เพื่อให้หัวโปรไฟล์กับหัวร้านหักบรรทัดเหมือนกันเป๊ะเมื่อจอแคบ */
.profile-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  flex-wrap: wrap;
}

a.btn-logout {
  margin-inline-start: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  white-space: nowrap;
  border-radius: var(--radius-btn, 50px);
  border: 1px solid rgba(var(--stat-error-rgb), 0.5);
  background: rgba(var(--stat-error-rgb), 0.12);
  color: var(--stat-error);
  text-decoration: none;
  transition: background 0.2s ease;
}

/* ยกเว้น a:hover ของ design ที่ทำให้ตัวอักษรหาย (กับดักข้อ 6) */
a.btn-logout:hover {
  background: rgba(var(--stat-error-rgb), 0.22);
  color: var(--stat-error);
  -webkit-text-fill-color: var(--stat-error);
  background-clip: border-box;
  animation: none;
}

/* ปุ่ม LOGOUT ใต้กล่องแก้ไขโปรไฟล์ผู้ซื้อ/ร้าน — นอกพื้นดำ กึ่งกลาง เหนือลิงก์นโยบาย (2026-10-04) */
.es-profile-logout {
  display: flex;
  justify-content: center;
  margin: 24px 0 8px;
}

/* ยาวและสูงเท่าปุ่ม UPDATE PROFILE / UPDATE STORE ในแถบล่าง (ผู้ใช้สั่ง 2026-10-04)
   กว้าง = สูตรเดียวกับ `.bottom-nav-container` (styles.css): calc(100% − 32px) · max 400px
   สูง 48px = ความสูงจริงของปุ่มหลักในแถบล่าง (วัดแล้ว · รวมขอบ เพราะ border-box) */
.es-profile-logout a.btn-logout {
  margin-inline-start: 0;
  justify-content: center;
  width: calc(100% - 32px);
  max-width: 400px;
  height: 48px;
  padding-block: 0;
  box-sizing: border-box;
}

/* ============================================================
   บัญชีที่เชื่อมไว้ (หน้าแก้ไขโปรไฟล์)
   ============================================================ */

.social-connections {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 18px;
}

.social-connection {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-radius: 12px;
  background: rgba(var(--text-primary-rgb), 0.05);
}

.social-connection__name {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  text-transform: capitalize;
}

/* ไอคอนของ provider — เป็นได้ทั้ง <i> ของ Font Awesome และ <svg> ที่ธีมฝังเอง
   (โลโก้ X ต้องฝัง SVG เพราะ Font Awesome 6.0.0-beta3 ยังไม่มี fa-x-twitter)
   จึงตั้งขนาดให้ทั้งสองแบบพร้อมกัน */
.social-connection__icon {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  font-size: 16px;
  line-height: 1;
}

.social-connection__status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--stat-success);
}

a.social-connection__action {
  margin-inline-start: auto;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  border-radius: var(--radius-btn, 50px);
  border: 1px solid rgba(var(--grad-2-rgb), 0.6);
  background: rgba(var(--grad-2-rgb), 0.12);
  color: var(--grad-2);
  text-decoration: none;
}

a.social-connection__action:hover {
  background: rgba(var(--grad-2-rgb), 0.22);
  color: var(--grad-2);
  -webkit-text-fill-color: var(--grad-2);
  background-clip: border-box;
  animation: none;
}

a.social-connection__action.is-unlink {
  border-color: rgba(var(--stat-error-rgb), 0.5);
  background: rgba(var(--stat-error-rgb), 0.1);
  color: var(--stat-error);
}

a.social-connection__action.is-unlink:hover {
  background: rgba(var(--stat-error-rgb), 0.2);
  color: var(--stat-error);
  -webkit-text-fill-color: var(--stat-error);
}

.social-connections__note {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-secondary);
}

/* ป้าย "ตั้งรหัสผ่านก่อนจึงยกเลิกได้" — แทนที่ปุ่มยกเลิกการเชื่อมเมื่อบัญชียัง
   ไม่มีรหัสผ่านของตัวเอง (inc/social-login.php) เป็นข้อความบอกสถานะ ไม่ใช่ปุ่ม
   จึงไม่มีกรอบและกดไม่ได้ */
span.social-connection__action.is-locked {
  margin-inline-start: auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  line-height: 1.5;
  font-weight: 500;
  color: var(--text-secondary);
  white-space: nowrap;
}

span.social-connection__action.is-locked i {
  font-size: 10px;
  opacity: 0.75;
}

/* ── คำอธิบายใต้หัวข้อ "ตั้งรหัสผ่าน" ในหน้าแก้ไขบัญชี ──
   ผู้ใช้ทักว่า "ดูใหญ่ ๆ เบียด ๆ" (2026-08-28)

   🔴 `.form-hint` เป็นคลาสร่วมทั้งเว็บ (assets/css/store.css) — ห้ามแก้กฎกลาง
   เขียนเจาะจงเฉพาะกล่องรหัสผ่านแทน */
.edit-profile-password > .form-hint {
  margin: 2px 0 14px;
  font-size: 11px;
  line-height: 1.7;
  letter-spacing: 0.02em;
  color: var(--text-secondary);
  opacity: 0.85;
}

/* ไอคอนหน้าปุ่มในแถบล่าง (SAVE PROFILE / UPDATE STORE)

   `.btn-gradient` กับ `.btn-update-store` ตั้ง letter-spacing 0.14em ไว้
   ระยะนั้นถูกเติมหลังตัวไอคอนด้วย ช่องไฟจริงจึงกว้างกว่าที่ตั้งไว้ราว 2px
   ทำเป็น flex + gap แล้วปิด letter-spacing เฉพาะไอคอน จะได้ช่องไฟ 6px
   เท่ากับปุ่มอื่นทั้งเว็บ (เทียบ `a.btn-logout { gap: 6px }`) */
.btn-gradient,
.btn-update-store {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.btn-gradient > i,
.btn-update-store > i {
  letter-spacing: normal;
  font-size: 0.92em;
}

@media (max-width: 420px) {
  .social-connection {
    flex-wrap: wrap;
  }

  a.social-connection__action {
    margin-inline-start: 0;
  }
}

/* กล่อง "ยังไม่มีคำสั่งซื้อในหมวดนี้" ชิดแถบแท็บเกินไป — เว้นระยะให้หายใจ */
.woocommerce-MyAccount-content > .es-notice:first-child {
  margin-top: 14px;
}

/* ============================================================
   ท้ายเว็บ — ลิงก์นโยบาย + ระยะห่าง

   design ให้ .app-footer มีแค่ padding: 20px 0 28px ซึ่ง
   1. ชิดเนื้อหาด้านบนเกินไป
   2. ถูกแถบล่างแบบ fixed (สูงราว 100px) บังในหลายหน้า
   ============================================================ */

.app-footer {
  /* ห่างจากเนื้อหาของหน้า — เดิม 48px + padding บน 20px (รวม ~90px ห่างเกิน · ผู้ใช้สั่งลด 2026-09-21)
     🔴 ท้ายเว็บยังติดล่างจอในหน้าที่เนื้อหาสั้นเหมือนเดิม (ดูหัวข้อ sticky footer) และแถบเมนูล่างไม่บัง
     (padding-bottom ของ .has-bottom-nav / .has-bottom-menu ข้างล่าง ห้ามลด) */
  margin-top: 16px;
  padding-top: 8px;
}

/* เว้นที่ให้แถบล่างเฉพาะหน้าที่มีแถบจริง
   .bottom-nav-container สูงอย่างน้อย 90px + ลอยขึ้นมา 10px */
.app-footer.has-bottom-nav {
  padding-bottom: 120px;
}

/* แถบเมนูแบบใหม่ สูงถึงยอดโดม 153px (ตามหน้า Scan 2026-09-14) + ลอยขึ้น 10px */
.app-footer.has-bottom-menu {
  padding-bottom: 180px;
}

.app-footer__links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 18px;
  margin-bottom: 10px;
}

.app-footer__links a {
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
  text-decoration: none;
}

/* ยกเว้น a:hover ของ design ที่ทำให้ตัวอักษรโปร่งใส (กับดักข้อ 6) */
.app-footer__links a:hover {
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  background: none;
  background-clip: border-box;
  animation: none;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* บรรทัดข้อมูลผู้ประกอบการ — ชื่อ · เลขทะเบียน · อีเมล · โทร
   เล็กและจางกว่าลิงก์นโยบาย เพราะเป็นข้อมูลอ้างอิง ไม่ใช่สิ่งที่คนมาหา
   แต่ต้องอ่านออกจริง — ห้ามจางกว่า --text-muted ของบรรทัดลิขสิทธิ์ */
.app-footer__biz {
  max-width: 640px;
  margin: 0 auto 4px;
  padding: 0 16px;
  font-size: 11px;
  line-height: 1.8;
  color: var(--text-secondary);
  letter-spacing: 0.03em;
}

/* อีเมลกับเบอร์โทรห้ามขึ้นบรรทัดใหม่กลางค่า
   ไม่งั้นจะได้ "02-" ค้างท้ายบรรทัดแล้ว "123-4567" ขึ้นบรรทัดถัดไป
   ซึ่งอ่านแล้วเหมือนเป็นคนละเบอร์ (เจอตอนตรวจจริง 2026-08-29) */
.app-footer__biz a {
  color: var(--text-secondary);
  text-decoration: none;
  white-space: nowrap;
}

.app-footer__biz a:hover {
  color: var(--text-primary);
  /* ยกเว้น a:hover ของ design ที่ทำตัวอักษรโปร่งใส (กับดักข้อ 6) */
  -webkit-text-fill-color: var(--text-primary);
  background: none;
  background-clip: border-box;
  animation: none;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ตัวคั่นจางกว่าตัวหนังสือ ให้ตากวาดผ่านได้โดยไม่สะดุด */
.app-footer__biz-sep {
  color: var(--text-muted);
}

/* 🔴 บังคับ 2 บรรทัดเสมอ (ผู้ใช้สั่ง 2026-08-29)
     บรรทัด 1 — ชื่อผู้ประกอบการ · เลขทะเบียน
     บรรทัด 2 — อีเมล · เบอร์โทร
   ปล่อยให้เบราว์เซอร์ตัดเอง จุดตัดจะย้ายไปมาตามความกว้างจอ บางทีเลขทะเบียน
   ไปอยู่บรรทัดเดียวกับอีเมล อ่านแล้วสับสนว่าอะไรเป็นของอะไร
   (ตัวจัดกลุ่มอยู่ที่ `es_marketplace_business_footer_line()`) */
.app-footer__biz-row {
  display: block;
}

/* กล่องข้อมูลผู้ประกอบการในหน้า "ติดต่อเรา" (shortcode [es_business_info])
   ใช้โครงเดียวกับ <ul> ในหน้าข้อกำหนด/นโยบาย จะได้ไม่ต้องมีสไตล์ซ้ำสองชุด */
.es-business em {
  color: var(--text-secondary);
  font-style: normal;
}

/* ขีดคั่นระหว่างลิงก์ */
.app-footer__links a + a {
  position: relative;
}

.app-footer__links a + a::before {
  content: '';
  position: absolute;
  left: -9px;
  top: 50%;
  width: 1px;
  height: 11px;
  transform: translateY(-50%);
  background: rgba(var(--text-secondary-rgb), 0.4);
}

/* ============================================================
   ท้ายเว็บติดล่างจอเมื่อเนื้อหาสั้น (sticky footer)

   design วางโครงไว้ให้แล้วครบ:
     body            → min-height: 100dvh + flex column   (styles.css:173)
     .page-*wrapper  → flex: 1 + flex column              (styles.css:363)
     .app-footer     → flex-shrink: 0                     (styles.css:842)

   ขาดชิ้นเดียวคือ **ตัวกลางที่ต้องยืดกินที่ว่าง** — `.main-content`
   (หน้าเข้าสู่ระบบ) มี `flex: 1` อยู่แล้ว แต่ `.site-main` ที่ใช้ทุกหน้าที่เหลือไม่มี
   ท้ายเว็บจึงลอยตามเนื้อหาแทนที่จะไปอยู่ล่างจอ

   ใส่ flex-grow ให้ก็จบ — ไม่ต้องใช้ JS และไม่ต้องวัดความสูง
   เนื้อหายาวเมื่อไหร่ก็ไหลตามปกติเอง เพราะ flex-grow มีผลเฉพาะตอนมีที่ว่างเหลือ
   ============================================================ */

.page-wrapper > .site-main,
.page-fix-wrapper > .site-main,
.page-fixs-wrapper > .site-main {
  flex: 1 0 auto;
}

/* ============================================================
   ความกว้างเนื้อหาจอใหญ่ — เท่ากันทั้งเว็บ 1024px อยู่กลางจอ (ผู้ใช้สั่ง 2026-09-16)

   *"ขนาดหน้าจอที่ fix ความกว้างของเนื้อหา อยากให้อ้างอิงเท่ากับเวลาเปิดดูรายละเอียดสินค้า
   หรือหน้าอื่น ๆ ทั้งเว็บควรจะกว้างเท่ากัน เวลาเปิดหน้าจอใหญ่"*

   วัดที่จอ 1920 ก่อนแก้:
     หน้ารายละเอียดสินค้า  `.single-product-container` 1024px (single-product.css:572)
     หน้าอื่น (`.page-fixs-wrapper`) max-width 1024 **รวม** padding ข้างละ 32 → เนื้อหาจริง 960
     หน้า shop (`.page-wrapper`) ไม่มี max-width → ตะแกรงยืด 1856px เพิ่มคอลัมน์ไปเรื่อย ๆ

   ทำให้เท่ากันที่ "เนื้อหา 1024px" = wrapper กว้างสุด 1024 + ขอบจอสองข้าง
   ใช้ `--side-padding` ไม่ใช่ 64 ตายตัว — หน้า shop ตั้งค่านี้ต่างจากหน้าอื่น (product.css)
   ⚠️ หน้าเข้าสู่ระบบ (`.page-fix-wrapper` 390px) ไม่เกี่ยว
   ⚠️ หัวเว็บกับแถบล่างอยู่นอก wrapper — ยังกว้างเต็มจอเหมือนเดิมทุกหน้า
   ============================================================ */
.page-wrapper,
.page-fixs-wrapper {
  max-width: calc(1024px + var(--side-padding) * 2);
}

/* ============================================================
   สินค้าที่ขายแล้วในหน้าร้าน — หรี่รูป แต่ป้าย sold ต้องคมชัด

   หรี่ที่ `<img>` ตัวเดียว ไม่หรี่ที่ `.product-item`
   เพราะ opacity บนตัวแม่จะลากป้าย sold (ลูกที่ position: absolute) ไปด้วย
   แล้วป้ายจะจางตามจนอ่านไม่ออก
   ============================================================ */

.product-item.is-sold img {
  opacity: 0.4;
  filter: grayscale(0.5);
  transition: opacity 0.3s ease, filter 0.3s ease;
}

/* ชี้แล้วให้เห็นภาพชัดขึ้นหน่อย จะได้ยังดูงานได้ */
.product-item.is-sold:hover img {
  opacity: 0.6;
  filter: grayscale(0.25);
}

/* รูปร้านบนหน้าร้านสาธารณะกดอะไรไม่ได้ ไม่ต้องทำเป็นเคอร์เซอร์รูปมือ
   `store-profile.css:31` ตั้ง `cursor: pointer` ไว้ให้ `.store-picture` ทุกที่
   ซึ่งถูกสำหรับหน้าตั้งค่าร้าน (กดเพื่ออัปโหลดรูปได้จริง) แต่ผิดสำหรับหน้านี้

   ⚠️ ของเดิมเขียนเป็น `.store-header > .store-picture` แล้วใช้ไม่ได้อีกต่อไป
   ตอนย้าย "ออนไลน์ล่าสุด" ไปไว้ใต้รูป รูปถูกห่อด้วย `.store-picture-col` เพิ่มอีกชั้น
   จึงไม่ใช่ลูกตรงของ `.store-header` แล้ว — เคอร์เซอร์รูปมือเลยกลับมา

   ระบุเป็น `div.store-picture` (0,1,1) เพื่อไม่ให้ไปโดนรูปบนหัว dashboard
   ซึ่งเป็น `<a>` และกดเข้าหน้าแรกของ dashboard ได้จริง */
.store-header div.store-picture,
.store-picture-col > .store-picture {
  cursor: default;
}

/* ป้ายอยู่เหนือรูปเสมอ ไม่โดนหรี่ */
.product-item.is-sold .product-badge {
  opacity: 1;
  z-index: 2;
}

/* ค้นหาไม่เจอ — บล็อกสินค้ามาใหม่ที่โชว์แทนหน้าเปล่า
   ตะแกรงใช้ .product-list ของ design อยู่แล้ว ที่นี่คุมแค่หัวข้อกับระยะห่าง */
.es-no-results-suggest {
  margin-top: 28px;
}

.es-no-results-suggest__title {
  margin: 0 0 14px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

/* ============================================================
   ปุ่มปิด lightbox (PhotoSwipe) — ต้องชิดขวาบน

   ⚠️ **เคยแก้ผิดมาแล้ว** — ย้ายไปซ้ายซึ่งไม่ใช่สิ่งที่ต้องการ
   ค่าเริ่มต้นของ PhotoSwipe ถูกอยู่แล้ว: `.pswp__top-bar` เป็น
   `display:flex; justify-content:flex-end` ปุ่มปิดจึงอยู่ขวาสุด
   ที่ดูเยื้องเข้ามาเพราะปุ่มกว้าง 44px แต่ไอคอนข้างในไม่ได้เต็มปุ่ม
   → ดึงเข้าขอบด้วย margin ลบเท่าที่เหลือ แทนการย้ายตำแหน่ง
   ============================================================ */

.pswp__top-bar {
  padding: 0;
  justify-content: flex-end;
}

.pswp__button--close {
  margin-right: 2px;
}

/* 🔴 จอ < 1024px ปุ่มปิด/เต็มจอ/ซูมไม่ชิดขวา (ผู้ใช้แจ้ง 2026-09-18)
   default skin ของ PhotoSwipe 4 ให้ตัวหมุน `.pswp__preloader` ลอยขวา (float:right)
   ในจอแคบ แล้วค่อยย้ายไปกลางจอที่ ≥ 1024px — แต่แถบบนเป็น flex แล้ว float ไม่มีผล
   ตัวหมุนจึงกลายเป็นช่องว่าง 44px ขวาสุดดันปุ่มทั้งแถวเข้ามา
   → ให้ตัวหมุนอยู่กลางแถบเหมือนจอใหญ่ทุกขนาด ไม่กินที่ในแถว */
.pswp__top-bar .pswp__preloader {
  position: absolute;
  top: 0;
  left: 50%;
  margin-left: -22px;
  float: none;
}

/* ============================================================
   ลิงก์ในกล่องแจ้งเตือน — ผู้ใช้ขอให้ "ดูตะกร้าสินค้า" เป็นตัวหนังสือขีดเส้นใต้
   ไม่ใช่ปุ่มแคปซูล
   ============================================================ */

/* ⚠️ ต้องมี `.woocommerce` และ `a.button` ให้ครบ — WooCommerce เขียนกฎปุ่มไว้ที่
   `.woocommerce a.button` ซึ่งเป็น (0,2,1) ถ้าเขียนแค่ `.woocommerce-message .button`
   จะเป็น (0,2,0) แล้วแพ้ ต่อให้ไฟล์เราโหลดทีหลังก็ตาม (กับดักข้อ 3) */
.woocommerce .woocommerce-message a.button,
.woocommerce .woocommerce-info a.button,
.woocommerce .woocommerce-error a.button,
.woocommerce-message a.button,
.woocommerce-info a.button,
.woocommerce-error a.button {
  /* WooCommerce วาง <a> ไว้ "ก่อน" ข้อความใน DOM — ดันไปอยู่หลังด้วย order */
  order: 2;
  justify-self: start;
  margin-left: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  color: inherit;
  font-size: inherit;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.woocommerce .woocommerce-message a.button:hover,
.woocommerce .woocommerce-info a.button:hover,
.woocommerce .woocommerce-error a.button:hover,
.woocommerce-message a.button:hover,
.woocommerce-info a.button:hover,
.woocommerce-error a.button:hover {
  background: none;
  color: inherit;
  -webkit-text-fill-color: currentColor;
  opacity: 0.8;
}

/* ============================================================
   ลากแถบ thumbnail บนมือถือ/แท็บเล็ต

   ⚠️ ปัญหาที่เจอจริง (iPad Safari / Android Chrome):
   ลากแล้วกลายเป็น "เลือกรูป" หรือลากรูปออกมา แทนที่จะเลื่อนแถบ
   เพราะเบราว์เซอร์มองว่ากำลังลาก <img> หรือเลือกข้อความ

   ต้องปิดทั้งสามอย่าง — ปิดอย่างเดียวไม่พอ:
     user-select        กันการเลือกข้อความ/รูป
     -webkit-user-drag  กัน Safari ลากรูปออกมาเป็นไฟล์
     -webkit-touch-callout  กันเมนูค้างนิ้วของ iOS
   ============================================================ */

.flex-control-thumbs,
.flex-control-thumbs li,
.flex-control-thumbs img {
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}

/* ปุ่มเปิดเสียงอ่านต้องอยู่ขวาเสมอ แม้คำบรรยายจะสั้น */
.product-description .description-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* 🔴 **บล็อกจอแคบด้านล่างต้องอยู่ตรงนี้ ห้ามย้ายขึ้นไปข้างบน**
   `.product-description .description-header` ถูกประกาศซ้ำในไฟล์นี้ถึง 5 ที่
   (บรรทัด ~660, ~671, ~743, ~1000 และตัวข้างบนนี้) ความเฉพาะเจาะจงเท่ากันหมด
   **ตัวที่อยู่ท้ายไฟล์สุดเป็นตัวชนะ** — เคยเขียน media query ไว้แถวบรรทัด 700
   แล้ว `justify-content` ไม่มีผลเลย เพราะตัวนี้มาทับทีหลัง (เจอ 2026-08-29) */
/* ============================================================
   จอแคบ — ปุ่มเปิดเสียงอ่านเหลือแต่ไอคอน อยู่บรรทัดเดียวกับหัวข้อ
   (ผู้ใช้สั่ง 2026-09-05 · แทนที่กฎ ≤519px ของ 2026-08-29 ทั้งก้อน)

   *"ปุ่มอ่านด้วยเสียง เอาตัวหนังสือออก เพราะมันทำให้ปุ่มเด้งอีกบรรทัด
   แล้วเวลากดอ่านด้วยเสียง กำลังอ่านอยู่ ตอน RWD ก็เอาตัวหนังสือออกเหมือนกัน"*

   ── ทำไมกฎเดิมถึงต้องหายไปทั้งก้อน ──────────────────────────────────
   ของเดิม (2026-08-29) แก้ปัญหา "ปุ่มกระโดดตอนปุ่มหยุดโผล่" ด้วยการ
   **ยอมให้หัวข้อกินเต็มบรรทัด แล้วดันแถวปุ่มลงบรรทัดสองตลอดเวลา**
   (`h3 { flex: 0 0 100% }`) — ตอนนั้นถูก เพราะปุ่มอ่านกว้าง 138px
   หัวข้อ 180 + หยุด 38 + อ่าน 138 + ช่องไฟ 24 = 380px ซึ่งเกินจอ 390px

   พอตัดตัวหนังสือออก ปุ่มอ่านเหลือ 38px เท่าปุ่มหยุด งบใหม่คือ
   หัวข้อ + 38 + 38 + ช่องไฟ 24 = ~100px สำหรับปุ่มทั้งคู่ **เหลือที่เยอะ**
   จอ 320px ก็ยังพอ (หัวข้อหดได้ด้วย ellipsis ที่ตั้งไว้แล้ว)
   กฎเดิมจึงกลายเป็นตัวที่ *ทำให้* ปุ่มตกบรรทัด ไม่ใช่ตัวที่กันไว้

   🔴 **ต้องอยู่ท้ายไฟล์** — `.product-description .description-header`
   ถูกประกาศซ้ำในไฟล์นี้ 5 ที่ ความเฉพาะเจาะจงเท่ากันหมด **ตัวท้ายชนะ**
   ย้ายขึ้นไปข้างบนเมื่อไร `justify-content` กับ `flex` ของ h3 จะไม่มีผลเลย
   (เจอมาแล้วทั้งรอบ 2026-08-29 และรอบ 2026-09-05)

   🔴 **ซ่อนข้อความด้วย CSS ไม่ใช่ลบใน JS** — `read-aloud.js` จำข้อความเดิม
   จาก `label.textContent` ตอนเริ่ม แล้วเอากลับมาใส่ตอนอ่านจบ ลบทิ้งเมื่อไร
   ปุ่มบนเดสก์ท็อปจะกลายเป็นปุ่มเปล่าหลังอ่านจบครั้งแรก
   ปุ่มยังมี `aria-label` ครบ screen reader จึงยังอ่านออกว่าปุ่มนี้คืออะไร
   ============================================================ */
@media (max-width: 600px) {
  .product-description .btn-read-aloud__label {
    display: none;
  }

  /* เหลือไอคอนตัวเดียว → สี่เหลี่ยมจัตุรัสเท่าปุ่มหยุดเป๊ะ
     ไม่งั้นเป็นแคปซูลแบน ๆ ที่กว้างกว่าสูงเพราะ padding ซ้ายขวา 16px */
  .product-description .btn-read-aloud {
    width: 38px;
    height: 38px;
    padding: 0;
    gap: 0;
    justify-content: center;
  }

  /* หัวข้อกลับมาอยู่บรรทัดเดียวกับปุ่ม — ดันปุ่มไปชิดขวาด้วยตัวเอง
     (`margin-right:auto` ประกาศไว้แล้วที่กฎจอกว้าง ตรงนี้แค่ปลดล็อก flex) */
  .product-description .description-header {
    justify-content: space-between;

    /*
     * 🔴 **`nowrap` คือตัวที่ทำให้หัวข้อ "หด" แทนที่จะ "ตกบรรทัด"**
     * (วัดจริงที่ 320px เมื่อ 2026-09-05 — ตอนกดอ่านแล้วปุ่มหยุดโผล่
     * ยังตกบรรทัดอยู่ ทั้งที่ปุ่มเหลือ 38px แล้ว)
     *
     * flex ที่เปิด `wrap` จะ **ตัดบรรทัดก่อน ไม่ยอมหด** ต่อให้ลูกมี
     * `min-width:0` + `flex-shrink:1` ครบ (การหดเกิดเฉพาะตอน `nowrap`)
     * งบที่ 320px: หัวข้อ 222 + หยุด 38 + อ่าน 38 + ช่องไฟ 24 = 322 > 272
     * → ของเดิมตัดบรรทัด · พอเป็น `nowrap` หัวข้อหดเหลือ 172 พร้อม ellipsis
     * ที่ตั้งไว้แล้ว ทุกอย่างอยู่บรรทัดเดียวเหมือนเดิม
     *
     * ⚠️ **ปลอดภัยเพราะไม่มีลูกตัวไหนต้องการบรรทัดเต็มอีกแล้ว**
     *   · `.es-speech-help` ถูก `read-aloud.js` ก๊อปไปแสดงในกล่องซ้อน
     *     ตัวในหน้า `hidden` ตลอดชีวิต (ยืนยันในโค้ดแล้ว)
     *   · `.btn-read-aloud__note` เลิกใช้แล้ว ไม่มีใครสร้างมันขึ้นมา
     * ถ้าวันหลังจะเพิ่มอะไรที่ต้องกินบรรทัดเต็มในแถวนี้ **ต้องกลับมาคิดใหม่**
     */
    flex-wrap: nowrap;

    /* แถวเดียวแล้ว ความสูงกลับไปเท่าจอกว้าง — ตัวเลขเดียวกับ min-height
       ที่จองไว้ข้างบน (ปุ่มหยุดสูงกว่าปุ่มอ่าน 1px เพราะมีขอบ) */
    min-height: 38px;
  }

  .product-description .description-header h2,
  .product-description .description-header h3 {
    flex: 1 1 auto;
    margin-right: auto;
  }
}

/* ============================================================
   คำบรรยายสินค้าเต็มความกว้าง — ไม่ให้ถูกดันไปกลาง

   🔴 ต้นเหตุ: `single-product.css:609` (ใน @media ≥768px) ตั้ง
       .product-description { max-width: 1024px; margin-left: auto; margin-right: auto }

   `.page-wrapper` ของหน้าสินค้าไม่มี max-width (ต่างจาก .page-fixs-wrapper)
   พอจอกว้างกว่า 1024px บล็อกคำบรรยายจึงหดเหลือ 1024px แล้ว auto margin
   ดันไปอยู่กึ่งกลาง — ในขณะที่แกลเลอรีกับข้อมูลสินค้าด้านบนกว้างเต็มจอ
   ดูเหมือนคำบรรยาย "ลอยไปอยู่กลาง" โดยเฉพาะเวลาข้อความสั้น

   ผู้ใช้สั่งให้เต็มความกว้าง หัวข้อชิดซ้าย ข้อความชิดซ้าย ปุ่มเสียงชิดขวา
   ============================================================ */

@media (min-width: 768px) {
  .product-description {
    max-width: none;
    margin-left: 0;
    margin-right: 0;
  }
}

.product-description {
  width: 100%;
}

/* ข้อความชิดซ้ายเสมอ ต่อให้สั้นแค่บรรทัดเดียว
 *
 * ⚠️ **ต้องมีทั้งสองชั้น** — เนื้อหาถูกครอบด้วย `.product-description__body`
 * ตอนทำไฮไลต์เสียงอ่าน (2026-08-21) ถ้าเขียนแค่ `.product-description > p`
 * กฎนี้จะหลุดไปเงียบ ๆ แล้วข้อความกลับไปลอยกลางจอบนจอกว้างเหมือนบั๊กเดิม
 * คงชั้นเก่าไว้ด้วยเผื่อ template ไหนยังไม่มีกล่องครอบ
 */
.product-description > p,
.product-description > ul,
.product-description > ol,
.product-description__body > p,
.product-description__body > ul,
.product-description__body > ol {
  text-align: left;
  margin-left: 0;
  margin-right: 0;
  max-width: none;
}

/* ============================================================
   กล่องเตือนสินค้า XXL ในหน้าสินค้าเดี่ยว

   ⚠️ **ต้องอยู่ในไฟล์นี้เท่านั้น ไม่ใช่ single-product.css**
   กฎรวมของกล่องแจ้งเตือน (`.es-notice`) ในไฟล์นี้ใช้ `margin: 0 0 12px`
   แบบ shorthand ซึ่ง **รีเซ็ต margin-top เป็น 0**
   และ woocommerce-bridge.css โหลด **หลัง** single-product.css เสมอ
   → เขียน `.es-xxl-notice { margin-top }` ไว้ที่นั่น specificity เท่ากัน
   แต่แพ้เพราะลำดับโหลด (กับดักข้อ 15)
   ============================================================ */

.es-xxl-notice {
  margin-top: 20px;
}

/* ============================================================
   INFINITE LOAD (โหลดสินค้าต่อเนื่อง) — ส่วนนี้ไม่มีใน design เดิม
   สีและรัศมีอ้างอิงจาก .product-card เพื่อให้กลมกลืนกับตะแกรง

   **ย้ายมาจาก product.css** เพราะไฟล์นั้น enqueue เฉพาะหน้า shop
   หน้าร้านของผู้ขายใช้ store-profile.css จึงไม่ได้สไตล์พวกนี้เลย
   ตัวบอกสถานะกลายเป็นข้อความ "กำลังโหลด…" ชิดซ้ายไม่มีวงหมุน
   ไฟล์นี้โหลดทุกหน้า (priority 999) จึงเป็นที่ที่ถูกต้องของกฎที่ใช้ร่วมกัน
   ============================================================ */

.product-sentinel {
  width: 100%;
  height: 1px;
}

/* ── ตัวบอกสถานะกำลังโหลด ── */
.product-loader {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 24px 0 40px;
  color: var(--text-secondary);
  font-size: 13px;
}

.product-loader[hidden] {
  display: none;
}

.product-loader__spinner {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  flex-shrink: 0;
  /* วงแหวนไล่สีชุดเดียวกับขอบการ์ด เจาะกลางด้วย mask
     🔴 ต้องมีช่วงโปร่ง (หางจาง) — วงปิดครบรอบหมุนแล้วเห็นแค่สีเลื่อน
     บน iPad ผู้ใช้เห็นเป็น "ไอคอนค้างไม่หมุน" (แจ้ง 19 ก.ย.) */
  background: conic-gradient(
    from 0deg,
    transparent 0 20%,
    var(--grad-1) 45%,
    var(--grad-2) 65%,
    var(--grad-3) 85%,
    var(--grad-4)
  );
  will-change: transform;
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 0);
  mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 0);
  animation: product-loader-spin 0.9s linear infinite;
}

@keyframes product-loader-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .product-loader__spinner {
    animation-duration: 3s;
  }
}

/* ── ปุ่มสำรอง: โผล่เมื่อโหลดอัตโนมัติล้มเหลว ── */
.product-load-more {
  display: block;
  width: fit-content;
  min-width: 200px;
  margin: 8px auto 40px;
  padding: 12px 32px;
  position: relative;
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
  background: var(--bg-primary);
  border-radius: 10px;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

/* ขอบไล่สีด้วย mask แบบเดียวกับที่ design ใช้กับปุ่มอื่น */
.product-load-more::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1.5px;
  background: var(--gradient, linear-gradient(90deg, var(--grad-1), var(--grad-2), var(--grad-3), var(--grad-4)));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.product-load-more:hover {
  color: var(--text-primary);
  transform: translateY(-2px);
  box-shadow: 0 10px 24px rgba(var(--grad-1-rgb), 0.25);
}

/* ============================================================
   ตะกร้า — ปรับตามที่ผู้ใช้สั่ง (2026-08-09)
   ============================================================ */

/* ── ชื่อสินค้า: ขาวธรรมดา → ฟ้าเมื่อ hover ──
   design ตั้ง `a { color: var(--grad-4) }` ให้ลิงก์ทุกตัวเป็นสีฟ้ามาตั้งแต่ต้น
   ชื่อสินค้าในตะกร้าจึงฟ้าตลอดเวลา ทั้งที่ `.cart-item-name` ตั้งไว้เป็นสีขาว
   (กฎของ design แพ้เพราะสีอยู่ที่ <a> ข้างใน ไม่ใช่ที่ <h3>) */
.cart-item-name a {
  color: var(--text-primary);
  transition: color 0.2s;
}

/* ⚠️ ต้องล้างไล่สีของ `a:hover` (styles.css:197 — กับดักข้อ 6) ด้วย
   ไม่งั้นตัวหนังสือโปร่งใสแล้วไล่สีทับ ไม่ได้สีฟ้าเรียบอย่างที่สั่ง */
.cart-item-name a:hover {
  color: var(--grad-4);
  -webkit-text-fill-color: var(--grad-4);
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

/* ── จำนวนชิ้น ชิดขวาบนบรรทัดเดียวกับราคา ── */
.cart-item-price {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.cart-item-qty {
  flex-shrink: 0;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
}

/* ── ปุ่มลบ: กากบาทต้องไม่หายตอน hover ──
   ไอคอนวาดด้วยฟอนต์ `-webkit-text-fill-color: transparent` ของ a:hover
   จึงทำให้มันหายไปทั้งตัว เหลือแต่วงกลมเปล่า */
a.cart-item-remove:hover {
  color: var(--grad-1);
  -webkit-text-fill-color: var(--grad-1);
  background: rgba(var(--grad-1-rgb), 0.2);
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

/* ── คูปอง: เว้นระยะจากบล็อกข้อมูลจัดส่ง ──
   design เว้นไว้ 4px ซึ่งใช้ได้ตอนที่บล็อกข้างบนเป็นการ์ดสินค้าใบเล็ก
   แต่ของจริงข้างบนเป็นกล่องข้อมูลจัดส่งพื้นทึบ ชิดกันจนดูเป็นก้อนเดียว */
.cart-coupon {
  margin-top: 22px;
}

/* ── ปุ่มไปชำระเงิน: ไอคอนนำหน้าข้อความ ── */
.btn-checkout {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

/* ── รูปสินค้าในตะกร้า 60px มุมโค้ง 8px (ผู้ใช้สั่ง 2026-08-09) ──
   design ตั้งไว้ 88px / 12px ซึ่งกินพื้นที่มากจนชื่อสินค้าเหลือที่น้อย */
.cart-item-image {
  width: 60px;
  height: 60px;
  border-radius: 8px;
}

/* ── ช่องกรอกคูปอง: ใช้ทรงเดียวกับ .form-input ของ design ──
   ห้ามมีขอบสีของแบรนด์ (ชมพู/ม่วง) ทั้งตอนปกติและตอนโฟกัส
   ระบุ `input` นำหน้าเพื่อให้ specificity (0,2,1) ชนะกฎที่มาจาก
   WooCommerce และ Dokan ที่ยึด `input.input-text` (0,2,1) เหมือนกัน
   แต่ไฟล์นี้โหลดท้ายสุดจึงชนะด้วยลำดับ */
input.cart-coupon-input,
input.cart-coupon-input:hover {
  background: transparent;
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  box-shadow: none;
}

input.cart-coupon-input:focus {
  /* ขาวจาง ๆ เท่ากับ .form-input:focus ของ design — ไม่ใช่สีแบรนด์ */
  border-color: var(--border-active);
  box-shadow: none;
  outline: none;
}

/* ── แจ้งเตือนคูปอง: แถวของตัวเองเหนือช่องกรอกเสมอ ──
   อยู่ข้างใน `.cart-coupon` (ดูเหตุผลใน cart.php) ซึ่งเป็น flex row
   → ต้องสั่ง wrap ที่พ่อ และให้ตัวมันกินเต็มแถวแล้วดันขึ้นไปบนสุด
   `order: -1` เผื่อวันหนึ่งย้ายลำดับใน markup ก็ยังอยู่บนอยู่ดี */
.cart-coupon {
  flex-wrap: wrap;
}

.cart-coupon-notices {
  display: block;
  flex: 0 0 100%;
  width: 100%;
  order: -1;
}

/* กรอบเหมือนแจ้งเตือนที่อื่นทั้งเว็บ — ย้ำไว้เผื่อกฎของ WooCommerce
   ที่ scope ด้วย `.woocommerce` มาทับตอน markup อยู่ในฟอร์ม */
.cart-coupon-notices .woocommerce-error,
.cart-coupon-notices .woocommerce-message,
.cart-coupon-notices .woocommerce-info {
  width: 100%;
  margin: 0 0 10px;
  float: none;
}

/* ── ข้อความคูปองที่ WooCommerce วาดด้วย AJAX ──
   `cart.js:218` ของปลั๊กอินสร้าง `<p class="coupon-error-notice">` แล้ว
   **`append()` ต่อท้าย `.coupon`** = ไปอยู่หลังปุ่มเสมอ
   และ CSS ของมันตั้ง `flex-basis: 100%` ไว้ ซึ่งไม่มีผลเพราะ design ตั้ง
   `.cart-coupon { display: flex }` **โดยไม่มี wrap** → ทุกอย่างถูกอัดอยู่แถวเดียว
   (นี่คือสาเหตุจริงที่ข้อความไปอยู่บรรทัดเดียวกับช่องกรอกและปุ่ม
   ไม่ใช่ตำแหน่งใน PHP — ตัวที่เห็นบนจอไม่ได้มาจาก PHP เลย)

   `flex-wrap: wrap` อยู่ในกฎ `.cart-coupon` ข้างบนแล้ว ที่นี่แค่ดันขึ้นไปบนสุด */
.cart-coupon .coupon-error-notice {
  order: -1;
  flex: 0 0 100%;
  width: 100%;
  margin: 0 0 10px;
  font-size: 14px;
  text-align: left;
}

/* ช่องกรอกตอนกรอกผิด — ขอบแดงจาง ๆ ไม่ใช่สีแบรนด์ */
input.cart-coupon-input.has-error,
input.cart-coupon-input.has-error:focus {
  border-color: var(--stat-error, #ef4444);
}

/* ============================================================
   หน้าชำระเงิน — ปรับตามที่ผู้ใช้สั่ง (2026-08-10)
   ============================================================ */

/* ── ข้อ 7: ระยะห่างระหว่าง section ──
   design ตั้ง gap ไว้แน่นเพราะตอนวาดมีแค่ 3 กล่อง ของจริงมี 4 กล่อง
   บวกปุ่มด้านล่าง ชิดกันจนแยกไม่ออกว่าเป็นคนละเรื่อง */
.checkout-form,
.checkout-wrapper {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.checkout-section {
  margin: 0;
}

/* ── ข้อ 6: ไอคอนหน้าหัวข้อ ใช้สีเดียวกับหัวข้อในหน้าตะกร้า ── */
.checkout-section-title {
  display: flex;
  align-items: center;
  gap: 8px;
}

.checkout-section-title > i {
  font-size: 14px;
  color: var(--grad-2);
  flex-shrink: 0;
}

/* ── ข้อ 10: วิธีชำระเงินเป็นการ์ดของตัวเอง ปุ่มอยู่นอกการ์ด ──
   `#payment` เป็นแค่กล่องครอบให้ AJAX แทนที่ได้ทั้งก้อน จึงต้องโปร่งใส */
#payment.woocommerce-checkout-payment {
  background: none;
  border: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* โครงของ .place-order และระยะไอคอน อยู่ในกฎ specificity สูงต้นไฟล์
   (ค้นหา `.woocommerce-checkout #payment .form-row.place-order`) */

/* ⚠️ **ห้ามใช้ `::before` / `::after` กับปุ่มนี้** — design ใช้ทั้งคู่ไปแล้ว
   (`checkout.css:415` ขอบไล่สี, `:425` พื้นทึบข้างใน) ถ้าเขียน `content` ทับ
   ขอบไล่สีจะหายและไอคอนก็ไม่โผล่ เพราะกล่องนั้น `position:absolute; z-index:-1`
   → ไอคอนเป็น `<i>` จริงใน DOM แล้วให้ `checkout-ui.js` คอยใส่คืน
   ทุกครั้งที่ `checkout.js:301` เขียนข้อความปุ่มทับด้วย `.text()` */
.btn-place-order > i {
  font-size: 15px;
  line-height: 1;
}

/* ── ข้อ 8: ข้อความเงื่อนไข (ไม่มีช่องติ๊กแล้ว) ── */
.es-terms-note {
  margin: 0;
}

.es-terms-note p {
  margin: 0;
  font-size: 12px;
  line-height: 1.7;
  color: var(--text-secondary);
  text-align: center;
}

.es-terms-note a {
  color: var(--grad-4);
  text-decoration: underline;
}

/* ── กล่อง "มีคูปองส่วนลด?" ──
   ⚠️ **ห้ามแตะ** — ผู้ใช้ยืนยันว่าทรง notice ของ WooCommerce ถูกอยู่แล้ว
   เคยเผลอเปลี่ยนพื้นหลังเป็นสีการ์ดแล้วโดนสั่งให้คืน 3 รอบ
   ที่ต้องปรับคือ **ฟอร์มคูปองที่กางออกมา** (`form.checkout_coupon`)
   ซึ่งย้ายไปอยู่ท้ายไฟล์แล้ว (ค้นหา "ฟอร์มคูปองหน้าชำระเงิน") */

/* ── ข้อ 3: ช่องประเทศมีตัวเลือกเดียว ──
   WooCommerce ตั้งใจออกเป็น <select> ที่มี option เดียวเมื่อขายประเทศเดียว
   (`wc-template-functions.php:3431`) กดแล้วเปิด dropdown ที่มีบรรทัดเดียว
   ดูเหมือนค้าง — ทำให้เป็นช่องอ่านอย่างเดียวไปเลย
   **ห้ามใส่ `disabled`** เพราะ select ที่ disabled จะไม่ถูกส่งไปกับฟอร์ม */
select.country_to_state--single {
  pointer-events: none;
  background-image: none;
  color: var(--text-secondary);
}

/* กฎของ Select2 ทั้งหมดอยู่ท้ายไฟล์ (ค้นหา "Select2 / selectWoo") */

/* ── textarea: ความสูงขั้นต่ำ ──
   (มุมโค้งอยู่ในก้อนรวมท้ายไฟล์ — ค้นหา "textarea: มุมโค้ง") */
.woocommerce textarea,
textarea.form-input,
.dokan-dashboard-content textarea {
  min-height: 110px;
}

/* ── ข้อ 12: รายการธนาคารของ Mobile Banking ── */
.omise-banks-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.omise-banks-list li.item {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  list-style: none;
  width: 100%;
}

.omise-banks-list li.item > div {
  width: 100%;
}

.omise-banks-list input[type='radio'] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.omise-banks-list label {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin: 0;
  padding: 10px 14px;
  border: 1px solid transparent;
  border-radius: 12px;
  background: rgba(var(--text-primary-rgb), 0.04);
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s;
}

.omise-banks-list label:hover {
  background: rgba(var(--text-primary-rgb), 0.08);
}

/* ธนาคารที่เลือกอยู่ — เข้มขึ้นให้เห็นชัดว่ากำลังเลือกอันไหน */
.omise-banks-list input[type='radio']:checked + label {
  background: rgba(var(--grad-2-rgb), 0.18);
  border-color: var(--grad-2);
}

.omise-banks-list .mobile-banking-logo {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  border-radius: 8px;
}

.omise-banks-list .mobile-banking-label {
  min-width: 0;
}

.omise-banks-list .mobile-banking-label .title {
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
}

/* ============================================================
   บัตรที่บันทึกไว้ของ Omise (ผู้ใช้สั่ง 2026-08-28)
   ------------------------------------------------------------
   markup มาจากปลั๊กอิน 2 ที่ **แก้ไฟล์ปลั๊กอินไม่ได้ ต้องคุมด้วย CSS อย่างเดียว**

     · หน้าเช็คเอาต์  omise/templates/payment/form.php
       #omise_cc_form > h3 + ul.omise-customer-card-list > li.item
       > input[type=radio] + label   แล้วต่อด้วย #new_card_info
     · หน้าบัญชี      omise/templates/myaccount/my-card.php
       #omise_card_panel > table (ไม่มีคลาสสักตัว) + button.delete_card

   ทั้งสองที่ไม่เคยถูกจัดหน้าตาเลย — บนธีมมืดจึงออกมาเป็นตัวหนังสือดำ
   บนพื้นดำ ปุ่มวิทยุของเบราว์เซอร์ล้วน ๆ และตารางไม่มีเส้น
   ใช้ทรงเดียวกับ .omise-banks-list ข้างบน จะได้อ่านเป็นภาษาเดียวกัน
   ============================================================ */

#omise_cc_form h3,
#omise_card_panel h3,
#omise_card_panel h4 {
  margin: 0 0 10px;
  font-family: var(--font);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text-primary);
}

/* หัวข้อก้อนที่สอง ("ใช้บัตรใบใหม่") ต้องมีที่หายใจจากรายการบัตรข้างบน */
#omise_cc_form #label-new_card_info h3,
#omise_card_panel h4 {
  margin-top: 16px;
}

/* 🔴 ต้องยิงด้วย `#omise_cc_form ul.…` ไม่ใช่คลาสเปล่า —
   omise-css.css ของปลั๊กอิน (บรรทัด 21) โหลด **ทีหลัง** ธีม
   และตั้ง `border-bottom:1px solid #ddd` + `box-shadow:0 1px 1px #fff` ไว้
   ความเฉพาะเจาะจงเท่ากันเมื่อไหร่ ตัวที่มาทีหลังชนะ → เห็นเป็นเส้นขาว
   พาดใต้รายการบัตรบนพื้นดำ (เจอตอนตรวจบนเบราว์เซอร์ 2026-08-28) */
#omise_cc_form ul.omise-customer-card-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0 0 4px;
  padding: 0;
  border: 0;
  box-shadow: none;
  list-style: none;
}

#omise_cc_form ul.omise-customer-card-list li.item {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  list-style: none;
}

/* ซ่อนปุ่มวิทยุของเบราว์เซอร์แล้วใช้ทั้งการ์ดเป็นปุ่มแทน
   (:checked + label ยังทำงานได้เพราะ input ยังอยู่ใน DOM) */
.omise-customer-card-list input[type='radio'],
#omise_cc_form #new_card_info {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.omise-customer-card-list label,
#omise_cc_form #label-new_card_info {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin: 0;
  padding: 12px 14px;
  border: 1px solid transparent;
  border-radius: 12px;
  background: rgba(var(--text-primary-rgb), 0.04);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 13px;
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s;
}

.omise-customer-card-list label:hover,
#omise_cc_form #label-new_card_info:hover {
  background: rgba(var(--text-primary-rgb), 0.08);
}

.omise-customer-card-list input[type='radio']:checked + label,
#omise_cc_form #new_card_info:checked + #label-new_card_info {
  background: rgba(var(--grad-2-rgb), 0.18);
  border-color: var(--grad-2);
}

/* ป้ายยี่ห้อบัตร — ปลั๊กอินส่งมาเป็น <strong>Visa</strong> เฉย ๆ */
.omise-customer-card-list label strong {
  display: inline-flex;
  align-items: center;
  padding: 3px 8px;
  border-radius: 6px;
  background: rgba(var(--text-primary-rgb), 0.12);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* หัวข้อในป้าย "ใช้บัตรใบใหม่" เป็น <h3> ซ้อนใน <label> — ตัดระยะทิ้ง
   ไม่งั้นการ์ดสูงกว่าเพื่อนเพราะ margin ของ h3 */
#omise_cc_form #label-new_card_info h3 {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
}

/* ฟอร์มบัตรใหม่ตอนที่มีบัตรเก่าอยู่แล้ว — ย่อหน้าเข้ามาให้เห็นว่าเป็นของก้อนนั้น */
.omise-new-card-form.card-exists {
  margin-top: 10px;
}

/* ── หน้าบัญชี: ตาราง "บัตรของฉัน" ──
   ตารางไม่มีคลาสเลย ต้องยิงผ่าน #omise_card_panel
   ห่อ overflow-x ไว้ที่แผง จอแคบจะได้เลื่อนในกล่อง ไม่ดันทั้งหน้าให้ล้น */
#omise_card_panel {
  margin-top: 24px;
  padding: 16px;
  border: 1px solid var(--border-input);
  border-radius: 14px;
  background: var(--bg-secondary);
  overflow-x: auto;
}

#omise_card_panel table {
  width: 100%;
  margin: 0 0 4px;
  border-collapse: collapse;
  font-family: var(--font);
  font-size: 13px;
  color: var(--text-primary);
}

#omise_card_panel th,
#omise_card_panel td {
  padding: 10px 12px;
  text-align: left;
  border-bottom: 1px solid var(--border-input);
  white-space: nowrap;
}

#omise_card_panel th {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

#omise_card_panel tr:last-child td {
  border-bottom: 0;
}

/* ปุ่มลบบัตร — ใช้สีเตือนของธีม ไม่ใช่ปุ่มเทาของ WordPress */
#omise_card_panel .delete_card {
  padding: 6px 14px;
  border: 1px solid var(--btn-danger);
  border-radius: 999px;
  background: transparent;
  color: var(--btn-danger);
  font-family: var(--font);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  cursor: pointer;
  height: auto;
}

#omise_card_panel .delete_card:hover {
  background: var(--btn-danger);
  color: #fff;
}

#omise_card_panel #omise_add_new_card {
  margin-top: 12px;
  padding: 10px 22px;
  border: 1px solid var(--grad-2);
  border-radius: 999px;
  background: rgba(var(--grad-2-rgb), 0.18);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
  height: auto;
}

#omise_card_panel #omise_add_new_card:hover {
  background: var(--grad-2);
}

/* กรอบฟอร์มบัตรของ Omise.js ในหน้าบัญชี — ปลั๊กอินตั้ง max-width:400px inline */
#omise_card_panel #omise-card {
  width: 100% !important;
  max-width: none !important;
}

/* ── ข้อ 10: ฟอร์มบัตรเครดิตของ Omise ใช้ฟอนต์เดียวกับเว็บ ── */
.payment_box,
.payment_box input,
.payment_box label,
.payment_box select,
.payment_box span,
.payment_box p,
#omise_checkout_form,
#omise_checkout_form input,
#omise_checkout_form label {
  font-family: var(--font);
}

/* ============================================================
   หน้าชำระเงิน — รอบแก้ที่ 2 (2026-08-10)
   ============================================================ */

/* ── ข้อ 2: หมายเหตุใต้ช่องประเทศ ── */
/* กฎจริงอยู่ท้ายไฟล์ (ค้นหา "หมายเหตุประเทศ") */

/* ── กล่องผลลัพธ์ของ Select2: แถบเลื่อนแบบ WebKit ──
   (พื้นหลังและทรงอยู่ในก้อนรวมท้ายไฟล์ — ค้นหา "Select2 / selectWoo") */
.select2-container .select2-results > .select2-results__options::-webkit-scrollbar {
  width: 8px;
}

.select2-container .select2-results > .select2-results__options::-webkit-scrollbar-track {
  background: transparent;
}

.select2-container .select2-results > .select2-results__options::-webkit-scrollbar-thumb {
  background: rgba(var(--text-primary-rgb), 0.22);
  border-radius: 8px;
}

.select2-container .select2-results > .select2-results__options::-webkit-scrollbar-thumb:hover {
  background: rgba(var(--text-primary-rgb), 0.35);
}

/* ระยะข้อความเงื่อนไข ↔ ปุ่ม อยู่ท้ายไฟล์ (ค้นหา "ระยะข้อความเงื่อนไข") */

/* ── ข้อ 6: การ์ดวิธีชำระเงิน padding พอดี ── */
.checkout-section--payment {
  padding: 18px;
  gap: 12px;
}

.payment-methods {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* กล่องที่กางออกมาใต้วิธีที่เลือก — เอากรอบขาวของ WooCommerce/Omise ออก */
.woocommerce-checkout #payment div.payment_box,
.payment_box {
  background: rgba(var(--text-primary-rgb), 0.04);
  border: 0;
  border-radius: 12px;
  margin: 8px 0 0;
  padding: 14px;
  color: var(--text-secondary);
}

/* WooCommerce วาดสามเหลี่ยมชี้ขึ้นด้วย ::before — สีไม่เข้ากับพื้นเรา */
.woocommerce-checkout #payment div.payment_box::before,
.payment_box::before {
  display: none;
}

.payment_box fieldset {
  border: 0;
  margin: 0;
  padding: 0;
}

/* ── ข้อ 6: รายการธนาคาร — ไม่มี margin ของ ul และช่องกว้างขึ้น ── */
.payment_box ul.omise-banks-list,
ul.omise-banks-list {
  margin: 0;
  padding: 0;
  gap: 10px;
}

.omise-banks-list label {
  padding: 14px 16px;
  gap: 14px;
}

.omise-banks-list .mobile-banking-logo {
  width: 36px;
  height: 36px;
}

.omise-banks-list .mobile-banking-label .title {
  font-size: 14px;
}

/* ============================================================
   หน้าชำระเงิน — รอบแก้ที่ 3 (2026-08-10)

   🔴 **สาเหตุที่รอบก่อนแก้ไม่ติดทั้งชุด: WooCommerce ใช้ selector ที่มี id**
   `#payment ul.payment_methods` ตั้ง padding 1em ด้วย specificity (1,1,1)
   กฎของเราที่เป็น `.payment-methods` = (0,1,0) จึงแพ้ทุกครั้ง
   **ทุกกฎที่เกี่ยวกับกล่องชำระเงินต้องขึ้นต้นด้วย `#payment` เท่านั้น**
   ตรวจก่อนเขียนเสมอด้วยการ grep หา selector ที่ขึ้นต้นด้วย #payment
   ในไฟล์ woocommerce.css ของปลั๊กอิน

   ⚠️ ห้ามใส่ปีกกาในคอมเมนต์ — ตัวนับปีกกาที่ใช้ตรวจไฟล์นี้จะเพี้ยน
   ============================================================ */

/* ── ข้อ 6: รายการวิธีชำระเงิน ── */
#payment ul.payment_methods,
#payment ul.payment-methods {
  padding: 0;
  margin: 0;
  border: 0;
  list-style: none;
}

#payment ul.payment_methods li {
  margin: 0;
  list-style: none;
}
.woocommerce-checkout #payment ul.payment_methods{ padding: 0; }

/* ── กล่องที่กางออกใต้วิธีที่เลือก ── */
#payment div.payment_box {
  background: rgba(var(--text-primary-rgb), 0.04);
  border: 0;
  border-radius: 12px;
  margin: 8px 0 0;
  padding: 14px;
  color: var(--text-secondary);
  font-size: 13px;
  line-height: 1.6;
}

#payment div.payment_box::before,
#payment div.payment_box::after {
  display: none;
}

/* ── ข้อ 6: ฟอนต์ในฟอร์มบัตรเครดิตของ Omise ──
   ปลั๊กอินตั้ง font-family ของตัวเองไว้ในไฟล์ที่โหลด **ก่อน** เรา
   แต่ selector มี id จึงชนะ — ต้องขึ้นต้นด้วย `#payment` ให้เท่ากัน */
#payment .payment_box,
#payment .payment_box *,
#payment .payment_box input,
#payment .payment_box label,
#payment .payment_box select {
  font-family: var(--font);
}

/* ── ข้อ 6: รายการธนาคาร Mobile Banking ── */
#payment ul.omise-banks-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
  border: 0;
}

#payment ul.omise-banks-list li.item {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  width: 100%;
}

#payment ul.omise-banks-list input[type='radio'] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

#payment ul.omise-banks-list label {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  margin: 0;
  padding: 14px 16px;
  border: 1px solid transparent;
  border-radius: 12px;
  background: rgba(var(--text-primary-rgb), 0.05);
  cursor: pointer;
}

#payment ul.omise-banks-list input[type='radio']:checked + label {
  background: rgba(var(--grad-2-rgb), 0.18);
  border-color: var(--grad-2);
}

#payment ul.omise-banks-list .mobile-banking-logo {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  /* ถอด margin-left 10px / margin-bottom 6px ของ omise-css.css (ผู้ใช้สั่ง 2026-10-01) — ระยะห่างใช้ gap ของ label แทน */
  margin-left: 0;
  margin-bottom: 0;
}

#payment ul.omise-banks-list .mobile-banking-label .title {
  font-family: var(--font);
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
}

/* ระยะข้อความเงื่อนไข ↔ ปุ่ม อยู่ในกฎ (1,3,0) ต้นไฟล์ (ค้นหา "place-order")
   ส่วนระยะไอคอน ↔ ตัวหนังสือ อยู่ในกฎ (2,2,0) ต้นไฟล์เช่นกัน
   ทั้งสองอันมี specificity สูงกว่าอะไรที่เขียนตรงนี้ได้ ห้ามเขียนซ้ำที่นี่ */

/* ============================================================
   ฟอร์มคูปองหน้าชำระเงิน — `form.checkout_coupon`

   ⚠️ อ่านก่อนแก้: **ที่นี่ไม่มีการเลียนแบบทรงของหน้าตะกร้าอีกแล้ว**

   ก่อนหน้านี้เขียน CSS ก๊อปค่าจาก cart.css มาทีละ property แล้วไม่เคยเหมือน
   จุดที่พลาดคือปุ่ม — `.btn-apply-coupon` ของ design ใช้ **ขอบไล่สีจาก
   `::before`/`::after`** ไม่ใช่ `border` ก๊อปเฉพาะ property ที่ตาเห็นจึงได้
   ปุ่มขอบเทาธรรมดาตลอด

   รอบนี้แก้ที่ต้นทาง: `woocommerce/checkout/form-coupon.php` ใช้คลาสชุด
   เดียวกับหน้าตะกร้า (`.cart-coupon` / `.cart-coupon-input` / `.btn-apply-coupon`)
   และ `inc/enqueue.php` โหลด cart.css ที่หน้านี้ด้วย
   → ทรงมาจาก **ไฟล์เดียวกัน** ไม่มีทางหลุดจากกันได้อีก

   เหลือไว้ที่นี่แค่การล้างกฎของ WooCommerce ที่ scope ด้วย `.woocommerce`
   (specificity 0,2,1) ซึ่งชนะคลาสของ design (0,1,0) เสมอไม่ว่าโหลดทีหลังแค่ไหน
   ============================================================ */

/* woocommerce.css: `border:1px solid #cfc8d8; padding:20px; margin:2em 0;
   border-radius:5px; text-align:left` — ทับให้เป็นการ์ดพื้นทึบไม่มีกรอบ
   ส่วน display/gap ปล่อยให้ `.cart-coupon` ของ design จัดการ */
.woocommerce form.checkout_coupon {
  background: var(--bg-primary);
  border: 0;
  border-radius: 16px;
  box-shadow: none;
  padding: 18px;
  margin: 0;
}

.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple, .select2-container--default.select2-container--open.select2-container--below .select2-selection--single {
    border-bottom-left-radius: var(--radius-input);
    border-bottom-right-radius: var(--radius-input);
}

/* แถวแจ้งเตือน — `checkout.js:1206` `append()` `<span class="coupon-error-notice">`
   ต่อท้ายตัวฟอร์ม (หน้าตะกร้าเป็น `<p>` จาก `cart.js:218` — คลาสเดียวกัน)
   ฟอร์มเป็น flex ที่ wrap ได้จาก `.cart-coupon` → ดันขึ้นแถวบนสุดได้เลย

   ต้องประกาศ `display: grid` กับสีซ้ำที่นี่ เพราะ woocommerce.css เขียน
   `.woocommerce form.checkout_coupon .coupon-error-notice { display:block;
   color:var(--wc-red); font-size:.75em }` ไว้ที่ (0,2,1) ซึ่งชนะกฎแจ้งเตือน
   รวมข้างบนของเรา (0,1,0) — ถ้าไม่ทับ กรอบกับไอคอนจะหายไปเฉพาะหน้านี้ */
.woocommerce form.checkout_coupon .coupon-error-notice {
  order: -1;
  flex: 0 0 100%;
  width: auto;
  margin: 0 0 10px;
  display: grid;
  font-size: 14px;
  text-align: left;
  color: var(--stat-error);
}

/* ช่องกรอกตอนกรอกผิด — ขอบแดงจาง ๆ เท่ากับหน้าตะกร้า */
.woocommerce form.checkout_coupon input.cart-coupon-input.has-error,
.woocommerce form.checkout_coupon input.cart-coupon-input.has-error:focus {
  border-color: var(--stat-error, #ef4444);
}

/* ── หมายเหตุประเทศ: บรรทัดของตัวเอง ใต้หัวข้อ เหนือช่องเลือก ──
   markup วางไว้นอก `.woocommerce-input-wrapper` แล้ว (`inc/woocommerce.php`)
   พ่อคือ `<p class="form-row form-group">` = flex column gap 8px
   จึงไม่ต้องใส่ margin เอง แค่ `width: 100%` กันกรณีพ่อเป็น flex row */
.es-country-note {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  margin: 0;
  font-size: 12px;
  line-height: 1.6;

  /* แดง (ผู้ใช้สั่ง 2026-08-10) — เป็นข้อจำกัดที่ต้องเห็นก่อนกรอกที่อยู่
     ใช้โทนเดียวกับดอกจัน "ต้องกรอก" ไม่ใช่สีของกล่องแจ้งเตือน
     เพราะเป็นข้อความสั้นบนพื้นทึบ ไม่มีพื้นหลังช่วยให้อ่านออก */
  color: var(--stat-error-bright);
}

.es-country-note i {
  font-size: 12px;
  color: inherit;
  flex-shrink: 0;
}

/* ============================================================
   Select2 / selectWoo — ที่เดียวจบ

   ⚠️ เคยกระจายอยู่ 3 ที่ในไฟล์นี้แล้วทับกันเอง (บางกฎใช้
   `.woocommerce .select2-container` บางกฎใช้ `.select2-container--default`)
   แก้จุดหนึ่งไปพังอีกจุด — รวมมาไว้ที่นี่ที่เดียว **ห้ามเขียนกฎ select2
   ที่อื่นในไฟล์นี้อีก**

   สอง scope ที่ต้องแยกกันให้ชัด:
   1. **ช่องที่ปิดอยู่** (`.select2-selection--single`) อยู่ในฟอร์ม
   2. **กล่อง dropdown** ถูกต่อไว้ที่ `<body>` → **ห้าม scope ด้วย `.woocommerce`**
      (นี่คือสาเหตุเดิมที่ dropdown หลุดธีมเป็นพื้นขาวตัวหนังสือดำ)

   ใช้ `.select2-container--default` เป็นหลักเพื่อให้ specificity เท่า
   `select2.css` ของปลั๊กอิน แล้วชนะด้วยลำดับ (ไฟล์นี้โหลดท้ายสุด)
   ============================================================ */

/* ── ช่องที่ปิดอยู่ = ทรงเดียวกับ .form-input ของ design ──
   ⚠️ `background: transparent` ไม่ใช่ `--bg-input`
   design ตั้ง `.form-input { background: transparent }` (styles.css:586)
   ช่องจังหวัดที่เคยเป็น `--bg-input` (#0c0a1e) จึงเป็นช่องเดียวในฟอร์ม
   ที่ไม่กลืนกับพื้นการ์ด — ผู้ใช้ทักว่า "พื้นหลังไม่เป็นสีเดียวกับ section" */
.select2-container--default .select2-selection--single,
.woocommerce select {
  background-color: transparent;
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  border-radius: var(--radius-input);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 13px;
  min-height: 48px;
}

.select2-container--default .select2-selection--single {
  display: flex;
  align-items: center;
  padding: 0 18px;
}

.select2-container--default .select2-selection--single .select2-selection__rendered {
  padding: 0;
  color: var(--text-primary);
  line-height: 1.4;
}

.select2-container--default .select2-selection--single .select2-selection__placeholder {
  color: var(--text-placeholder);
}

/* ลูกศร — วาดเองด้วย Font Awesome ให้เหมือนลูกศรของ .form-input */
.select2-container--default .select2-selection--single .select2-selection__arrow b {
  display: none;
}

.select2-container--default .select2-selection--single .select2-selection__arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  right: 14px;
}

.select2-container--default .select2-selection--single .select2-selection__arrow::after {
  content: '\f078'; /* chevron-down */
  font-family: 'Font Awesome 6 Free', 'Font Awesome 5 Free', sans-serif;
  font-weight: 900;
  font-size: 11px;
  color: var(--text-secondary);
}

/* ตอนเปิด — Select2 ตัดมุมล่างของช่องให้เอง ซึ่งไม่เข้ากับทรงของ design */
.select2-container--open .select2-selection--single {
  border-color: var(--border-active);
  border-radius: var(--radius-input);
}

/* ── 🔴 ห้ามให้กรอบเขียวตอนกรอกผ่าน — design ไม่มีสถานะนี้ ──
   `woocommerce.css` เขียนไว้ว่า
   `.woocommerce form .form-row.woocommerce-validated
    .select2-container:not(.select2-container--open) .select2-selection`
   ซึ่งนับ specificity ได้ **(0,6,1)** — argument ใน `:not()` นับเป็น class ด้วย
   กฎเดิมของเราที่ไม่มี `:not()` อยู่แค่ (0,5,1) จึงแพ้ตลอด
   นี่คือสาเหตุที่ "กรอบเขียว" ไม่ยอมหายทั้งที่ถอดกฎของเราออกไปแล้ว */
.woocommerce form .form-row.woocommerce-validated .select2-container:not(.select2-container--open) .select2-selection,
.woocommerce form .form-row.woocommerce-validated .select2-container:not(.select2-container--open) .select2-selection--single {
  border-color: rgba(var(--text-primary-rgb), 0.12);
}

/* ── กล่อง dropdown (ต่อไว้ที่ <body>) ── */
.select2-dropdown,
.select2-container--default .select2-dropdown,
.select2-container--open .select2-dropdown {
  background: var(--bg-primary);
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  border-radius: 12px;
  color: var(--text-primary);
  overflow: hidden;
}

.select2-container--default .select2-results__options {
  background: transparent;
}

.select2-container--default .select2-search--dropdown {
  padding: 10px;
}

.select2-container--default .select2-search--dropdown .select2-search__field {
  background: transparent;
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  border-radius: var(--radius-input);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 13px;
  padding: 10px 14px;
  outline: none;
}

.select2-container--default .select2-results__option {
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font);
  font-size: 13px;
  padding: 10px 16px;
}

.select2-container--default .select2-results__option--highlighted,
.select2-container--default .select2-results__option--highlighted[aria-selected] {
  background: rgba(var(--text-primary-rgb), 0.10);
  color: var(--text-primary);
}

.select2-container--default .select2-results__option[aria-selected='true'],
.select2-container--default .select2-results__option[data-selected='true'] {
  background: rgba(var(--grad-2-rgb), 0.16);
  color: var(--text-primary);
}

/* แถบเลื่อนในกล่องผลลัพธ์ */
.select2-container--default .select2-results > .select2-results__options {
  max-height: 260px;
  scrollbar-width: thin;
  scrollbar-color: rgba(var(--text-primary-rgb), 0.25) transparent;
}

/* ============================================================
   🔴 ซ่อน radio วิธีชำระเงินโดยไม่ให้โผล่ตอน focus

   `wc-blocks.css` (โหลดทุกหน้าที่มี WooCommerce) มีกฎ
   `.screen-reader-text:focus { clip: auto !important; display: block;
    left: 5px; top: 5px; z-index: 100000; background: #fff; padding: 15px 23px }`
   ซึ่งออกแบบมาให้ลิงก์ "ข้ามไปที่เนื้อหา" โผล่ตอนกด Tab

   แต่ radio วิธีชำระเงินก็เคยใช้คลาสนี้ซ่อนอยู่ → พอกดป้ายเพื่อเลือกวิธีจ่าย
   radio ได้ focus แล้ว **โผล่เป็นกล่องขาวลอยมุมบนซ้ายของหน้า**
   และเบราว์เซอร์ต้องเลื่อนไปหา element ที่ focus → **หน้าเด้งขึ้น top**

   = สาเหตุเดียวของทั้งสองอาการที่ไล่แก้กันมาหลายรอบ
   (ไม่ใช่ `$.scroll_to_notices` — ตัวนั้นก็มีจริงแต่คนละกรณี)

   `es-sr-only` ซ่อนแบบเดียวกันแต่ไม่มีกฎ `:focus` มาเปิดเผย
   ============================================================ */

.es-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* คีย์บอร์ดยังต้องเห็นว่าตอนนี้อยู่ที่วิธีไหน — ย้ายกรอบโฟกัสไปที่ป้าย
   ใช้ `+` ได้เพราะ template วาง `<label>` ต่อจาก `<input>` ทันที */
.payment-method input.es-sr-only:focus-visible + label {
  outline: 2px solid var(--border-active);
  outline-offset: 4px;
  border-radius: 8px;
}

/* ── textarea: มุมโค้ง 15px (ผู้ใช้สั่ง 2026-08-10) ──
   `--radius-input` เป็นทรงแคปซูลสำหรับช่องบรรทัดเดียว พอเอามาใช้กับกล่อง
   หลายบรรทัดที่ลากขยายได้ มุมจะดูบวมผิดรูป

   ⚠️ **ที่เดียวจบ** — เคยมีสองก้อนในไฟล์นี้ตั้ง 8px เท่ากันแล้วแก้ไปทีละก้อน
   จนไม่รู้ว่าตัวไหนมีผลจริง รวมมาไว้ที่นี่แล้ว
   ต้องระบุ `#order_comments` ด้วย เพราะ WooCommerce ไม่ได้ใส่คลาสอะไรให้ */
.woocommerce textarea,
.woocommerce #order_comments,
textarea.form-input,
textarea.input-text,
.dokan-dashboard-content textarea,
.input-wrapper .form-input.form-textarea,
.form-group .form-input.form-textarea {
  border-radius: 15px!important;
}

/* ก้อน `.form-textarea` ของ design ตั้ง 20px ไว้แบบ `!important` (บรรทัด ~2466)
   จึงต้องทวงคืนด้วย `!important` เท่ากัน ไม่งั้น textarea ในโปรไฟล์กับ
   dashboard จะยังเป็น 20px อยู่ช่องเดียวที่ไม่เท่าที่อื่น */
.input-wrapper .form-input.form-textarea,
.form-group .form-input.form-textarea {
  border-radius: 15px !important;
}

/* ============================================================
   หน้าคำสั่งซื้อ — สีชื่อสินค้าและไอคอน (ผู้ใช้สั่ง 2026-08-11)

   ให้เหมือนหน้าตะกร้าเป๊ะ ๆ: ชื่อสินค้าขาวธรรมดา → ฟ้าเมื่อ hover
   ไอคอนข้อมูล (ร้าน / ขนส่ง) เป็นชมพู --grad-2 เหมือน .cart-shipping-header i

   ครอบทั้งหน้ารายการ (.order-card) และหน้ารายละเอียด (.payment-*)
   ทุกแท็บ เพราะใช้ markup ชุดเดียวกันหมด
   ============================================================ */

/* ── ชื่อสินค้า ── */
.order-card__product-info h4 a,
.order-card__product-info-left h4 a,
.payment-product__info h4 a {
  color: var(--text-primary);
  font: inherit;
  text-decoration: none;
  transition: color 0.2s;
}

/*
 * ⚠️ ต้องล้างไล่สีของ `a:hover` (styles.css:197 — กับดักข้อ 6) ด้วย
 * ไม่งั้นตัวหนังสือโปร่งใสแล้วไล่สีทับ ไม่ได้สีฟ้าเรียบอย่างที่สั่ง
 *
 * กฎนี้ต้องอยู่ **ท้ายไฟล์** เพราะมีกฎเดิมที่ specificity เท่ากัน
 * (บล็อก a:hover รวมที่บรรทัด ~1516) สั่งให้ hover เป็นสีขาว — ตัวหลังชนะ
 */
.order-card__product-info h4 a:hover,
.order-card__product-info-left h4 a:hover,
.payment-product__info h4 a:hover {
  color: var(--grad-4);
  -webkit-text-fill-color: var(--grad-4);
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

/* ── ไอคอนข้อมูล ──
   ไอคอนหัวข้อและป้ายบอกข้อมูลทั้งหมดในหน้าคำสั่งซื้อ ทั้งฝั่งผู้ซื้อและผู้ขาย
   ทั้งหน้ารายการและหน้ารายละเอียด

   ⚠️ **ไอคอนใต้ชื่อสินค้า (บริษัทขนส่ง) ไม่รวมอยู่ในนี้** — ผู้ใช้สั่งให้คงสีเดิมไว้
   (`.order-card__shipping i` / `.payment-product__shipping i`)

   ⚠️ **ตั้งใจไม่แตะ** ไอคอนในแถบนับถอยหลัง (.order-card__timer / .payment-timer)
   และไอคอนในปุ่ม (.vendor-action-btn / .btn-return-plain / .order-tracking-btn)
   สองกลุ่มนั้นอยู่บนพื้นสีของตัวเองและใช้สีบอกสถานะอยู่แล้ว
   ถ้าบังคับเป็นชมพูจะอ่านไม่ออกและเสียความหมาย */
.order-card__vendor-wrap i,
.order-card__buyer-info > i,
.payment-vendor__wrap i,
.payment-vendor__header h3 i,
.payment-shipping-address h3 i,
.order-detail-payment-method h3 i,
.return-status-box > h3 i {
  color: var(--grad-2);
}

/* ============================================================
   กล่องแจ้งเลขพัสดุ + dropdown บริษัทขนส่งที่มีไอคอน (2026-08-11)

   กล่องยืมโครงจาก .avatar-cropper (กล่องตัดรูปโปรไฟล์) ทั้งพื้นหลัง
   ปุ่ม และการจัดวาง — ผู้ใช้สั่งให้ "เด้ง modal เหมือนเวลา crop รูป"
   ============================================================ */

.es-ship-modal__box {
  max-width: 420px;
  max-height: 88vh;
  overflow-y: auto;
  text-align: left;
}

.es-ship-modal__order {
  margin: -8px 0 14px;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--text-secondary);
}

/* หมายเหตุใบส่งด่วน/ส่งทั่วไป (2026-09-14) — .form-note มีแต่ระยะบน ของที่อยู่ถัดลงมา (รูปสินค้า · ช่องเลือกขนส่ง) เลยติดกล่อง */
/* 🔴 ต้องมี .es-ship-modal__box นำหน้า — `.form-note { margin: 8px 0 0 }` อยู่ท้ายไฟล์ (specificity เท่ากัน มาทีหลังชนะ)
   รอบแรกเขียน .es-ship-modal__express เดี่ยว ๆ บนเว็บจริงหมายเหตุยังติดรูปสินค้า */
.es-ship-modal__box .es-ship-modal__express,
.return-status-box > .form-note {
  margin: 0 0 14px;
}

/* ปุ่มคัดลอกที่อยู่ไปวางในแอปขนส่ง (2026-09-14) — ใช้ทรง .tracking-copy-btn เดิม */
.es-address-copy {
  align-self: flex-start;
  margin-top: 8px;
}

/* ที่อยู่ร้านสำหรับส่งของคืน — ขึ้นหลังผู้ขายอนุมัติคำขอคืนแล้วเท่านั้น */
.es-return-address {
  display: flex;
  flex-direction: column;
  margin: 12px 0;
  padding: 10px 12px;
  border-radius: 10px;
  background: rgba(var(--text-primary-rgb), 0.05);
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.es-return-address p {
  margin: 0;
}

.es-return-address .es-return-address__label {
  margin-bottom: 2px;
  font-weight: 600;
  color: var(--text-primary);
}

.es-ship-modal__items {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 14px;
}

.es-ship-modal__item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.es-ship-modal__item img {
  width: 44px;
  height: 44px;
  border-radius: 8px;
  object-fit: cover;
  flex-shrink: 0;
}

.es-ship-modal__item-info h4 {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-primary);
}

.es-ship-modal__item-info span {
  font-size: 12px;
  color: var(--text-secondary);
}

.es-ship-modal__address {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 16px;
  padding: 10px 12px;
  border-radius: 10px;
  background: rgba(var(--text-primary-rgb), 0.05);
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.es-ship-modal__address strong {
  font-size: 13px;
  letter-spacing: 0.03em;
  color: var(--grad-2);
}

.es-ship-modal__field {
  display: block;
  margin-bottom: 12px;
}

/* ป้ายกำกับในกล่องต้องอ่านเป็นชุดเดียวกับ `.form-label` ของฟอร์มหน้าอื่น
   (styles.css:569 — 13px / letter-spacing 0.03em / สีตัวอักษรหลัก) */
.es-ship-modal__field > span {
  display: block;
  margin-bottom: 8px;
  padding-left: 2px;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.03em;
  color: var(--text-primary);
}

/*
 * ⚠️ กรอบตอน focus ต้องเป็นสีเดียวกับทุกหน้า
 *
 * `dokan-tailwind.css` ใส่กฎ
 *   :is(input:where([type=text]), …):focus { border-color:<น้ำเงิน>; box-shadow:<ring> }
 * ซึ่ง `:where()` ไม่นับ specificity แต่ `:focus` นับ → รวมเป็น (0,1,1)
 * ชนะ `.form-input:focus` (0,1,0) ของ design ทุกช่องในหน้า dashboard
 * จึงต้องระบุชื่อ element เพิ่มให้ specificity เท่ากัน (ไฟล์นี้โหลดทีหลังจึงชนะ)
 */
input.form-input:focus,
textarea.form-input:focus,
select.form-input:focus {
  border-color: var(--border-active);
  box-shadow: none;
  outline: none;
  --tw-ring-shadow: 0 0 #0000;
  --tw-ring-offset-shadow: 0 0 #0000;
}

.es-ship-modal__error {
  margin: 0 0 4px;
  font-size: 12px;
  color: #e5484d;
}

/* "ยังไม่ได้แนบรูปหลักฐาน" ในฟอร์มขอคืนสินค้า (assets/js/return-form.js) */
.es-return-image-error {
  margin: 10px 0 0;
  font-size: 13px;
  color: #e5484d;
}

/* ── dropdown ที่มีไอคอนหน้าตัวเลือก (assets/js/icon-select.js) ──
   ใช้ร่วมกัน 3 ที่: บริษัทขนส่ง · ธนาคารรับเงินคืน · เปิด/ปิดร้านรายวัน */

/*
 * ⚠️ `.input-wrapper` ของ design เป็น `display: flex` (styles.css:577)
 * กล่องนี้จึงกลายเป็น flex item ที่กว้างเท่าเนื้อหา ไม่ใช่เต็มบรรทัด
 * ต้องสั่ง flex-basis เอง ไม่งั้น dropdown จะสั้นกว่าช่องกรอกอื่นในฟอร์ม
 */
.icon-select {
  position: relative;
  flex: 1 1 100%;
  width: 100%;
  min-width: 0;
}

/*
 * ⚠️ ซ่อน <select> ตัวจริงด้วย opacity/ขนาด ไม่ใช่ `display: none`
 * เพราะช่องที่ `display: none` จะไม่ถูกตรวจ `required` และ browser
 * จะฟ้อง "not focusable" ตอน submit ฟอร์มในหน้ารายละเอียด
 */
.icon-select__native {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  pointer-events: none;
}

/*
 * ⚠️ ระบุสองคลาส (0,2,0) เพื่อกันกฎของ Dokan/WooCommerce ที่ยิงใส่
 * `button` หรือ `.form-input` ในหน้า dashboard มาเปลี่ยน display
 * ถ้า display หลุดจาก flex เมื่อไหร่ <span> ข้างในจะตกไปอยู่บรรทัดใหม่ใต้โลโก้
 * (เคยเกิดในหน้ารายละเอียดออเดอร์ ทั้งที่ในกล่อง modal ปกติดี)
 */
.icon-select .icon-select__button {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  cursor: pointer;
}

/* ชื่อต้องอยู่กึ่งกลางตามแนวตั้งเทียบกับโลโก้ ไม่ใช่ลอยตามเส้นฐานตัวอักษร
   ใช้ line-height เท่าความสูงไอคอนแทน display:flex — กล่องบล็อกธรรมดา
   ทำให้ text-overflow: ellipsis ทำงานจริง (ในกล่อง flex ใช้ไม่ได้) */
.icon-select__button > span,
.icon-select__option > span {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  line-height: 24px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.icon-select__placeholder {
  color: var(--text-secondary);
}

.icon-select__caret {
  flex-shrink: 0;
  margin-left: auto;
  font-size: 12px;
  color: var(--text-secondary);
}

.icon-select__list {
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 260px;
  overflow-y: auto;
  margin: 0;
  padding: 6px;
  list-style: none;
  border-radius: 12px;
  /*
   * ⚠️ ต้องเป็นพื้นดำ ไม่ใช่ `--bg-card` (#1a1a2e น้ำเงินเข้ม)
   * ตัวช่องกรอกในฟอร์มเป็นพื้นโปร่งบนพื้นดำของหน้า รายการที่กางออกมา
   * จึงต้องเป็นดำตามให้เป็นชุดเดียวกัน
   */
  background: var(--bg-primary);
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
}

/*
 * ⚠️ **นี่คือต้นเหตุที่ชื่อบริษัทขนส่งเคยตกไปอยู่บรรทัดใหม่ใต้โลโก้**
 *
 * กฎ reset ของเราเองที่ช่วง "โครงหลัก" ด้านบน
 *   .dokan-dashboard .dokan-dashboard-content ul li { display: list-item; padding: 0 }
 * มี specificity (0,2,2) ชนะคลาสเดี่ยว รายการที่กางออกมาจึงกลายเป็น list-item
 * แล้ว <span> ข้างในซึ่งเป็นบล็อกก็ตกลงไปบรรทัดถัดจาก <img>
 * ในกล่อง modal ไม่เป็น เพราะกล่องนั้นต่อไว้ที่ <body> อยู่นอก .dokan-dashboard-content
 *
 * ต้องดันให้เกิน (0,2,2) → ใช้ 3 คลาส + 1 element
 */
.icon-select .icon-select__list li.icon-select__option {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  margin: 0;
  border-radius: 8px;
  font-size: 13px;
  color: var(--text-primary);
  cursor: pointer;
}

/* hover = ชมพู (`--grad-1`) เหมือนกันทั้งเว็บ — ผู้ใช้สั่ง 2026-08-17
   ของเดิมเป็นฟ้า `--grad-2` ซึ่งไม่ตรงกับสีเน้นของธีมที่ใช้ที่อื่น */
.icon-select .icon-select__list li.icon-select__option:hover,
.icon-select .icon-select__list li.icon-select__option:focus-visible {
  background: rgba(var(--grad-1-rgb), 0.22);
  color: var(--text-primary);
}

/* ตัวที่เลือกอยู่ — จางกว่า hover เพื่อให้ยังแยกออกตอนเลื่อนเมาส์ผ่าน */
.icon-select .icon-select__list li.icon-select__option.is-selected {
  background: rgba(var(--grad-1-rgb), 0.10);
}

/* ตัวเลือกที่ปิดไว้ (<option disabled>) — เห็นได้แต่กดไม่ได้
   เช่น ขนส่งด่วนในใบที่ผู้ซื้อเลือกส่งทั่วไป (2026-09-14) · ต้องชนะ :hover ข้างบน */
.icon-select .icon-select__list li.icon-select__option.is-disabled,
.icon-select .icon-select__list li.icon-select__option.is-disabled:hover {
  opacity: 0.45;
  cursor: not-allowed;
  background: transparent;
}

/* 🔴 **ความสูงต้องเท่าช่อง text/number เป๊ะ ๆ**
   (ผู้ใช้แจ้ง 2026-08-17 ว่า dropdown ทั้งเว็บดูสูงกว่าช่องกรอกอื่น)

   คิดจาก `.form-input`: padding 14+14 · ตัวอักษร 13px (line-height ปกติ ~16px)
   · เส้นขอบ 1.5×2 = **47px**
   ปุ่มนี้เนื้อในสูง 20px (ไอคอน/บรรทัด) จึงต้องลด padding เหลือ 12+12
   → 12+12+20+3 = 47px เท่ากันพอดี

   ⚠️ padding ซ้าย-ขวาต้องคง 20px ไว้ให้ตรงกับช่องอื่น ไม่งั้นตัวหนังสือ
   ในแถว 2 คอลัมน์จะเยื้องกันเห็นชัด · ต้องมี !important สู้
   `.form-group .form-input { padding: 14px 20px !important }` */
.icon-select .icon-select__button.form-input {
  padding: 12px 20px !important;
}

.icon-select__icon {
  width: 20px;
  height: 20px;
  object-fit: contain;
  flex-shrink: 0;
}

.icon-select__button > span,
.icon-select__option > span {
  line-height: 20px;
}

/* ไอคอนแบบฟอนต์ (ธนาคาร) — กล่องสี่เหลี่ยมมนเท่ากับไอคอนแบบรูป */
.icon-select__icon--font {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  line-height: 1;
  border-radius: 5px;
  color: #fff;
  overflow: hidden;
}

/* ธนาคารที่ฟอนต์ thbanks ไม่มีโลโก้ให้ (พร้อมเพย์) ใช้ไอคอนทั่วไปแทน */
.icon-select__icon--font:not([class*="thbanks-"]) {
  color: var(--grad-2);
  font-size: 16px;
}

/* ── รูป + ชื่อร้านบนหัว dashboard = ทางไปหน้าโปรไฟล์ร้านสาธารณะ ──
   (template-parts/vendor/dashboard-store-header.php)

   `a.store-picture` ต้องสั่ง display เอง — <a> เป็น inline ตามค่าเริ่มต้น
   ความกว้าง/สูงที่ store.css ตั้งไว้จะไม่มีผลเลยถ้าไม่แปลงเป็น block */
a.store-picture {
  display: block;
  overflow: hidden;
}

/*
 * 🔴 กดได้เฉพาะตัวชื่อ ไม่ใช่ทั้งบรรทัด (ผู้ใช้แจ้ง 2026-09-21: hover ที่ว่างข้างชื่อร้านแล้วเมาส์เป็นรูปมือ + ชื่อจางลง)
 * store.css ของ design ใส่ cursor: pointer + opacity ตอน hover ไว้ที่ <h2 class="store-name"> ซึ่งกว้างเต็มแถว
 * (prototype ใช้ JS ดักคลิกทั้งกล่อง — store.js ไม่ได้โหลดในธีม ลิงก์จริงคือ <a> ข้างใน)
 * → ถอดออกจากกล่อง ปล่อยให้ <a> เป็นตัวเดียวที่กดได้ (ไม่แตะ store.css ตามกฎโปรเจ็ค)
 */
.store-name {
  cursor: auto;
}

.store-name:hover {
  opacity: 1;
}

.store-name a {
  cursor: pointer;
}

/* ปกติชื่อร้านต้องเป็นสีตัวอักษรปกติ ไม่ใช่สีลิงก์ (`a { color: var(--grad-4) }`) */
.store-header .store-name a {
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-decoration: none;
}

/*
 * hover แล้วชื่อร้านไล่สี — เอฟเฟกต์เดียวกับลิงก์ทั่วเว็บ (`a:hover` styles.css:196)
 * ยกมาเขียนซ้ำเพราะต้องให้ **การ hover ที่รูป** ทำให้ชื่อไล่สีด้วย
 * (ตัวเลือก `a.store-picture:hover + .store-info …` ใช้กฎของ styles.css ไม่ได้)
 *
 * ⚠ ผูกไว้กับรูปกับชื่อเท่านั้น ไม่ใช่ทั้งแถว — ผู้ใช้สั่งไว้ชัด (2026-08-11)
 */
.store-header .store-name a:hover,
a.store-picture:hover + .store-info .store-name a {
  color: transparent;
  background: linear-gradient(90deg,
    var(--grad-1) 0%,
    var(--grad-2) 12.5%,
    var(--grad-3) 25%,
    var(--grad-4) 37.5%,
    var(--grad-1) 50%,
    var(--grad-2) 62.5%,
    var(--grad-3) 75%,
    var(--grad-4) 87.5%,
    var(--grad-1) 100%
  );
  background-size: 200% 100%;
  background-position: 0% 50%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: gradient-slide 1.5s linear infinite;
}

a.store-picture:hover img {
  opacity: 0.85;
}

/* ============================================================
   ปุ่มบนหัวโปรไฟล์ / หัวร้าน (ผู้ใช้สั่ง 2026-08-11)
   ============================================================ */

/*
 * EDIT PROFILE ต้องขนาดเท่า EDIT STORE เป๊ะ ๆ
 * design ตั้งไว้ต่างกันเล็กน้อย — profile.css:47 (padding 7px / 12px)
 * กับ store.css:86 (padding 8px / 11px) ยึดของหน้าร้านเป็นหลักตามที่สั่ง
 */
/*
 * ⚠️ `.profile-actions` เป็น flex (บรรทัด ~3847) ปุ่มจึงถูกบีบให้แคบกว่า
 * `width: 120px` ที่ design ตั้งไว้ได้ เพราะ flex-shrink ค่าเริ่มต้นคือ 1
 * "EDIT PROFILE" ยาวกว่า "EDIT STORE" เลยตกบรรทัดใหม่
 */
.btn-edit-profile {
  padding: 8px 10px;
  font-size: 11px;
  flex-shrink: 0;
  white-space: nowrap;
}

/* แถวปุ่มบนหัวร้าน — EDIT STORE + LOGOUT */
.store-header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* ปุ่มออกจากระบบชิดขวาสุดของแถว เหมือนหัวโปรไฟล์ฝั่งผู้ซื้อ */
.store-header-actions a.btn-logout {
  margin-inline-start: auto;
}

.store-header-actions .btn-edit-store {
  flex-shrink: 0;
}

/* ============================================================
   บรรทัดบริษัทขนส่งใต้ชื่อสินค้า + ปุ่มคัดลอกเลขพัสดุ (2026-08-12)

   ผู้ใช้สั่งให้ทุกจุดที่บอกชื่อบริษัทขนส่งใช้ **โลโก้จริง** แทนไอคอนรถ
   ตัววาดอยู่ที่ es_marketplace_carrier_line() (inc/shipping-providers.php)
   ============================================================ */

/* โลโก้กับชื่อต้องอยู่กึ่งกลางตามแนวตั้งเทียบกัน ไม่ใช่ลอยตามเส้นฐานตัวอักษร */
.order-card__shipping,
.payment-product__shipping {
  display: flex;
  align-items: center;
  gap: 6px;
}

.order-card__shipping .carrier-icon,
.payment-product__shipping .carrier-icon {
  flex-shrink: 0;
}

/*
 * ปุ่มคัดลอกเลขพัสดุตอนคัดลอกสำเร็จ — เขียวทั้งตัวอักษรและกรอบ
 * design เซ็ต `color: #10b981` ตรง ๆ (profile.js:420) ที่นี่ใช้ตัวแปรเดียวกับ
 * ปุ่มคัดลอกลิงก์ร้าน (`.store-profile-link.is-copied`) จะได้เป็นชุดเดียวกันทั้งเว็บ
 */
.tracking-copy-btn.is-copied {
  color: var(--stat-success, #22c55e);
  background: rgba(var(--stat-success-rgb, 34, 197, 94), 0.12);
  border-color: rgba(var(--stat-success-rgb, 34, 197, 94), 0.35);
}

.tracking-copy-btn.is-copied i {
  color: var(--stat-success, #22c55e);
}

/*
 * 🔴 **หลักประกันว่ารายการที่กางออกมาปิดได้จริง**
 *
 * `[hidden]` มาจาก user-agent stylesheet ซึ่ง **แพ้กฎของธีม/ปลั๊กอินเสมอ**
 * ไม่ว่า specificity จะต่ำแค่ไหน — กฎอย่าง `.dokan-dashboard … ul li { display }`
 * หรือ `dokan-tailwind` ที่ยิงใส่ element กว้าง ๆ จึงทำให้ dropdown ปิดไม่ลงได้
 * (ผู้ใช้เจอในกล่องแจ้งเลขพัสดุ 2026-08-12 — เลือกขนส่งแล้วรายการยังค้างอยู่)
 *
 * ประกาศทับด้วย `!important` ที่นี่ที่เดียว ไม่ต้องไล่เดาว่ากฎไหนเป็นตัวชน
 */
.icon-select__list[hidden] {
  display: none !important;
}

/* ============================================================
   เก็บตกจากการไล่ดูหน้าจริงด้วยเบราว์เซอร์ (2026-08-12)
   ============================================================ */

/*
 * โลโก้บริษัทขนส่งใต้ชื่อสินค้า — เดิม 18px ซึ่งใหญ่กว่าตัวหนังสือข้าง ๆ
 * (การ์ด 11px · หน้ารายละเอียด 12px) เกือบเท่าตัว ผู้ใช้ทักว่าใหญ่เกินไป
 * design ใช้ไอคอนรถของ Font Awesome ซึ่งสูงเท่า font-size พอดี
 * ตั้ง 14px = อ่านโลโก้ออกแต่ไม่ข่มตัวหนังสือ
 *
 * `.carrier-icon` ตัวกลางยังเป็น 18px เหมือนเดิมสำหรับที่อื่น
 * (กล่องเลือกวิธีส่งของคืน ซึ่งตัวหนังสือใหญ่กว่า)
 */
.order-card__shipping .carrier-icon,
.payment-product__shipping .carrier-icon {
  height: 14px;
  max-width: 48px;
}

/*
 * 🔴 **ปุ่ม RETURN ตัวหนังสือหายตอน hover — กับดักข้อ 6 อีกครั้ง**
 *
 * `styles.css` มีกฎ `a:hover { color: transparent; background-clip: text }`
 * ไว้ทำตัวหนังสือไล่สีกับลิงก์ทั่วไป — design วาดปุ่มนี้เป็น `<button>`
 * แต่ของจริงต้องเป็น `<a>` เพราะพาไปหน้าฟอร์มขอคืนสินค้า จึงโดนกฎนั้นเต็ม ๆ
 *
 * `.btn-return-plain:hover` ที่มีอยู่แก้แค่ border กับ background **ไม่ได้แตะ color**
 * ตัวหนังสือจึงโปร่งใสโดยไม่มีไล่สีอะไรอยู่ข้างหลัง = หายไปทั้งคำ
 *
 * ต้องคืนทั้ง `color` และ `-webkit-text-fill-color` (Safari/Chrome อ่านตัวหลัง
 * เป็นตัวตัดสินเมื่อมี background-clip: text) — แพทเทิร์นเดียวกับที่ใช้กับ
 * ลิงก์ในกล่องแจ้งเตือนที่ท้ายไฟล์นี้
 */
a.btn-return-plain:hover,
a.btn-return-plain:focus {
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  background: rgba(var(--text-primary-rgb), 0.04);
  background-clip: border-box;
  -webkit-background-clip: border-box;
}

a.btn-return-plain:hover i,
a.btn-return-plain:focus i {
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
}

/*
 * แถบเตือน "เลยกำหนดส่งแล้ว" — ต้องอ่านออกว่าเป็นเรื่องด่วน ไม่ใช่แถบนับถอยหลังปกติ
 * (เพิ่ม 2026-08-12 หลังผู้ใช้ทักว่าเห็น "หมดเวลาในการจัดส่งสินค้า" แล้วไม่รู้ว่าต้องทำอะไรต่อ)
 */
.order-card__timer--warning,
.order-detail-timer--warning {
  color: #f87171;
  background: rgba(248, 113, 113, 0.12);
}

.order-card__timer--warning i,
.order-detail-timer--warning i {
  color: #f87171;
}

/* ============================================================
   แถบนับเวลาบนมือถือ — ข้อความไหลเป็นบรรทัดปกติ (ผู้ใช้แจ้ง 2026-09-16)
   *"ในมือถือ RWD ปรับตัวเลขนับเวลาแสดงผลบรรทัดไม่ตรงในส่วนของ order"*

   ต้นเหตุ: แถบเป็น `display:flex` (styles.css:2072 · 2785) ลูกคือ ไอคอน · <span>ข้อความ · <span>ตัวเลข (· <span>ข้อความท้าย)
   จอแคบข้อความยาวกว่าบรรทัด → **แต่ละ <span> กลายเป็นคอลัมน์ของตัวเอง** แล้วตัดบรรทัดในคอลัมน์
   เห็นเป็น "คุณมี / เวลา" | "14 วัน / 23:59:59" | "ในการให้คะแนนรีวิว / สินค้า" สามก้อนเรียงข้างกัน
   (แถบที่ `flex-wrap` ก็หล่นเป็นก้อน ๆ ไม่ต่อกันเป็นประโยค)

   แก้: จอ < 600px เปลี่ยนเป็นบล็อกข้อความธรรมดาจัดกลาง ไอคอนอยู่ในบรรทัดแรก
   ตัวเลขนับเวลา `nowrap` ไม่ให้ "14 วัน" กับ "23:59:59" แยกบรรทัดกัน
   แท็บเล็ต/เดสก์ท็อปไม่แตะ (ผู้ใช้บอกว่าดีแล้ว) · ครอบทุกแถบที่ใช้สองคลาสนี้:
   การ์ดคำสั่งซื้อผู้ซื้อ/ผู้ขาย · การ์ดคำขอคืน · หน้ารายละเอียด · หน้าชำระเงิน · หน้าขอบคุณ */
@media (max-width: 599px) {
  .order-card__timer,
  .payment-timer {
    display: block;
    text-align: center;
    line-height: 1.6;
    text-wrap: balance;
  }

  .order-card__timer > i,
  .payment-timer > i {
    margin-right: 6px;
    vertical-align: -1px;
  }

  .order-card__timer > span[class*="countdown"],
  .payment-timer > span[class*="countdown"] {
    white-space: nowrap;
  }
}

/* ── เก็บตกหน้าฟอร์มขอคืนสินค้า (2026-08-12) ── */

/*
 * โลโก้ขนส่งในรายการสินค้าที่จะขอคืน — เพิ่มคลาสนี้เข้าชุด 14px
 * ⚠️ ถ้าลืมใส่คลาสตอนเรียก es_marketplace_carrier_line() โลโก้จะออกมา
 * เท่าขนาดไฟล์จริง (150px) เพราะไม่มีกฎไหนคุม — เคยพลาดมาแล้วที่หน้านี้
 */
.return-product-item__shipping {
  display: flex;
  align-items: center;
  gap: 6px;
}

.return-product-item__shipping .carrier-icon {
  height: 14px;
  max-width: 48px;
  flex-shrink: 0;
}

/* ไอคอนหัวข้อในฟอร์มขอคืน ต้องเป็นสีแบรนด์เหมือนหัวข้ออื่นทั้งเว็บ
   (`.payment-shipping-address h3 i` / `.return-status-box > h3 i` ก็ใช้สีนี้)
   ของเดิม styles.css ตั้งเป็น --text-secondary ซึ่งจมไปกับพื้นหลัง */
.return-form-section h3 i {
  color: var(--grad-2);
}

/*
 * 🔴 **ห้ามใส่กรอบชมพูตอนโฟกัสช่องพิมพ์ข้อความ**
 *
 * กฎ `:focus-visible { outline: 2px solid var(--grad-2) }` ด้านบนตั้งใจทำไว้ให้
 * คนใช้คีย์บอร์ด แต่ **เบราว์เซอร์นับช่องพิมพ์ข้อความเป็น `:focus-visible` เสมอ
 * แม้จะคลิกด้วยเมาส์** (สเปกกำหนดไว้แบบนั้น เพราะช่องพิมพ์ต้องรู้ว่าตัวเองรับคีย์อยู่)
 * ผลคือทุกครั้งที่คลิกจะพิมพ์ จะมีวงชมพูล้อมทั้งช่อง — ผู้ใช้ทักว่าเน้นเกินไป
 *
 * ตัวบอกโฟกัสยังมีอยู่: `.form-input:focus` / `.form-textarea:focus`
 * เปลี่ยนสีกรอบจากขาว 12% เป็นขาว 40% ซึ่งเห็นชัดพอโดยไม่ตะโกน
 * ปุ่ม/ลิงก์/ช่องติ๊ก ยังมีวงชมพูเหมือนเดิม เพราะมันขึ้นเฉพาะตอนใช้คีย์บอร์ดจริง
 */
input:not([type='checkbox']):not([type='radio']):not([type='button']):not([type='submit']):focus-visible,
textarea:focus-visible {
  outline: none;
}

/*
 * ⚠️ **ตัดวงชมพูออกแล้วต้องมีตัวบอกโฟกัสอย่างอื่นแทนเสมอ**
 * ไม่งั้นคนที่ใช้คีย์บอร์ดจะไม่รู้เลยว่าเคอร์เซอร์อยู่ช่องไหน
 *
 * ประกาศที่ไฟล์นี้ (โหลดท้ายสุด) เพราะ `.form-textarea:focus` ใน styles.css
 * ไม่ได้ผลจริงบนหน้านี้ — ตรวจด้วยเบราว์เซอร์แล้วกรอบยังเป็นขาว 12% เท่าเดิม
 *
 * ใช้กรอบขาวเข้มขึ้น + เงาจาง ๆ รอบช่อง เห็นชัดว่าโฟกัสอยู่ตรงไหนโดยไม่ตะโกน
 */
.form-input:focus,
.form-textarea:focus,
input.form-input:focus,
textarea.form-textarea:focus,
select.form-input:focus {
  border-color: var(--border-active);
  box-shadow: 0 0 0 3px rgba(var(--text-primary-rgb), 0.08);
}

/* ── โลโก้ขนส่ง: กล่องกว้างคงที่ + ชื่อสินค้า hover สีฟ้า (2026-08-12) ── */

/*
 * **โลโก้ขนส่งเป็นรูปจัตุรัส — กล่องก็ต้องจัตุรัส**
 *
 * ตรวจไฟล์จริงแล้ว: 200×200 และ**เนื้อโลโก้กินเต็มกรอบ 198×198 ไม่มีขอบว่าง**
 * เป็นโลโก้ทรงป้ายสี่เหลี่ยมจัตุรัส ไม่ใช่โลโก้แนวนอน
 *
 * ⚠️ **เคยตั้ง `width: 34px` ไว้ ซึ่งผิด** — `object-fit: contain` ย่อรูปให้พอดี
 * ด้านที่คับกว่า (ความสูง 14px) ได้ภาพ 14×14 ชิดซ้าย **เหลือที่ว่างขวาอีก 20px**
 * กลายเป็นช่องว่างก่อนถึงชื่อบริษัท รูปจัตุรัสไม่มีทางเต็มกล่องที่กว้างกว่าได้
 *
 * ระยะห่างจากชื่อคุมด้วย `gap: 6px` ของ `.order-card__shipping` อย่างเดียวพอ
 */
.order-card__shipping .carrier-icon,
.payment-product__shipping .carrier-icon,
.return-product-item__shipping .carrier-icon {
  width: 14px;
  height: 14px;
  max-width: none;
  object-fit: contain;
}

/*
 * ชื่อสินค้าในการ์ด/หน้ารายละเอียด — hover แล้วเป็นฟ้า
 * ชุดเดียวกับชื่อสินค้าในตะกร้า (`.cart-item-name a:hover`) ที่ผู้ใช้อนุมัติไปแล้ว
 *
 * ⚠️ ต้องล้างไล่สีของ `a:hover` (กับดักข้อ 6) ให้ครบทุกบรรทัด
 * ไม่งั้นตัวหนังสือโปร่งใสแล้วไล่สีทับ ไม่ได้ฟ้าเรียบ
 * และต้องมาหลังกฎที่บรรทัด 1523 ซึ่งบังคับเป็นสีขาวอยู่
 */
.order-card__product-info h4 a:hover,
.order-card__product-info-left h4 a:hover,
.payment-product__info h4 a:hover {
  color: var(--grad-4);
  -webkit-text-fill-color: var(--grad-4);
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

/*
 * ชื่อสินค้าในฟอร์มขอคืนสินค้า — hover แล้วเป็นฟ้าเหมือนชื่อสินค้าที่อื่น
 *
 * ⚠️ **ไม่ทำเป็นลิงก์** ถึงที่อื่นจะเป็นลิงก์ก็ตาม — ทั้งก้อนอยู่ใน
 * `<label for="product-…">` ซึ่งคลิกแล้วติ๊ก checkbox เลือกสินค้าที่จะคืน
 * ถ้าใส่ `<a>` เข้าไป คลิกทีเดียวจะทั้งติ๊กและพาออกจากหน้าไปพร้อมกัน
 * (ปัญหา label activation ตัวเดียวกับ dropdown ขนส่ง)
 * ใช้ hover ที่ตัวป้ายแทน ได้ผลตอบสนองเหมือนกันโดยไม่ชนกัน
 */
.return-product-item__label:hover h4 {
  color: var(--grad-4);
}

.return-product-item__label h4 {
  transition: color 0.2s;
}

/* ── ระบบคืนสินค้า รอบ 2026-08-13 ── */

/*
 * ไอคอนหัวข้อ "ขั้นตอนการคืนสินค้า" ให้เป็นสีแบรนด์เหมือนหัวข้ออื่นทั้งเว็บ
 * (`styles.css` ตั้งเป็น --text-secondary ซึ่งจมไปกับพื้นหลัง)
 *
 * ⚠️ **ไม่แตะไอคอนในวงกลมของแต่ละขั้น** (`.step__circle i`) — สีตรงนั้นมีความหมาย
 * เขียว = ผ่านแล้ว · ขอบไล่สี = กำลังทำอยู่ · เทา = ยังไม่ถึง
 */
.return-status-header__title i {
  color: var(--grad-2);
}

/* กล่องข้อมูลการจัดส่ง (template-parts/shipping-info-box.php) */
.es-shipping-info__carrier {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 4px 0 0;
  color: var(--text-secondary);
}

.es-shipping-info__carrier .carrier-icon {
  width: 14px;
  height: 14px;
  max-width: none;
  object-fit: contain;
  flex-shrink: 0;
}

/* แถวเลขพัสดุในกล่องนี้ไม่ต้องมีพื้นหลังซ้อนอีกชั้น กล่องมีอยู่แล้ว */
.es-shipping-info__row {
  margin: 6px 0 0;
  padding: 0;
  background: none;
}

.es-shipping-info__last {
  margin-bottom: 0;
}

/* ── หน้าร้าน: อีเมล/เบอร์โทร + ป้ายเปิด-ปิดร้าน (2026-08-13) ── */

/* อยู่บรรทัดเดียวกันตามที่สั่ง แต่ตัดลงบรรทัดใหม่ได้เมื่อจอแคบ */
.store-profile-contact {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  margin-top: 6px;
}

.store-contact-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text-secondary);
  text-decoration: none;
  transition: color 0.2s;
}

.store-contact-btn i {
  font-size: 12px;
  color: var(--grad-2);
}

/* ⚠️ ต้องล้างไล่สีของ a:hover ด้วย (กับดักข้อ 6) — คลาสนี้ไม่มีคำว่า btn/button
   จึงไม่เข้ากฎกลางด้านบน */
.store-contact-btn:hover,
.store-contact-btn:focus {
  color: var(--grad-4);
  -webkit-text-fill-color: var(--grad-4);
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
}

.store-contact-btn:hover i,
.store-contact-btn:focus i {
  color: var(--grad-4);
  -webkit-text-fill-color: var(--grad-4);
}

/* ป้ายเปิด-ปิดร้าน วางเหนือคำอธิบายร้าน
   ⚠️ ทุกอย่างในหัวร้านจัดกึ่งกลาง ป้ายนี้เป็น inline-flex จึงต้องมีตัวห่อจัดให้
   ใช้ block + margin auto แทนการไปแก้ container ซึ่งกระทบของเดิม */
.store-open-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
}

.store-open-badge-wrap {
  text-align: center;
}

.store-open-badge--open {
  color: var(--stat-success, #22c55e);
  background: rgba(var(--stat-success-rgb, 34, 197, 94), 0.12);
}

.store-open-badge--closed {
  color: #f87171;
  background: rgba(248, 113, 113, 0.12);
}

/* ── ช่องกรอกโซเชียลแบบใส่แค่ชื่อผู้ใช้ + ไอคอนโซเชียลหน้าร้าน (2026-08-13) ── */

/* โดเมนเป็นป้ายติดหน้าช่อง ไม่ใช่ส่วนที่ต้องพิมพ์ */
.es-social-input {
  display: flex;
  align-items: stretch;
  gap: 0;
}

.es-social-prefix {
  display: flex;
  align-items: center;
  padding: 0 10px;
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  border-right: none;
  border-radius: var(--radius-input, 10px) 0 0 var(--radius-input, 10px);
  background: rgba(var(--text-primary-rgb), 0.05);
  font-size: 12px;
  white-space: nowrap;
  color: var(--text-secondary);
}

/*
 * ⚠️ ต้องตัด **ทั้งเส้นขอบซ้ายและมุมโค้งซ้าย** ของช่องกรอก
 * ไม่งั้นจะเห็นเส้นสองเส้นซ้อนกันตรงรอยต่อกับป้ายโดเมน และมุมโค้งค้างอยู่กลางกล่อง
 * (ผู้ใช้ทัก 2026-08-13 ว่า "แปลก ๆ")
 */
.es-social-input .form-input {
  /*
   * ⚠️ **ต้องมี `!important`** — ก้อน `.input-wrapper .form-input { border … !important }`
   * (บรรทัด ~2880 ที่ทำไว้สู้ dokan-tailwind) ใส่ !important กับทั้ง `border`
   * และ `border-radius` ไว้ กฎธรรมดาจึงแพ้ไม่ว่าจะ specificity สูงแค่ไหน
   */
  border-top-left-radius: 0 !important;
  border-bottom-left-radius: 0 !important;
  border-left: none !important;
}

/* ไอคอนโซเชียลหน้าร้าน — ใต้อีเมล/เบอร์โทร
   เว้นบน-ล่างเท่ากัน (ผู้ใช้สั่ง 2026-09-13) */
.store-profile-social {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin: 8px 0;
}

/* จอแคบให้ชิดซ้ายตามที่ผู้ใช้สั่ง (2026-08-13) — จอกว้างยังกึ่งกลางเหมือนเดิม */
@media (max-width: 768px) {
  .store-profile-social {
    justify-content: flex-start;
  }
}

.store-social-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid rgba(var(--text-primary-rgb), 0.14);
  color: var(--text-secondary);
  font-size: 13px;
  text-decoration: none;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}

/* ปุ่ม X วาดด้วย SVG ในหน้า (ดู dokan/store-header.php) ไม่ใช่ฟอนต์ไอคอน
   ต้อง display:block ไม่งั้นมีช่องว่างใต้เส้นฐานแล้ววงกลมเบี้ยว */
.store-social-btn svg {
  display: block;
  width: 1em;
  height: 1em;
}

/* ⚠️ ต้องล้างไล่สีของ a:hover เอง — คลาสนี้ไม่มีคำว่า btn/button จึงไม่เข้ากฎกลาง */
.store-social-btn:hover,
.store-social-btn:focus {
  color: var(--grad-2);
  -webkit-text-fill-color: var(--grad-2);
  border-color: var(--grad-2);
  background: rgba(var(--grad-2-rgb), 0.12);
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
}

/*
 * สวิตช์ "แสดงอีเมล / แสดงเบอร์โทร" บนหน้าตั้งค่าร้าน — สองคอลัมน์แล้วตกบรรทัดเอง
 * (ผู้ใช้สั่ง 2026-08-13)
 *
 * ใช้ grid `auto-fit` + `minmax` แทน media query — พอที่ไม่พอสำหรับสองคอลัมน์
 * มันจะยุบเหลือคอลัมน์เดียวให้เอง ไม่ต้องเดา breakpoint
 */
.es-toggle-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px 20px;
  align-items: center;
}

/* ส่งด่วนในพื้นที่ (2026-09-14) — ป้าย + คำอธิบายสั้นเป็นก้อนเดียวกันเต็มแถว
   ไม่ให้ไปเบียดคอลัมน์กับสวิตช์อีเมล/เบอร์โทร */
.es-toggle-row > .es-toggle-row__express,
.es-toggle-row > .form-note {
  grid-column: 1 / -1;
}

/*
 * ปุ่มหน้าขอบคุณ — design วาดเป็น <button> แต่ของจริงต้องเป็น <a>
 * (มีปลายทางจริง WordPress จึงต้องเป็นลิงก์ ไม่ใช่ปุ่ม onclick)
 *
 * ⚠️ <a> ที่เป็น flex item จะถูก blockify แล้วข้อความ **ชิดซ้าย**
 * ไม่เหมือน <button> ที่จัดกลางให้เอง — ต้องสั่ง justify-content เอง
 * และ inline-flex ยังทำให้ไอคอนหน้าข้อความเรียงตัวได้พอดีด้วย
 * (ผู้ใช้สั่งเพิ่มไอคอน 2026-08-13)
 */
.thankyou-actions > a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-decoration: none;
  text-align: center;
}

.thankyou-actions > a i {
  font-size: 0.95em;
  line-height: 1;
}

/*
 * ปุ่ม PAY NOW หน้า order-pay — ไอคอนเคยติดตัวอักษร
 *
 * ⚠️ ต้นเหตุคือ `letter-spacing: 0.12em` ของ `.payment-pay-btn` เอง
 * มันบีบ "เว้นวรรค" ระหว่างไอคอนกับข้อความให้แคบลงด้วย
 * เพิ่มเว้นวรรคซ้ำก็ไม่ช่วย — ต้องเลิกใช้ text node แล้วคุมด้วย gap ของ flex
 * (ผู้ใช้ทัก 2026-08-13) ระยะ 10px ชุดเดียวกับปุ่มหน้าขอบคุณ
 */
.payment-pay-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.payment-pay-btn i {
  font-size: 0.95em;
  line-height: 1;
}

/*
 * ให้ดาวสินค้าหลังคำสั่งซื้อสำเร็จ (2026-08-13)
 *
 * โครงหลักอยู่ใน styles.css ของ design แล้ว (.order-card__review-section /
 * .star-rating) ที่นี่เติมเฉพาะสิ่งที่ design ไม่มีเพราะเป็นตัวจำลอง
 */

/* design ใช้ inline style สีแดงกับป้าย "หมดเวลา" — ทำเป็นคลาสแทน */
.order-card__review-label--expired {
  color: var(--stat-cancelled, #ef4444);
  font-weight: 600;
}

/* ดาวที่ยังกดเลือกได้ ต้องดูรู้ว่ากดได้ (design ให้ cursor: pointer มาแล้ว
   แต่ไม่ได้แยกดาวที่กดได้ออกจากดาวอ่านอย่างเดียวด้วยสายตา) */
.star-rating[data-item] .star-rating__star {
  cursor: pointer;
}

/* แถวดาวเป็นลูกของ .payment-product__info ที่เป็น flex column อยู่แล้ว
   บนจอแคบป้ายกับดาวต้องไม่เบียดกันจนดาวตกขอบ */
@media (max-width: 420px) {
  .order-card__review-row {
    flex-wrap: wrap;
    row-gap: 4px;
  }
}

/*
 * ⚠️ **กับดักเดิมของ [hidden]** (เคยเจอกับ .icon-select__list มาแล้ว)
 * `hidden` ของ HTML ให้ `display: none` มาจาก UA stylesheet ซึ่ง **แพ้**
 * `display: flex` ที่ design ตั้งไว้ให้แถบเวลาและปุ่ม
 * JS ที่สั่ง `el.hidden = true` จึงไม่มีผลถ้าไม่มีกฎนี้
 */
.es-review-timer[hidden],
.order-review-btn[hidden] {
  display: none !important;
}

/*
 * ── ขนาดดาวให้เท่ากันทุกดวง (ผู้ใช้ทัก 2026-08-13 "ดาวมันบัคๆ ขนาดไม่ตรงกัน") ──
 *
 * ⚠️ **ต้นเหตุคือความกว้างของ glyph ไม่เท่ากัน** ไม่ใช่ font-size
 * Font Awesome ให้ `fas fa-star`, `fas fa-star-half-alt` และ `far fa-star`
 * มี advance width คนละค่า พอ JS สลับคลาสตอน hover แถวดาวจึงขยับซ้ายขวา
 * ทั้งแถว ดูเหมือนดาวเต้น — design ไม่ได้กันไว้เพราะเป็นแค่ต้นแบบนิ่ง ๆ
 *
 * ตรึงความกว้างเป็น 1em แล้วจัดกลาง สลับคลาสยังไงแถวก็ไม่ขยับ
 */
.star-rating__star {
  width: 1em;
  text-align: center;
  flex: 0 0 auto;
}

/* กันสั่นตอน hover — scale ของ design ทำให้ดวงที่ชี้อยู่ดันเพื่อนบ้าน
   ถ้าไม่ยกออกจาก flow ด้วย transform อย่างเดียว */
.star-rating__star:hover {
  will-change: transform;
}

/* ============================================================
   🔴 ชื่อคลาส `.star-rating` ชนกับของ WooCommerce เต็ม ๆ

   `woocommerce.css` มี `.woocommerce .star-rating` เป็น **วิดเจ็ตดาวแบบฟอนต์**
   ของมันเอง (`font-family: star` + `::before` วาดดาวห้าดวงเป็นตัวอักษร):

       float: right; overflow: hidden; position: relative;
       height: 1em; width: 5.4em; font-family: star;

   design ดันตั้งชื่อคลาสเดียวกันกับแถวดาวที่เป็น <i> ของ Font Awesome
   specificity `.woocommerce .star-rating` (0,2,0) **ชนะ** `.star-rating` (0,1,0)
   ของ design ทุกหน้าที่มีคลาส `woocommerce` ที่ <body> — ซึ่งคือหน้าบัญชี
   และ dashboard ทั้งหมด ผลคือ:

     • `height: 1em` + `overflow: hidden` → กล่องสูง 16px แต่ดาวสูง 18px **ถูกตัด**
       (นี่คือ "ขนาดไม่ตรงกัน" ที่ผู้ใช้ทัก)
     • `position: relative` + `::before` ของ WooCommerce ลอยทับ <i> ทั้งแถว
       → **hover/คลิกไม่โดนดาวเลย** โดนแต่กล่องครอบ
       (`document.elementFromPoint()` คืนค่า `.star-rating` ทุกจุด ยืนยันแล้ว)

   ⚠️ **ห้ามล้างทั้งเว็บ** — วิดเจ็ตของ WooCommerce ยังใช้จริงที่หน้าสินค้า
   และรายการสินค้า จำกัดขอบเขตด้วย `.order-card__review-row` ซึ่งเป็น
   กล่องที่แถวดาวของ design อยู่เท่านั้น
   ============================================================ */
.order-card__review-row .star-rating {
  float: none;
  overflow: visible;
  position: static;
  height: auto;
  width: auto;
  margin: 0;
  font-family: inherit;
  font-size: inherit;
  line-height: 1;
  letter-spacing: normal;
  text-indent: 0;
}

/* ดาวปลอมของ WooCommerce ที่วาดด้วย ::before — ตัวที่บังไม่ให้กดโดน */
.order-card__review-row .star-rating::before,
.order-card__review-row .star-rating > span::before {
  content: none;
  display: none;
}

/* ============================================================
   หน้าขอเปิดร้าน — ให้ตรง create-store.html
   ============================================================ */

/* ⚠ ฟอร์มนี้มีคลาส `register` ติดมาจาก Dokan จึงโดน
   `.woocommerce form.register { border:1px solid #cfc8d8; padding:20px;
    margin:2em 0; border-radius:5px }` ของ WooCommerce เต็ม ๆ
   (woocommerce.css — กับดักตัวเดียวกับหน้าเข้าระบบ ดูบรรทัด 2047)

   ค่าพวกนั้น specificity (0,2,1) ชนะ `.create-store-wrapper` (0,1,0) ของ design
   ทั้งชุด ผลคือได้กรอบเทา 1px, มุมโค้ง 5px แทน 20px, padding 20px แทน 24/20
   และที่ ≥769px `margin: 2em 0` ทับ `margin: 0 auto` ฟอร์มจึงไม่อยู่กลางจอ

   ต้องเขียน `.woocommerce form.register.create-store-wrapper` ให้ specificity
   สูงกว่า — เขียนแค่ `.create-store-wrapper` เฉย ๆ จะแพ้เงียบ ๆ โดยไม่มีอะไรฟ้อง

   🔁 ค่าทั้งหมดยกมาจาก assets/css/create-store.css ตรง ๆ แก้ที่นั่นต้องแก้ที่นี่ด้วย */
.woocommerce form.register.create-store-wrapper,
.woocommerce-account form.register.create-store-wrapper {
  border: 0;
  border-radius: 20px;
  padding: 24px 20px;
  /* design ใส่ `margin-bottom: 80px !important` ไว้ที่กฎฐาน มันจึงรอดจาก
     `margin: 0 auto` ของ media query ด้วย — รวมร่างเป็นค่าเดียวตรงนี้ */
  margin: 0 0 80px;
  background: var(--bg-primary);
}

@media (min-width: 769px) {
  .woocommerce form.register.create-store-wrapper,
  .woocommerce-account form.register.create-store-wrapper {
    max-width: 800px;
    margin: 0 auto 80px;
    padding: 40px 32px;
  }
}

/* หัวข้อ section มีไอคอนนำหน้าและเป็นสีชมพูของธีม (ผู้ใช้สั่ง 2026-08-15)
   design เป็นตัวหนังสือเทาเปล่า ๆ ซึ่งจมไปกับฟอร์ม */
.create-store-wrapper .profile-section-title {
  display: flex;
  align-items: center;
  gap: 8px;
}

.create-store-wrapper .profile-section-title i {
  color: var(--grad-1);
  font-size: 15px;
}

/* ปุ่มยืนยันในแถบล่าง — ไอคอนกับข้อความอยู่บรรทัดเดียวกัน */
.bottom-nav-container .btn-gradient {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

/* ── ลิงก์ร้าน ──
   ค่านี้แก้ไม่ได้หลังเปิดร้าน จึงต้องเตือนให้ชัดกว่า form-hint ธรรมดา
   ใช้ทั้งหน้าขอเปิดร้านและหน้าตั้งค่าร้าน (ช่องที่ disabled ไว้) */
.form-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 8px 0 0;
  padding: 9px 11px;
  border-radius: 8px;
  background: rgba(var(--text-primary-rgb), 0.05);
  border: 1px solid rgba(var(--text-secondary-rgb), 0.18);
  font-size: 12px;
  line-height: 1.65;
  color: var(--text-secondary);
}

.form-note i {
  flex: 0 0 auto;
  margin-top: 3px;
  font-size: 11px;
  color: var(--text-secondary);
}

/* ช่องที่แสดงอย่างเดียว (ประเภทร้าน · อีเมลบัญชี) — ต้องดูไม่เหมือนช่องที่กรอกได้ตั้งแต่แรกเห็น
   ผู้ใช้สั่ง 2026-09-13: ไม่มีกรอบ · กดไม่ได้ · พิมพ์ไม่ได้ → ดูเป็นข้อความธรรมดาใต้หัวข้อ
   🔴 ต้องมี pointer-events: none — ไม่งั้นแตะบนมือถือแล้วบางเครื่องยังขึ้นเคอร์เซอร์/แว่นขยาย
   🔴 กรอบ/พื้น/ระยะในต้องมี !important — ก้อน `.input-wrapper .form-input, .form-group .form-input`
      ของไฟล์นี้ตั้ง border + padding แบบ !important ไว้ ไม่งั้นแพ้เงียบ ๆ (เจอจากการวัดจริง 2026-09-13) */
.form-group--locked .form-input[disabled] {
  opacity: 1;
  cursor: default;
  pointer-events: none;
  -webkit-user-select: text;
  user-select: text;
  color: var(--text-secondary);
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  -webkit-text-fill-color: var(--text-secondary);
}

/* ผลการเช็คว่าลิงก์ร้านซ้ำหรือยัง — ว่างไว้ตอนยังไม่ได้เช็ค จึงต้องไม่กินที่ */
#es-shopurl-status:empty {
  display: none;
}

#es-shopurl-status.is-free {
  color: var(--stat-success, #22c55e);
}

#es-shopurl-status.is-taken {
  color: var(--stat-error, #ef4444);
}

/* สถานะชื่อร้านตอนพิมพ์ในตั้งค่าร้าน (inc/store-name.php · store-name-check.js)
   ทรงเดียวกับลิงก์ร้านตอนขอเปิดร้าน — ผู้ใช้สั่ง 2026-09-14 "อยากให้เหมือน url ร้านตอนตั้งตอนแรก" */
.es-store-name-status:empty {
  display: none;
}

.es-store-name-status.is-free {
  color: var(--stat-success, #22c55e);
}

.es-store-name-status.is-taken {
  color: var(--stat-error, #ef4444);
}

/* ── แถวชื่อร้าน + ประเภทร้าน (ผู้ใช้แก้คำสั่ง 2026-09-15) ──
   *"ประเภทร้านเอาไว้เป็น 2 column เหมือนเดิม ... พอเป็น desktop คำอธิบาย ... ต้องการให้มันสุด"*
   DOM: .es-store-name-group · .es-store-name-extra (สถานะ + ข้อความ) · .es-store-type-group
   จอเล็ก (store.css ให้ .form-row-2col เป็น flex แนวตั้ง) = ชื่อ → ข้อความ → ประเภท ตามลำดับ DOM
   จอใหญ่ ≥ 769px (จุดเดียวกับที่ store.css เปลี่ยนเป็น 2 คอลัมน์) = grid: ชื่อ | ประเภท แล้วข้อความเต็มแถวข้างล่าง
   ร้านเก่าที่ไม่มีประเภทร้าน ไม่มีคลาส form-row-2col → ชื่อร้านเต็มแถวตามปกติ */
.es-store-name-row > .es-store-name-group,
.es-note-row > .es-note-row__main {
  margin-bottom: 0;
}

.es-store-name-extra,
.es-note-row__extra {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 8px 0 18px;
}

.es-store-name-extra .form-note,
.es-note-row__extra .form-note {
  margin: 0;
}

/* แถวอื่นที่ใช้โครงเดียวกัน (อีเมลร้าน | เบอร์โทร · 2026-09-16) — ว่าง = ไม่เว้นที่ */
.es-note-row__extra:empty {
  display: none;
}

@media (min-width: 769px) {
  .es-store-name-row.form-row-2col,
  .es-note-row.form-row-2col {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 16px;
    row-gap: 0;
  }

  .es-store-name-row > .es-store-name-group,
  .es-note-row > .es-note-row__main {
    grid-column: 1;
    grid-row: 1;
  }

  /* `.es-store-name-side` = ช่องคู่ของชื่อร้านในหน้าขอเปิดร้าน (เบอร์โทร · 2026-09-16) */
  .es-store-name-row > .es-store-type-group,
  .es-store-name-row > .es-store-name-side,
  .es-note-row > .es-note-row__side {
    grid-column: 2;
    grid-row: 1;
    margin-bottom: 0;
  }

  .es-store-name-row > .es-store-name-extra,
  .es-note-row > .es-note-row__extra {
    grid-column: 1 / -1;
    grid-row: 2;
  }
}

/* ตัวอย่าง URL อาจยาวเกินจอมือถือ — ให้ตัดคำได้ ไม่ดันหน้าให้เลื่อนแนวนอน */
.create-store-wrapper .form-hint code {
  overflow-wrap: anywhere;
}

/* ── ช่องแนบเอกสารยืนยันตัวตน ──

   🔴 ปุ่มกับข้อความของ input[type=file] เป็นของเบราว์เซอร์ **เปลี่ยนคำไม่ได้**
   ทั้ง CSS และ `.mo` — ทั้งหน้าเป็นภาษาไทยแต่ช่องนี้ขึ้น "Choose File /
   No file chosen" (ผู้ใช้เจอ 2026-08-17)

   จึงคง input ไว้ในโฟลว์ (ห้าม `display:none` — `required` จะทำให้ Chrome
   ฟ้อง "not focusable" แล้วส่งฟอร์มไม่ได้) แต่ทำตัวอักษรกับปุ่มของมันให้หายไป
   แล้ววาดกล่องภาษาไทยทับด้วย <label for> ซึ่งกดแล้วเปิดหน้าต่างเลือกไฟล์ได้เอง */
.es-file {
  position: relative;
}

/* ⚠️ `opacity: 0` ไม่ใช่ `display: none` / `visibility: hidden`
   สองตัวหลังทำให้ Chrome ฟ้อง "An invalid form control is not focusable"
   แล้ว **ส่งฟอร์มไม่ได้เลย** เพราะช่องนี้ `required`
   (`color: transparent` เอาไม่อยู่ — ข้อความ "No file chosen" ของ Chrome
   ไม่ได้รับสีจาก `color` ของตัว input) */
.form-input.form-file {
  padding: 10px 12px;
  line-height: 1.4;
  cursor: pointer;
  opacity: 0;
}

/* กรอบของช่องย้ายมาอยู่ที่ label แทน เพราะตัว input โปร่งใสทั้งตัวไปแล้ว */
.es-file__box {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 12px;
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  border-radius: var(--radius-input);
  cursor: pointer;
}

.es-file__box:hover {
  border-color: rgba(var(--text-primary-rgb), 0.24);
}

/* โฟกัสด้วยคีย์บอร์ดยังไปตกที่ input จริง — สะท้อนออกมาที่กรอบที่คนเห็น */
.es-file__input:focus-visible + .es-file__box {
  border-color: var(--grad-2);
}

.es-file__btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid rgba(var(--text-secondary-rgb), 0.35);
  border-radius: 6px;
  background: rgba(var(--text-primary-rgb), 0.06);
  color: var(--text-primary);
  font-size: 12px;
  letter-spacing: 0.03em;
}

.es-file__box:hover .es-file__btn {
  border-color: rgba(var(--text-primary-rgb), 0.45);
  background: rgba(var(--text-primary-rgb), 0.1);
}

/* ชื่อไฟล์ยาวกว่ากล่องได้ง่าย — ตัดด้วย … ไม่ใช่ดันกล่องให้ล้น */
.es-file__name {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 13px;
  color: var(--text-secondary);
}

.es-file__name.has-file {
  color: var(--text-primary);
}

/* ขั้นตอนถัดไปในกล่อง "ส่งคำขอเรียบร้อย" — เป็นคำแนะนำ ไม่ใช่เนื้อความหลัก
   จึงต้องเบากว่าย่อหน้าบนแต่ยังอ่านออก */
.modal-content .modal-next-step {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 24px;
  padding: 10px 12px;
  border-radius: 8px;
  background: rgba(var(--text-primary-rgb), 0.05);
  border: 1px solid rgba(var(--text-secondary-rgb), 0.18);
  font-size: 12px;
  line-height: 1.65;
  text-align: left;
}

.modal-content .modal-next-step i {
  flex: 0 0 auto;
  margin-top: 3px;
  color: var(--grad-1);
}

/* ── โน้ตเหนือปุ่ม "รอแอดมินอนุมัติ" ในหน้าโปรไฟล์ ──
   ผู้ขายที่เพิ่งสมัครต้องรู้ว่าต้องรออะไรและนานแค่ไหน

   🔴 โน้ตต้องอยู่ **เหนือ** ปุ่ม ไม่ใช่ข้าง ๆ
   `.bottom-nav-container` เป็น `display:flex` แนวนอน (styles.css:1050)
   โน้ตกับปุ่มจึงกลายเป็นสองคอลัมน์เบียดกันเอง — แก้ด้วย `flex-wrap` บวก
   `width:100%` ที่ตัวโน้ต เพื่อดันปุ่มลงบรรทัดถัดไป
   (ใช้วิธีนี้แทน `:has()` เพราะได้ผลกับทุกเบราว์เซอร์ ไม่ต้องรอ support) */
.bottom-nav-container {
  flex-wrap: wrap;
}

/* ── ปุ่ม SHOP ในแถบล่าง (ผู้ใช้สั่ง 2026-09-16) ──
   ย้ายมาจากปุ่ม Market บนหัวเว็บ · วางซ้ายมือของ CREATE STORE / OPEN STORE / ADD NEW PRODUCT
   ปุ่มกลม **ไอคอนอย่างเดียว** (ร้าน + หมุด ชุดเดียวกับหัวเว็บเดิม — ผู้ใช้สั่ง "ไม่ต้องมีตัวหนังสือ")
   ขอบสีชมพูทึบ = สีซ้ายสุดของขอบไล่สีปุ่มหลัก (`--grad-1`)
   โครงขอบเหมือน `.btn-gradient` (`::before` inset -2px + `::after` ปิดพื้น) เส้นจึงหนาเท่ากันเป๊ะ

   ขนาด 48px = ความสูงจริงของปุ่มหลักในแถบล่าง (วัดที่จอ 320/360/480 ได้ 48 เท่ากัน)
   🔴 ปุ่มหลักทั้งสามตั้ง `width: 100%` — มี SHOP นำหน้าเมื่อไรต้องหดเป็น `flex: 1` ไม่งั้นตกบรรทัด
   เลือกด้วย `~` (SHOP พิมพ์ก่อนเสมอ) แทน `:has()`
   ⚠️ `#createStoreBtn` มี `margin-top: 20px` → SHOP ที่คู่กับปุ่มนี้ (`--store`) ต้องมีระยะบนเท่ากัน สองปุ่มจึงเสมอกัน
   (align-self: flex-end ไม่พอ — แถบ min-height 90px ยืดบรรทัด ปุ่มหล่นต่ำกว่ากันราว 11px วัดจริง) */
.bottom-nav-container .btn-bottom-shop {
  position: relative;
  z-index: 1;
  isolation: isolate;
  flex: 0 0 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  margin: 0 12px 0 2px;
  padding: 0;
  border-radius: 50%;
  background: var(--bg-primary);
  color: var(--text-primary);
  text-decoration: none;
  transition: box-shadow 0.3s;
}

.bottom-nav-container .btn-bottom-shop--store {
  margin-top: 20px;
}

.bottom-nav-container .btn-bottom-shop::before {
  content: '';
  position: absolute;
  inset: -2px;
  z-index: -1;
  border-radius: inherit;
  background: var(--grad-1);
}

.bottom-nav-container .btn-bottom-shop::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--bg-primary);
}

/* กับดักข้อ 6 — a:hover ของ design ทำตัวอักษรโปร่งใส (background-clip: text) ไอคอนเป็นตัวอักษร จะหาย */
.bottom-nav-container .btn-bottom-shop:hover,
.bottom-nav-container .btn-bottom-shop:focus-visible {
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
  box-shadow: 0 0 12px 3px rgba(var(--grad-1-rgb), 0.28);
}

/* ไอคอนร้าน + หมุดมุมขวาล่าง — ตัวเลขชุดเดียวกับ `.btn-shop` บนหัวเว็บ ขยายตามปุ่มที่ใหญ่กว่า (42 → 48) */
.bottom-nav-container .btn-bottom-shop .es-market-icon .fa-shop {
  font-size: 17px;
}

.bottom-nav-container .btn-bottom-shop .es-market-icon .fa-location-dot {
  right: -6px;
  bottom: -3px;
  font-size: 9px;
}

.bottom-nav-container .btn-bottom-shop ~ #createStoreBtn,
.bottom-nav-container .btn-bottom-shop ~ .btn-add-new-product {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
  white-space: nowrap;
}

/* จอ 320 (แถบ 288) — "ADD NEW PRODUCT" (243px) ยังเกินราว 14px → บีบระยะตัวอักษรเฉพาะตอนมี SHOP นำหน้า */
@media (max-width: 359px) {
  .bottom-nav-container .btn-bottom-shop ~ #createStoreBtn,
  .bottom-nav-container .btn-bottom-shop ~ .btn-add-new-product {
    letter-spacing: 0.06em;
  }
}

.store-pending-note {
  width: 100%;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 10px;
  padding: 10px 12px;
  border-radius: 8px;
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.2);
  font-size: 12px;
  line-height: 1.65;
  color: var(--text-secondary);
  text-align: left;
}

.store-pending-note i {
  flex: 0 0 auto;
  margin-top: 2px;
  color: rgb(245, 158, 11);
}

/* ── ร้านถูกระงับ / คำขอถูกปฏิเสธ ──
   ใช้กล่องเดียวกับสถานะรออนุมัติแต่เป็นโทนแดง — สองสถานะนี้เป็นข่าวร้าย
   ต้องแยกออกจากสีส้มของ "กำลังรอตรวจ" ซึ่งเป็นกลาง ๆ */
.store-state-note--suspended,
.store-state-note--rejected {
  background: rgba(var(--stat-error-rgb, 239, 68, 68), 0.08);
  border-color: rgba(var(--stat-error-rgb, 239, 68, 68), 0.25);
}

.store-state-note--suspended i,
.store-state-note--rejected i {
  color: var(--stat-error, #ef4444);
}

/* ข้อความที่แอดมินพิมพ์ ขึ้นบรรทัดใหม่ให้แยกจากคำอธิบายของระบบ */
.store-state-note__msg {
  display: block;
  margin-top: 6px;
  color: var(--text-primary);
}

/* ── ปุ่มปิดโน้ต ──
   flex: 0 0 auto กันไม่ให้โดนข้อความยาว ๆ บีบจนกดไม่โดน
   พื้นที่กด 28px เท่ากับขั้นต่ำที่นิ้วแตะได้บนมือถือ ถึงไอคอนจะเล็กกว่านั้น */
.store-note__close {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  margin: -4px -4px 0 auto;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 0.2s, background 0.2s;
}

.store-note__close:hover,
.store-note__close:focus-visible {
  opacity: 1;
  background: rgba(var(--text-primary-rgb), 0.08);
}

/* ⚠️ ระยะเวลาต้องตรงกับ setTimeout ใน assets/js/store-note.js (200ms)
   แก้ที่นี่ต้องแก้ที่นั่นด้วย ไม่งั้นโน้ตจะหายก่อนจางจบหรือค้างเป็นก้อนว่าง */
.store-pending-note {
  transition: opacity 0.2s ease;
}

.store-pending-note.is-closing {
  opacity: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .store-pending-note { transition: none; }
}

/* ปุ่มสถานะที่กดไม่ได้ — เทาลงเหมือน is-pending แต่คนละความหมาย */
#createStoreBtn.is-suspended {
  opacity: 0.65;
  cursor: not-allowed;
}

/* ── กล่องสร้างร้านสำเร็จ ── */
.btn-get-started {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.modal-countdown {
  margin: 14px 0 0;
  font-size: 12px;
  color: var(--text-secondary);
}

.modal-countdown span {
  font-weight: 700;
  color: var(--grad-1);
  font-variant-numeric: tabular-nums;
}

/* ค่อย ๆ จางก่อนเด้งกลับหน้าโปรไฟล์ — ระยะเวลาต้องตรงกับ setTimeout
   ใน assets/js/store-created.js (400ms) ถ้าแก้ที่นี่ต้องแก้ที่นั่นด้วย */
.modal-overlay {
  transition: opacity 0.4s ease;
}

.modal-overlay.is-leaving {
  opacity: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .modal-overlay { transition: none; }
}

/* ── หน้าร้านที่ปิด/ถูกระงับ ──
   ของเดิมเป็นข้อความบรรทัดเดียวลอย ๆ กลางหน้าว่าง ๆ คนกดลิงก์ที่เซฟไว้เข้ามา
   อ่านแล้วยังไม่รู้ว่าควรรอหรือไปหาที่อื่น (ผู้ใช้สั่งให้บอกว่าเหลือกี่วัน) */
.es-store-closed {
  max-width: 520px;
  margin: 64px auto;
  padding: 32px 28px;
  text-align: center;
  border: 1px solid var(--border-input);
  border-radius: 18px;
  background: rgba(var(--text-primary-rgb), 0.03);
}

.es-store-closed__title {
  margin: 0 0 10px;
  font-size: 20px;
  line-height: 1.4;
  color: var(--text-primary);
}

.es-store-closed__text {
  margin: 0 0 22px;
  font-size: 14px;
  line-height: 1.7;
  color: var(--text-secondary);
}

/* ใช้ทรงเดียวกับปุ่มหลักของธีม (`.btn-gradient`) — ผู้ใช้สั่ง 2026-08-17
   ⚠️ ต้องทับ `width: 100%` ของ .btn-gradient เพราะตัวนี้เป็น <a> ในการ์ด
   ที่จัดกึ่งกลาง ถ้าปล่อยเต็มความกว้างจะดูเป็นแถบยาวไม่ใช่ปุ่ม */
.es-store-closed__btn.btn-gradient {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: auto;
  padding: 15px 30px;
  text-decoration: none;
}

/* ⚠️ ต้องล้างเอฟเฟกต์ตัวอักษรไล่สีของ `a:hover` (styles.css:197) ออก
   ไม่งั้น hover แล้วตัวหนังสือกับไอคอนกลายเป็นโปร่งใสหายไปทั้งปุ่ม
   (บทเรียนเดียวกับชิปแท็กในหน้าสินค้า) */
.es-store-closed__btn.btn-gradient:hover {
  color: var(--text-primary);
  -webkit-text-fill-color: currentColor;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  background: var(--bg-primary);
  animation: none;
}

/* ── หน้ารวมสินค้าตามแท็ก + แท็กในหน้าสินค้า (ผู้ใช้สั่ง 2026-08-16) ── */
.es-tag-intro {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  width: 100%;
  margin: 0 0 18px;
  padding: 12px 16px;
  border: 1px solid rgba(var(--grad-1-rgb), 0.25);
  border-radius: 12px;
  background: rgba(var(--grad-1-rgb), 0.07);
}

.es-tag-intro__text {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 13.5px;
  color: var(--text-primary);
}

.es-tag-intro__text i {
  color: var(--grad-1);
}

.es-tag-intro__clear {
  font-size: 12.5px;
  color: var(--text-secondary);
  text-decoration: underline;
  white-space: nowrap;
}

/* 🔴 ต้องล้าง `background` ด้วย (ผู้ใช้แจ้ง 2026-09-12 — "effect เวลา hover บัค")
   กฎ `a:hover` ของธีม (styles.css:244) ใส่ gradient เป็นพื้น แล้วกฎรวมข้างล่างเปลี่ยน
   `background-clip` กลับเป็น border-box → gradient กลายเป็นกล่องสีทึบทับหลังตัวอักษร */
.es-tag-intro__clear:hover,
.es-empty-cart__link:hover {
  color: var(--grad-1);
  -webkit-text-fill-color: var(--grad-1);
  background: none;
}

/* ตะกร้าว่าง — ข้อความชิดซ้ายเหมือนแจ้งเตือนกล่องอื่นทั้งเว็บ (ผู้ใช้สั่ง 2026-09-13)

   🔴 **ชื่อคลาสชนกันโดยบังเอิญ** — `.cart-empty` ของ design (cart.css:396) เป็นบล็อก
   ตะกร้าว่างคนละตัว (ไอคอนใหญ่ + ข้อความกลางจอ) และใส่ `text-align: center` ไว้
   ส่วน WooCommerce ก็ตั้งชื่อกล่องแจ้งเตือนของมันว่า `.cart-empty` เหมือนกัน
   ข้อความในกล่องจึงถูกดันไปกลางคอลัมน์ขวาของ grid ทั้งที่ไอคอนอยู่ซ้าย

   แก้เฉพาะตัวที่เป็นกล่องแจ้งเตือนจริง (`.woocommerce-info`) — บล็อกของ design
   ถ้าถูกใช้ที่อื่นต้องยังอยู่กลางเหมือนเดิม */
.woocommerce .cart-empty,
.cart-empty.woocommerce-info {
  text-align: left;
}

/* ตะกร้าว่าง — ข้อความกับลิงก์ต้องอยู่บรรทัดเดียวกัน (ผู้ใช้สั่ง 2026-09-12)
   ตัวห่อนี้คือไอเทมเดียวของ grid ในกล่องแจ้งเตือน ข้างในจึงไหลเป็นข้อความปกติ
   (ดูเหตุผลเต็มที่ `es_marketplace_empty_cart_link()` ใน inc/woocommerce.php) */
.es-empty-cart__msg {
  display: inline;
}

/* ลบสินค้าจากตะกร้า — "ย้อนกลับ?" อยู่บรรทัดเดียวกับข้อความ (ผู้ใช้สั่ง 2026-09-13)
   หลักการเดียวกับตะกร้าว่าง: ตัวห่อคือไอเทมเดียวของ grid ข้างในจึงไหลเป็นข้อความปกติ
   (ดู `es_marketplace_cart_undo_inline()` ใน inc/woocommerce.php) */
.es-cart-undo {
  display: inline;
}

.es-cart-undo .restore-item {
  margin-left: 6px;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}

/* ตะกร้าว่าง — ลิงก์ "ดูสินค้าทั้งหมด" ต่อท้ายข้อความ (ผู้ใช้สั่ง 2026-09-12 · มีเส้นใต้) */
.es-empty-cart__link {
  margin-left: 6px;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}

.es-empty-cart__link:hover {
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

.product-tags {
  margin: 24px 0 0;
}

/* ไอคอนหน้าหัวข้อ INFORMATION — ชุดเดียวกับหัวข้อ section ที่อื่นทั้งเว็บ */
.product-description .description-header h2,
.product-description .description-header h3 {
  display: flex;
  align-items: center;
  gap: 8px;
}

.product-description .description-header h2 .es-section-icon,
.product-description .description-header h3 .es-section-icon {
  color: var(--grad-1);
  font-size: 0.9em;
}

/* ขนาดเท่าหัวข้อ INFORMATION (single-product.css:377) — ผู้ใช้สั่ง 2026-08-17 */
.product-tags__title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 16px;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-primary);
}

.product-tags__title i {
  color: var(--grad-1);
}

.product-tags__list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.product-tags__list li {
  margin: 0;
  list-style: none;
}

.product-tags__item {
  display: inline-block;
  padding: 5px 13px;
  border-radius: 999px;
  border: 1px solid rgba(var(--grad-1-rgb), 0.3);
  background: rgba(var(--grad-1-rgb), 0.08);
  color: var(--text-primary);
  font-size: 13px;
  text-decoration: none;
  transition: background 0.2s, border-color 0.2s;
}

/* 🔴 **ต้นเหตุจริงที่ตัวหนังสือหายตอน hover คือกฎ `a:hover` ของธีม**
   (styles.css:197) ซึ่งทำลิงก์ทั้งเว็บเป็นตัวอักษรไล่สี ด้วยสูตร
   `color: transparent` + `background-clip: text` + `-webkit-text-fill-color: transparent`
   พอมาโดนชิปที่มีพื้นหลังของตัวเอง ผลคือ **พื้นชิปถูกแทนที่ด้วย gradient
   แล้วตัวอักษรกลายเป็นโปร่งใส** = หายทั้งคู่

   แค่เขียนทับ `color` ไม่พอ ต้องล้าง `-webkit-text-fill-color` กับ
   `background-clip` ด้วย ไม่งั้นตัวอักษรยังโปร่งอยู่เหมือนเดิม
   (แก้รอบแรก 2026-08-17 พลาดตรงนี้ ผู้ใช้แจ้งซ้ำว่ายังหาย) */
.product-tags__item:hover,
.es-permalink__url:hover,
.product-edit-btn:hover,
.es-tag-intro__clear:hover {
  -webkit-text-fill-color: currentColor;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

.product-tags__item:hover {
  border-color: var(--grad-1);
  background: rgba(var(--grad-1-rgb), 0.22);
  color: var(--text-primary);
}

.es-permalink__url:hover,
.product-edit-btn:hover {
  background: transparent;
  color: var(--grad-1);
}

/* ── ป้าย SOLD / SALE (ผู้ใช้สั่ง 2026-08-16) ──
   SALE ได้สีที่ SOLD เคยใช้ (--btn-danger แดง) ส่วน SOLD เปลี่ยนเป็นเทาเข้ม
   เหตุผล: แดงคือสีที่ดึงสายตา ควรใช้กับของที่ยัง "ซื้อได้"
   ส่วนของที่ขายไปแล้วไม่ต้องเรียกร้องความสนใจ แค่บอกให้รู้พอ

   🔴 **ฐานของป้ายอยู่ที่นี่ ไม่ใช่ store-profile.css** (ย้ายมา 2026-08-29)
   ไฟล์นั้นโหลดเฉพาะหน้าร้าน ป้ายในหน้ารวมสินค้าจึงเคยไม่มีแสงกวาด
   และหน้าสินค้าเดี่ยวไม่มีป้ายเลย — ไฟล์นี้โหลดทุกหน้าที่มี WooCommerce */
.product-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 2;
  /* ⚠️ ความสูงมาจาก padding บน-ล่างล้วน ๆ เพราะ `line-height: 1`
     ผู้ใช้สั่งเพิ่มความสูง 2026-09-04 (ทั้ง SALE และ SOLD) — 3px → 6px
     ได้ป้ายสูง ~22px จากเดิม ~16px  ห้ามไปเพิ่มที่ `height` แทน
     ป้ายจะสูงคงที่แล้วตัวหนังสือไทยที่มีสระบนล่างจะถูกตัด */
  padding: 6px 9px;
  border-radius: 4px;
  background: var(--btn-danger);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1;
  text-transform: uppercase;
  overflow: hidden;
}

/* แสงสีขาวกวาดจากซ้ายไปขวา — ตัวที่ผู้ใช้เรียกว่า "effect ของหน้าร้าน" */
.product-badge::after {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 60%;
  height: 100%;
  background: linear-gradient(
    135deg,
    transparent 0%,
    rgba(var(--text-primary-rgb), 0.4) 50%,
    transparent 100%
  );
  animation: badgeShimmer 2s ease-in-out infinite;
}

@keyframes badgeShimmer {
  0%   { left: -100%; }
  100% { left: 150%; }
}

/* เครื่องที่ตั้งให้ลดการเคลื่อนไหว — ซ่อนแสงกวาดไปเลย ป้ายยังอ่านได้ปกติ */
@media (prefers-reduced-motion: reduce) {
  .product-badge::after {
    display: none;
  }
}

.product-badge--sale {
  background: var(--btn-danger);
}

.product-badge--sold {
  background: rgba(20, 16, 31, 0.82);
  color: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.18);
}

/* แสงกวาดเก็บไว้เฉพาะ SALE — ของที่ขายแล้วไม่ต้องกะพริบเรียกสายตา */
.product-badge--sold::after {
  display: none;
}

/* การ์ดในหน้า shop ยังไม่เคยมีป้าย ต้องมี positioning ให้ป้ายเกาะ */
.product-card__image {
  position: relative;
}

/* ── ป้ายในหน้าสินค้าเดี่ยว ──
   เกาะ `.woocommerce-product-gallery` ซึ่ง `position:relative` อยู่แล้ว
   (`assets/css/single-product.css`) — ป้ายถูกพิมพ์ไว้**นอก** `<figure>`
   เพื่อไม่ให้ FlexSlider นับเป็นสไลด์ (ดู woocommerce/single-product/product-image.php)

   ⚠️ ต้องเลื่อนลงมาให้พ้นขอบมนของรูป และใหญ่กว่าบนการ์ดเล็กน้อย
   เพราะหน้านี้รูปใหญ่ ป้ายขนาดการ์ดจะเล็กจนแทบมองไม่เห็น */
.woocommerce-product-gallery > .product-badge {
  top: 12px;
  right: 12px;
  /* สูงกว่าบนการ์ดนิดหน่อยตามสัดส่วนเดิม (รูปหน้านี้ใหญ่กว่ามาก) */
  padding: 7px 11px;
  font-size: 11px;
}

/* ── 🔴 ระยะขอบต้องพ้น "ขอบมน" ของกรอบรูป (แก้ 2026-09-04) ──────────
   ผู้ใช้แจ้ง: *"ขยับป้าย sale ตรงหน้า shop ลงมาอีกนิด ขอบมันกิน ชิดขอบเกิน"*

   `.product-card__image` ตั้ง `border-radius: 40px` + `overflow: hidden`
   (`assets/css/product.css:27`) มุมขวาบนจึงเป็น**ส่วนโค้งรัศมี 40px**
   ป้ายที่ห่างขอบ 8px มีมุมขวาบนอยู่ห่างจุดศูนย์กลางของส่วนโค้ง
   √(32² + 32²) = **45.3px** ซึ่งเกิน 40 → มุมป้ายโผล่นอกวงกลม
   **แล้วถูกตัดทิ้ง** (วัดของจริงในเบราว์เซอร์แล้ว)

   สูตร: ระยะขอบ `i` ที่ปลอดภัยต้องทำให้ √2 × (40 − i) ≤ 40 → **i ≥ 11.7px**
   ใช้ 18px เผื่อไว้ทั้งสองด้าน (ได้ระยะ 31.1px จาก 40) — ป้ายจะไปนั่งอยู่
   ในเนื้อรูปพอดี พ้นทั้งส่วนโค้งและ `padding: 10px` ของกรอบ

   ⚠️ **แก้รัศมีของกรอบเมื่อไร ต้องคิดระยะนี้ใหม่** ไม่ใช่ปรับด้วยสายตา */
.product-card__image .product-badge {
  position: absolute;
  top: 18px;
  right: 18px;
  z-index: 2;
  padding: 6px 9px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--text-primary);
  overflow: hidden;
}

/* ── ราคาปกติ + ราคาลด ──
   🔴 WooCommerce ออก `<del>ราคาเดิม</del> <ins>ราคาลด</ins>` เองเมื่อมีราคาลด
   ซึ่ง design ไม่ได้เผื่อไว้ ถ้าไม่จัดการ ราคาสองก้อนจะเรียงต่อกันเป็น
   บรรทัดยาวจนดันปุ่มใส่ตะกร้าตกบรรทัด และบนการ์ดแคบ ๆ จะล้นกล่อง
   ครอบทุกที่ที่แสดงราคา: การ์ด shop · หน้าสินค้า · ตะกร้า · เช็คเอาต์ · อีเมล */
.price del,
.product-price del,
.woocommerce-Price-amount del,
.product-card .price del,
.order-item__price del {
  display: inline;
  margin-right: 6px;
  opacity: 0.55;
  font-size: 0.82em;
  font-weight: 400;
  text-decoration: line-through;
}

.price ins,
.product-price ins,
.product-card .price ins,
.order-item__price ins {
  display: inline;
  background: none;
  color: var(--btn-danger);
  text-decoration: none;
  font-weight: inherit;
}

/* 🔴 **การ์ดในตะแกรงต้องสูงเท่ากันทุกใบ ไม่ว่าจะลดราคาหรือไม่**
   วัดจริงแล้วถ้าปล่อยให้ราคาสองก้อนเรียงต่อกันในบรรทัดเดียว การ์ดที่ลดราคา
   จะสูง 315px ส่วนใบอื่น 303px และปุ่มใส่ตะกร้าถูกดันตกจนหลุดขอบการ์ด
   (ผู้ใช้สั่งว่า "ต้องไม่ทำ layout พังในทุก ๆ หน้าที่สินค้าแสดงราคา")

   วิธีแก้: ราคาเดิมเป็นบรรทัดเล็กอยู่เหนือราคาจริง แล้ว **จองความสูงไว้
   เท่ากันทุกใบ** ด้วย min-height — ใบที่ไม่ลดราคาก็เว้นที่ว่างไว้เท่ากัน */
.product-card .product-action {
  flex-wrap: nowrap;
  align-items: center;
}

.product-card .product-price {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  /* เท่ากับความสูงของราคาสองบรรทัดพอดี (1.35em + 1.3em) — ใบที่ไม่ลดราคา
     จะเว้นที่ว่างไว้เท่ากัน การ์ดทุกใบจึงสูงเท่ากันหมด */
  min-height: 2.65em;
  overflow-wrap: anywhere;
}

.product-card .product-price del {
  display: block;
  margin: 0;
  font-size: 0.7em;
  line-height: 1.3;
}

/* ── ราคาลดในหน้า "สินค้าของฉัน" ของผู้ขาย (ผู้ใช้สั่ง 2026-08-29) ──
   `template-parts/vendor/product-card.php` พิมพ์ `get_price_html()` ลงใน
   `.order-item__price` ซึ่ง**ไม่เคยอยู่ในกลุ่มตัวเลือกด้านบนเลย** — สินค้าที่
   ลดราคาจึงออกมาเป็นราคาสองก้อนสีขาวเรียงต่อกัน ไม่มีสีแดง ไม่มีตัวจาง
   คนละหน้าตากับการ์ดหน้า shop ทั้งที่เป็นสินค้าตัวเดียวกัน

   ตอนนี้ใช้ทรงเดียวกับการ์ดหน้า shop เป๊ะ ๆ: ราคาเดิมตัวเล็กจางอยู่บรรทัดบน
   ราคาลดสีแดง (`--btn-danger`) อยู่บรรทัดล่าง

   ⚠️ `.order-item__price` ยังใช้ในการ์ดคำสั่งซื้อทั้งฝั่งผู้ซื้อและผู้ขายด้วย
   ตรงนั้นพิมพ์ด้วย `wc_price()` ซึ่งไม่เคยมี `<del>/<ins>` กฎนี้จึงไม่ไปแตะ */
.order-item__price del {
  display: block;
  margin: 0;
  font-size: 0.7em;
  line-height: 1.3;
}

/* หน้าสินค้าเดี่ยว — ราคาเดิมตัวเล็กลอยอยู่เหนือราคาจริง อ่านง่ายกว่าเรียงต่อกัน */
.product-price .price-value del {
  display: block;
  margin: 0 0 2px;
  font-size: 0.5em;
}

/* ── ไอคอนนำหน้า**หัวข้อ section** — ใช้ทั่วทั้งเว็บ ──
   🔴 **อยู่ที่หัวข้อเท่านั้น ไม่ใช่ที่ป้ายช่องกรอก** (ผู้ใช้สั่ง 2026-08-16 รอบสอง)
   รอบแรกเข้าใจผิดว่าให้ใส่ทุกป้าย ผลคือฟอร์มเต็มไปด้วยไอคอนจนอ่านยาก
   ถ้าจะเพิ่มไอคอนที่ไหนอีก ให้เพิ่มที่หัวข้อ อย่าย้อนกลับไปที่ `.form-label` */
.store-section-title > .es-section-icon,
.profile-section-title > .es-section-icon,
.product-section-title > .es-section-icon,
.edit-profile-password > summary > .es-section-icon {
  color: var(--grad-1);
  margin-right: 8px;
  font-size: 0.95em;
}

/* ============================================================
   ด่านกั้นก่อนเข้าหน้าคำสั่งซื้อ (STEP 7.5 · C3)
   ============================================================
   WooCommerce แทรกฟอร์มสองตัวนี้กลางหน้า checkout เมื่อระบุตัวผู้ซื้อไม่ได้
     · woocommerce/checkout/form-verify-email.php — guest กรอกอีเมลยืนยัน
     · woocommerce/global/form-login.php          — สมาชิกที่ยังไม่ล็อกอิน

   ทั้งสองไฟล์ใช้คลาสของ design ล้วน (`.title-section` `.form-group` `.form-input`
   `.btn-submit` `.forgot-wrapper` `.es-notice`) ที่นี่จึงเหลือแค่ 3 กฎ:
   ความกว้าง · ลำดับหัวเรื่อง · ล้าง border ที่ WooCommerce ยัดให้ฟอร์ม

   📏 **คุมความกว้างที่กล่องแม่ที่เดียว** ลูกทุกตัว (หัวเรื่อง · แจ้งเตือน · ฟอร์ม)
   แคบตามเองโดยไม่ต้องประกาศ max-width ซ้ำทีละตัว

   🔴 **ต้องกว้างเท่าฟอร์มหน้าเข้าสู่ระบบเป๊ะ** (ผู้ใช้สั่ง 2026-08-17)
   หน้านั้นคือ `.page-fix-wrapper` (`--max-width`) ที่มี `padding: 0 var(--side-padding)`
   ฟอร์มข้างในจึงกว้าง = max-width − side-padding × 2 → **วัดจากหน้าจริงได้ 326px**
   (390 − 32×2 · `--side-padding` เป็น 32px ตั้งแต่จอ ≥480px, styles.css:856)
   เขียนเป็นสูตรจาก token กลาง ไม่ใส่ 326 ลงไปตรง ๆ — ถ้าวันหลัง design ขยับ
   `--max-width` หรือ `--side-padding` ด่านกั้นจะขยับตามเอง ไม่หลุดจากหน้า login
   ⚠️ ที่นี่ใช้ max-width แทน padding เพราะ `.woocommerce` เป็นกล่องที่ WooCommerce
   สร้างเอง ใส่ padding แล้วจะไปกินพื้นที่ของแจ้งเตือนที่กว้างเต็มกล่องอยู่แล้ว */
.woocommerce:has(> form.es-gate-login),
.woocommerce:has(> form.es-verify-form),
.woocommerce:has(> .es-gate-mismatch) {
  max-width: calc(var(--max-width) - var(--side-padding) * 2);
  margin-inline: auto;
}

/* กล่อง "บัญชีไม่ตรง" — ล็อกอินอยู่แต่คนละบัญชีกับเจ้าของคำสั่งซื้อ
   ⚠️ ต้องซ่อนแจ้งเตือน "กรุณาเข้าสู่ระบบเพื่อดูคำสั่งซื้อนี้" ที่ core พิมพ์ไว้ก่อนหน้า
   เพราะคนอ่านล็อกอินอยู่แล้ว — บอกให้ทำสิ่งที่ทำอยู่ ยิ่งงง
   ข้อความจริงอยู่ในกล่องนี้แล้ว (ระบุด้วยว่าตอนนี้ใช้บัญชีอะไรอยู่) */
.woocommerce:has(> .es-gate-mismatch) > .woocommerce-info {
  display: none;
}

.es-gate-mismatch {
  display: flex;
  flex-direction: column;
}

/* 🔴 **หัวเรื่องของด่าน login ต้องดันขึ้นบนสุดด้วย `order`**
   `WC_Shortcode_Checkout` พิมพ์แจ้งเตือนด้วย `wc_print_notice()` **ก่อน** เรียก
   `woocommerce_login_form()` เสมอ และไม่มี hook คั่นกลาง — เรียงจากฝั่ง PHP ไม่ได้
   เบราว์เซอร์ที่ไม่รองรับ :has() จะเห็นหัวเรื่องใต้แจ้งเตือน ยังอ่านได้ ไม่พัง */
.woocommerce:has(> form.es-gate-login) {
  display: flex;
  flex-direction: column;
}

.woocommerce:has(> form.es-gate-login) > .es-gate-title {
  order: -1;
}

/* ⚠ ฟอร์มยืนยันอีเมลไม่มีคลาส `.login-form` จึงไม่ได้ flex column จาก styles.css
   และไม่ถูกก้อนล้าง border/padding ที่บรรทัด ~1939 ครอบถึง ต้องล้างเอง
   (ต้องมี `form` ในตัวเลือกให้ specificity ถึง (0,2,1) เท่า `.woocommerce form.login`
    ไม่งั้นแพ้เงียบ ๆ — กับดักข้อ 31 ตัวเดิม) */
.woocommerce form.es-verify-form {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  border: 0;
  text-align: start;
}

/* ============================================================
   ปุ่มสแกน / ปุ่มแชท ที่ยังไม่ได้ตั้งค่าในหลังบ้าน
   ------------------------------------------------------------
   design วาดปุ่มสองตัวนี้ไว้เต็มรูปแบบ แต่ปลายทางอยู่นอกเว็บนี้
   (ตั้งค่ามาร์เก็ตเพลส → แท็บ "ปุ่มสแกนและแชท")

   ยังไม่ได้ตั้งค่า = หรี่ลงและกดไม่ได้ ไม่ใช่ปุ่มที่ดูใช้ได้เต็มที่
   แต่กดแล้วเงียบ — ผู้ใช้จะได้ไม่คิดว่าเว็บพัง

   ปุ่มสแกนตอนปิดเป็น <span> ไม่ใช่ <a> จึงไม่ต้องกัน hover เพิ่ม
   ส่วนปุ่มแชทเป็น <button disabled> ที่ยังมีขอบ gradient ของ design อยู่
   ============================================================ */
.bnav-item.is-off,
.bnav-btn.is-off {
  opacity: 0.4;
  cursor: default;
}

/* กัน glow เต้นตอน hover — ปุ่มที่กดไม่ได้ไม่ควรตอบสนองเหมือนกดได้
   (.bnav-btn:hover ใน styles.css:1023 ใส่ animation ไว้ที่ตัวปุ่มเอง) */
.bnav-btn.is-off:hover {
  animation: none;
}

/* ============================================================
   แถบเมนูล่างแบบใหม่ — 4 เมนู + ปุ่มแชทในโดมเหนือแถบ
   (ผู้ใช้สั่ง 2026-09-11 ส่งรูปตัวอย่าง: "กว้างเท่าเดิม … การจัดวางหน้าตา พื้นหลังให้เหมือนตัวอย่าง")

   ใช้เฉพาะแถบเมนูมาตรฐาน (`--menu` ใส่ใน footer.php) — แถบปุ่มเฉพาะหน้า
   (CREATE STORE ฯลฯ) ใช้ .bottom-nav-container ตัวเดียวกันแต่ไม่โดนกฎชุดนี้

   🔴 รอบ 5 (2026-09-14) ผู้ใช้ส่งภาพหน้า Scan บนมือถือมา: "ยังไม่ตรงนะ" — รอบ 4 วัดในหน้าต่าง 561px ซึ่งแถบของหน้า Scan กว้างเต็ม 380
     กฎจริงของหน้า Scan: กว้าง min(380px, 100vw − 24px) · สูง 153 คงที่ · พื้นหลังยืด 100% 100%
     → บนมือถือ (กว้าง ~333) พื้นหลังหดเท่ากันทั้งสองแกน ×0.877 โดมจึงเป็น**วงกลม**รัศมี 47.8 ขอบดำรอบปุ่ม ~9px เท่ากันรอบวง
     ของเราจึงหดชิ้นกลางเท่ากันทั้งสองแกน: โดมกว้าง 172 × 0.877 = 151 · svg 153 × 153 · ปลายแถบมน 35.5 ทั้งสองแกน
     ความสูงรวม 153 · แถบ 71 · ปุ่ม 78 top 13 เหมือนรอบ 4

   รอบ 4 (ประวัติ) อ้างอิงหน้า Scan https://eyestyle-art.com/th/home — ผู้ใช้: "เว้นขนาด border พื้นหลังให้เท่ากัน"
     วัดจริงจากหน้า Scan: ใช้ SVG ตัวเดียวกัน (group-18481.svg) แต่ **ยืดเป็น 380 × 153** (background-size 100% 100%)
     → ทุกค่าแนวตั้งคูณ 153 / 174.39 = 0.877 · ปุ่มสแกนโตเต็ม 78px (รวมขอบไล่สี) ศูนย์กลางห่างขอบบน 49px
     ของเราจึงเป็น: กล่องสูง 153 · แถบ 71 (81 × 0.877) · ปลายมนเป็นวงรี 40.5 / 35.5
     ปุ่มแชท 72 + ขอบไล่สี 3 รอบ = 78 · top = 49 − 36 = 13px · ไอคอน 33px · effect เดิมทั้งหมด (ไม่เอาวงโคจรของหน้า Scan)
     ความกว้างโดม 172 ไม่เปลี่ยน (ผู้ใช้: ความยาวโอเคแล้ว) — path ใน footer.php เดิม ยืดด้วย preserveAspectRatio="none"

   รอบ 3 (ประวัติ) ใช้ SVG จากทีมออกแบบขนาดจริง 174px:
     พื้นหลังต้นฉบับ 380 × 174.39 · แถบสูง 81px ปลายมนรัศมี 40.5 (ครึ่งหนึ่งของความสูง)
     โดมกว้าง 172px (x 104–276 ของต้นฉบับ) · วงกลมรัศมี 54.5 ศูนย์กลางห่างยอด 54.4px
     → ปุ่มแชท 66px อยู่กลางวง top = 54.4 − 33 ≈ 21px · กล่องทั้งหมดสูง 174px
     ชิ้นกลางใน footer.php ตัดจากต้นฉบับช่วง x 103–277 (ยื่นข้างละ 1px ทับรอยต่อ)
     ไอคอน 4 ตัวเป็น SVG (`es_marketplace_nav_icon()`) สีตาม currentColor — effect เดิมทุกอย่าง

   เรขาคณิตรอบ 2 (ประวัติ) — ปรับรอบ 2 ตามที่ผู้ใช้สั่ง
   ("กรอบพื้นหลังสีดำให้เล็กลงหน่อย และตำแหน่งเลื่อนลงมาชิดกับชุดล่าง" · เมนูเล็กลง):
     แถบสูง 72px (รอบแรก 84) · โดมรัศมี 46 (รอบแรก 52 = ขอบดำรอบปุ่ม 16 → 10)
     ศูนย์กลางโดมเหนือขอบบนแถบ 36px = ขอบไล่สีของปุ่มแชทแตะขอบบนแถบพอดี (รอบแรกลอยห่าง 8px)
     → ยอดโดมสูงจากขอบบนแถบ 82px · กล่องทั้งหมดสูง 82 + 72 = 154px
     ปุ่มแชท 66px (+ขอบไล่สี 3px — ขนาดเดิม ผู้ใช้บอกว่าโอเคแล้ว) → top = 46 − 33 = 13px
     มุมที่โดมชนแถบโค้งรัศมี 14 → ชิ้นกลางกว้าง 116px
   ปุ่มแชท ไอคอน Scan/Profile และสถานะปิด (.is-off) ไม่เปลี่ยน
   hover ยังเป็นกฎเดิม `a.bnav-item:hover` (styles.css:266) — จากเทาเป็นขาว
   ============================================================ */

/* พื้นหลังจางเริ่มแถวขอบบนแถบ ไม่ใช่ตั้งแต่ยอดโดม
   (ข้าง ๆ โดมต้องยังเห็นเนื้อหาหน้าเว็บตามรูปตัวอย่าง)
   ขอบบนแถบอยู่ห่างจากล่างสุดของ wrapper 82px (แถบ 72 + ลอยขึ้น 10) */
.bottom-nav-wrapper--menu {
  background: linear-gradient(180deg, transparent 0, transparent calc(100% - 130px), var(--bg-bottom) calc(100% - 81px));
}

.bottom-nav-container--menu {
  min-height: 153px;
}

.bottom-nav-container--menu .bnav-bar,
.bottom-nav-container--menu .bnav-items {
  height: 71px;
}

/* ปลายแถบมนเต็มครึ่งความสูงตามต้นฉบับ (styles.css ตั้ง 25px ไว้) */
.bottom-nav-container--menu .bnav-left {
  border-radius: 35.5px 0 0 35.5px;
}

.bottom-nav-container--menu .bnav-right {
  border-radius: 0 35.5px 35.5px 0;
}

.bottom-nav-container--menu .bnav-notch {
  position: relative;
  width: 151px;
}

/* svg ยื่นซ้าย-ขวาข้างละ 1px ทับรอยต่อกับ .bnav-left/.bnav-right
   ไม่งั้นความกว้างเศษพิกเซลทำให้เห็นเส้นบาง ๆ ตรงรอยต่อ */
.bottom-nav-container--menu .bnav-notch svg {
  position: absolute;
  left: -1px;
  bottom: 0;
  width: 153px;
  height: 153px;
  pointer-events: none;
}

/* ส่วนที่เป็นสีดำเท่านั้นที่กันการกดทะลุ — มุมโปร่งข้างโดมยังกดเนื้อหาข้างหลังได้ */
.bottom-nav-container--menu .bnav-notch path {
  pointer-events: visiblePainted;
}

.bottom-nav-container--menu .bnav-center {
  top: 13px;
}

/* ปุ่มแชทโตเท่าปุ่มสแกนของหน้า Scan: 72 + ขอบไล่สี 3px รอบ (::before inset −3 ใน styles.css) = 78px */
.bottom-nav-container--menu .bnav-btn {
  width: 72px;
  height: 72px;
}

.bottom-nav-container--menu .bnav-btn i {
  font-size: 33px;
}

/* 4 ช่องเท่ากัน ศูนย์กลางปุ่มแชทตกกลางระหว่าง Scan กับ Market พอดี
   ไม่เว้นขอบซ้าย-ขวา (ผู้ใช้สั่งเอา padding: 0 8% ออก) */
.bottom-nav-container--menu .bnav-items {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  align-items: center;
  justify-items: center;
  padding: 0;
}

.bottom-nav-container--menu .bnav-item {
  min-width: 52px;
  gap: 0;
  color: rgba(255, 255, 255, 0.5);
}

/* รอบ 2: ไอคอน 24 → 20 · ตัวหนังสือ 13 → 11 · ระยะไอคอน–ตัวหนังสือ 6 → 7 (ผู้ใช้สั่ง "ห่างกันกว่านี้นิดนึง") */
.bottom-nav-container--menu .bnav-item i {
  font-size: 20px;
}

/* ไอคอน SVG (2026-09-14) — สีมาจาก currentColor ของ .bnav-item */
.bottom-nav-container--menu .bnav-icon {
  display: block;
  width: 22px;
  height: 22px;
}

.bottom-nav-container--menu .bnav-label {
  margin-top: 7px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  color: inherit;
}

.bottom-nav-container--menu .bnav-item.is-current {
  color: var(--text-primary);
}

/* ไอคอน Market = ร้าน + หมุดตำแหน่งมุมขวาล่าง (ตามรูปตัวอย่าง)
   FontAwesome ฟรีไม่มีไอคอนนี้สำเร็จรูป จึงซ้อนสองตัว
   หมุดมีพื้นดำรองให้ดูเหมือนเจาะทะลุไอคอนร้าน
   ใช้ร่วมกับปุ่ม .btn-shop บนหัวเว็บ (หน้าบัญชี/แดชบอร์ดร้าน) — ขนาดแยกตามที่ */
.es-market-icon {
  position: relative;
  display: inline-block;
  line-height: 1;
}

.es-market-icon .fa-location-dot {
  position: absolute;
  padding: 1px 2px;
  background: var(--bg-primary);
  border-radius: 50%;
}

/* ============================================================
   แผงแชทแบบกรอบ sandbox (โหมด frame)
   ------------------------------------------------------------
   หน้าต่างแชทอยู่ใน <iframe> คนละโดเมน จึงแตะหน้าเว็บนี้ไม่ได้
   ที่นี่คุมแค่กล่องที่ครอบมันไว้ — ข้างในเป็นหน้าตาของฝั่งนั้นทั้งหมด

   วางไว้ *นอก* .bottom-nav-wrapper เพราะ .bottom-nav-container มี transform
   ซึ่งทำให้ position:fixed ข้างในยึดกับกล่องนั้นแทน viewport
   z-index ต้องมากกว่า 999 ของแถบล่าง
   ============================================================ */
.es-chat-panel[hidden] {
  display: none;
}

.es-chat-panel__backdrop {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

.es-chat-panel__sheet {
  position: fixed;
  z-index: 1001;
  left: 50%;
  transform: translateX(-50%);
  /* เหนือโดมปุ่มแชทของแถบล่าง ไม่ให้ปุ่มโดนบัง
     (2026-09-11 แถบแบบใหม่ยอดโดมสูง 164px จากขอบจอ — เดิม 110) */
  bottom: 174px;
  width: calc(100% - 32px);
  max-width: 400px;
  height: min(70vh, 560px);
  height: min(70vh, 560px, calc(100dvh - 190px));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 18px;
  background: var(--bg-secondary);
  border: 0; /* ผู้ใช้สั่ง 2026-10-13 เอาขอบออก (แถบบนเป็นไล่สีแล้ว ขอบเทาดูเป็นกรอบซ้อน) */
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
}

/* ผู้ใช้สั่ง 2026-08-28: *"ปรับ header chat ให้เล็กลงหน่อย มันดูใหญ่เกิน
   (ปรับ css เป็น padding: 4px 12px;)"* — ตัวปุ่มจึงย่อเหลือ 28px ตามไปด้วย
   ไม่งั้นปุ่มสูงกว่าแถบแล้วดันความสูงกลับขึ้นไปเท่าเดิม */
.es-chat-panel__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 12px;
  flex-shrink: 0;
  /* พื้นไล่สีแบรนด์ ทั้งธีมมืดและสว่าง (ผู้ใช้สั่ง 2026-10-13 ตามรูปตัวอย่าง · เดิมพื้นเดียวกับแผง + เส้นใต้)
     ตัวหนังสือ/ไอคอนบนไล่สีต้องขาวเสมอ (กฎ 25 ก.ย.) จึงไม่ต้องมีกฎแยกใน theme-light.css */
  background: var(--gradient);
  border-bottom: 0;
}

.es-chat-panel__title {
  font-size: 15px;
  font-weight: 600;
  color: #fff;
}

.es-chat-panel__tools {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}

.es-chat-panel__tool {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  background: transparent;
  color: #fff;
  font-size: 14px;
}

.es-chat-panel__tool:hover {
  background: rgba(255, 255, 255, 0.2);
}

/* ปุ่มปิดใหญ่กว่าเพื่อน — เป็นทางออกหลัก กดพลาดไม่ได้ */
.es-chat-panel__close {
  font-size: 16px;
}

/* ── โหมดเต็มจอ ──
   🔴 ต้องล้าง transform ของ .es-chat-panel__sheet ด้วย ไม่งั้นแผงเลื่อนไป
   ครึ่งจอซ้ายเพราะ translateX(-50%) ยังทำงานอยู่ */
.es-chat-panel__sheet.is-full {
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  transform: none;
  width: 100%;
  max-width: none;
  height: 100%;
  border: 0;
  border-radius: 0;
}

/* พื้นขาวไว้ก่อน — หน้าแชทส่วนใหญ่พื้นสว่าง ถ้าปล่อยโปร่งจะเห็นดำวาบตอนโหลด */
.es-chat-panel__frame {
  flex: 1;
  width: 100%;
  border: 0;
  background: #ffffff;
  transition: opacity 0.2s ease;
}

/* ระหว่างโหลดหน้าแชท (ผู้ใช้สั่ง 2026-10-13: เปิดแล้วเห็นพื้นขาว) — กรอบโปร่งไว้ก่อน เห็นพื้นแผงตามธีม + ตัวหมุน
   .is-loading ใส่/ถอดโดย bottom-chat.js (ถอดเมื่อ <iframe> ยิง load) · ตัวหมุน/ข้อความใช้คลาสเดียวกับ .es-loading
   แถบบนต้องอยู่เหนือชั้นโหลด (ปุ่มปิดกดได้ตลอด) */
.es-chat-panel__bar {
  position: relative;
  z-index: 2;
}

.es-chat-panel__loading {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  background: var(--bg-secondary);
}

.es-chat-panel.is-loading .es-chat-panel__loading {
  display: flex;
}

.es-chat-panel.is-loading .es-chat-panel__frame {
  opacity: 0;
}

/* ล็อกไม่ให้หน้าหลังเลื่อนตามตอนแชทเปิดอยู่ */
body.es-chat-open {
  overflow: hidden;
}

/* ── หน้าบัญชีรับเงินของร้าน (F7 · 2026-08-21) ──
   ลิงก์ย้อนกลับเป็นข้อความเล็ก ๆ ทรงเดียวกับ .link-edit-bank ในหน้าการเงิน
   ไม่ใช้ .btn-return-plain เพราะตัวนั้นเป็นปุ่มเต็มความกว้างตัวพิมพ์ใหญ่
   จะไปแย่งสายตากับปุ่ม "บันทึก" ที่เป็นปุ่มหลักของหน้า */
.es-payment-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 18px;
  color: #8b5cf6;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-decoration: none;
  transition: color 0.2s;
}

.es-payment-back:hover {
  color: #a78bfa;
}

/* การ์ดบัญชีที่ตั้งไว้แล้ว — ชื่อธนาคารซ้าย ปุ่มแก้ไขขวา */
.es-payment-card {
  align-items: center;
}

.es-payment-card .es-bank-cell {
  font-size: 15px;
  font-weight: 600;
}

.es-payment-add {
  margin-top: 18px;
}

/* จุดยึดล่องหนสำหรับ dokan.js (ดู dokan/settings/header.php) — ต้องไม่กินที่ */
.es-dokan-anchor {
  height: 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

/* ============================================================
   FONT AWESOME 4 → 6 — ตัวประสานสำหรับไอคอนที่เหลือของ Dokan
   (STEP 8 · 2026-08-22)

   ก่อนหน้านี้เว็บโหลด Font Awesome **สองชุด**: ของ Dokan (v4, 100 KB CSS
   + ไฟล์ฟอนต์ของตัวเอง) กับของธีม (v6, 82 KB) ผู้ใช้จึงดาวน์โหลด
   `fa-solid-900.woff2` สองรอบคนละไฟล์ รวมทั้งชุดราว 580 KB ต่อหน้า

   ตอนนี้ปิดของ Dokan ไปแล้วผ่าน `DOKAN_LOAD_STYLE` (wp-config.php)
   เทมเพลตของธีมใช้ v6 ล้วนอยู่แล้ว **229 จุด ไม่มี v4 เลยสักจุด**
   ที่เหลือคือเทมเพลตของ Dokan ที่ธีมยังไม่ override ซึ่งสแกนแล้วเหลือ
   **ไฟล์เดียว จุดเดียว** (`withdraw/status-listing.php` — `fa fa-money`)

   แทนที่จะ copy ทั้งเทมเพลตมาแก้ไอคอนตัวเดียว (แล้วต้องตามแก้ทุกครั้งที่
   ปลั๊กอินอัปเดต) ใช้ตัวประสานสั้น ๆ ตรงนี้แทน — ครอบคลุมไอคอน v4 ตัวอื่น
   ที่ Dokan อาจเพิ่มมาในอนาคตด้วยโดยไม่ต้องมาไล่แก้อีก

   ⚠️ `.fa` เปล่า ๆ ใน v6 ไม่มีน้ำหนักฟอนต์ติดมา ต้องบอก font-family
   กับ font-weight เองถึงจะวาดสัญลักษณ์ออกมา
   ============================================================ */
.fa:not(.fas):not(.far):not(.fab):not(.fa-solid):not(.fa-regular):not(.fa-brands) {
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-smoothing: antialiased;
  display: inline-block;
  font-style: normal;
  font-variant: normal;
  line-height: 1;
  text-rendering: auto;
}

/* ชื่อ v4 ที่ v6 เปลี่ยนไป — เติมเฉพาะตัวที่ Dokan ใช้จริง */
.fa-money::before { content: '\f0d6'; }   /* v6 = fa-money-bill */

/* ============================================================
   ปุ่มแว่นขยายในช่องค้นหาบน header

   `styles.css:971` ตั้ง `.search-icon { pointer-events:none }` ไว้ตั้งแต่ตอน
   ยังเป็น `<i>` เฉย ๆ — ตอนนี้เปลี่ยนเป็น `<button type="submit">` แล้ว
   ต้องเปิดให้กดได้ และล้างหน้าตาปุ่มมาตรฐานของเบราว์เซอร์ทิ้ง
   (แก้ที่นี่ไม่ใช่ที่ styles.css ตามกฎของโปรเจ็ค — styles.css เก็บไว้เทียบ prototype)
   ============================================================ */
.header-search-wrapper .search-icon {
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  /* พื้นที่กดต้องกว้างกว่าตัวไอคอน — 16px แตะพลาดง่ายมากบนมือถือ */
  width: 38px;
  height: 38px;
  right: 4px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--text-secondary);
  font-family: inherit;
  cursor: pointer;
  transition: color 0.2s, background 0.2s;
}

.header-search-wrapper .search-icon:hover,
.header-search-wrapper .search-icon:focus-visible {
  color: var(--text-primary);
  background: rgba(var(--text-primary-rgb), 0.08);
}

.header-search-wrapper .search-icon:focus {
  outline: none;
}

.header-search-wrapper .search-icon:focus-visible {
  outline: 2px solid var(--grad-1);
  outline-offset: -2px;
}

.header-search-wrapper .search-icon i {
  font-size: 16px;
  line-height: 1;
  pointer-events: none;
}

/* ช่องกรอกต้องไม่ลอดใต้ปุ่ม ไม่งั้นข้อความยาว ๆ วิ่งไปทับแว่นขยาย */
.header-search-wrapper .search-input {
  padding-right: 46px;
}

/* ============================================================
   ขอบช่องค้นหา — ปกติ "เทา" เหมือนช่องกรอกหน้าอื่น
   ไล่สีวิ่งเฉพาะตอนชี้เมาส์หรือกำลังพิมพ์ (ผู้ใช้สั่ง 2026-09-12)

   เดิมขอบไล่สีตลอดเวลา ทำให้ช่องค้นหาเด่นกว่าช่องกรอกทั้งเว็บโดยไม่มีเหตุผล
   ใช้สีเดียวกับ `.form-input` เป๊ะ ๆ คือ `rgba(var(--text-primary-rgb), 0.12)`

   ขอบตัวจริงคือ `::before` (inset -2px) ของ design — ที่นี่เปลี่ยนแค่ผืนสีของมัน
   ไม่แตะ `::after` ที่ปิดทับเป็นพื้นช่อง โครงเดิมจึงยังทำงานเหมือนเดิมทุกอย่าง
   (แก้ที่นี่ไม่ใช่ที่ styles.css ตามกฎของโปรเจ็ค)

   🔴 ต้องเป็น `:focus-within` ไม่ใช่ `:focus` — ตัวที่ได้โฟกัสจริงคือ `<input>`
   ข้างใน ส่วนตัวที่วาดขอบคือ wrapper ข้างนอก
   ============================================================ */
.header-search-wrapper::before {
  /* บางลงให้เท่าเส้น 1.5px ของ .form-input (เดิมหนา 2px เพราะเป็นขอบไล่สี) */
  inset: -1.5px;
  background: rgba(var(--text-primary-rgb), 0.12);
  transition: background 0.25s ease;
}

.header-search-wrapper:hover::before,
.header-search-wrapper:focus-within::before {
  inset: -2px;
  background: linear-gradient(90deg,
    var(--grad-1) 0%,
    var(--grad-2) 12.5%,
    var(--grad-3) 25%,
    var(--grad-4) 37.5%,
    var(--grad-1) 50%,
    var(--grad-2) 62.5%,
    var(--grad-3) 75%,
    var(--grad-4) 87.5%,
    var(--grad-1) 100%
  );
  background-size: 200% 100%;
  animation: gradient-slide 1s linear infinite;
}

/* เครื่องที่ตั้งให้ลดการเคลื่อนไหว — ขอบยังเปลี่ยนเป็นไล่สี แต่ไม่วิ่ง */
@media (prefers-reduced-motion: reduce) {
  .header-search-wrapper:hover::before,
  .header-search-wrapper:focus-within::before {
    animation: none;
  }
}

/* ============================================================
   หมายเหตุเรื่องยอดที่จะได้คืน — หน้าขอคืนสินค้าและการ์ดคำขอคืน
   ผู้ใช้สั่งให้แจ้งชัด ๆ ว่าค่าจัดส่งตอนสั่งซื้อไม่ได้คืน (2026-08-23)
   ============================================================ */

.es-refund-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 10px 0 0 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: rgba(var(--grad-1-rgb), 0.08);
  border: 1px solid rgba(var(--grad-1-rgb), 0.25);
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.es-refund-note i {
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--grad-1);
}

.es-refund-note strong {
  color: var(--text-primary);
  font-weight: 600;
}

/* ============================================================
   ยอดเงินของคำขอคืน — ฝั่งผู้ขาย (template-parts/vendor/return-money.php)
   ร้านต้องเห็นทั้งยอดที่ผู้ซื้อได้คืน และยอดที่จะถูกหักจากรายได้
   ก่อนกด CONFIRM (เพิ่ม 2026-08-23)
   ============================================================ */

.return-money {
  margin: 12px 0 0 0;
  padding: 12px 14px;
  border-radius: 10px;
  background: rgba(var(--grad-1-rgb), 0.06);
  border: 1px solid rgba(var(--grad-1-rgb), 0.22);
}

.return-money__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  line-height: 1.7;
}

.return-money__label {
  color: var(--text-secondary);
}

.return-money__amount {
  font-weight: 600;
  color: var(--text-primary);
  white-space: nowrap;
}

/* ยอดที่ร้านเสียไป — ให้สะดุดตาแยกจากยอดที่ผู้ซื้อได้ */
.return-money__row--deduct .return-money__amount {
  color: var(--danger, #ff6b81);
}

.return-money__note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 8px 0 0 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.return-money__note i {
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--grad-1);
}

/* ============================================================
   แจ้งผู้ขายว่าสินค้าที่รับคืนยังไม่ได้เปิดขายใหม่
   (template-parts/vendor/return-detail.php · inc/restock.php)
   ระบบไม่เปิดขายให้เอง เพราะของอาจชำรุด — ผู้ขายกดเอง (2026-08-24)
   ============================================================ */

.return-restock {
  margin-top: 14px;
}

.return-restock__note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 12px 0;
  padding: 12px 14px;
  border-radius: 10px;
  background: rgba(var(--grad-1-rgb), 0.08);
  border: 1px solid rgba(var(--grad-1-rgb), 0.25);
  font-size: 13px;
  line-height: 1.65;
  color: var(--text-secondary);
}

.return-restock__note i {
  flex-shrink: 0;
  margin-top: 3px;
  color: var(--grad-1);
}

/* ============================================================
   ชื่อร้าน / ชื่อสินค้า ที่กดเข้าหน้านั้น ๆ ได้

   ผู้ใช้สั่ง 2026-08-28: *"ถ้ามีชื่อร้านปรับเป็นกดแล้วเข้าลิงก์หน้าร้านได้
   และชื่อสินค้ากดแล้วก็เข้าไปดูสินค้านั้น ๆ เหมือนกัน"*

   🔴 **ต้องล้างสไตล์ลิงก์กลางทิ้ง** — กฎ `a` ใน styles.css ตั้งสีฟ้า `--grad-4`
   และ `a:hover` เล่นไล่สีวิ่ง (`gradient-slide`) ถ้าไม่ล้าง ชื่อร้านในการ์ด
   คำสั่งซื้อจะกลายเป็นตัวหนังสือฟ้าวิบวับ อ่านแล้วนึกว่าเป็นปุ่มอื่น

   ที่นี่ให้ลิงก์ **สืบสีจากข้อความรอบตัว** แล้วบอกว่ากดได้ด้วยเส้นใต้ตอน hover
   ซึ่งเป็นสัญญาณที่เบาพอจะไม่รบกวนการอ่าน
   ============================================================ */
.order-card__vendor-name a,
.cart-shipping-vendor-name a,
.vendor-shipping-vendor a,
.payment-vendor__name a,
.order-detail-actions__label a,
.checkout-totals-label a,
.checkout-order-item-name a,
.cart-item-name a,
.return-reason-item__title a,
.product-vendor a,
.vendor-title a {
  color: inherit;
  text-decoration: none;
  background: none;
  -webkit-text-fill-color: currentColor;
}

/* ── ชื่อสินค้า: hover เป็นสีฟ้าเรียบ ──
   ผู้ใช้สั่ง 2026-08-29 ให้ทุกที่เหมือนกัน — ชุดนี้คือชุดเดียวกับ
   `.order-card__product-info h4 a:hover` ที่ใช้อยู่เดิมท้ายไฟล์
   (ชื่อ**ร้าน**ต่างหากที่เป็นไล่สี ดูบล็อกถัดไป) */
.checkout-order-item-name a:hover,
.checkout-order-item-name a:focus-visible,
.cart-item-name a:hover,
.cart-item-name a:focus-visible,
.return-reason-item__title a:hover,
.return-reason-item__title a:focus-visible {
  color: var(--grad-4);
  -webkit-text-fill-color: var(--grad-4);
  background: none;
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
  text-decoration: none;
}

/* ── ชื่อร้าน: hover เป็นตัวหนังสือไล่สีวิ่ง ──
   ผู้ใช้สั่ง 2026-08-28 ให้ใช้ไล่สีชุดเดียวกับลิงก์ทั่วเว็บ
   (`a:hover` ใน styles.css + `@keyframes gradient-slide` ที่ styles.css:784)

   🔴 **ต้องมี padding แนวตั้ง** — `background-clip:text` ตัดพื้นหลังตามรูป
   ตัวอักษร แต่พื้นหลังวาดแค่ในกล่อง content ส่วนวรรณยุกต์ไทยที่ซ้อนชั้นบน
   ล้นขอบออกไป ตรงนั้นไม่มีพื้นให้ตัด = มาร์กหายทั้งตัว (เจอในสไลด์นำเสนอมาแล้ว)
   ⚠️ padding ของ element แบบ inline ไม่กระทบ layout จึงใส่ได้ปลอดภัย */
.order-card__vendor-name a:hover,
.order-card__vendor-name a:focus-visible,
.cart-shipping-vendor-name a:hover,
.cart-shipping-vendor-name a:focus-visible,
.vendor-shipping-vendor a:hover,
.vendor-shipping-vendor a:focus-visible,
.payment-vendor__name a:hover,
.payment-vendor__name a:focus-visible,
.order-detail-actions__label a:hover,
.order-detail-actions__label a:focus-visible,
.checkout-totals-label a:hover,
.checkout-totals-label a:focus-visible,
.product-vendor a:hover,
.product-vendor a:focus-visible,
.vendor-title a:hover,
.vendor-title a:focus-visible {
  color: transparent;
  background: linear-gradient(90deg,
    var(--grad-1) 0%,
    var(--grad-2) 12.5%,
    var(--grad-3) 25%,
    var(--grad-4) 37.5%,
    var(--grad-1) 50%,
    var(--grad-2) 62.5%,
    var(--grad-3) 75%,
    var(--grad-4) 87.5%,
    var(--grad-1) 100%
  );
  background-size: 200% 100%;
  background-position: 0% 50%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: gradient-slide 1.5s linear infinite;
  padding: 0.22em 0 0.12em;
  text-decoration: none;
}

/* คนที่ตั้งเครื่องให้ลดการเคลื่อนไหว — คงไล่สีไว้แต่หยุดวิ่ง */
@media (prefers-reduced-motion: reduce) {
  .order-card__vendor-name a:hover,
  .cart-shipping-vendor-name a:hover,
  .vendor-shipping-vendor a:hover,
  .payment-vendor__name a:hover,
  .order-detail-actions__label a:hover,
  .checkout-totals-label a:hover,
  .product-vendor a:hover,
  .vendor-title a:hover {
    animation: none;
  }
}

/* ============================================================
   หัวโปรไฟล์ผู้ซื้อให้เท่ากับหัวร้าน (ผู้ใช้สั่ง 2026-08-29)

   `.profile-header` (my-account) กับ `.store-header` (dashboard ผู้ขาย)
   ต้องเป็นบล็อกเดียวกันเป๊ะ ๆ — วัดจริงบนเบราว์เซอร์แล้วเจอต่างกัน 4 จุด
   (สูง 139px กับ 114px):

     | จุด            | หัวร้าน (ยึดตามนี้) | หัวโปรไฟล์เดิม |
     |----------------|--------------------|----------------|
     | gap ของกล่องขวา | 6px                | 8px            |
     | ป้ายใต้ชื่อ      | 11px สูง 20px      | 12px สูง 26px  |
     | ปุ่มแก้ไข        | ไม่มี margin-top    | margin-top 5px |
     | แถวปุ่ม         | flex-wrap: wrap    | nowrap         |

   ⚠️ **ความสูงของชื่อไม่ใช่บั๊ก** — วัดแล้ว `.profile-name` สูง 32px
   ส่วน `.store-name` สูง 22px ทั้งที่ font-size 20px เท่ากัน เพราะชื่อร้าน
   ตัวอย่างเป็นอักษรไทย ฟอนต์สำรองไทย (LINESeedSansTH_W) มี metric สูงกว่า
   ทดสอบด้วยข้อความอังกฤษในกล่องเดียวกันได้ 22px เท่ากันพอดี
   **ห้ามไปบังคับ line-height ให้เตี้ยลง** วรรณยุกต์ไทยจะโดนตัด
   ============================================================ */

/* ระยะห่างแนวตั้งในกล่องขวา
   เจาะจงที่ `.profile-header` เพราะหน้าแก้ไขบัญชีใช้ `.profile-info`
   เป็นกล่องฟอร์ม คนละงานกัน และมีกฎ gap ของตัวเองอยู่แล้ว (บรรทัด ~2198)

   ผู้ใช้สั่ง 2026-08-29 รอบสอง: *"ให้ลิงก์หรืออีเมลชิดกับชื่อด้านบนกว่านี้
   และห่างจากปุ่ม edit profile กับ edit store เพิ่มมาเล็กน้อย"*
   → ลด gap ของคอลัมน์เหลือ 4px (ชื่อ→ป้าย) แล้วดันเฉพาะแถวปุ่มลงอีก 6px
   ได้ระยะ ป้าย→ปุ่ม เป็น 10px ทั้งสองหน้า

   `:has(.store-header-actions)` = หัวร้านใน**แดชบอร์ดผู้ขาย**เท่านั้น
   หน้าร้านสาธารณะไม่มีแถวปุ่ม (ใต้ป้ายเป็นดาวกับจำนวนผลงาน) จึงไม่โดนกฎนี้ */
.profile-header .profile-info,
.store-header:has(.store-header-actions) .store-info {
  gap: 4px;
}

.profile-actions,
.store-header-actions {
  margin-top: 6px;
}

/* 🔴 ชื่อต้องสูงเท่ากันไม่ว่าจะเป็นภาษาอะไร (ผู้ใช้แจ้ง 2026-08-29 รอบสอง)
   `line-height: normal` ให้ความสูงตาม metric ของฟอนต์ที่ใช้จริง —
   ชื่อไทย (ฟอนต์สำรอง LINESeedSansTH_W) ได้ 32px ส่วนชื่ออังกฤษ
   (ArchivoSemiExpanded) ได้ 22px หัวโปรไฟล์กับหัวร้านจึงต่างกัน 10px
   ทั้งที่ CSS ทุกตัวเหมือนกันหมด

   ตรึงเป็น 1.6 = 32px ที่ font-size 20px คือ**ค่าที่ไทยได้อยู่แล้ว**
   จึงไม่มีทางเฉือนวรรณยุกต์ ส่วนชื่ออังกฤษถูกดันขึ้นมาเท่ากันพอดี
   ⚠️ ห้ามลดต่ำกว่า 1.6 — วรรณยุกต์ไทยจะโดนตัด */
.profile-header .profile-name,
.store-header .store-name {
  line-height: 1.6;
}

/* ปุ่ม EDIT PROFILE — `.btn-edit-store` ไม่มี margin-top ปุ่มนี้จึงต้องไม่มีด้วย
   (profile.css:47 ตั้ง margin-top: 5px ไว้ ทำให้แถวปุ่มต่ำลงกว่าหัวร้าน 5px) */
.profile-header .btn-edit-profile {
  margin-top: 0;
}

/* ============================================================
   อีเมลใต้ชื่อในหน้าโปรไฟล์ (ผู้ใช้สั่ง 2026-08-29)

   ทรงเดียวกับป้ายลิงก์ร้าน **ในหน้า dashboard** (`.store-profile-link`
   ใน assets/css/store.css:54 + กฎกว้างที่บรรทัด ~5999 ของไฟล์นี้)
   — แต่ **แสดงอย่างเดียว** จึงไม่มี `cursor:pointer` ไม่มี hover ไม่ใช่ลิงก์

   ⚠️ ห้ามลอกค่าจาก `store-profile.css` — นั่นเป็นของ **หน้าร้านสาธารณะ**
   ซึ่งขยายป้ายเป็น 12px / max-width 400px ที่ ≥769px หน้า dashboard ไม่ขยาย
   ลอกผิดไฟล์คือสาเหตุที่ป้ายอีเมลเคยสูงกว่าป้ายลิงก์ร้าน 6px
   ============================================================ */
.profile-email {
  display: inline-flex;
  /* `.profile-info` เป็น flex column — ถ้าไม่บอกให้หดเอง ป้ายจะยืดเต็มความกว้าง
     กลายเป็นแถบยาวแทนที่จะเป็นป้ายพอดีตัวอักษรเหมือนป้ายลิงก์ร้าน
     (ตรงกับ `width: max-content; max-width: 100%` ของป้ายลิงก์ร้าน) */
  align-self: flex-start;
  width: max-content;
  max-width: 100%;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 4px 10px;
  border-radius: 6px;
  background: rgba(var(--text-primary-rgb), 0.06);
  color: var(--text-secondary);
  font-size: 11px;
  user-select: text;
}

.profile-email i {
  flex-shrink: 0;
  font-size: 12px;
}

/* อีเมลยาวเกินป้ายให้ตัดด้วย … (ตัวเต็มอยู่ใน title ของป้าย) */
.profile-email span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* ============================================================
   ช่องติ๊กยอมรับข้อกำหนดในฟอร์มสมัคร + หน้ากั้นหลังล็อกอิน (2026-08-29)
   คู่กับ inc/terms-gate.php
   ============================================================ */

/* ── ช่องติ๊กในฟอร์มสมัคร ────────────────────────────────── */

.es-terms-check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 4px 0 18px;
  font-size: 13px;
  line-height: 1.65;
  color: var(--text-secondary);
  cursor: pointer;
}

/* ⚠️ ช่องติ๊กต้องไม่หดตามข้อความที่ขึ้นบรรทัดใหม่
   (flex item หดได้เป็นค่าเริ่มต้น — ปล่อยไว้จะได้ช่องติ๊กแบน ๆ บนจอแคบ) */
.es-terms-check input[type="checkbox"] {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  margin: 2px 0 0;
  accent-color: var(--grad-2);
  cursor: pointer;
}

.es-terms-check a {
  color: var(--grad-2);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ── หน้ากั้น ────────────────────────────────────────────── */

.es-gate {
  max-width: 520px;
  margin: 0 auto;
  padding: 48px 20px 32px;
  text-align: center;
}

.es-gate__icon {
  margin-bottom: 18px;
  font-size: 40px;
  background: var(--gradient);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.es-gate__title {
  margin: 0 0 12px;
  font-size: 22px;
  line-height: 1.5;
  color: var(--text-primary);
}

.es-gate__text {
  margin: 0 0 24px;
  font-size: 14px;
  line-height: 1.75;
  color: var(--text-secondary);
}

/* รายการเอกสาร — จัดกลางแนวนอน ข้อความในแต่ละอันอ่านง่ายในบรรทัดเดียว */
.es-gate__docs {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0 0 10px;
  padding: 0;
  list-style: none;
}

.es-gate__docs a {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 16px;
  border-radius: 12px;
  border: 1px solid rgba(var(--text-primary-rgb), 0.16);
  background: var(--bg-card, #1a1a2e);
  color: var(--text-primary);
  font-size: 14px;
  text-decoration: none;
  transition: border-color 0.2s;
}

.es-gate__docs a:hover {
  border-color: var(--grad-2);
  /* ยกเว้น a:hover ของ design ที่ทำตัวอักษรโปร่งใส (กับดักข้อ 6) */
  -webkit-text-fill-color: var(--text-primary);
  background: var(--bg-card, #1a1a2e);
  background-clip: border-box;
  animation: none;
}

.es-gate__docs i {
  font-size: 12px;
  color: var(--text-secondary);
}

.es-gate__hint {
  margin: 0 0 26px;
  font-size: 12px;
  line-height: 1.7;
  color: var(--text-muted);
}

.es-gate__form {
  margin: 0 0 18px;
}

/* ปุ่มยอมรับ — ชุดเดียวกับ `.btn-read-aloud` และแถบคุกกี้ (ผู้ใช้สั่ง 2026-08-29)
   🔴 ต้นทางอยู่ที่ `assets/css/single-product.css:394-457` แก้ที่นั่นต้องมาแก้ที่นี่
   (ปุ่มนี้เต็มความกว้างและข้อความยาวกว่า จึงคุมขนาดเอง ที่เหลือเหมือนกันหมด) */
.es-gate__btn {
  display: block;
  position: relative;
  z-index: 1;
  isolation: isolate;
  width: 100%;
  padding: 15px 20px;
  border: 0;
  border-radius: var(--radius-btn, 50px);
  background: transparent;
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.06em;
  line-height: 1.6;
  cursor: pointer;
  transition: box-shadow 0.3s;
  /* เผื่อกรณีที่ยังตกบรรทัดจริง ๆ — ให้แบ่งสองบรรทัดยาวเท่า ๆ กัน
     ดีกว่าเหลือคำเดียวห้อยอยู่บรรทัดล่าง (เบราว์เซอร์เก่าไม่รู้จักก็ข้ามไปเอง) */
  text-wrap: balance;
}

.es-gate__btn::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: var(--radius-btn, 50px);
  background: var(--gradient);
  z-index: -1;
  transition: background-size 0.4s ease, filter 0.3s;
}

.es-gate__btn::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--radius-btn, 50px);
  background: transparent;
  z-index: -1;
}

.es-gate__btn:hover::before,
.es-gate__btn:focus-visible::before {
  background: linear-gradient(90deg,
    var(--grad-1) 0%,
    var(--grad-2) 12.5%,
    var(--grad-3) 25%,
    var(--grad-4) 37.5%,
    var(--grad-1) 50%,
    var(--grad-2) 62.5%,
    var(--grad-3) 75%,
    var(--grad-4) 87.5%,
    var(--grad-1) 100%
  );
  background-size: 200% 100%;
  animation: gradient-slide 4.5s linear infinite;
}

.es-gate__btn:active {
  box-shadow:
    0 0 12px 3px rgba(var(--grad-1-rgb), 0.28),
    0 0 16px 4px rgba(var(--grad-4-rgb), 0.20);
}

/* จอเล็ก — บีบตัวอักษรลงเล็กน้อยให้เหลือที่หายใจมากขึ้น

   ⚠️ นี่คือ **ตาข่ายรับ ไม่ใช่ทางแก้หลัก** ทางแก้หลักคือข้อความสั้นพอ
   (ดูคอมเมนต์ในไฟล์ `template-parts/terms-gate.php`) ตัวนี้เผื่อไว้สำหรับ
   เครื่องที่ผู้ใช้ตั้งขนาดตัวอักษรใหญ่กว่าปกติ หรือฟอนต์ธีมโหลดไม่ทัน
   แล้วตัวสำรองของเครื่องกว้างกว่า */
@media (max-width: 400px) {
  .es-gate {
    padding-left: 14px;
    padding-right: 14px;
  }

  .es-gate__btn {
    padding-left: 14px;
    padding-right: 14px;
    font-size: 13px;
    letter-spacing: 0.03em;
  }
}

.es-gate__out {
  display: inline-block;
  padding: 8px 4px;
  font-size: 13px;
  color: var(--text-secondary);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.es-gate__out:hover {
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  background: none;
  background-clip: border-box;
  animation: none;
}

/* ============================================================
   แถบขอความยินยอมคุกกี้ (2026-08-29) — คู่กับ inc/consent.php

   ลอยล่างจอ ไม่บังเนื้อหา ไม่มีฉากดำคลุมทั้งหน้า

   🔴 **ตำแหน่งล่างมาจาก JS ไม่ใช่เลขตายตัว**
   เว็บนี้มีแถบเมนูล่างแบบลอย ซึ่งมี 3 กรณีและสูงไม่เท่ากัน (ดู footer.php)
   ตั้งเลขตายตัวเมื่อไรจะมีหน้าที่แถบไปทับเมนูจนกดไม่ได้เสมอ
   consent.js จึงวัดของจริงแล้วเขียนลง `--es-consent-lift` ให้
   ค่าสำรองด้านล่างใช้ตอน JS ยังไม่ทัน — เผื่อไว้ให้พ้นเมนูไว้ก่อน
   ============================================================ */
.es-consent {
  position: fixed;
  left: 50%;
  bottom: calc(12px + var(--es-consent-lift, 0px) + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 9500;
  width: calc(100% - 24px);
  max-width: 560px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 18px;
  border-radius: 14px;
  border: 1px solid rgba(var(--text-primary-rgb), 0.14);
  background: var(--bg-card, #16162c);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
}

/* `hidden` ต้องชนะ `display:flex` ข้างบน ไม่งั้นแถบโผล่ตลอดเวลา
   (กับดักเดียวกับที่เจอในแถบลิงก์สินค้าของผู้ขาย) */
.es-consent[hidden],
.es-consent [hidden] {
  display: none;
}

.es-consent__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

/* 🔴 คอนทราสต์ — ห้ามกลับไปใช้ `--text-secondary` ที่นี่ (แก้ 2026-09-05)
   `--text-secondary` (#7b7399) บนพื้นกล่อง `--bg-card` (#1a1a2e) ได้แค่
   **3.86:1** ต่ำกว่าเกณฑ์ AA (4.5:1) — Lighthouse ฟ้องกล่องนี้ตรง ๆ
   #9d95bd คือโทนเดียวกันอ่อนขึ้นหนึ่งขั้น ได้ **6.07:1**
   ⚠️ แก้เฉพาะในกล่องนี้ ไม่แตะตัวแปรกลาง — `--text-secondary` ยังถูกใช้
   อีกหลายร้อยจุดบนพื้นหลังที่เข้มกว่านี้ซึ่งผ่านเกณฑ์อยู่แล้ว */
.es-consent__text {
  margin: 0;
  font-size: 13px;
  line-height: 1.65;
  color: #9d95bd;
}

/* บรรทัด "ตอนนี้: …" / "บันทึกแล้ว — …"
   ต้องเด่นกว่าตัวอธิบาย เพราะเป็นคำตอบของคำถามที่คนกดเข้ามาถาม */
.es-consent__state {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.6;
  color: var(--text-primary);
}

.es-consent__state.is-saved {
  color: var(--grad-2);
}

.es-consent__more {
  margin: 0;
  font-size: 13px;
  line-height: 1.65;
}

/* 🔴 คอนทราสต์ — `--grad-2` (#D91BC0) บนพื้นกล่องได้ **3.95:1** ตกเกณฑ์
   #f07fe0 เป็นชมพูตัวเดียวกันอ่อนลง ได้ **7.16:1** (แก้ 2026-09-05) */
.es-consent__more a,
.es-consent__text a {
  color: #f07fe0;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.es-consent__actions {
  display: flex;
  gap: 10px;
}

/* 🔴 ปุ่มสองอันต้องกว้างเท่ากันและเด่นเท่ากัน
   แถบที่ทำปุ่มปฏิเสธเล็ก/จางกว่า ถือว่าความยินยอมไม่สมบูรณ์ตามหลัก PDPA

   ── หน้าตายืมมาจากปุ่มเสียงอ่านทั้งคู่ (ผู้ใช้สั่ง 2026-08-29) ──────────
   ปุ่มยอมรับ  = `.btn-read-aloud` (วงแหวนไล่สีเต็มปุ่ม)
   ปุ่มปฏิเสธ  = `.btn-read-stop`  (เส้นขอบจาง ๆ)
   สองตัวนั้นเป็นคู่กันอยู่แล้วในหน้าสินค้า เอามาทั้งคู่จึงได้ภาษาเดียวกัน
   ทั้งตอนปกติและตอน hover โดยไม่ต้องคิดใหม่

   🔴 **ต้นทางอยู่ที่ `assets/css/single-product.css:394-457`**
   แก้เอฟเฟกต์ที่นั่นเมื่อไร ต้องมาแก้ที่นี่ด้วย — คัดลอกมา ไม่ได้ใช้คลาสร่วมกัน
   เพราะกฎต้นทางผูกกับ `.product-description` ซึ่งไม่มีในแถบคุกกี้ */
.es-consent__btn {
  flex: 1 1 0;
  position: relative;
  z-index: 1;
  isolation: isolate;
  padding: 10px 18px;
  border: 1px solid rgba(var(--text-secondary-rgb), 0.4);
  border-radius: var(--radius-btn, 50px);
  background: transparent;
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s, background 0.2s, box-shadow 0.3s;
}

/* ปุ่มปฏิเสธ — hover ชุดเดียวกับปุ่มหยุดอ่าน (`.btn-read-stop`) */
.es-consent__btn:hover,
.es-consent__btn:focus-visible {
  border-color: var(--grad-4);
  color: var(--grad-4);
  background: rgba(var(--grad-4-rgb), 0.1);
}

/* ── ปุ่มยอมรับ — ชุดเดียวกับ `.btn-read-aloud` ─────────────────────── */
.es-consent__btn--yes {
  border: none;
  color: var(--text-primary);
}

/* วงแหวนไล่สี ล้ำออกนอกปุ่ม 2px ให้ขอบดูนุ่ม (ค่าเดียวกับต้นทาง) */
.es-consent__btn--yes::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: var(--radius-btn, 50px);
  background: var(--gradient);
  z-index: -1;
  transition: background-size 0.4s ease, filter 0.3s;
}

.es-consent__btn--yes::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--radius-btn, 50px);
  background: transparent;
  z-index: -1;
}

/* ⚠️ ต้องล้าง hover ของปุ่มปฏิเสธออก ไม่งั้นปุ่มยอมรับจะได้ขอบกับพื้นหลัง
   ของอีกแบบมาทับไล่สี (กฎด้านบนมี specificity เท่ากันและมาก่อน) */
.es-consent__btn--yes:hover,
.es-consent__btn--yes:focus-visible {
  border-color: transparent;
  color: var(--text-primary);
  background: transparent;
}

/* ไล่สีวิ่ง — กฎชุดเดียวกับ `.btn-read-aloud:hover::before` เป๊ะ ๆ
   (`@keyframes gradient-slide` อยู่ใน styles.css:794 ซึ่งโหลดทุกหน้า) */

/* ── ความเร็วของไล่สีวิ่ง ────────────────────────────────────────────
   🔴 **ยิ่งปุ่มกว้าง ยิ่งต้องช้าลง** (ผู้ใช้สั่ง 2026-08-29)
   `gradient-slide` เลื่อนพื้นหลังไป 1 รอบเต็มในเวลาที่กำหนด ไม่ว่าปุ่มจะ
   กว้างเท่าไร — ปุ่มยิ่งกว้าง ระยะทางที่สีต้องวิ่งยิ่งไกล ความเร็วที่ตาเห็น
   จึงยิ่งสูงขึ้นตามความกว้าง ใช้ 1s ของปุ่มเสียงอ่าน (กว้างราว 150px)
   กับปุ่มเต็มความกว้างแล้วจะกลายเป็นสีกระพริบจนลายตา

   ค่าที่ใช้ (คิดจาก "สีวิ่งกี่พิกเซลต่อวินาที" ไม่ใช่จากตัวเลขวินาทีลอย ๆ):

     | ปุ่ม | กว้างราว | รอบละ | สีวิ่ง |
     |---|---|---|---|
     | เสียงอ่าน (ต้นทาง) | 150px | 1s | 150 px/วิ |
     | ยอมรับคุกกี้ | 80px | 1.8s | 44 px/วิ |
     | ยอมรับข้อกำหนด | 480px | 4.5s | 107 px/วิ |
     | ส่งข้อความในทิกเก็ต | 150px | 1.4s | 107 px/วิ |

   🔴 เพิ่มปุ่มใหม่ที่ใช้เอฟเฟกต์นี้เมื่อไร **อย่าลอก 1s มาเฉย ๆ**
   ให้เอาความกว้างหารด้วยความเร็วที่ต้องการก่อน
   ------------------------------------------------------------------ */
.es-consent__btn--yes:hover::before,
.es-consent__btn--yes:focus-visible::before {
  background: linear-gradient(90deg,
    var(--grad-1) 0%,
    var(--grad-2) 12.5%,
    var(--grad-3) 25%,
    var(--grad-4) 37.5%,
    var(--grad-1) 50%,
    var(--grad-2) 62.5%,
    var(--grad-3) 75%,
    var(--grad-4) 87.5%,
    var(--grad-1) 100%
  );
  background-size: 200% 100%;
  animation: gradient-slide 1.8s linear infinite;
}

.es-consent__btn--yes:active {
  box-shadow:
    0 0 12px 3px rgba(var(--grad-1-rgb), 0.28),
    0 0 16px 4px rgba(var(--grad-4-rgb), 0.20);
}

/* ปุ่มที่กำลังใช้อยู่ตอนเปิดโหมดจัดการ — ต้องดูออกโดยไม่ต้องอ่านข้อความ

   🔴 **ห้ามใช้เส้นขอบหรือวงแหวนรอบปุ่ม** (ผู้ใช้สั่ง 2026-08-29)
   ใช้วิธีเดียวกับ `.btn-read-aloud.is-speaking` แทน คือ **เอากฎของ :hover
   มาค้างไว้** — ปุ่มที่ใช้อยู่จึงดูเหมือนถูกชี้ค้างไว้ตลอด ไม่มีของใหม่
   งอกขึ้นมาบนหน้าจอเลย (แพทเทิร์นเดิมของธีมอยู่ที่ woocommerce-bridge.css
   หัวข้อ "ปุ่มเปิดเสียงอ่าน — สถานะกำลังอ่าน") */
.es-consent__btn--yes.is-current::before {
  background: linear-gradient(90deg,
    var(--grad-1) 0%,
    var(--grad-2) 12.5%,
    var(--grad-3) 25%,
    var(--grad-4) 37.5%,
    var(--grad-1) 50%,
    var(--grad-2) 62.5%,
    var(--grad-3) 75%,
    var(--grad-4) 87.5%,
    var(--grad-1) 100%
  );
  background-size: 200% 100%;
  animation: gradient-slide 1.8s linear infinite;
}

/* ปุ่มปฏิเสธที่ใช้อยู่ — ค้างสีของ hover ไว้ (ชุดเดียวกับ `.btn-read-stop:hover`) */
.es-consent__btn.is-current:not(.es-consent__btn--yes) {
  border-color: var(--grad-4);
  color: var(--grad-4);
  background: rgba(var(--grad-4-rgb), 0.1);
}

/* ปุ่มปิด มีเฉพาะโหมดจัดการ (ตอนถามครั้งแรก JS ซ่อนไว้) */
.es-consent__close {
  position: absolute;
  top: 6px;
  right: 10px;
  padding: 0 6px;
  border: 0;
  background: none;
  color: var(--text-secondary);
  font-size: 20px;
  line-height: 1.4;
  cursor: pointer;
}

.es-consent__close:hover {
  color: var(--text-primary);
}

/* แถวล่าง = ลิงก์อ่านนโยบาย + ปุ่มชิดขวา · คำอธิบายข้างบนกว้างเต็มกล่อง (ผู้ใช้สั่ง 2026-09-22)
   จอแคบที่ไม่พอบรรทัดเดียว ปุ่มตกลงบรรทัดใหม่แล้วกว้างเต็มแถว (สองปุ่มเท่ากัน) */
.es-consent__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
}

.es-consent__foot .es-consent__more {
  flex: 1 1 auto;
}

.es-consent__foot .es-consent__actions {
  flex: 1 0 auto;
  justify-content: flex-end;
}

/* ไอคอน + ข้อความในปุ่ม (2026-09-22) */
.es-consent__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

@media (min-width: 560px) {
  .es-consent__foot .es-consent__actions {
    flex: 0 0 auto;
    margin-left: auto;
  }

  .es-consent__btn {
    flex: 0 0 auto;
    white-space: nowrap;
  }
}

/* โหมดจัดการมีปุ่มปิดมุมขวาบน — เว้นที่เฉพาะบรรทัดแรก ("ตอนนี้: …") คำอธิบายข้างล่างยังกว้างเต็มกล่อง */
.es-consent.is-manage .es-consent__body > :first-child:not([hidden]),
.es-consent.is-manage .es-consent__state:not([hidden]) {
  padding-right: 22px;
}

/* ============================================================
   กล่องแจ้งสินค้า/ร้านค้าที่ไม่เหมาะสม (2026-08-30)
   คู่กับ inc/abuse-reports.php + assets/js/report-abuse.js

   ── หลักคิดของหน้าตา ──────────────────────────────────────
   🔴 **ต้องหาเจอ แต่ต้องไม่เด่นกว่าปุ่มซื้อ**
   ทำให้เด่นเท่าปุ่มหลักเมื่อไร คนจะกดเข้ามาดูเพราะสงสัยว่าคืออะไร
   แล้วหน้าสินค้าจะกลายเป็นหน้าที่ชวนให้ระแวงร้านค้าไปโดยปริยาย
   → ตัวเปิดเป็นลิงก์เล็ก ๆ สีจาง อยู่ล่างสุดของหน้า ส่วนฟอร์มอยู่ใน modal

   🔴 **ชื่อบล็อกคือ `es-abuse` ไม่ใช่ `es-report`**
   `es-report` ถูกจองไว้แล้วโดย "ศูนย์รายงาน" (ใช้อยู่ 68 จุด — `.es-report__table`
   `.es-report__menu` ฯลฯ) ตอนแรกเผลอตั้งชื่อทับ แล้วกฎ `.es-report { border-top }`
   ของกล่องนี้จะไปตีเส้นให้ศูนย์รายงานด้วย ตั้งชื่อตามตาราง `es_abuse` แทน

   ⚠️ **ตัวกล่อง modal ไม่ได้เขียนที่นี่** — ยืม `.avatar-cropper` /
   `.avatar-cropper__box` จาก `assets/css/image-cropper.css` มาทั้งชุด
   (แบบเดียวกับ `.es-bank-modal` · `.es-ship-modal` · `.es-detail-modal`)
   ที่นี่มีแต่ส่วนต่างของกล่องนี้เท่านั้น
   🔴 ไฟล์นั้นต้องถูก enqueue คู่กันเสมอ — ดู `inc/enqueue.php`
   ============================================================ */

/* ⚠️ ไม่ตั้ง max-width/padding เอง — ปล่อยให้กว้างตามกล่องแม่เหมือน
   `.product-tags` (บรรทัด 9786) ถ้าตั้งเองจะไม่ตรงขอบกับส่วนอื่นของหน้า
   ทั้งบนมือถือและตอนขยายเป็น 1024px บนจอใหญ่ */
.es-abuse {
  margin: 28px 0 8px;
  border-top: 1px solid rgba(var(--text-muted-rgb), 0.35);
  padding-top: 14px;
}

.es-abuse__open {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 2px;
  color: var(--text-secondary);
  font-size: 13px;
  text-decoration: none;
  transition: color 0.2s;
}

/* ⚠️ ลิงก์ทั่วเว็บมีเอฟเฟกต์ไล่สีที่ `:hover` (styles.css) ซึ่งทำให้ตัวหนังสือ
   โปร่งใสด้วย `-webkit-text-fill-color` ตัวนี้ไม่ควรวิบวับ — ปิดทับให้ครบ
   ทั้งสามอย่าง ไม่งั้นข้อความจะหายไปตอนเอาเมาส์ชี้ */
.es-abuse__open:hover,
.es-abuse__open:focus-visible {
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  background: none;
  background-clip: border-box;
  animation: none;
}

.es-abuse__open i {
  font-size: 12px;
  opacity: 0.8;
}

/* ── ตัวกล่อง ──
   `.avatar-cropper__box` ตั้ง `text-align: center` ไว้สำหรับกล่องตัดรูป
   ฟอร์มต้องชิดซ้าย ไม่งั้นป้ายช่องกับข้อความช่วยจะลอยอยู่กลางกล่อง
   ส่วนหัวเรื่องยังกลางไว้เหมือนกล่องอื่น

   🔴 `max-height` + `overflow-y` ขาดไม่ได้ — ฟอร์มนี้สูงกว่าจอมือถือ
   ถ้าไม่ใส่ ปุ่ม "ส่งเรื่อง" จะตกอยู่นอกจอและกดไม่ได้เลย
   (กล่องเลขพัสดุเคยเจอปัญหาเดียวกัน — ดู assets/js/icon-select.js) */
.es-abuse-modal__box {
  max-width: 440px;
  max-height: 88vh;
  overflow-y: auto;
  text-align: left;
}

.es-abuse-modal__box .avatar-cropper__title {
  text-align: center;
}

.es-abuse__lead {
  margin: 0 0 16px;
  color: var(--text-secondary);
  font-size: 13px;
  line-height: 1.7;
}

.es-abuse__hint {
  margin: 6px 0 0;
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1.6;
}

/* ── กล่องผลลัพธ์หลังกดส่ง ──
   สีเขียว/แดงตรงนี้ยืมตัวแปรของสถิติมาใช้ ไม่ตั้งสีใหม่
   เว็บนี้มีชุดสีบอกสถานะอยู่แล้ว การเพิ่มสีใหม่จะทำให้เขียว 2 เฉด */
.es-abuse__notice {
  margin: 0 0 16px;
  padding: 12px 14px;
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.7;
}

.es-abuse__notice--success {
  border: 1px solid rgba(var(--stat-success-rgb), 0.45);
  background: rgba(var(--stat-success-rgb), 0.12);
  color: var(--text-primary);
}

.es-abuse__notice--error {
  border: 1px solid rgba(var(--stat-error-rgb), 0.45);
  background: rgba(var(--stat-error-rgb), 0.12);
  color: var(--text-primary);
}

/* ── ช่องล่อบอท ──
   🔴 **ห้ามเปลี่ยนเป็น `display: none` หรือ `hidden`**
   บอทที่เขียนมาดีจะข้ามช่องที่ถูกซ่อนแบบนั้นเพราะรู้ว่าเป็นกับดัก
   วิธีนี้ทำให้ช่องยัง "มีอยู่จริง" ในสายตาเครื่อง แต่คนมองไม่เห็น
   (ตัวฟอร์มใส่ aria-hidden + tabindex="-1" กันคนใช้คีย์บอร์ด/โปรแกรม
   อ่านหน้าจอหลงเข้าไปแล้ว) */
.es-abuse__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ── แถบปุ่มล่าง ──
   🔴 **ต้องปักติดก้นกล่องไว้เสมอ** ฟอร์มนี้ยาวกว่าจอมือถือ ถ้าปล่อยให้
   ปุ่มไหลไปอยู่ท้ายสุดของเนื้อหา คนที่เปิดมาจะเห็นแต่ช่องกรอกและไม่รู้ว่า
   ต้องเลื่อนลงอีกเพื่อหาปุ่มส่ง — ปุ่มที่มองไม่เห็นเท่ากับไม่มีปุ่ม

   ระยะติดลบคือการ "ถอย" ออกไปกลบ padding 22px ของ `.avatar-cropper__box`
   ให้แถบปุ่มเต็มความกว้างกล่องและไม่มีช่องโหว่ให้เห็นเนื้อหาไหลลอดข้างล่าง */
.es-abuse-modal .avatar-cropper__actions {
  position: sticky;
  bottom: -22px;
  margin: 18px -22px -22px;
  padding: 14px 22px 22px;
  background: var(--bg-primary, #14101f);
}

/* ⚠️ ไม่ต้องทับสไตล์ปุ่ม — ใช้ CANCEL/SEND เป็นอังกฤษตัวใหญ่เหมือนกล่องอื่น
   จึงพอดีกับสเปกกลางของ `.avatar-cropper__actions > button` อยู่แล้ว
   (เคยทับไว้ตอนที่ปุ่มยังเป็นภาษาไทย ซึ่งยาวจนตกบรรทัด) */

/* ============================================================
   ทิกเก็ตติดต่อทีมงาน (2026-08-30)
   คู่กับ inc/tickets.php + assets/js/tickets.js

   ⚠️ **ตัวกล่อง modal ไม่ได้เขียนที่นี่** — ยืม `.avatar-cropper` /
   `.avatar-cropper__box` จาก `assets/css/image-cropper.css` มาทั้งชุด
   แบบเดียวกับกล่องรายงานสินค้า (`.es-abuse-modal`) และกล่องบัญชีรับเงิน
   🔴 ไฟล์นั้นต้องถูก enqueue คู่กันเสมอ — ดู `inc/enqueue.php`
   ============================================================ */

/* ── กลุ่มปุ่มฝั่งขวาของหัวโปรไฟล์ (2026-08-30) ──
   SUPPORT · TICKETS · LOGOUT อยู่ด้วยกันแล้วชิดขวา (ผู้ใช้สั่ง)

   🔴 **`margin-inline-start: auto` ต้องอยู่ที่กล่องนี้เท่านั้น**
   `a.btn-logout` (บรรทัด ~6618) มีของตัวเองอยู่แล้วสำหรับตอนที่ยังไม่มีกล่อง
   ถ้าปล่อยไว้ ปุ่มออกจากระบบจะดันตัวเองห่างจาก SUPPORT ออกไปอีกที
   จนสองปุ่มไม่ได้อยู่ด้วยกันจริง — ล้างทิ้งเมื่ออยู่ในกล่องนี้
   ⚠️ ล้างเฉพาะในกล่องนี้ ห้ามลบกฎต้นทาง หัวร้านในแดชบอร์ดผู้ขายยังใช้อยู่ */
.profile-actions__side {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-inline-start: auto;
  flex-wrap: wrap;
}

.profile-actions__side a.btn-logout {
  margin-inline-start: 0;
}

/* ── จอเล็ก: กลุ่มปุ่มฝั่งขวาเหลือแค่ไอคอน (ผู้ใช้สั่ง 2026-08-30) ──

   ⚠️ **ย่อเฉพาะกลุ่มขวา (SUPPORT · TICKETS · LOGOUT) เท่านั้น**
   `EDIT PROFILE` คงตัวหนังสือไว้เหมือนเดิมทุกขนาดจอ ตามที่ผู้ใช้สั่ง
   (เคยย่อทั้งสี่ปุ่มแล้วถูกสั่งให้คืนปุ่มซ้าย) — กฎทุกข้อในบล็อกนี้จึงต้อง
   ขึ้นต้นด้วย `.profile-actions__side` ห้ามเขียนถึง `.btn-edit-profile`

   **ที่มาของเลข 700px** (วัดจริงบนเบราว์เซอร์ 2026-08-30 ไม่ได้เดา):
     - โหมดตัวหนังสือ ปุ่มสี่ตัว + ช่องไฟ = **511px**
     - แถวปุ่มแคบกว่าจอ **152px** เสมอ (รูปโปรไฟล์ + ขอบซ้ายขวา)
     → ต้องมีจออย่างน้อย 511 + 152 = **663px** ตัวหนังสือถึงจะอยู่บรรทัดเดียว
   ⚠️ เคยตั้งไว้ 600px แล้ววัดเจอว่าช่วง 601–663px ปุ่มจะหักบรรทัดพอดี
   เผื่อไว้ถึง 700px เพราะฟอนต์สำรองของบางเครื่องกว้างกว่าฟอนต์ธีม

   🔴 **ซ่อนป้ายด้วยวิธี sr-only ไม่ใช่ `display: none`**
   `display: none` = โปรแกรมอ่านหน้าจออ่านไม่เจอ ปุ่มจะกลายเป็นปุ่มไม่มีชื่อ
   คนตาบอดจะใช้หน้าโปรไฟล์ไม่ได้เลย (ชุดกฎเดียวกับ `.es-sr-only`
   บรรทัด ~8256 — คัดลอกมาเพราะต้องมีผลเฉพาะในสื่อจอเล็ก) */
@media (max-width: 700px) {
  .profile-actions__side .btn-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* 🔴 **ความสูงต้องเท่าปุ่ม EDIT PROFILE** (ผู้ใช้สั่ง) — ไม่ตรึงเป็นตัวเลข
     `stretch` ทำให้กลุ่มสูงเท่าแถว ซึ่งแถวสูงตามปุ่มที่สูงที่สุดคือ EDIT PROFILE
     แล้วปุ่มข้างในสูง 100% ตาม → วันหลังใครแก้ padding ของปุ่ม EDIT
     ปุ่มไอคอนจะขยับตามเอง ไม่ต้องกลับมาแก้เลขที่นี่อีก
     (ตรึงเป็น px เมื่อไร วันที่ฟอนต์หรือ padding เปลี่ยน สองฝั่งจะสูงไม่เท่ากัน
      แล้วไม่มีใครสังเกตจนกว่าจะมีคนทัก) */
  .profile-actions__side {
    width: auto;
    margin-inline-start: auto;
    flex-wrap: nowrap;
    align-self: stretch;
  }

  .profile-actions__side a.btn-support,
  .profile-actions__side a.btn-tickets,
  .profile-actions__side a.btn-logout {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0;
    height: 100%;
    padding: 0;
    /* กลมพอดีโดยไม่ต้องรู้ความสูงล่วงหน้า — เบราว์เซอร์ที่ไม่รู้จัก
       `aspect-ratio` จะตกไปใช้ `min-width` แทน ปุ่มจะรีขึ้นแต่ยังกดได้ */
    aspect-ratio: 1;
    min-width: 30px;
    font-size: 14px;
  }

  /* ตัวเลขค้างอ่านย้ายไปเกาะมุมปุ่ม — ไม่มีที่ให้วางต่อท้ายแล้ว */
  .profile-actions__side a.btn-tickets {
    position: relative;
  }

  .profile-actions__side a.btn-tickets .es-ticket__badge {
    position: absolute;
    top: -3px;
    inset-inline-end: -3px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    font-size: 10px;
  }
}

/* ── ปุ่มติดต่อทีมงาน ──
   ทรงเดียวกับ `a.btn-logout` ทุกค่า ต่างแค่สี */
a.btn-support,
a.btn-tickets {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  white-space: nowrap;
  border-radius: var(--radius-btn, 50px);
  text-decoration: none;
  transition: background 0.2s ease;
}

a.btn-support {
  border: 1px solid rgba(var(--grad-4-rgb), 0.5);
  background: rgba(var(--grad-4-rgb), 0.12);
  color: var(--grad-4);
}

a.btn-tickets {
  border: 1px solid rgba(var(--text-secondary-rgb), 0.45);
  background: transparent;
  color: var(--text-secondary);
}

/* ยกเว้น a:hover ของ design ที่ทำให้ตัวอักษรหาย (กับดักข้อ 6)
   — ต้องปิดทั้งสามอย่าง ไม่งั้นข้อความหายตอนเอาเมาส์ชี้ */
a.btn-support:hover,
a.btn-support:focus-visible {
  background: rgba(var(--grad-4-rgb), 0.22);
  color: var(--grad-4);
  -webkit-text-fill-color: var(--grad-4);
  background-clip: border-box;
  animation: none;
}

a.btn-tickets:hover,
a.btn-tickets:focus-visible {
  background: rgba(var(--text-primary-rgb), 0.08);
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  background-clip: border-box;
  animation: none;
}

/* ไอคอนในปุ่ม SUPPORT / TICKETS / LOGOUT ต้องสีเดียวกับตัวหนังสือตอน hover (ผู้ใช้แจ้ง 2026-09-11)
   ต้นเหตุ: กฎกลาง `a[class*='btn']:hover i` (หัวข้อ "ปุ่มที่เราแปลงจาก <button>")
   บังคับไอคอนเป็นสีขาว ขณะที่ตัวหนังสือยังเป็นแดง/ฟ้าของปุ่ม
   specificity เท่ากัน (0,2,2) — ชนะด้วยลำดับ (อยู่หลัง) */
a.btn-support:hover i,
a.btn-support:focus-visible i,
a.btn-tickets:hover i,
a.btn-tickets:focus-visible i,
a.btn-logout:hover i,
a.btn-logout:focus-visible i {
  color: inherit;
  -webkit-text-fill-color: currentColor;
}

/* ป้ายตัวเลข "ยังไม่ได้อ่าน" — ใช้สีแดงชุดเดียวกับป้ายแจ้งเตือนอื่นในเว็บ */
.es-ticket__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--stat-error);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

/* ── กล่องเปิดทิกเก็ต ──
   🔴 `max-height` + `overflow-y` ขาดไม่ได้ — ฟอร์มนี้สูงกว่าจอมือถือ
   ไม่ใส่แล้วปุ่ม SEND จะตกอยู่นอกจอและกดไม่ได้เลย */
.es-ticket-modal__box {
  max-width: 460px;
  max-height: 88vh;
  overflow-y: auto;
  text-align: left;
}

.es-ticket-modal__box .avatar-cropper__title {
  text-align: center;
}

.es-ticket__lead {
  margin: 0 0 16px;
  color: var(--text-secondary);
  font-size: 13px;
  line-height: 1.7;
}

.es-ticket__hint {
  margin: 6px 0 0;
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1.6;
}

.es-ticket__notice {
  margin: 0 0 16px;
  padding: 12px 14px;
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.7;
}

.es-ticket__notice--success {
  border: 1px solid rgba(var(--stat-success-rgb), 0.45);
  background: rgba(var(--stat-success-rgb), 0.12);
  color: var(--text-primary);
}

.es-ticket__notice--error {
  border: 1px solid rgba(var(--stat-error-rgb), 0.45);
  background: rgba(var(--stat-error-rgb), 0.12);
  color: var(--text-primary);
}

/* แถบปุ่มล่างปักติดก้นกล่อง — เหตุผลเดียวกับกล่องรายงานสินค้า
   ปุ่มที่มองไม่เห็นเท่ากับไม่มีปุ่ม (ระยะติดลบคือการกลบ padding 22px ของกล่อง) */
.es-ticket-modal .avatar-cropper__actions {
  position: sticky;
  bottom: -22px;
  margin: 18px -22px -22px;
  padding: 14px 22px 22px;
  background: var(--bg-primary, #14101f);
}

/* ปุ่ม "MY TICKETS" ในกล่องเป็น <a> ไม่ใช่ <button> จึงไม่โดนกฎ
   `.avatar-cropper__actions > button` ของไฟล์ image-cropper — เขียนให้ตรงกัน */
.es-ticket-modal .avatar-cropper__actions > a {
  flex: 1 1 0;
  min-width: 0;
  padding: 16px 10px;
  border-radius: var(--radius-btn, 50px);
  font-family: var(--font, inherit);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

/* ── หน้า "ทิกเก็ตของฉัน" ── */
.es-ticket-list__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.es-ticket-list__head h3 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}

.es-ticket-list__head h3 i {
  color: var(--grad-1);
  font-size: 0.9em;
}

.es-ticket-list__new {
  font-size: 13px;
  color: var(--grad-4);
  text-decoration: none;
  white-space: nowrap;
}

.es-ticket-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  margin-bottom: 10px;
  border: 1px solid rgba(var(--text-muted-rgb), 0.4);
  border-radius: 14px;
  background: rgba(var(--bg-card-rgb), 0.55);
  text-decoration: none;
  transition: border-color 0.2s ease;
}

/* ============================================================
   🔴 hover ของทุกชิ้นในหน้าทิกเก็ต — เขียนใหม่ทั้งก้อน 2026-09-04

   ── อาการที่ผู้ใช้แจ้ง ──────────────────────────────────────
   *"effect เวลา hover ว่ามาจากไหน และทั้งหมด มันบัคๆ เวลา hover"*

   ── ต้นเหตุ ────────────────────────────────────────────────
   `assets/css/styles.css:197` ตั้ง `a:hover` **ทั้งเว็บ** ให้เป็นไล่สี
   วิ่งวน — background gradient + `background-clip: text` +
   `-webkit-text-fill-color: transparent` + `animation`
   ของเดิมพยายามปิดทีละชิ้นแล้วพลาด 3 จุด (วัดของจริงแล้วทุกข้อ):

     1. เขียน `background: none` ทับที่ `.es-ticket-card:hover`
        ซึ่งลบ `background: rgba(--bg-card-rgb, .55)` ของการ์ดไปด้วย
        → **การ์ดกลายเป็นโปร่งใสตอนเอาเมาส์ชี้**
     2. คืนสีตัวอักษรให้แค่ `__subject` กับ `__meta`
        → `.status-badge` กับป้าย "ใหม่" ที่อยู่ในการ์ดเดียวกัน
        **ยังรับ `-webkit-text-fill-color: transparent` มาทางมรดก
        = ตัวหนังสือหายไปเลย**
     3. `.es-ticket-tab` ไม่ได้ปิดอะไรเลยสักอย่าง
        → พิลล์ทั้งอันโดน `background-clip: text` ตัดเหลือแต่ตัวอักษร
        แล้ววิ่งไล่สีอยู่อย่างนั้น (นี่คือ "ป้ายว่ามาจากไหน" ที่แจ้งมา)

   ── วิธีที่ใช้แทน ──────────────────────────────────────────
   ปิดที่ตัวลิงก์ครั้งเดียว แล้วสั่งให้**ลูกทุกตัว**ระบายด้วยสีของตัวเอง
   (`currentColor`) แทนการไล่ระบุทีละคลาส — ชิ้นใหม่ที่เพิ่มเข้ามาทีหลัง
   จะไม่พังซ้ำอีก

   ⚠️ **`background-image: none` ไม่ใช่ `background: none`**
   ตัวหลังลบสีพื้นของการ์ดกับแท็บที่กำลังเปิดอยู่ไปด้วย
   ============================================================ */
.es-ticket-card:hover,
.es-ticket-card:focus-visible,
.es-ticket-tab:hover,
.es-ticket-tab:focus-visible,
.es-ticket-list__new:hover,
.es-ticket-list__new:focus-visible,
.es-ticket-thread__back:hover,
.es-ticket-thread__back:focus-visible {
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  animation: none;
}

.es-ticket-card:hover,
.es-ticket-card:hover *,
.es-ticket-card:focus-visible,
.es-ticket-card:focus-visible *,
.es-ticket-tab:hover,
.es-ticket-tab:hover *,
.es-ticket-tab:focus-visible,
.es-ticket-tab:focus-visible *,
.es-ticket-list__new:hover,
.es-ticket-list__new:hover *,
.es-ticket-list__new:focus-visible,
.es-ticket-list__new:focus-visible *,
.es-ticket-thread__back:hover,
.es-ticket-thread__back:hover *,
.es-ticket-thread__back:focus-visible,
.es-ticket-thread__back:focus-visible * {
  -webkit-text-fill-color: currentColor;
}

/* การ์ด: hover แล้วเปลี่ยน **แค่กรอบ** ตามที่ผู้ใช้สั่งไว้ 2026-08-30
   ไม่ไปยุ่งกับสีตัวอักษรอีกแล้ว — ของเดิมดันหัวข้อกับบรรทัดรองให้เป็น
   สีเดียวกันหมดตอน hover ซึ่งทำให้ลำดับความสำคัญที่ตั้งใจไว้หายไป */
.es-ticket-card:hover,
.es-ticket-card:focus-visible {
  border-color: rgba(var(--grad-4-rgb), 0.5);
  /* 🔴 พื้นการ์ดหายตอน hover (ผู้ใช้แจ้งซ้ำ 2026-09-11)
     `a:hover` ของ design เขียน `background:` แบบ shorthand ซึ่งล้าง background-color
     เป็นโปร่งใสด้วย และ `a:hover` (0,1,1) ชนะ `.es-ticket-card` (0,1,0)
     → การตั้ง background-image: none ข้างบนไม่พอ ต้องคืนสีพื้นตรงนี้ด้วย */
  background-color: rgba(var(--bg-card-rgb), 0.55);
}

/* ลิงก์ตัวหนังสือล้วนสองตัวนี้ไม่มีกรอบให้เปลี่ยน จึงใช้ความสว่างบอกแทน */
.es-ticket-list__new:hover,
.es-ticket-list__new:focus-visible,
.es-ticket-thread__back:hover,
.es-ticket-thread__back:focus-visible {
  color: var(--text-primary);
  opacity: 1;
}

/* เรื่องที่มีคนตอบแล้วแต่ยังไม่ได้เปิดอ่าน — ขอบซ้ายหนาให้เห็นตั้งแต่กวาดตา */
.es-ticket-card--unread {
  border-left: 3px solid var(--grad-1);
}

.es-ticket-card__main {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.es-ticket-card__subject {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-primary);
  font-weight: 600;
  font-size: 14px;
}

.es-ticket-card__meta {
  color: var(--text-secondary);
  font-size: 12px;
}

/* ── เส้นสนทนา ── */
.es-ticket-thread__back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 12px;
  color: var(--text-secondary);
  font-size: 13px;
  text-decoration: none;
}

.es-ticket-thread__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.es-ticket-thread__head h3 {
  margin: 0;
}

.es-ticket-thread__meta {
  margin: 6px 0 18px;
  color: var(--text-secondary);
  font-size: 12px;
}

.es-ticket-msgs {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 22px;
}

/* ข้อความของสองฝั่งต้องแยกออกจากกันด้วย **ตำแหน่งกับสี** ไม่ใช่แค่ชื่อคนพูด
   คนกวาดตาอ่านย้อนหลังต้องรู้ทันทีว่าอันไหนทีมงานตอบ */
.es-ticket-msg {
  max-width: 88%;
  padding: 12px 14px;
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.75;
}

.es-ticket-msg--user {
  align-self: flex-end;
  border: 1px solid rgba(var(--grad-4-rgb), 0.35);
  background: rgba(var(--grad-4-rgb), 0.10);
}

.es-ticket-msg--admin {
  align-self: flex-start;
  border: 1px solid rgba(var(--text-muted-rgb), 0.45);
  background: rgba(var(--bg-card-rgb), 0.6);
}

.es-ticket-msg__who {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 6px;
  color: var(--text-primary);
  font-weight: 600;
  font-size: 12px;
}

.es-ticket-msg__when {
  color: var(--text-muted);
  font-weight: 400;
  font-size: 11px;
}

.es-ticket-msg__body {
  color: var(--text-primary);
}

/* ── ปุ่มส่งข้อความในเส้นสนทนา ──
   ชุดเอฟเฟกต์เดียวกับ `.btn-read-aloud` / `.es-gate__btn` / `.es-abuse__submit`
   ⚠️ ต้องมี `::before` ซ้อนใต้ปุ่มแทนการใส่ `background` ที่ตัวปุ่มตรง ๆ
   ไม่งั้น `animation` จะไปขยับพื้นหลังของตัวหนังสือด้วย ตัวอักษรจะกะพริบตาม

   ความเร็วไล่สี 1.4s สำหรับปุ่มกว้างราว 150px ≈ 107 px/วิ
   (ดูตารางความเร็วในหัวข้อแถบคุกกี้ก่อนแก้ตัวเลขนี้ — ยิ่งปุ่มกว้างยิ่งต้องช้าลง) */
/* ── แถวล่างของช่องตอบกลับ ──
   ผู้ใช้สั่ง 2026-08-30: ปุ่มแนบรูปกับปุ่มส่งอยู่บรรทัดเดียวกัน ปุ่มส่งชิดขวา */
.es-ticket-reply__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

/* ============================================================
   🔴 ช่องพิมพ์ตอบทิกเก็ตต้องสีเดียวกันทั้งสองฝั่ง (แก้ 2026-09-06)

   ผู้ใช้แจ้งว่า "ช่องพิมตอนกดอ่านทิกเก็ตแล้วพิมตอบ โปรไฟล์กับร้านค้าคนละสี"
   วัดของจริงแล้วต่างกันจริง:

   | | ฝั่งโปรไฟล์ | ฝั่งร้าน |
   |---|---|---|
   | `.form-textarea` background | `transparent` → เห็นพื้นหน้า `#0a0820` | **`#0c0a1e`** (`--bg-input`) |

   สาเหตุ: `.dokan-dashboard-content textarea` (บรรทัด ~2684) ตั้ง
   `background: var(--bg-input)` ไว้ **แต่มีผลเฉพาะในแดชบอร์ดร้าน**
   เธรดฝั่งโปรไฟล์อยู่ที่ `/my-account/tickets/` ซึ่งไม่ได้อยู่ใน
   `.dokan-dashboard-content` ช่องจึงโปร่งใสและกลายเป็นสีพื้นหน้าแทน

   ผู้ใช้เลือกให้ยึด **สีฝั่งร้าน** → บังคับ `--bg-input` ให้ทั้งสองฝั่ง
   (ฝั่งร้านได้ค่าเดิมอยู่แล้ว กฎนี้จึงไม่เปลี่ยนอะไรที่นั่น)

   ⚠️ จำกัดขอบเขตไว้ใน `.es-ticket-thread` เท่านั้น — ไม่แตะ `.form-textarea`
   ที่อื่นทั้งเว็บ ซึ่งตั้งใจให้โปร่งใสตาม design
   ============================================================ */

.es-ticket-thread .form-textarea {
  background: var(--bg-input);
}

/* ── ปุ่มแนบรูป ──
   🔴 **ซ่อน `<input type="file">` แล้วใช้ `<label>` เป็นปุ่มแทน**
   ปุ่ม "Choose File" เป็นของเบราว์เซอร์ จัดสไตล์ไม่ได้เลยและหน้าตาคนละเรื่อง
   กับทั้งเว็บ (ผู้ใช้ทักว่า "ยัง choose file แปลก ๆ อยู่")

   ⚠️ **ซ่อนด้วยวิธี sr-only ไม่ใช่ `display: none`** — `display: none`
   ทำให้ช่องหลุดจากลำดับ tab คนที่ใช้คีย์บอร์ดจะแนบไฟล์ไม่ได้เลย
   (ชุดกฎเดียวกับ `.es-sr-only` บรรทัด ~8256) */
.es-attach-pick {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.es-attach-pick__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.es-attach-pick__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid rgba(var(--text-secondary-rgb), 0.45);
  border-radius: var(--radius-btn, 50px);
  background: transparent;
  color: var(--text-secondary);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}

.es-attach-pick__btn:hover {
  border-color: rgba(var(--grad-4-rgb), 0.6);
  color: var(--text-primary);
}

/* คีย์บอร์ดต้องเห็นว่าตอนนี้โฟกัสอยู่ที่ช่องแนบไฟล์
   (`+` ใช้ได้เพราะ `<label>` ถูกวางต่อจาก `<input>` ทันที) */
.es-attach-pick__input:focus-visible + .es-attach-pick__btn {
  outline: 2px solid var(--grad-4);
  outline-offset: 2px;
  color: var(--text-primary);
}

/* จำนวนไฟล์ที่เลือก — JS เป็นคนเติม ไม่มี JS ก็แค่ไม่เห็นตัวเลข ยังแนบได้ปกติ */
.es-attach-pick__count {
  color: var(--text-muted);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.es-ticket-reply__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  position: relative;
  z-index: 1;
  isolation: isolate;
  padding: 12px 22px;
  border: 0;
  border-radius: var(--radius-btn, 50px);
  background: transparent;
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: box-shadow 0.3s;
}

.es-ticket-reply__btn::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--radius-btn, 50px);
  background: var(--gradient);
  z-index: -1;
  transition: background-size 0.4s ease, filter 0.3s;
}

.es-ticket-reply__btn:hover::before,
.es-ticket-reply__btn:focus-visible::before {
  background: linear-gradient(90deg,
    var(--grad-1) 0%,
    var(--grad-2) 12.5%,
    var(--grad-3) 25%,
    var(--grad-4) 37.5%,
    var(--grad-1) 50%,
    var(--grad-2) 62.5%,
    var(--grad-3) 75%,
    var(--grad-4) 87.5%,
    var(--grad-1) 100%
  );
  background-size: 200% 100%;
  animation: gradient-slide 1.4s linear infinite;
}

.es-ticket-reply__btn:active {
  box-shadow:
    0 0 12px 3px rgba(var(--grad-1-rgb), 0.28),
    0 0 16px 4px rgba(var(--grad-4-rgb), 0.20);
}

/* ── เส้นสนทนาในหลังบ้าน ──
   หลังบ้านไม่มีตัวแปรสีของหน้าบ้าน (styles.css ไม่ถูกโหลด) จึงเขียนสีตรง ๆ
   ⚠️ กฎชุดนี้อยู่ในไฟล์หน้าบ้าน แต่ `.es-tk-*` ถูกใช้เฉพาะในหลังบ้าน
   ซึ่งได้สไตล์จาก `es_marketplace_admin_css()` — ที่นี่จึงเป็นแค่ตาข่ายรับ
   เผื่อวันหนึ่งเอาเส้นสนทนามาโชว์ในหน้ามอนิเตอร์ */
.es-tk-thread {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ============================================================
   รูปแนบและลิงก์จากผู้ใช้ (2026-08-30)
   คู่กับ inc/attachments.php
   ============================================================ */

.es-attach {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.es-attach__item {
  display: block;
  width: 72px;
  height: 72px;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(var(--text-muted-rgb), 0.45);
  /* ยกเว้นเอฟเฟกต์ไล่สีของ a:hover ทั้งเว็บ — ลิงก์นี้ห่อรูป ไม่มีตัวหนังสือ */
  background: none;
}

.es-attach__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.es-attach__item:hover {
  border-color: rgba(var(--grad-4-rgb), 0.6);
}

/* รูปที่ถูกลบตามนโยบายเก็บข้อมูล (inc/tickets.php หัวข้อ "นโยบายเก็บรูปแนบ")
   เป็นหมายเหตุของระบบ ไม่ใช่ข้อความของคน จึงต้องดูต่างจากเนื้อความชัด ๆ */
.es-attach__gone {
  margin: 6px 0 0;
  padding: 4px 0 4px 10px;
  border-inline-start: 2px solid var(--border, rgba(140, 140, 150, 0.35));
  font-size: 12px;
  font-style: italic;
  color: var(--text-muted);
}

/* ── ลิงก์ที่ผู้ใช้พิมพ์มาในข้อความ ── */

/* โดเมนจริงต่อท้ายลิงก์ — คนอ่านต้องเห็นว่ากำลังจะไปไหนก่อนกด */
.es-link__host {
  color: var(--text-muted);
  font-size: 0.9em;
}

/* 🔴 ลิงก์ที่ถูกตีตก (scheme อันตราย เช่น `javascript:`) แสดงเป็นข้อความ
   ขีดเส้นใต้ประ **ไม่ใช่ซ่อนทิ้ง** — แอดมินต้องเห็นว่าคนคนนี้พยายามส่งอะไรมา
   ซึ่งเป็นข้อมูลสำคัญเวลาตัดสินว่าเป็นสแปมหรือไม่ แค่ต้องกดไม่ได้ */
.es-link--blocked {
  color: var(--stat-error);
  text-decoration: underline dotted;
  word-break: break-all;
}

/* ช่องเลือกไฟล์ — `.form-input` ของธีมออกแบบมาสำหรับช่องพิมพ์
   ต้องคลายความสูงกับ padding ออก ไม่งั้นปุ่ม "เลือกไฟล์" ของเบราว์เซอร์ถูกบีบ */
.es-attach__input {
  height: auto;
  padding: 10px 12px;
  font-size: 12px;
  line-height: 1.5;
}

/* ── รูปกับชื่อโปรไฟล์กดกลับหน้าบัญชีได้ (ผู้ใช้สั่ง 2026-08-30) ──
   🔴 `.profile-picture` เปลี่ยนจาก `<div>` เป็น `<a>` — ต้องล้างสไตล์ลิงก์
   ของ design ออกให้หมด ไม่งั้นจะได้ขีดเส้นใต้กับเอฟเฟกต์ไล่สีบนกรอบรูป
   และชื่อจะจางหายตอน hover (กับดักข้อ 6 ที่เจอซ้ำมาหลายรอบแล้ว) */
a.profile-picture,
.profile-name__link {
  text-decoration: none;
  color: inherit;
}

/* กรอบรูปเองต้องไม่ไล่สี — ล้างเอฟเฟกต์ลิงก์กลางออกเฉพาะตัวรูป */
a.profile-picture:hover {
  color: inherit;
  -webkit-text-fill-color: currentColor;
  background: none;
  background-clip: border-box;
  animation: none;
}

/* บอกว่ากดได้ด้วยการสว่างขึ้นเล็กน้อย ไม่ใช่เปลี่ยนสี */
a.profile-picture:hover img {
  filter: brightness(1.12);
}

/* ── ชื่อโปรไฟล์: hover แล้วไล่สีวิ่ง (ผู้ใช้สั่ง 2026-08-30) ──
   ชุดเดียวกับชื่อร้าน (`.store-header .store-name a:hover` ด้านบน)
   ยกมาเขียนซ้ำเพราะต้องให้ **การ hover ที่รูป** ทำให้ชื่อไล่สีด้วย
   โครง markup: `a.profile-picture` + `.profile-info > h2.profile-name > a`
   (woocommerce/myaccount/my-account.php) — เป็นพี่น้องติดกันแบบเดียวกับหน้าร้าน

   🔴 **ต้องมี padding แนวตั้ง** — `background-clip:text` วาดพื้นหลังแค่ในกล่อง
   content วรรณยุกต์ไทยที่ล้นขอบบนจะไม่มีพื้นให้ตัด = มาร์กหายทั้งตัว
   (เหตุผลเดียวกับบล็อกชื่อร้านที่ ~บรรทัด 10600) */
.profile-name__link:hover,
.profile-name__link:focus-visible,
a.profile-picture:hover + .profile-info .profile-name__link {
  color: transparent;
  background: linear-gradient(90deg,
    var(--grad-1) 0%,
    var(--grad-2) 12.5%,
    var(--grad-3) 25%,
    var(--grad-4) 37.5%,
    var(--grad-1) 50%,
    var(--grad-2) 62.5%,
    var(--grad-3) 75%,
    var(--grad-4) 87.5%,
    var(--grad-1) 100%
  );
  background-size: 200% 100%;
  background-position: 0% 50%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: gradient-slide 1.5s linear infinite;
  padding: 0.22em 0 0.12em;
  text-decoration: none;
}

/* คนที่ตั้งเครื่องให้ลดการเคลื่อนไหว — คงไล่สีไว้แต่หยุดวิ่ง */
@media (prefers-reduced-motion: reduce) {
  .profile-name__link:hover,
  .profile-name__link:focus-visible,
  a.profile-picture:hover + .profile-info .profile-name__link {
    animation: none;
  }
}

/* ============================================================
   กล่องซ้อนเปิดแล้วหน้าต้องไม่กระตุก (ผู้ใช้แจ้ง 2026-09-03)

   ── อาการ ──
   กล่องซ้อนทุกตัวในเว็บล็อกการเลื่อนด้วย `body.style.overflow = 'hidden'`
   (`confirm-modal.js` · `tickets.js` · `report-abuse.js` · `finance-ui.js` ·
    `avatar-crop.js` · `vendor-dashboard-ui.js`) พอ overflow เป็น hidden
   **แถบเลื่อนหายไป หน้าจึงกว้างขึ้นเท่าความกว้างแถบ (~8–15px) ทันที**
   เนื้อหาทั้งหน้าเลยกระตุกไปทางขวาหนึ่งที ปิดกล่องก็กระตุกกลับอีกที

   ── ทำไมแก้ที่นี่ที่เดียว ไม่ไปแก้ JS 6 ไฟล์ ──
   `scrollbar-gutter: stable` สั่งให้เบราว์เซอร์ **จองที่ของแถบเลื่อนไว้ตลอด**
   ไม่ว่าตอนนั้นจะมีแถบให้เห็นหรือไม่ → ความกว้างของพื้นที่เนื้อหาไม่เคย
   เปลี่ยน ไม่มีอะไรกระตุก และครอบกล่องซ้อน **ทุกตัวรวมทั้งที่จะเขียนใหม่
   ในอนาคต** โดยไม่ต้องจำว่าต้องชดเชย padding เอง

   ⚠️ ต้องอยู่ที่ `html` ไม่ใช่ `body` — ตัวที่เลื่อนจริงคือ viewport
   ซึ่งอ่านคุณสมบัตินี้จาก `html` เท่านั้น

   ⚠️ **Safari รุ่นก่อน 18.2 ยังไม่รู้จักคุณสมบัตินี้ ซึ่งไม่เป็นไร** —
   แถบเลื่อนของ macOS/iOS เป็นแบบลอยทับ (overlay) ไม่กินความกว้างอยู่แล้ว
   อาการนี้จึงเกิดเฉพาะวินโดวส์/ลินุกซ์ ที่ Chrome/Edge/Firefox รองรับครบ

   🔴 ผลข้างเคียงที่ยอมรับ: หน้าที่สั้นกว่าจอจะมีที่ว่างด้านขวา ~8px
   ค้างไว้ ซึ่งแลกกับการไม่กระตุกแล้วคุ้มกว่า (และตรงกับที่ผู้ใช้สั่ง)
   ============================================================ */
html {
  scrollbar-gutter: stable;
}

/* ============================================================
   ปุ่มย้อนกลับลอย — เฉพาะโหมดแอป บนหน้าที่ไม่มีแถบหัวเว็บ

   ผู้ใช้แจ้ง 2026-09-03: *"ต้องปัดแอพทิ้งและเข้าใหม่ตลอดเลย"*

   หน้า 404 ปิดแถบหัวเว็บไว้โดยตั้งใจ (`es_marketplace_show_app_header()`)
   บนเบราว์เซอร์ไม่เป็นปัญหาเพราะมีปุ่มย้อนกลับของเบราว์เซอร์ แต่ในโหมด
   `display: standalone` ไม่มี UI ของเบราว์เซอร์เลย = พิมพ์ URL ผิดแล้วตาย

   ตัวใส่คือ `assets/js/app-nav.js` ซึ่งใส่ให้เฉพาะเมื่ออยู่ในโหมดแอป
   **และในหน้านั้นไม่มี `.btn-back` อยู่แล้ว** จึงไม่มีทางซ้อนกันสองปุ่ม

   ⚠️ ใช้รูปทรงและสีชุดเดียวกับ `.btn-back` ในแถบหัวเว็บ เพื่อให้คนที่
   คุ้นปุ่มนั้นแล้วกดตัวนี้ได้ทันทีโดยไม่ต้องเดา
   (2026-09-11 เปลี่ยนตาม `.btn-back` เป็นวงกลม 42px ขอบไล่สี ไม่มี hover)
   ============================================================ */
.es-app-back {
  position: fixed;
  top: max(12px, env(safe-area-inset-top));
  left: max(12px, env(safe-area-inset-left));
  z-index: 60;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--bg-primary);
  color: var(--text-primary);
  cursor: pointer;
}

.es-app-back::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--grad-1) 0%, var(--grad-2) 33%, var(--grad-3) 66%, var(--grad-4) 100%);
  z-index: -1;
}

.es-app-back::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--bg-primary);
  z-index: -1;
}

/* ============================================================
   กล่องอ่านข้อกำหนด/นโยบาย (ผู้ใช้สั่ง 2026-09-03 · ระบุว่า "สำคัญมาก")

   *"แก้ให้เป็น modal ทับอีกที พออ่านเสร็จก็กดปิด แล้วก็อ่านเรื่องอื่น
     ต้องง่ายและรองรับ RWD"*

   ต่อยอดจากเปลือกกล่องซ้อนที่มีอยู่ (`.avatar-cropper`) แล้วเติมสามอย่าง
   ที่เอกสารยาว ๆ ต้องมีและกล่องยืนยันสั้น ๆ ไม่ต้องมี:

     1. **หัวกล่องกับปุ่มปิดค้างอยู่** เลื่อนอ่านไปหน้าไหนก็ยังกดปิดได้
        (เอกสารกฎหมายยาวหลายจอ ถ้าปุ่มปิดเลื่อนหายไปคนจะหาทางปิดไม่เจอ)
     2. **เนื้อหาเลื่อนข้างในกล่อง ไม่ใช่เลื่อนทั้งหน้า**
     3. **จอเล็กกางเต็มจอ** — เอกสารกฎหมายอ่านในกรอบแคบ ๆ กลางจอไม่ได้

   🔴 ใช้ `100dvh` ไม่ใช่ `100vh` — บนมือถือ `vh` นับรวมแถบที่อยู่ของ
   เบราว์เซอร์ที่ซ่อนตัวได้ กล่องจะสูงเกินจอแล้วปุ่มปิดหลุดขอบล่างไป
   (กับดักเดียวกับที่ `body { min-height: 100dvh }` ของ design แก้ไว้แล้ว)
   ============================================================ */
.es-policy__box {
  display: flex;
  flex-direction: column;
  width: 100%;
  /* ⚠️ ต้องเขียน `max-width` ทับเอง — `.avatar-cropper__box` ตั้งไว้ 380px
     ซึ่งพอสำหรับกล่องยืนยันสองบรรทัด แต่แคบเกินไปสำหรับเอกสารกฎหมาย
     (ความเฉพาะเจาะจงเท่ากัน ไม่มีอะไรมาทับให้เอง) */
  max-width: 760px;
  max-height: min(88dvh, 900px);
  padding: 0;
  overflow: hidden;
  text-align: left;
}

/* ── หัวกล่อง — ค้างอยู่ ── */
.es-policy__head {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 18px 20px 14px;
  border-bottom: 1px solid rgba(var(--text-secondary-rgb), 0.2);
}

.es-policy__title {
  flex: 1 1 auto;
  margin: 0;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.45;
  color: var(--text-primary);
}

.es-policy__x {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin: -4px -4px 0 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--text-secondary);
  font-size: 16px;
  cursor: pointer;
}

.es-policy__x:hover,
.es-policy__x:focus-visible {
  background: rgba(var(--text-secondary-rgb), 0.14);
  color: var(--text-primary);
}

/* ── เนื้อหา — ตัวที่เลื่อน ── */
.es-policy__body {
  flex: 1 1 auto;
  min-height: 0;          /* ⚠️ ไม่มีบรรทัดนี้ flex item จะไม่ยอมหดแล้วไม่เกิด scroll */
  padding: 16px 20px 20px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  font-size: 14px;
  line-height: 1.85;
  color: var(--text-secondary);
}

.es-policy__body:focus {
  outline: none;          /* โฟกัสไว้เพื่อเลื่อนด้วยคีย์บอร์ด ไม่ใช่เพื่อโชว์กรอบ */
}

.es-policy__body > :first-child {
  margin-top: 0;
}

.es-policy__body > :last-child {
  margin-bottom: 0;
}

.es-policy__body h1,
.es-policy__body h2,
.es-policy__body h3,
.es-policy__body h4 {
  margin: 22px 0 8px;
  color: var(--text-primary);
  line-height: 1.5;
}

.es-policy__body h1 { font-size: 19px; }
.es-policy__body h2 { font-size: 17px; }
.es-policy__body h3 { font-size: 15px; }
.es-policy__body h4 { font-size: 14px; }

.es-policy__body p,
.es-policy__body li {
  font-size: 14px;
  line-height: 1.85;
}

.es-policy__body ul,
.es-policy__body ol {
  margin: 8px 0 14px;
  padding-left: 22px;
}

.es-policy__body a {
  color: var(--grad-4);
  text-decoration: underline;
}

/* ตารางในหน้ากฎ (เช่นตารางค่าธรรมเนียม) ต้องเลื่อนในกล่องของตัวเอง
   ไม่ใช่ดันกล่องให้กว้างเกินจอ */
.es-policy__body table {
  display: block;
  width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
}

.es-policy__body img {
  max-width: 100%;
  height: auto;
}

.es-policy__loading,
.es-policy__error {
  margin: 0;
  color: var(--text-secondary);
}

/* ข้อที่ลิงก์ "อ่านกฎข้อนี้" ชี้ — ไฮไลต์สั้น ๆ ตอนเปิด (policy-modal.js jump()) */
.es-policy__body [id] {
  border-radius: 8px;
  transition: background-color 0.6s ease, box-shadow 0.6s ease;
}

.es-policy__body .es-policy__hit {
  background-color: color-mix(in srgb, var(--grad-4) 16%, transparent);
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--grad-4) 16%, transparent);
}

/* เปิดหน้ากฎตรง ๆ ด้วย #id (ไม่มี JS) — เว้นที่ให้หัวเว็บที่ลอยอยู่ */
.entry-content :is(h3, h4, li, p)[id] {
  scroll-margin-top: 96px;
}

/* ── ลิงก์ "อ่านกฎข้อนี้" ใต้คำอธิบายกฎ (es_marketplace_rule_link()) ── */
.es-rule-link {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: flex-start;   /* บางฟอร์มของ Dokan จัดกลางลูกทั้งหมด */
  align-self: stretch;           /* ฟอร์มสินค้าเป็น flex column จัดกลาง → ให้เต็มความกว้างแล้วชิดซ้าย */
  text-align: left;
  gap: 4px 6px;
  margin: 8px 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.es-rule-link > i {
  font-size: 12px;
  color: var(--grad-4);
}

.es-rule-link a {
  color: var(--grad-4);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ส่วนบัญชีรับเงินคืน (หน้าแก้ไขโปรไฟล์): ล่างสุดของส่วน ใต้รายการบัญชี */
.es-bank-accounts > .es-rule-link {
  margin: 12px 0 0;
}

/* ล่างสุดของกล่อง "จัดส่งสินค้า" ของร้าน */
.return-status-box > .es-rule-link {
  margin: 12px 0 0;
}

/* ใต้หัวข้อส่วนในฟอร์มสินค้า: ชิดหัวข้อ เว้นจากช่องกรอกข้างล่าง */
.product-section-title + .es-rule-link {
  margin: -6px 0 14px;
}

/* แดชบอร์ดร้าน: Dokan ปิดเส้นใต้ลิงก์ทั้งหน้า (.dokan-dashboard .dokan-dashboard-content a) */
.dokan-dashboard .dokan-dashboard-content .es-rule-link a {
  text-decoration: underline;
}

/* ในกล่องยืนยันยกเลิก: เว้นจากหัวข้อ "เหตุผลที่ยกเลิก" ข้างล่าง */
.es-cancel__form .es-rule-link {
  margin: 4px 0 16px;
}

/* ใต้ปุ่มที่มีข้อความกำกับกึ่งกลาง (เช่น "ยกเลิกได้ถึง…") → จัดกลางตามข้อความนั้น */
.es-cancel-cell .es-rule-link {
  justify-content: center;
  margin-top: 4px;
  font-size: 12px;
}

.es-policy__fallback {
  display: inline-block;
  margin-top: 10px;
  color: var(--grad-4);
  text-decoration: underline;
}

/* ── ท้ายกล่อง — ปุ่มปิดตัวใหญ่ ค้างอยู่ ──
   มีสองปุ่มปิดโดยตั้งใจ: กากบาทมุมขวาบนสำหรับคนที่เลิกอ่านกลางทาง
   กับปุ่มใหญ่ท้ายกล่องสำหรับคนที่อ่านจบแล้วเลื่อนมาถึงล่างสุด
   (ผู้ใช้สั่งว่า "พออ่านเสร็จก็กดปิด" — ปุ่มต้องอยู่ตรงที่สายตาอยู่พอดี) */
.es-policy__foot {
  flex: 0 0 auto;
  padding: 12px 20px max(12px, env(safe-area-inset-bottom));
  border-top: 1px solid rgba(var(--text-secondary-rgb), 0.2);
}

.es-policy__done {
  /* ไอคอนถูก + GOT IT บรรทัดเดียวกันกึ่งกลาง (2026-09-16) */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 13px 18px;
  border: 0;
  border-radius: var(--radius-btn);
  color: #fff;
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}

/* ── จอเล็ก: กางเต็มจอ ──
   🔴 เอกสารกฎหมายอ่านในกรอบเล็ก ๆ กลางจอมือถือไม่ได้ — บรรทัดสั้นเกินไป
   ต้องเลื่อนถี่มากจนจับใจความไม่ได้ (ผู้ใช้สั่งให้ "ง่ายและรองรับ RWD") */
@media (max-width: 599px) {
  .es-policy {
    padding: 0;
  }

  .es-policy__box {
    width: 100%;
    max-width: none;
    height: 100dvh;
    max-height: none;
    border-radius: 0;
  }

  .es-policy__head {
    padding: max(14px, env(safe-area-inset-top)) 16px 12px;
  }

  .es-policy__body {
    padding: 14px 16px 18px;
  }

  .es-policy__foot {
    padding: 10px 16px max(10px, env(safe-area-inset-bottom));
  }
}

/* ป้าย "ขายแล้ว ลบไม่ได้" แทนปุ่ม REMOVE ในการ์ดสินค้าของผู้ขาย
   (ผู้ใช้ถาม 2026-09-03 · เหตุผลใน template-parts/vendor/product-card.php)
   ทรงเดียวกับ `.vendor-action-btn` แต่ดูชัดว่ากดไม่ได้ */
.vendor-action-row .vendor-action-note {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 10px 14px;
  border: 1px dashed rgba(var(--text-secondary-rgb), 0.4);
  border-radius: var(--radius-btn);
  color: var(--text-secondary);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  cursor: not-allowed;
}

/* กล่องเตือนในฟอร์มแก้ไขสินค้า — ไม่ใช่ลูกของแถวปุ่ม จึงต้องเว้นระยะเอง */
.add-new-product-wrapper ~ .es-speech-help,
.dokan-dashboard-content > .es-speech-help {
  margin-bottom: 20px;
}

/* ============================================================
   หัวร้านในแดชบอร์ดผู้ขาย — ปุ่มฝั่งขวา (ผู้ใช้สั่ง 2026-09-03)

   *"ในโปรไฟล์ store หน้าบ้าน ปรับปุ่มไปอยู่ด้านขวา และ RWD
     เหมือนหน้าโปรไฟล์ผู้ซื้อ"*

   🔴 **ไม่มีกฎใหม่เรื่องการวางหรือ RWD เลยโดยตั้งใจ** — markup ของหัวร้าน
   เปลี่ยนมาใช้คลาส `.profile-actions__side` ตัวเดียวกับหัวโปรไฟล์ผู้ซื้อ
   (`template-parts/vendor/dashboard-store-header.php`) กฎทั้งชุดรวมทั้ง
   จุดตัด 700px ที่วัดมาจากของจริงจึงมีผลกับหัวร้านทันที
   → มีที่เดียวที่ต้องดูแล ไม่มีวันที่สองหน้าเพี้ยนไม่ตรงกัน

   ที่นี่มีแค่การล้างของเดิมที่ขัดกัน
   ============================================================ */

/* ⚠️ ของเดิมดัน `a.btn-logout` เองด้วย `margin-inline-start: auto`
   (บรรทัด ~8776) พอย้ายเข้ากล่องฝั่งขวา ตัวมันจะดันตัวเองห่างจาก
   SUPPORT/TICKETS ออกไปอีกที จนสามปุ่มไม่ได้อยู่ด้วยกันจริง
   ความเฉพาะเจาะจงเท่ากัน (0,2,1) กฎนี้อยู่ท้ายไฟล์กว่าจึงชนะ —
   เขียนไว้ให้ชัดกันคนย้ายบล็อกในอนาคต */
.store-header-actions .profile-actions__side a.btn-logout {
  margin-inline-start: 0;
}

/* ============================================================
   แท็บแยกที่มาของทิกเก็ตในหน้า "ทิกเก็ตของฉัน" (ผู้ใช้สั่ง 2026-09-03)

   *"ทิกเก็ตยังไม่แยกว่าจากร้าน หรือจากโปรไฟล์"*

   ⚠️ โผล่เฉพาะคนที่มีเรื่องจากทั้งสองทาง (ดู `es_marketplace_ticket_render_list()`)
   ผู้ซื้อทั่วไปจึงไม่เห็นแถบนี้เลย
   ============================================================ */
.es-ticket-list__tabs {
  display: flex;
  gap: 8px;
  margin: 0 0 12px;
  flex-wrap: wrap;
}

.es-ticket-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border: 1px solid rgba(var(--text-secondary-rgb), 0.32);
  border-radius: var(--radius-btn, 50px);
  color: var(--text-secondary);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  text-decoration: none;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}

.es-ticket-tab:hover,
.es-ticket-tab:focus-visible {
  border-color: var(--grad-4);
  color: var(--grad-4);
}

.es-ticket-tab.is-active {
  border-color: var(--grad-4);
  background: rgba(var(--grad-4-rgb), 0.14);
  color: var(--text-primary);
}

.es-ticket-tab__n {
  min-width: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: rgba(var(--text-secondary-rgb), 0.22);
  font-size: 11px;
  text-align: center;
}

.es-ticket-tab.is-active .es-ticket-tab__n {
  background: rgba(var(--grad-4-rgb), 0.3);
  color: var(--text-primary);
}

/* ป้ายที่มาในการ์ดทิกเก็ต — เน้นเบา ๆ ให้กวาดตาเจอ แต่ไม่แย่งหัวข้อเรื่อง
   ⚠️ ตั้งแต่ 2026-09-04 ป้ายนี้โผล่เฉพาะหน้าที่รวมทุกที่มา (คนที่เข้า
   แดชบอร์ดร้านไม่ได้แล้ว) — หน้าปกติแยกเป็นคนละหน้าไปแล้ว จึงไม่ต้องบอกซ้ำ
   ดู `es_marketplace_ticket_render_list()` พารามิเตอร์ `$lock` */
.es-ticket-card__src {
  font-weight: 600;
  color: var(--text-primary);
}

/* ============================================================
   เลือกที่อยู่จากแผนที่ (ผู้ใช้สั่ง 2026-09-14 · inc/map-picker.php · assets/js/map-picker.js)
   กล่องยืม .avatar-cropper · หมุดอยู่กลางแผนที่ ผู้ใช้เลื่อนแผนที่แทนการลากหมุด
   ============================================================ */
.es-map-row {
  flex: 0 0 100%;
  grid-column: 1 / -1;
  width: 100%;
  margin: 0 0 12px;
}

.es-map-row .es-map-note {
  margin: 6px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--stat-success, #22c55e);
}

.es-map-picker__box {
  max-width: 520px;
  text-align: left;
}

.es-map-picker__hint {
  margin: -8px 0 10px;
  font-size: 12px;
  color: var(--text-secondary);
}

.es-map-picker__map-wrap {
  position: relative;
  overflow: hidden;
  border-radius: 12px;
}

.es-map-picker__map {
  height: min(55vh, 360px);
  background: #1a1a2e;
}

/* หมุด — Leaflet marker (L.divIcon ขนาด 0×0 ยึดที่จุดปักพอดี) ลากได้ · สีพื้นหลังเว็บ ขอบขาว ขยับขึ้นลง
   (ผู้ใช้สั่ง 2026-09-14 · เดิมไอคอนชมพูค้างกลางจอ)
   กล่อง 34px หมุน -45° มุมแหลมชี้ลง: ปลายแหลมห่างจากกึ่งกลางกล่อง 34×√2÷2 ≈ 24px
   → ขอบบนกล่อง = จุดปัก − 17 − 24 = −41px ปลายหมุดจึงแตะจุดที่ปักพอดี */
.es-map-marker {
  overflow: visible;
}

.es-map-picker__pin {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  cursor: grab;
  width: 34px;
  height: 34px;
  margin: -41px 0 0 -17px;
  animation: es-map-pin-bob 1.6s ease-in-out infinite;
  transition: transform 0.15s ease;
}

.es-map-picker__pin::before {
  content: '';
  position: absolute;
  inset: 0;
  box-sizing: border-box;
  border: 3px solid #fff;
  border-radius: 50% 50% 50% 0;
  background: var(--bg-header, #0c0816);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.45);
  transform: rotate(-45deg);
}

.es-map-picker__pin::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 10px;
  height: 10px;
  margin: -5px 0 0 -5px;
  border-radius: 50%;
  background: #fff;
}

/* ออร่าตรงจุดใต้หมุด — จุดเงา + วงกระจายเป็นจังหวะเดียวกับหมุด (เป็น guide mark ว่าปักตรงไหน) */
.es-map-picker__aura {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  width: 14px;
  height: 6px;
  margin: -3px 0 0 -7px;
  border-radius: 50%;
  background: rgba(12, 8, 22, 0.5);
  pointer-events: none;
}

.es-map-picker__aura::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 52px;
  height: 22px;
  margin: -11px 0 0 -26px;
  box-sizing: border-box;
  border: 2px solid rgba(12, 8, 22, 0.7);
  border-radius: 50%;
  background: rgba(12, 8, 22, 0.12);
  animation: es-map-pin-aura 1.6s ease-out infinite;
}

/* กดค้างที่หมุด = ยกหมุดค้างไว้ เลิกเด้ง (ออร่ายังกระพริบตรงจุดที่จะวาง) */
.es-map-marker.is-lifted .es-map-picker__pin {
  cursor: grabbing;
  animation: none;
  transform: translateY(-16px);
}

@keyframes es-map-pin-bob {
  0%,
  100% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(-8px);
  }
}

@keyframes es-map-pin-aura {
  0% {
    opacity: 0.9;
    transform: scale(0.3);
  }

  100% {
    opacity: 0;
    transform: scale(1.3);
  }
}

@media (prefers-reduced-motion: reduce) {
  .es-map-picker__pin,
  .es-map-picker__aura::after {
    animation: none;
  }
}

.es-map-picker__locate {
  position: absolute;
  right: 10px;
  bottom: 28px;
  z-index: 1000;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border: 0;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  color: #111;
  cursor: pointer;
}

.es-map-picker__result {
  min-height: 2.8em;
  margin: 10px 0 14px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-primary);
}

.es-map-picker .leaflet-control-attribution {
  font-size: 10px;
}

/* ============================================================
   Step หน้าชำระเงิน (ผู้ใช้สั่ง 2026-09-14)
   - วงกลมเล็กลง 40 → 30px · จอ iPad/คอมเส้นเชื่อมยาวขึ้นให้ห่างกัน
   - ขั้นปัจจุบัน: ขอบเขียว (เดิมขอบไล่สีด้วย ::before/::after)
   - เส้นที่ผ่านมาแล้ว (ต่อจากขั้นที่เสร็จ) เขียวทึบ · เส้นไปขั้นที่ยังไม่ถึง = เส้นประ เข้าชุดกับวงกลมเส้นประ
   ⚠️ ไม่แตะ .step-indicator--return (หน้าคืนสินค้าใช้คลาสเดียวกันแต่มีขนาดของตัวเอง)
   ============================================================ */
.step-indicator:not(.step-indicator--return) .step__circle {
  width: 30px;
  height: 30px;
  font-size: 12px;
}

.step-indicator:not(.step-indicator--return) .step--active .step__circle {
  border: 2px solid var(--stat-success);
  background: var(--bg-primary);
}

.step-indicator:not(.step-indicator--return) .step--active .step__circle::before,
.step-indicator:not(.step-indicator--return) .step--active .step__circle::after {
  content: none;
}

.step-indicator:not(.step-indicator--return) .step-connector {
  width: 28px;
  height: 0;
  margin-top: 14px;
  background: none;
  border-top: 1.5px dashed var(--border-inactive);
}

.step-indicator:not(.step-indicator--return) .step--completed + .step-connector {
  border-top-style: solid;
  border-top-color: var(--stat-success);
}

@media (min-width: 768px) {
  .step-indicator:not(.step-indicator--return) .step-connector {
    width: 72px;
  }
}

@media (min-width: 1024px) {
  .step-indicator:not(.step-indicator--return) .step-connector {
    width: 100px;
  }
}

/* หน้าชำระเงิน: ช่องประเทศถูกล็อกเป็นไทย — ซ่อนทั้งแถว (inc/woocommerce.php · es_marketplace_country_note)
   ⚠️ !important เพราะ address-i18n.js ของ WooCommerce แสดง/ซ่อนแถวเองได้ */
.form-row.es-country-locked {
  display: none !important;
}

/* ============================================================
   หน้าชำระเงิน: ที่อยู่แบบย่อ (ผู้ใช้สั่ง 2026-09-14 · assets/js/checkout-address.js)
   กรอกครบอยู่แล้ว → การ์ดสรุป + ปุ่ม EDIT · กดแล้วค่อยเห็นฟอร์มเต็มและปุ่มเลือกจากแผนที่
   ============================================================ */
.woocommerce-billing-fields__field-wrapper.es-collapsed,
[data-es-address].es-collapsed {
  display: none !important;
}

.es-checkout-address {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 8px;
  padding: 14px 16px;
  border: 1px solid rgba(var(--text-primary-rgb), 0.12);
  border-radius: 12px;
  background: rgba(var(--text-primary-rgb), 0.04);
}

.es-checkout-address__body {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
}

.es-checkout-address__icon {
  flex: 0 0 auto;
  margin-top: 3px;
  color: var(--stat-success, #22c55e);
}

.es-checkout-address__text {
  min-width: 0;
}

.es-checkout-address__text p {
  margin: 0;
  overflow-wrap: anywhere;
}

.es-checkout-address__name {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-primary);
}

.es-checkout-address__line {
  margin-top: 2px !important;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.es-checkout-address__edit {
  flex: 0 0 auto;
}

/* ปุ่ม "เลือกจากแผนที่" — เต็มแถว สูงขึ้น พื้นเป็นแผนที่เส้นถนนขาวดำจาง ๆ ตัวหนังสือกลาง (ผู้ใช้สั่ง 2026-09-14)
   ลายแผนที่เป็น SVG ในบรรทัด (ไม่โหลดรูปจากข้างนอก) · เส้นขาวบาง opacity ต่ำบนพื้นเข้ม */
.es-map-row .es-map-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 48px;
  padding: 12px 16px;
  overflow: hidden;
  border: 1px solid rgba(var(--text-primary-rgb), 0.18);
  border-radius: 12px;
  background-color: #151419;
  /* แผนที่เมืองจำลอง (วาดเองในธีม — ไม่ใช่ภาพจาก OpenStreetMap จึงไม่ต้องมีเครดิต/ไม่โหลดจากข้างนอก)
     ชั้นบน = ไล่มืดตรงกลางให้ตัวหนังสืออ่านง่าย */
  background-image: radial-gradient(ellipse at center, rgba(10, 8, 20, 0.55) 0%, rgba(10, 8, 20, 0.15) 70%), url("../images/map-texture.svg?v=1");
  background-position: center, center;
  background-size: 100% 100%, cover;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
  font-size: 13px;
  text-align: center;
}

.es-map-row .es-map-btn:hover {
  border-color: rgba(var(--text-primary-rgb), 0.35);
  background-color: #1d1c23;
}

.es-map-row .es-map-note {
  text-align: center;
}

/* หัวข้อ "ข้อมูลผู้ซื้อ" ไม่ชิดการ์ดที่อยู่แบบย่อ / ฟอร์ม (ผู้ใช้สั่ง 2026-09-14) */
#customer_details .woocommerce-billing-fields > h3 {
  margin-bottom: 14px;
}

/* แถวปุ่มแผนที่เป็น .form-row (ให้ WooCommerce เรียงลำดับถูก) — แต่ต้องไม่ใช่ flex แบบ .form-row
   🔴 วัดจริง: clearfix ของ WooCommerce `.form-row::before { content:" "; display:table }` กลายเป็น flex item
      + gap 12px ของ .form-row (styles.css) ดันปุ่มไปทางขวา 12px · padding 3px ของ `.woocommerce form .form-row` ชนะกฎเดิม
   → display:block + ปิด ::before/::after + selector ที่มี .woocommerce form นำหน้า */
.woocommerce form .form-row.es-map-row,
.form-row.es-map-row {
  display: block;
  padding: 0;
  margin: 0 0 14px;
}

.woocommerce form .form-row.es-map-row::before,
.woocommerce form .form-row.es-map-row::after,
.form-row.es-map-row::before,
.form-row.es-map-row::after {
  content: none;
  display: none;
}

/* ============================================================
   หน้าตั้งค่าร้าน: สวิตช์อยู่บรรทัดเดียวกับหัวข้อ ชิดขวา (ผู้ใช้สั่ง 2026-09-14)
   อีเมลร้าน · เบอร์โทรร้าน · หัวข้อเวลาเปิด-ปิดร้าน
   ============================================================ */
.es-label-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 12px;
  margin-bottom: 8px;
}

.es-label-row > .form-label {
  margin-bottom: 0;
}

.es-checkbox.es-checkbox--inline {
  margin-left: auto;
  font-size: 12px;
  white-space: nowrap;
}

.es-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px 12px;
  margin: 16px 0 10px;
}

.es-section-head > .store-section-title {
  margin: 0;
}

/* แถวสวิตช์ที่เหลือแค่ส่งด่วนในพื้นที่ — ร้านนอกพื้นที่ไม่มีอะไรข้างใน อย่าเว้นที่ว่าง */
.es-toggle-row:not(:has(*)) {
  display: none;
}

/* เปิด/ปิดรายวันเป็น toggle switch (เดิม dropdown) — ป้าย "เปิด" สีตามสวิตช์ · "ปิด" สีจาง */
.es-store-hours__status {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.es-store-hours__status .es-switch__label {
  min-width: 2.5em;
  color: var(--text-secondary);
}

/* หน้าชำระเงินเมื่อสินค้าในตะกร้ามีปัญหา (ผู้ใช้แจ้ง 2026-09-14 — หลุด design)
   กล่องแจ้งเตือนแบบเดียวกับทั้งเว็บ · ลิงก์ "กลับไปที่ตะกร้าสินค้า" ต่อท้ายข้อความ มีเส้นใต้
   (ใช้ .es-empty-cart__msg / __link ชุดเดียวกับตะกร้าว่าง · woocommerce/checkout/cart-errors.php) */
.es-cart-errors {
  margin: 8px 0 24px;
}

/* ที่อยู่แบบย่อในหน้าแก้ไขโปรไฟล์ / ตั้งค่าร้าน (ผู้ใช้สั่ง 2026-09-14) — การ์ดเดียวกับหน้าชำระเงิน
   เว้นระยะจากหัวข้อ/ส่วนถัดไปให้เท่ากับ .form-group */
.es-checkout-address:has(+ [data-es-address]) {
  margin-bottom: 20px;
}

/* แผนที่: จุดที่อาจไม่ถูกต้อง — นอกประเทศไทย · ในน้ำ · ห่างถนน/ที่อยู่ (ผู้ใช้สั่ง 2026-09-14)
   กล่องเตือนสีเหลืองใต้ที่อยู่ในกล่องแผนที่ + โน้ตใต้ปุ่มหลังกรอกเป็นสีเหลืองแทนสีเขียว */
.es-map-picker__warn {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 8px;
  padding: 10px 12px;
  border: 1px solid rgba(var(--stat-warning-rgb), 0.45);
  border-radius: 10px;
  background: rgba(var(--stat-warning-rgb), 0.1);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-primary);
}

.es-map-picker__warn i {
  flex-shrink: 0;
  margin-top: 3px;
  color: var(--stat-warning);
}

.es-map-picker__result:empty,
.es-map-picker__result > .es-map-picker__warn:first-child {
  margin-top: 0;
}

.es-map-row .es-map-note.is-warn {
  color: var(--stat-warning);
}

/* กล่องแผนที่: ปุ่ม CANCEL / USE ADDRESS / USE ANYWAY ต้องบรรทัดเดียว (ผู้ใช้แจ้ง 2026-09-14 — มือถือขึ้น 2 บรรทัด)
   ปุ่มกว้างครึ่งกล่อง + ตัวใหญ่ 15px + ระยะตัวอักษรกว้างของ .btn-gradient → ข้อความตัดบรรทัด
   → ห้ามตัดบรรทัด · จอแคบลดขนาดตัว/ระยะตัวอักษร/ช่องไฟลงตามความกว้างจอ */
.es-map-picker .avatar-cropper__actions {
  gap: 8px;
}

.es-map-picker .avatar-cropper__actions > button {
  gap: 6px;
  padding: 14px 8px;
  font-size: clamp(12px, 3.4vw, 15px);
  letter-spacing: 0.04em;
  white-space: nowrap;
  /* 🔴 ห้าม overflow:hidden — กรอบไล่สีของ .btn-gradient วาดด้วย ::before ล้นขอบปุ่ม ตัดแล้วกรอบหาย (ผู้ใช้แจ้ง 2026-09-14) */
}

/* ============================================================
   รายการสินค้าโหลดเพิ่ม (หน้า shop · หน้าร้าน) — การ์ดใหม่จางเข้ามาทีละใบ (ผู้ใช้สั่ง 2026-09-14)
   assets/js/product-infinite.js ใส่คลาส + animation-delay ให้แล้วถอดออกเมื่อจบ
   ============================================================ */
@keyframes esCardIn {
  from {
    opacity: 0;
    transform: translate3d(0, 16px, 0);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.product-list > .es-card-enter {
  animation: esCardIn 0.55s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

@media (prefers-reduced-motion: reduce) {
  .product-list > .es-card-enter {
    animation: none;
  }
}

/* ============================================================
   เนื้อหาเลื่อนขึ้นตอนแสดงผล (ผู้ใช้สั่ง 2026-09-20 — "ให้หน้าเว็บดูไม่นิ่ง")
   ตัวสั่งงานอยู่ assets/js/reveal.js · ที่นี่มีแค่ท่าเล่น
   🔴 `.es-reveal` (ซ่อนรอ) ใส่ได้เฉพาะของที่ยังอยู่นอกจอ — JS เป็นคนดูแล
      ถ้าใส่กับของบนจอจะเห็นภาพกะพริบ · ของที่ค้างซ่อนมีตัวกันใน JS
   ============================================================ */
@keyframes esRevealUp {
  from {
    opacity: 0;
    transform: translateY(12px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.es-reveal {
  opacity: 0;
}

.es-reveal--in {
  animation: esRevealUp 0.42s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  will-change: opacity, transform;
}

/* ของที่อยู่บนจอตั้งแต่เปิดหน้า — เลื่อนขึ้นอย่างเดียว **ห้ามจางจาก 0** (2026-09-22)
   เบราว์เซอร์วาดของพวกนี้ไปแล้วก่อน reveal.js ทำงาน ถ้าเริ่มจาก opacity 0 = เห็น → หาย → ค่อย ๆ มา (กะพริบ)
   ขัดกฎข้อ 1 ในหัว reveal.js เอง — รอบแรกใช้ keyframe เดียวกับ --in จึงกะพริบทุกหน้า */
@keyframes esRevealNow {
  from {
    transform: translateY(12px);
  }

  to {
    transform: none;
  }
}

.es-reveal--now {
  animation: esRevealNow 0.42s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
  .es-reveal,
  .es-reveal--in,
  .es-reveal--now {
    opacity: 1;
    animation: none;
    transform: none;
  }
}

/* ============================================================
   บัญชีรับเงินคืน (แก้ไขโปรไฟล์) — บัญชีที่บันทึกแล้วแสดงแบบย่อ ทรงเดียวกับบัญชีรับเงินของร้าน (ผู้ใช้สั่ง 2026-09-14)
   กด "แก้ไขบัญชี" → เห็นช่องกรอก (assets/js/bank-accounts.js) · ไม่มี JS = เห็นทั้งสรุปและฟอร์ม
   🔴 store.css (ที่มีกฎ .store-finance-card / .link-edit-bank) ไม่โหลดในหน้าโปรไฟล์ → เขียนค่าที่ต้องใช้ซ้ำไว้ตรงนี้
   ============================================================ */
.es-bank-card__summary.store-finance-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-radius: 12px;
  background: rgba(var(--text-primary-rgb), 0.04);
}

.es-bank-card__summary .store-finance-card__label {
  min-width: 0;
  font-size: 13px;
  color: var(--text-secondary);
  letter-spacing: 0.04em;
}

.es-bank-card__summary .es-bank-cell {
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

.es-bank-card__summary-actions {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 10px;
}

.es-bank-card__badge {
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(var(--grad-1-rgb), 0.16);
  color: var(--grad-1);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.es-bank-card__summary .link-edit-bank {
  padding: 0;
  border: 0;
  background: none;
  color: #8b5cf6;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.2s;
}

.es-bank-card__summary .link-edit-bank:hover {
  color: #a78bfa;
  background: none;
}

/* มี JS: บัญชีที่บันทึกแล้วซ่อนฟอร์ม เหลือแถวสรุป */
.es-bank-accounts.has-js .es-bank-card[data-bank-collapsible]:not(.is-open) {
  padding: 0;
  border: 0;
  background: none;
}

.es-bank-accounts.has-js .es-bank-card[data-bank-collapsible]:not(.is-open) > :not(.es-bank-card__summary) {
  display: none;
}

/* กดแก้ไขแล้ว (หรือไม่มี JS) — ไม่ต้องมีแถวสรุปซ้ำเหนือฟอร์ม */
.es-bank-card.is-open > .es-bank-card__summary,
.es-bank-accounts:not(.has-js) .es-bank-card__summary {
  display: none;
}

/* ติ๊กลบแล้วยังดูได้ว่าบัญชีไหนกำลังจะหาย */
.es-bank-accounts.has-js .es-bank-card.is-removing {
  padding: 14px;
}

@media (max-width: 480px) {
  .es-bank-card__summary.store-finance-card {
    align-items: flex-start;
  }

  .es-bank-card__summary-actions {
    flex-direction: column;
    align-items: flex-end;
    gap: 6px;
  }
}

/* บัญชีรับเงินคืน — ยังไม่มีบัญชี: ข้อความแทนฟอร์มว่าง · คำแนะนำใต้ช่อง (ผู้ใช้สั่ง 2026-09-14) */
.es-bank-empty {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 14px 0 0;
  padding: 12px 16px;
  border: 1px dashed rgba(var(--text-secondary-rgb), 0.35);
  border-radius: 12px;
  font-size: 13px;
  color: var(--text-secondary);
}

.es-bank-empty i {
  color: var(--grad-1);
}

.es-bank-accounts.has-js [data-bank-placeholder] {
  display: none;
}

.es-bank-card__hint {
  margin: 6px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-secondary);
}

/* 🔴 ข้อความ "ยังไม่มีบัญชีรับเงินคืน" มี display:flex → ชนะ [hidden] ของเบราว์เซอร์ โผล่ทั้งที่มีบัญชีแล้ว (เจอ 2026-09-14) */
.es-bank-empty[hidden] {
  display: none;
}

/* ============================================================
   ตั้งค่าร้าน — สวิตช์เล็ก แสดง/ซ่อน + ปุ่ม PREVIEW + กล่องตัวอย่างหน้าร้าน (ผู้ใช้สั่ง 2026-09-14)
   dokan/settings/store-form.php · assets/js/store-preview.js
   ============================================================ */
.es-switch.es-switch--mini {
  gap: 6px;
  margin-left: auto;
  line-height: 1;
}

.es-switch--mini .es-switch__track {
  width: 30px;
  height: 18px;
}

.es-switch--mini .es-switch__dot {
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
}

.es-switch--mini .es-switch__input:checked + .es-switch__track .es-switch__dot {
  transform: translateX(12px);
}

.es-switch--mini .es-switch__label {
  min-width: 2.2em;
  font-size: 12px;
  color: var(--text-secondary);
}

.es-label-row > .es-switch--mini,
.es-section-head > .es-switch--mini {
  flex: 0 0 auto;
}

.es-section-head > .es-store-preview-btn {
  margin-left: auto;
  font-size: 11px;
}

.es-section-head > .es-store-preview-btn + .es-switch--mini {
  margin-left: 0;
}

/* ── ตัวอย่างหน้าร้าน — หน้าร้านจริงเต็มจอในกรอบ (ผู้ใช้สั่ง 2026-09-16) ──
   JS: assets/js/store-preview.js · กรอบกว้างเท่าจอ หน้าร้านในกรอบจึงจัดหน้าตาม breakpoint เดียวกับของจริง (มือถือ/แท็บเล็ต/เดสก์ท็อป)
   z-index 100001 = ชั้นเดียวกับกล่องตัดรูป (ใต้ตัวหมุนโหลดหน้า 100002) */
.es-store-preview {
  position: fixed;
  inset: 0;
  z-index: 100001;
  display: flex;
  flex-direction: column;
  background: var(--bg-header, #000);
}

.es-store-preview__bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  padding-top: max(10px, env(safe-area-inset-top));
  border-bottom: 1px solid rgba(var(--text-secondary-rgb), 0.25);
  background: var(--bg-primary, #000);
}

.es-store-preview__head {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.es-store-preview__title {
  font-size: 14px;
  color: var(--text-primary);
}

.es-store-preview__notice {
  font-size: 12px;
  line-height: 1.5;
  color: var(--stat-warning, #f59e0b);
}

.es-store-preview__close {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border: 1px solid rgba(var(--text-secondary-rgb), 0.45);
  border-radius: var(--radius-btn, 50px);
  background: transparent;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  cursor: pointer;
}

.es-store-preview__close:hover,
.es-store-preview__close:focus-visible {
  border-color: var(--text-primary);
}

.es-store-preview__stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
}

.es-store-preview__frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: var(--bg-header, #000);
  transition: opacity 0.25s ease;
}

.es-store-preview__spin {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 46px;
  height: 46px;
  margin: -23px 0 0 -23px;
  border: 3px solid rgba(var(--text-primary-rgb), 0.15);
  border-top-color: var(--grad-1);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  animation: es-loading-spin 0.7s linear infinite;
  transition: opacity 0.25s ease;
}

.es-store-preview__stage.is-loading .es-store-preview__frame {
  opacity: 0;
}

.es-store-preview__stage.is-loading .es-store-preview__spin {
  opacity: 1;
}

/* หน้าหลังกรอบไม่เลื่อนตาม */
body.es-store-preview-open {
  overflow: hidden;
}

/* แถวปุ่ม PREVIEW ล่างสุดเมื่อไม่มีหมวดตั้งค่าอื่นๆ (แอดมินปิดส่งด่วน) */
.es-section-head.es-section-head--end {
  justify-content: flex-end;
}

/* ไอคอนหัวข้อในหน้ากฎ (ข้อกำหนด · นโยบาย · คุกกี้) บางข้อไม่ขึ้น — ผู้ใช้ทัก 2026-09-14
   ธีมใช้ Font Awesome 6.0.0-beta3 ซึ่งยังไม่มีชื่อไอคอนรุ่นหลังพวกนี้ → ชี้ไปหาไอคอนที่มีอยู่ในฟอนต์แทน
   (แก้ที่ธีมจึงไม่ต้องไปแก้เนื้อหาหน้ากฎบนเว็บจริง) · 🔴 จะใส่ไอคอนใหม่ ตรวจชื่อใน assets/fonts/fontawesome/css/all.min.css ก่อน */
.fa-chart-simple::before { content: "\f080"; }         /* → chart-bar */
.fa-child-reaching::before { content: "\f1ae"; }       /* → child */
.fa-file-pen::before { content: "\f573"; }             /* → file-signature */
.fa-money-bill-transfer::before { content: "\f53a"; }  /* → money-bill-wave */
.fa-building-columns::before { content: "\f19c"; }     /* → university (หัวข้อบัญชีรับเงิน/บัญชีรับเงินคืน) */
.fa-shield-halved::before { content: "\f3ed"; }        /* → shield-blank (หน้าเปิดร้าน) */

/* ============================================================
   กันบันทึกรูปผลงานในโหมดแอป (ผู้ใช้สั่ง 2026-09-16)
   คู่กับ assets/js/app-nav.js (ตัดเมนูคลิกขวา/กดค้าง) — `.es-app-mode` ใส่โดยไฟล์นั้นเฉพาะตอนเปิดจากไอคอนบนหน้าจอโฮม

   `-webkit-touch-callout: none` = iOS ไม่เด้งเมนู "บันทึกรูปภาพ / แชร์" ตอนกดค้าง
   `user-select` + `-webkit-user-drag` = ไม่เลือก/ลากรูปออกไปวาง
   ⚠️ ตัวกันมือเท่านั้น (ภาพหน้าจอยังได้) · 🔴 ห้ามขยายไปรูปสลิป/หลักฐาน — รายการ selector ต้องตรงกับใน app-nav.js
   ============================================================ */
.es-app-mode .product-card img,
.es-app-mode .product-item img,
.es-app-mode .woocommerce-product-gallery img,
.es-app-mode .flex-control-thumbs img,
.es-app-mode .pswp img,
.es-app-mode .order-card__product img,
.es-app-mode .cart-item img,
.es-app-mode .es-protect-img {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
}

/* ============================================================
   หน้ารายละเอียดสินค้า — "สินค้าถูกขายไปแล้ว" ชิดขวา โทนแดง (ผู้ใช้สั่ง 2026-09-16)
   ข้อความมาจาก `es_marketplace_sold_availability_text()` (inc/woocommerce.php)
   ============================================================ */
.single-product-summary .stock.out-of-stock {
  text-align: right;
  color: var(--stat-error);
  font-weight: 600;
}

/* ============================================================
   หน้าตั้งค่าร้าน — ช่องโซเชียล 2 คอลัมน์บนจอใหญ่ (ผู้ใช้สั่ง 2026-09-16)
   จุดตัด 769px เดียวกับ `.form-row-2col` (store.css) · จอเล็กเรียงคอลัมน์เดียวตามเดิม
   ============================================================ */
@media (min-width: 769px) {
  .es-social-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 16px;
  }
}

/* ============================================================
   หน้ารายละเอียดคำสั่งซื้อ/คำขอคืน ฝั่งร้าน — หัวข้อ "สินค้า" เท่าหัวข้ออื่น (ผู้ใช้แจ้ง 2026-09-16)
   <h3> ใน `.payment-vendor__header` ไม่มีกฎของ design คุม ขนาดจึงเป็นค่าตั้งต้นของเบราว์เซอร์ (18.7px)
   ส่วน "ที่อยู่จัดส่ง / จัดส่งสินค้า" ใช้ `.payment-shipping-address h3` (styles.css:2998) 14px 600 — ใช้ชุดเดียวกัน
   ============================================================ */
.payment-vendor__header h3 {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--text-primary);
}

.payment-vendor__header h3 i {
  font-size: 14px;
}

/* ── สรุปยอดฝั่งร้าน (ผู้ใช้สั่ง 2026-09-18) ──
   --head  หัวข้อ "ยอดที่หักจากรายได้ร้าน" สีขาว ขนาดเท่าบรรทัดอื่น
   --earn  รายได้ของร้านรวมทั้งหมด (ใบปกติ) สีเขียว
   --deduct ยอดที่หักรวมทั้งสิ้น (ใบคืนเงิน) ติดลบ สีแดง
   ราคาใน wc_price() มี <bdi> ที่ธีมตั้งสีไว้ต่างหาก ต้องสั่งให้สืบทอดสีด้วย */
.payment-summary__row--head {
  color: var(--text-primary);
  font-weight: 600;
  margin-top: 4px;
}

.payment-summary__row > span:first-child {
  min-width: 0;
}

.payment-summary__row > span + span {
  flex: 0 0 auto;
  padding-left: 12px;
  text-align: right;
}

.payment-summary__row--earn,
.payment-summary__row--deduct {
  font-weight: 700;
}

.payment-summary__row--earn,
.payment-summary__row--earn .woocommerce-Price-amount,
.payment-summary__row--earn bdi {
  color: var(--stat-success, #22c55e);
}

.payment-summary__row--deduct,
.payment-summary__row--deduct .woocommerce-Price-amount,
.payment-summary__row--deduct bdi {
  color: var(--stat-error, #ef4444);
}

/* ── แถวข้อมูลสินค้า (Technique · Artist/Brand · Edition …) หัวข้อไม่ตรงบรรทัดแรกของค่า ──
   (ผู้ใช้แจ้งซ้ำ 2026-09-18 ทั้งค่าสั้นและค่ายาวหลายบรรทัด)
   🔴 สาเหตุ: ทั้งสองฝั่ง `line-height: normal` + ฟอนต์ Archivo ไม่มีตัวไทย
   ค่าที่มีตัวไทยจึงใช้ฟอนต์สำรอง (LINE Seed) ที่ ascent/descent สูงกว่า → กล่องบรรทัด
   ของค่าสูง 22px แต่หัวข้อ (อังกฤษล้วน) สูง 15.5px · จัดชิดบน (flex-start) ทำให้
   **เส้นฐานตัวอักษรของสองฝั่งไม่ตรงกัน** ตัวไทยจมลงไปราว 3px ทุกแถวที่มีภาษาไทย
   แก้: ตั้ง line-height ตายตัวเท่ากันทั้งสองฝั่ง + จัดแถวที่ "เส้นฐานบรรทัดแรก" (baseline)
   ค่าที่ยาวหลายบรรทัดหัวข้อก็ยังตรงบรรทัดแรก */
.product-additional-info .info-row {
  align-items: baseline;
}

.product-additional-info .info-row > h2,
.product-additional-info .info-row > h3,
.product-additional-info .info-row > span {
  line-height: 1.6;
}

/* ── กล่องยืนยัน "ได้รับของ/ของคืนถึงร้านแล้วจริงหรือยัง?" (ผู้ใช้สั่ง 2026-09-18) ──
   ชิดซ้ายทั้งกล่อง + ตัวหนาสีขาวตรงส่วนที่ต้องอ่าน + ย่อหน้าผลที่ย้อนไม่ได้เป็นสีเตือน
   ข้อความมาจาก inc/receipt-guard.php (`**…**` = ตัวหนา) · JS assets/js/receipt-guard.js */
.es-confirm--left .avatar-cropper__title,
.es-confirm--left .es-confirm__text {
  text-align: left;
}

.es-confirm--left .es-confirm__text p {
  margin: 0 0 10px;
}

.es-confirm--left .es-confirm__text p:last-child {
  margin-bottom: 0;
}

.es-confirm--left .es-confirm__text strong {
  color: var(--text-primary);
  font-weight: 700;
}

.es-confirm--left .es-confirm__warn {
  padding: 8px 10px;
  border-left: 3px solid var(--stat-warning, #f59e0b);
  border-radius: 6px;
  background: rgba(245, 158, 11, 0.08);
}

.es-confirm--left .es-confirm__warn strong {
  color: var(--stat-warning, #f59e0b);
}

/* ── หน้าทิกเก็ต + หน้ารายละเอียด (แชท) ใส่พื้นกล่องโทนดำ (ผู้ใช้สั่ง 2026-09-18) ──
   *"พื้นหลังสีโทนดำใน section หรือใน panel chat"* — ทรงเดียวกับกล่องในหน้ารายละเอียดออเดอร์
   (`.payment-summary` พื้น --bg-primary มุมมน) · ใช้ทั้งฝั่งโปรไฟล์และฝั่งร้าน (มาร์กอัปเดียวกัน)
   ⚠️ ไม่ใช่ภาพพื้นหลังทั้งหน้า (scan-bg) — หน้าในโปรไฟล์ยังไม่มีภาพพื้นหลังตามที่สั่งไว้ 17 ก.ย. */
.es-ticket-list,
.es-ticket-thread {
  padding: 20px;
  border-radius: 16px;
  background: var(--bg-primary);
}

.es-ticket-thread .es-ticket-msgs {
  padding: 16px;
  border-radius: 12px;
  background: rgba(var(--bg-card-rgb), 0.35);
}

@media (max-width: 480px) {
  .es-ticket-list,
  .es-ticket-thread {
    padding: 16px 14px;
  }

  .es-ticket-thread .es-ticket-msgs {
    padding: 12px 10px;
  }
}

/* ── × ของปุ่มล้างค่า (วันที่ลดราคา · ศิลปิน/แบรนด์) วาดด้วยเส้น 2 เส้น (ผู้ใช้แจ้ง 2026-09-18 รอบ 2 "กากบาทยังเอียง")
   ตัวอักษร × ของฟอนต์ LINE Seed นั่งต่ำกว่ากึ่งกลางและหนาไม่เท่ากัน → ซ่อนตัวอักษร (font-size 0) แล้ววาดเอง
   ตัวอักษรยังอยู่ใน DOM ให้โปรแกรมอ่านหน้าจอ (aria-label ก็มี) */
.es-terms.is-single .es-terms__remove {
  position: relative;
}

.es-terms.is-single .es-terms__remove,
.es-clear-btn {
  font-size: 0;
  color: var(--text-primary);
}

.es-terms.is-single .es-terms__remove::before,
.es-terms.is-single .es-terms__remove::after,
.es-clear-btn::before,
.es-clear-btn::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 11px;
  height: 1.6px;
  margin: -0.8px 0 0 -5.5px;
  border-radius: 1px;
  background: currentColor;
  transform: rotate(45deg);
}

.es-terms.is-single .es-terms__remove::after,
.es-clear-btn::after {
  transform: rotate(-45deg);
}

/* ── ดอกจันช่องบังคับ ทั้งเว็บ: สีแดง ไม่มีเส้นใต้ (ผู้ใช้สั่ง 2026-09-18) ──
   บางจุดใช้ <abbr> (WooCommerce/Dokan) ซึ่งเบราว์เซอร์ขีดเส้นประใต้ให้เอง
   และ `abbr[title="required"]` ของ styles.css ไม่จับเพราะ title ถูกแปลเป็นไทย */
.required,
abbr.required,
span.required,
.form-label .required,
label .required {
  color: var(--stat-error-bright, #ff4444);
  text-decoration: none;
  border-bottom: 0;
  cursor: default;
  -webkit-text-fill-color: currentColor;
}

abbr.required[title],
abbr[title].required {
  text-decoration: none;
}

/* ── เปลี่ยนหน้าแบบแอป (View Transitions ข้ามหน้า) — ผู้ใช้ถาม 2026-09-18 ข้อ 9 ──
   WordPress ต้องโหลดหน้าใหม่ทุกครั้ง แต่เบราว์เซอร์รุ่นใหม่ (Chrome/Android 126+ · Safari/iOS 18.2+)
   **ค้างภาพหน้าเดิมไว้จนหน้าใหม่พร้อม** แล้วค่อยจางเข้า — ไม่มีจังหวะจอโล่งระหว่างรอ
   หัวเว็บกับเมนูล่างตั้งชื่อไว้ → ไม่กะพริบตาม อยู่นิ่งเหมือนแอป (เปลี่ยนเฉพาะเนื้อหา)
   เบราว์เซอร์ที่ไม่รู้จักข้ามทั้งก้อนเอง = เหมือนเดิมทุกอย่าง (ไม่มีความเสี่ยงหน้าพัง)
   ⚠️ ชื่อ view-transition-name ต้องไม่ซ้ำในหน้าเดียว — มีหัวเว็บ/เมนูล่างอย่างละชุดเดียวอยู่แล้ว */
@view-transition {
  navigation: auto;
}

.app-header {
  view-transition-name: es-header;
}

.bottom-nav-wrapper {
  view-transition-name: es-bottom-nav;
}

/* ── iOS/iPadOS: safe area (รอยบาก · แถบ home) — ผู้ใช้แจ้ง 2026-10-08 ──
   อาการ: เลื่อนลงสุดแล้วแถบ URL ยุบ แถบเมนูล่างเด้งขึ้น เห็นแถบพื้นหลังใต้เมนู
   (Safari · Opera GX บน iPad · แอปที่เปิดเว็บผ่าน WebView/TestFlight)
   ต้นเหตุ: หน้าเว็บไม่ได้ประกาศ viewport-fit=cover → iOS ตัดแถบ home ออกจากพื้นที่ของหน้า
   position:fixed; bottom:0 จึงไปหยุดเหนือแถบ home และ CSS วาดอะไรลงช่องนั้นไม่ได้เลย
   แก้: header.php ใส่ viewport-fit=cover แล้วให้ของที่ติดขอบจอเว้นระยะเอง
   env(...) เป็น 0 บนเครื่องที่ไม่มีรอยบาก/แถบ home และบน Android = หน้าตาเดิมทุกอย่าง */
/* ระยะยกแถบเมนูเหนือแถบ home (v1.39.21 · ผู้ใช้แจ้งว่ายกสูงเกิน)
   ตัวแถบลอยจากขอบล่างเองอยู่แล้ว 10px (.bottom-nav-container bottom:10px)
   ถ้ายกเต็มค่า safe area อีก = ห่างขอบจอ 44px บน iPhone ดูลอยสูงผิดตา
   → หักออก 24px: iPhone (34) ยกเพิ่ม 10 = ห่างขอบ 20px พ้นเส้น home พอดี · iPad (20) ไม่ยกเพิ่ม = 10px เท่าเดิม
   ช่องใต้แถบยังเป็นสีแถบเมนูเต็มถึงขอบจอ (พื้นของ .bottom-nav-wrapper) */
:root {
  --es-nav-lift: max(0px, env(safe-area-inset-bottom, 0px) - 24px);
}

.bottom-nav-wrapper {
  padding-bottom: var(--es-nav-lift);
}

.app-footer.has-bottom-nav {
  padding-bottom: calc(120px + var(--es-nav-lift));
}

.app-footer.has-bottom-menu {
  padding-bottom: calc(180px + var(--es-nav-lift));
}

.es-chat-panel__sheet {
  bottom: calc(174px + var(--es-nav-lift));
}

/* จอเตี้ย (แอปเปิดคีย์บอร์ด · มือถือแนวนอน · หน้าต่างคอมเล็ก/ซูม): แผงสูงอย่างน้อย 460px หรือเท่าที่จอมี
   แล้วค่อยหดช่อง 174px ใต้แผงเท่าที่จำเป็น (ฉากหลังบังแถบล่างอยู่แล้ว · แผงมีปุ่มปิดของตัวเอง)
   จอที่มีที่พอ (สูง ≥ ~626px) ได้ค่าเดิมทุกตัว
   🔴 WebView ของแอปเตี้ยลงจริงตอนคีย์บอร์ดเปิด vh/dvh จึงหดตาม ถ้าคง 174 + หัก 190 ช่องในแชทเหลือ ~250px ปุ่มส่งตกขอบ
   หน้าแชทต้องการช่องราว 400px ถึงเห็นช่องชื่อเล่น + ปุ่มส่งครบ = แผง 460 (แถบหัว 36)
   🔴 แก้แค่ bottom ไม่ได้พื้นที่คืน height กับ bottom ต้องคิดจากค่าเดียวกัน (--es-chat-h)
   🔴 ครอบ @supports: เบราว์เซอร์ที่ไม่รู้จัก dvh จะได้ height/bottom เป็นค่าว่าง แผงยุบ → ใช้กฎเดิมแทน
   .is-full ชนะกฎนี้ด้วย specificity */
@supports (height: 100dvh) {
  .es-chat-panel__sheet {
    --es-chat-h: max(min(70vh, 560px, calc(100dvh - 190px)), min(460px, calc(100dvh - 16px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px))));
    height: var(--es-chat-h);
    bottom: max(calc(8px + env(safe-area-inset-bottom, 0px)), min(calc(174px + var(--es-nav-lift)), calc(100dvh - var(--es-chat-h) - 8px - env(safe-area-inset-top, 0px))));
  }
}

/* แชทเต็มจอ: ช่องพิมพ์ต้องไม่จมใต้แถบ home · หัวแผงไม่ชนแถบสถานะ */
.es-chat-panel__sheet.is-full {
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}

/* หัวเว็บใต้แถบสถานะ (โหมดแอปที่ตั้ง status bar แบบโปร่ง · แอปที่ให้ WebView เต็มจอ)
   ในเบราว์เซอร์แนวตั้งค่านี้เป็น 0 */
.app-header {
  padding-top: env(safe-area-inset-top, 0px);
}

/* แนวนอนบน iPhone รอยบากอยู่ซ้าย/ขวา */
body {
  padding-left: env(safe-area-inset-left, 0px);
  padding-right: env(safe-area-inset-right, 0px);
}

/* ต่อพื้นสีล่างสุดของแถบลงไปใต้ขอบจอ กันช่องตอนเด้งดึงหน้า (rubber band) */
.bottom-nav-wrapper::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: max(160px, 40vh);
  background: var(--bg-bottom);
  pointer-events: none;
}

@media (min-width: 1280px) {
  .bottom-nav-wrapper::after {
    display: none;
  }
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.18s;
}

::view-transition-group(es-header),
::view-transition-group(es-bottom-nav) {
  animation-duration: 0s;
}

/* iPad/iPhone (WebKit): หัวเว็บกะพริบตอนสลับแท็บรัว ๆ (ผู้ใช้แจ้ง 2026-10-12 หน้า CUSTOMER PROFILE)
   ต้นเหตุ: WebKit โหลดฟอนต์ใหม่ทุกหน้า (จากแคชก็ยัง ~50–100ms) · หัวข้อ (Archivo) กับไอคอนตะกร้า (Font Awesome) เป็น font-display:block
   → ภาพหัวเว็บหน้าใหม่ถูกถ่ายตอนตัวหนังสือ/ไอคอนยังล่องหน แล้วโผล่ทันทีเพราะ group 0s = หัวข้อ/ไอคอนหายวูบแล้วกลับมา
   แก้: ค้างภาพหัวเว็บหน้าเดิมไว้ 0.25 วิ แล้วค่อยสลับเป็นหัวเว็บจริง (ตอนนั้นฟอนต์มาแล้ว) · หัวเว็บสองหน้าเหมือนกันจึงมองไม่เห็นการค้าง
   `font: -apple-system-body` มีเฉพาะ WebKit = Chrome/Android ไม่โดน (ยังสลับทันทีเหมือนเดิม) */
@supports (font: -apple-system-body) {
  ::view-transition-group(es-header) {
    animation-duration: 0.25s;
  }

  ::view-transition-old(es-header) {
    animation: none;
    opacity: 1;
  }

  ::view-transition-new(es-header) {
    animation: es-vt-hold 0.25s step-end both;
  }
}

@keyframes es-vt-hold {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  @view-transition {
    navigation: none;
  }
}

/* ============================================================
   ยกเลิกคำสั่งซื้อก่อนจัดส่ง — กล่องยืนยัน (inc/order-cancel.php · 2026-09-18)
   ใช้โครง .avatar-cropper ร่วม (image-cropper.css) · เนื้อหาชิดซ้าย เลื่อนได้ถ้าจอเตี้ย
   ============================================================ */
.es-cancel-modal .es-cancel-modal__box {
  max-width: 440px;
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  text-align: left;
}

.es-cancel__lead {
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.es-cancel__warn {
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--stat-error-bright);
}

.es-cancel__money {
  display: grid;
  gap: 8px;
  margin: 0 0 14px;
  padding: 12px 14px;
  border: 1px solid rgba(var(--text-primary-rgb), 0.12);
  border-radius: 10px;
}

.es-cancel__row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  line-height: 1.5;
}

.es-cancel__row > span:last-child {
  flex: none;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.es-cancel__row--cost > span:last-child {
  color: var(--stat-error-bright);
}

.es-cancel__row--total {
  padding-top: 8px;
  border-top: 1px solid rgba(var(--text-primary-rgb), 0.12);
  font-weight: 700;
}

.es-cancel__row--total > span:last-child {
  color: var(--stat-success, #2ecc71);
}

.es-cancel__notes {
  margin: 0 0 16px;
  padding-left: 18px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.es-cancel__notes li + li {
  margin-top: 4px;
}

.es-cancel-modal .form-group {
  margin-bottom: 16px;
}

.es-cancel-modal .form-textarea {
  width: 100%;
  min-height: 84px;
  resize: vertical;
}

.order-detail-actions__hint {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-secondary);
}

/* รายการหมายเหตุในกล่องยกเลิก — หน้าร้าน (Dokan) รีเซ็ต list-style ทิ้ง ต้องใส่คืนเอง */
.es-cancel-modal .es-cancel__notes {
  list-style: disc;
}

.es-cancel-modal .es-cancel__notes li {
  list-style: inherit;
}

/* ── ฟอร์มเพิ่ม/แก้ไขสินค้า: ระยะห่างเท่าหน้าแก้ไขร้าน (ผู้ใช้สั่ง 2026-09-18 รอบ 3) ──
   เดิม gap ของตัวห่อ (16 มือถือ / 24 จอใหญ่) + margin-bottom ของ .form-group (14 / 18) ซ้อนกัน = 30–42px
   หน้าแก้ไขร้านห่างราว 18px → ถอด margin ของช่องออก ให้ gap ตัวเดียวคุม และหัวข้อส่วนใช้ระยะแบบหน้าร้าน */
.add-new-product-wrapper .form-group {
  margin-bottom: 0;
}

.add-new-product-wrapper .form-row-2col {
  row-gap: 16px;
}

.add-new-product-wrapper .product-section-title {
  margin: 6px 0 -4px;
}

@media (min-width: 769px) {
  .add-new-product-wrapper {
    gap: 18px;
  }

  .add-new-product-wrapper .product-section-title {
    margin: 6px 0 -6px;
  }
}

/* ── ปุ่มยกเลิกคำสั่งซื้อ: รายการ + แถวเดียวกับ RECEIPT (ผู้ใช้สั่ง 2026-09-18 รอบ 3) ──
   .es-cancel-cell = ปุ่ม + "ยกเลิกได้ถึง …" ใต้ปุ่ม กว้างเท่าปุ่มข้าง ๆ · แถวจัดชิดบน ปุ่มข้างไม่ยืดตามข้อความ */
.order-action-row:has(.es-cancel-cell) {
  align-items: flex-start;
}

.order-action-row .es-cancel-cell {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.order-action-row .es-cancel-cell .btn-return-plain {
  width: 100%;
}

.es-cancel-cell .order-detail-actions__hint {
  margin: 8px 0 0;
  text-align: center;
}

/* กรอบปุ่มให้เท่ากับ RECEIPT ข้าง ๆ (ผู้ใช้แจ้ง 2026-10-03 "ดูไม่เท่ากับปุ่มข้าง ๆ")
   กรอบไล่สีของ RECEIPT คือ ::before ที่ล้นออกนอกปุ่ม 2px ทุกด้าน ส่วนปุ่มนี้กรอบ 1px อยู่ในตัว
   → ขยายออก 2px ทุกด้านเท่ากัน + padding บน-ล่างเพิ่ม 1px ชดเชยความสูง
   แถวเป็นกริดสองคอลัมน์เท่ากัน — flex เดิมนับ padding ของ RECEIPT เพิ่มให้ ปุ่มยกเลิกเลยแคบกว่า 12–20px */
.order-action-row--cancel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: start;
}

.order-action-row--cancel .es-cancel-cell .btn-return-plain {
  width: calc(100% + 4px);
  margin: -2px -2px 0;
  padding-top: 15px;
  padding-bottom: 15px;
}

/* หน้ารายละเอียดผู้ซื้อ สั่งข้ามร้าน: ป้ายสถานะรายร้านใต้ชื่อร้าน (2026-10-03 · template-parts/account/order-detail-body.php) */
.payment-vendor__status {
  margin: -2px 0 10px;
}

/* มือถือ: "CANCEL ORDER" ตกเป็น 2 บรรทัดข้าง RECEIPT (ผู้ใช้แจ้ง 2026-10-03)
   ย่อทั้งคู่เท่ากัน ปุ่มสองใบจะได้สูงเท่ากัน · ช่องไฟตัวอักษรแคบลงก่อน แล้วค่อยลดขนาด */
@media (max-width: 480px) {
  .order-action-row--cancel .btn-return-plain,
  .order-action-row--cancel .order-tracking-btn {
    padding-left: 6px;
    padding-right: 6px;
    font-size: 12px;
    letter-spacing: 0.04em;
    white-space: nowrap;
    gap: 6px;
  }
}

@media (max-width: 360px) {
  .order-action-row--cancel .btn-return-plain,
  .order-action-row--cancel .order-tracking-btn {
    font-size: 11px;
    letter-spacing: 0.02em;
  }
}

/* การ์ดออเดอร์ร้าน — ทรงเดียวกับ SEND TRACKING แต่เป็นปุ่มขอบ (ไม่ใช่ปุ่มหลัก) */
.vendor-action-btn--cancel {
  width: 100%;
  padding: 12px 10px;
  border-radius: var(--radius-btn);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  background: transparent;
  border: 1px solid rgba(var(--text-primary-rgb), 0.2);
  color: var(--text-primary);
}

.vendor-action-btn--cancel:hover {
  border-color: rgba(var(--text-primary-rgb), 0.4);
  background: rgba(var(--text-primary-rgb), 0.04);
}

/* เลยเวลายกเลิกแล้ว (order-cancel.js) — ปุ่มยังอยู่แต่กดไม่ได้ จนกว่าจะรีเฟรช */
.es-cancel-open:disabled,
.es-cancel-open.is-expired {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

.es-cancel__submit:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ── ช่องที่เบราว์เซอร์กรอกให้อัตโนมัติ (autofill) ต้องใสเหมือนช่องปกติ (ผู้ใช้แจ้ง 2026-09-18 รอบ 3) ──
   styles.css ของ design ทาเงาทึบ `0 0 0 1000px var(--bg-input) inset` ทับพื้น autofill ของ Chrome
   → ช่องที่ถูกกรอกให้เป็นกล่องทึบ ต่างจากช่องอื่น และพอแตะ (focus) พื้นหายวูบ = "บัค"
   ถอดเงาทึบออก แล้วใช้ transition หน่วงสีพื้นของเบราว์เซอร์ไว้ (พื้นคงเป็นของช่องเดิม) */
.form-input:-webkit-autofill,
.form-input:-webkit-autofill:hover,
.form-input:-webkit-autofill:focus,
.form-input:-webkit-autofill:active {
  -webkit-box-shadow: none;
  box-shadow: none;
  -webkit-text-fill-color: var(--text-primary);
  caret-color: var(--text-primary);
  transition: background-color 600000s 0s, color 600000s 0s;
}

/* ── ตัวนับความยาวท้ายหัวข้อช่องกรอก "(12/5,000)" (ผู้ใช้สั่ง 2026-09-19 · assets/js/field-limits.js) ──
   เทาเล็ก ๆ · เกินเพดาน (ข้อมูลเก่าที่ยาวอยู่แล้ว) เป็นสีแดง */
.es-count {
  margin-left: 6px;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--text-secondary);
  opacity: 0.8;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  -webkit-text-fill-color: currentColor;
}

.es-count.is-over {
  color: var(--stat-error-bright, #ff4444);
  opacity: 1;
  font-weight: 600;
}

/* ── ชื่อสินค้า/ข้อความยาวที่ไม่มีช่องว่าง ห้ามดันหน้ากว้าง (ผู้ใช้แจ้ง 2026-09-19 · ชื่อสินค้ายาวมากแล้วบัค) ──
   ชื่อยาวติดกันไม่มีเว้นวรรค (เช่น AAAA… หรือลิงก์) เบราว์เซอร์ตัดบรรทัดไม่ได้ → ล้นขวา/การ์ดขยาย
   `anywhere` ให้ตัดกลางคำได้เมื่อจำเป็นเท่านั้น และไม่นับคำยาวเป็นความกว้างขั้นต่ำของกล่อง
   เพดานความยาว (inc/field-limits.php) กันไม่ให้ยาวเกิน ส่วนนี้กันไม่ให้หน้าเพี้ยน */
.product-title,
.product-name,
.cart-item-name,
.checkout-order-item-name,
.order-card__product-info,
.order-card__product-info-left,
.payment-product__info,
.return-product-item__label,
.rc__c-name,
.store-name,
.store-bio,
.product-description,
.woocommerce-product-details__short-description {
  overflow-wrap: anywhere;
  min-width: 0;
}

/* ============================================================
   ฟอนต์ไม่สลับกลางหน้า (ผู้ใช้แจ้ง 2026-09-21: "หัวข้อแสดง font นึงก่อน แล้วถึงแสดง font ที่ถูกต้อง
   ทำให้ตำแหน่ง/ขนาดตัวหนังสือกระพริบ")

   ต้นเหตุ: @font-face ใน styles.css ตั้ง `font-display: swap` = วาดด้วยฟอนต์ของเครื่องก่อน
   แล้วสลับเมื่อไฟล์ฟอนต์มาถึง · ฟอนต์ของเครื่องกว้าง/สูงไม่เท่า Archivo + LINE Seed
   หัวข้อจึงเด้งทุกครั้งที่เปลี่ยนหน้า (หัวข้อใช้ตัวหนา 700 ซึ่งเดิมไม่ได้ preload ด้วย)

   แก้: ประกาศ @font-face ชุดเดิมซ้ำด้วย `font-display: block` — กฎที่มาทีหลังชนะเมื่อ
   family/weight/style ตรงกัน (ไม่แตะ styles.css ตามกฎโปรเจ็ค) · รอฟอนต์จริงแทนการโชว์ฟอนต์สำรอง
   ไฟล์ฟอนต์ทุกน้ำหนักที่ใช้ preload ไว้ใน <head> แล้ว (es_marketplace_preload_fonts · inc/enqueue.php)
   และเก็บแคช 1 ปี — ปกติมาทันก่อนวาดครั้งแรก จึงไม่เห็นช่วงตัวหนังสือว่าง
   🔴 path สัมพัทธ์ `../fonts/` ใช้ได้เพราะไฟล์นี้กับ .min อยู่โฟลเดอร์เดียวกับ styles.css
   🔴 เพิ่มน้ำหนักฟอนต์ใหม่ใน styles.css ต้องมาเพิ่มคู่ที่นี่ด้วย ไม่งั้นตัวนั้นกลับไป swap
   ============================================================ */
@font-face {
  font-family: 'ArchivoSemiExpanded';
  src: url('../fonts/archivo/ArchivoSemiExpanded-Regular.woff2') format('woff2');
  unicode-range: U+0000-0DFF, U+0E80-10FFFF;
  font-weight: 400;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'ArchivoSemiExpanded';
  src: url('../fonts/archivo/ArchivoSemiExpanded-Medium.woff2') format('woff2');
  unicode-range: U+0000-0DFF, U+0E80-10FFFF;
  font-weight: 500;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'ArchivoSemiExpanded';
  src: url('../fonts/archivo/ArchivoSemiExpanded-Bold.woff2') format('woff2');
  unicode-range: U+0000-0DFF, U+0E80-10FFFF;
  font-weight: 700;
  font-style: normal;
  font-display: block;
}
/* Archivo ตัวย่อ Latin-1 + เครื่องหมาย (2026-10-12 · PageSpeed): ~12 KB แทน ~33 KB ต่อน้ำหนัก
   ต้องอยู่ "หลัง" ตัวเต็มข้างบน (ตัวที่ประกาศทีหลังชนะในช่วงที่ทับกัน) · ตัวเต็มถูกจำกัดช่วงไม่รวมอักษรไทย
   ทั้งที่นี่และใน styles.css ไม่งั้นข้อความไทย (ซึ่งใช้ LINE Seed) ทำให้เบราว์เซอร์โหลดไฟล์เต็มมาเช็คก่อน
   อักษรนอกตัวย่อ (เช่น ā ő) → โหลดไฟล์เต็มเอง · สร้างตัวย่อใหม่: deploy/build-fa-subset.py
   🔴 unicode-range ข้างล่างต้องตรงกับค่า 'archivo' ใน inc/data/fa-subset.php */
@font-face {
  font-family: 'ArchivoSemiExpanded';
  src: url('../fonts/archivo/ArchivoSemiExpanded-Regular.sub.woff2') format('woff2');
  unicode-range: U+20-7e, U+a0-ff, U+131, U+152-153, U+2c6, U+2da, U+2dc, U+2000-206f, U+20ac, U+20bf, U+2122, U+2190-2193, U+2212, U+2215, U+feff;
  font-weight: 400;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'ArchivoSemiExpanded';
  src: url('../fonts/archivo/ArchivoSemiExpanded-Medium.sub.woff2') format('woff2');
  unicode-range: U+20-7e, U+a0-ff, U+131, U+152-153, U+2c6, U+2da, U+2dc, U+2000-206f, U+20ac, U+20bf, U+2122, U+2190-2193, U+2212, U+2215, U+feff;
  font-weight: 500;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'ArchivoSemiExpanded';
  src: url('../fonts/archivo/ArchivoSemiExpanded-Bold.sub.woff2') format('woff2');
  unicode-range: U+20-7e, U+a0-ff, U+131, U+152-153, U+2c6, U+2da, U+2dc, U+2000-206f, U+20ac, U+20bf, U+2122, U+2190-2193, U+2212, U+2215, U+feff;
  font-weight: 700;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'LINESeedSansTH_W';
  src: url('../fonts/lineseed/LINESeedSansTH_W_Th.woff2') format('woff2');
  font-weight: 100;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'LINESeedSansTH_W';
  src: url('../fonts/lineseed/LINESeedSansTH_W_Rg.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'LINESeedSansTH_W';
  src: url('../fonts/lineseed/LINESeedSansTH_W_Bd.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: block;
}

/* ============================================================
   ฟอร์มเพิ่ม/แก้ไขสินค้า — ผังรูปใหม่ (ผู้ใช้สั่ง 2026-09-21)
   *"รูปปกอยู่ซ้ายมือ แล้วแกล 3 บรรทัด 2 column จะมองง่ายกว่าไหม RWD จากเดิมที่แกลอยู่ใต้รูปปก"*

   กริดเดียว 2 คอลัมน์ (3 : 2) ทุกขนาดจอ:
     แถว 1  ป้าย "รูปปก"           ป้าย "แกลเลอรี"      ← ป้ายสองฝั่งอยู่แถวเดียวกัน ยาวไม่เท่ากันก็ไม่เหลื่อม
     แถว 2  กล่องรูปปก (สูงเท่าแกล)  แกลเลอรี 2 × 3
     แถว 3  ตัวนับ "0/6 รูปที่อัปโหลด" ชิดขวา
     แถว 4  ข้อความเตือน "ยังไม่มีรูปปก" (ถ้ามี)
   กล่องห่อ 3 ชั้นเป็น `display: contents` → ลูกของมันกลายเป็นช่องของกริดนี้โดยตรง
   🔴 JS ที่อ้าง `.trade-item-cover-box-wrap` ห้ามใช้ scrollIntoView / getBoundingClientRect กับตัวนั้น (ไม่มีกรอบแล้ว)
   สัดส่วน 3 : 2 ทำให้กล่องปก ≈ จัตุรัส (สูง = แกล 3 แถว) คลาดไม่เกิน ~2px
   🔴 **เฉพาะมือถือ ≤ 768px** — desktop/tablet คงผังเดิม (ปกซ้าย 220px + แกล 3 × 2) ผู้ใช้สั่งย้ำ 2026-09-21
   ⛔ แทนกฎมือถือเดิม "รูปปก = 2 ช่องของตาราง 3 คอลัมน์" (2026-09-20) ข้างบน — กฎนี้อยู่ท้ายไฟล์และเจาะจงกว่า จึงชนะ
   ============================================================ */
@media (max-width: 768px) {
  .add-new-product-wrapper .product-images-row {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    column-gap: 12px;
    row-gap: 8px;
    align-items: end;
    max-width: 640px;
  }

  .add-new-product-wrapper .product-images-row .trade-item-cover-box-wrap,
  .add-new-product-wrapper .product-images-row .trade-item-gall-box-wrap,
  .add-new-product-wrapper .product-images-row .trade-item-gall-box {
    display: contents;
  }

  .add-new-product-wrapper .trade-item-cover-box-wrap > .form-label {
    grid-column: 1;
    grid-row: 1;
  }

  .add-new-product-wrapper .trade-item-gall-box-wrap > .form-label {
    grid-column: 2;
    grid-row: 1;
  }

  .add-new-product-wrapper .trade-item-cover-box-wrap .trade-item-cover-box {
    grid-column: 1;
    grid-row: 2;
    align-self: stretch;
    width: 100%;
    max-width: none;
    height: auto;
    min-height: 0;
    aspect-ratio: auto;
    margin: 0;
  }

  .add-new-product-wrapper .trade-item-gall-box #dokan-product-images {
    grid-column: 2;
    grid-row: 2;
    align-self: start;
    min-width: 0;
  }

  .add-new-product-wrapper .trade-item-gall-box .gall-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }

  .add-new-product-wrapper .trade-item-gall-box .gall-image-count {
    grid-column: 1 / -1;
    grid-row: 3;
    text-align: right;
  }

  .add-new-product-wrapper .trade-item-cover-box-wrap .es-cover-error {
    grid-column: 1 / -1;
    grid-row: 4;
    margin: 0;
  }
}

/* ข้อ 3 (2026-09-21): กดขอบ ๆ ในกรอบรูปปกแล้วไม่เปิดเลือกไฟล์
   ต้นเหตุ: กล่องปกเป็น flex คอลัมน์ `align-items:center` → `.instruction-inside` หดเหลือกว้างเท่าไอคอน
   ปุ่มข้างในที่ตั้ง `width:100%` จึงกว้างแค่ไอคอนตาม (อาการเดียวกับ `.image-wrap` ที่เจอ 2026-08-16)
   วางเต็มกรอบแบบ absolute เหมือน `.image-wrap` → ปุ่มกินทั้งกรอบจริง */
.trade-item-cover-box .instruction-inside {
  position: absolute;
  inset: 0;
}

/* ============================================================
   ปฏิทินเลือกวันลดราคา — พื้นดำ ไฮไลต์ชมพู (ผู้ใช้สั่ง 2026-09-21)
   เดิมพื้นกรมท่า (--bg-card) · วันนี้ขอบฟ้า · วันที่เลือกไล่สีชมพู→ฟ้า (ดูเป็นสีฟ้าเขียว)
   ============================================================ */
#ui-datepicker-div.ui-datepicker {
  border-color: rgba(var(--grad-1-rgb), 0.35);
  background: #000;
}

#ui-datepicker-div .ui-datepicker-prev,
#ui-datepicker-div .ui-datepicker-next {
  background: rgba(var(--grad-1-rgb), 0.1);
}

#ui-datepicker-div .ui-datepicker-prev:hover,
#ui-datepicker-div .ui-datepicker-next:hover,
#ui-datepicker-div .ui-datepicker-calendar td a:hover {
  background: rgba(var(--grad-1-rgb), 0.24);
}

#ui-datepicker-div .ui-datepicker-calendar td.ui-datepicker-today a {
  box-shadow: inset 0 0 0 1px var(--grad-1);
  color: var(--grad-1);
}

#ui-datepicker-div .ui-datepicker-calendar td a.ui-state-active,
#ui-datepicker-div .ui-datepicker-calendar td.ui-datepicker-current-day a {
  background: var(--grad-1);
  box-shadow: none;
  color: #fff;
}

/* ============================================================
   ตัวแก้ไขคำบรรยายสินค้า (assets/js/rich-editor.js · 2026-09-21)
   แถบเครื่องมือติดหัวกล่อง · กล่องพิมพ์สูงไม่เกิน 60% ของจอแล้วเลื่อนในตัว
   → แถบเครื่องมืออยู่บนจอเสมอตอนพิมพ์ยาว ๆ บนมือถือ ไม่ต้องทำ sticky
   ============================================================ */
.es-rte.is-ready {
  position: relative;
  display: block;
}

.es-rte__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px;
  padding: 6px 8px;
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  border-bottom: 0;
  border-radius: 15px 15px 0 0;
  background: rgba(var(--text-primary-rgb), 0.04);
}

.es-rte__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 14px;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}

.es-rte__btn:hover {
  background: rgba(var(--text-primary-rgb), 0.08);
  color: var(--text-primary);
}

.es-rte__btn[aria-pressed="true"],
.es-rte__btn[aria-expanded="true"] {
  background: rgba(var(--grad-1-rgb), 0.2);
  color: var(--grad-1);
}

.es-rte__btn:focus-visible {
  outline: 2px solid var(--grad-1);
  outline-offset: -2px;
}

.es-rte__sep {
  width: 1px;
  height: 20px;
  margin: 0 4px;
  background: rgba(var(--text-primary-rgb), 0.14);
}

/* แผงสี / แผงลิงก์ — อยู่ในกระแสใต้แถบ (ไม่ลอยทับ) แถบเครื่องมือตัดบรรทัดบนมือถือจะได้ไม่คำนวณตำแหน่งผิด */
.es-rte__pop {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-left: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  border-right: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  background: #000;
}

.es-rte__pop[hidden] {
  display: none;
}

.es-rte__swatch {
  width: 30px;
  height: 30px;
  padding: 0;
  border: 2px solid rgba(var(--text-primary-rgb), 0.2);
  border-radius: 50%;
  cursor: pointer;
}

.es-rte__swatch.is-default {
  background: #fff;
}

.es-rte__swatch:hover,
.es-rte__swatch:focus-visible {
  border-color: #fff;
  outline: none;
  transform: scale(1.08);
}

.es-rte__linkpop .es-rte__linkinput {
  flex: 1 1 220px;
  min-width: 0;
  padding: 10px 16px;
}

.es-rte__linkpop .es-rte__linkinput.is-invalid {
  border-color: var(--stat-error);
}

.es-rte__linkbtn {
  /* ไอคอน + ข้อความอังกฤษ (2026-09-22) */
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  letter-spacing: 0.06em;
  white-space: nowrap;
  padding: 9px 14px;
  border: 1.5px solid rgba(var(--text-primary-rgb), 0.2);
  border-radius: 50px;
  background: transparent;
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 12px;
  cursor: pointer;
}

.es-rte__linkbtn.is-primary {
  border-color: var(--grad-1);
  background: var(--grad-1);
}

.es-rte__linkbtn[hidden] {
  display: none;
}

/* กล่องพิมพ์ — ต้องชนะกฎ .form-input (มุม 50px) และ textarea (15px !important) ของธีม */
.input-wrapper.es-rte .es-rte__area.form-input {
  position: relative;
  display: block;
  min-height: 180px;
  max-height: 60vh;
  height: auto;
  padding: 14px 18px;
  overflow-y: auto;
  border-radius: 0 0 15px 15px !important;
  /* ตัวอักษร/ระยะบรรทัด/สี = คำบรรยายในหน้าสินค้า (single-product.css `.product-description p`)
     ผู้ใช้แจ้ง 2026-09-21: เคาะบรรทัดใน editor ไม่เหมือนหน้าจริง + สีปกติต้องเหมือนหน้าเว็บ
     🔴 แก้ค่าที่นั่นเมื่อไรต้องแก้ตรงนี้ด้วย · rich-editor.js อ่านสีนี้เป็น "สีปกติ" (ไม่เก็บลง HTML) */
  /* !important — กฎกลาง `.input-wrapper .form-input` ตั้งสี/ระยะบรรทัดแบบ !important ไว้ */
  font-size: 14px !important;
  letter-spacing: 0.02em !important;
  line-height: 1.8 !important;
  color: var(--text-secondary) !important;
  white-space: normal;
  overflow-wrap: anywhere;
  cursor: text;
  -webkit-user-select: text;
  user-select: text;
}

.es-rte__area p {
  margin: 0; /* หน้าสินค้าไม่มีระยะระหว่างย่อหน้า (reset ทั้งเว็บ) — Enter 1 ครั้ง = ขึ้นบรรทัดใหม่ · 2 ครั้ง = เว้นบรรทัด */
}

.es-rte__area a {
  color: var(--grad-1);
  text-decoration: underline;
}

.es-rte__area img {
  display: inline-block;
  max-width: 100%;
  height: auto;
  border-radius: 10px;
  vertical-align: top;
}

.es-rte__area img[data-es-uploading] {
  opacity: 0.45;
}

.es-rte__area img.is-picked {
  outline: 2px solid var(--grad-1);
  outline-offset: 2px;
}

.es-rte.is-empty .es-rte__area::before {
  content: attr(data-placeholder);
  position: absolute;
  top: 14px;
  left: 18px;
  right: 18px;
  color: var(--text-placeholder);
  font-size: 12px;
  letter-spacing: 0.08em;
  pointer-events: none;
}

.es-rte__imgdel {
  position: absolute;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: var(--stat-error);
  color: #fff;
  font-size: 12px;
  cursor: pointer;
}

.es-rte__imgdel[hidden] {
  display: none;
}

.es-rte.is-uploading .es-rte__btn[data-cmd="image"] i {
  animation: es-rte-pulse 1s ease-in-out infinite;
}

@keyframes es-rte-pulse {
  50% { opacity: 0.35; }
}

@media (max-width: 480px) {
  .es-rte__btn {
    width: 36px;
    height: 36px;
  }

  .es-rte__sep {
    margin: 0 2px;
  }
}

/* บรรทัดว่างในคำบรรยาย — Enter 2 ครั้งใน editor ได้ <p><br></p> แต่ the_content (wpautop) ลอกเหลือ <p></p>
   ซึ่งสูง 0 → บรรทัดว่างหายในหน้าจริง/PREVIEW (ผู้ใช้แจ้ง 2026-09-21) · เติมช่องว่างให้สูงเท่าหนึ่งบรรทัด */
.product-description__body > p:empty::before {
  content: "\00a0";
}

/* หน้าสินค้า: รูปในคำบรรยายไม่ล้นจอ · ลิงก์เห็นว่าเป็นลิงก์ (2026-09-21) */
.product-description__body img {
  display: inline-block;
  max-width: 100%;
  height: auto;
  margin: 6px 0;
  border-radius: 12px;
  vertical-align: top;
}

.product-description__body a {
  color: var(--grad-1);
  text-decoration: underline;
  overflow-wrap: anywhere;
}

/* ตัวแก้ไขคำบรรยาย: วงสีอิสระ แถวเดียวกับวงสีอื่น (2026-09-30 · เดิมเป็นแถววงล้อ + ช่องรหัสสี + APPLY)
   วงสายรุ้ง + ไอคอนหลอดดูดสี · ตัวเลือกสีของเครื่อง (input type=color) โปร่งใสทับเต็มวง กดโดนตัว input ตรง ๆ */
.es-rte__swatch-custom {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin: 0;
  border: 2px solid rgba(var(--text-primary-rgb), 0.2);
  border-radius: 50%;
  background: conic-gradient(#f87171, #facc15, #4ade80, #00eeff, #a78bfa, #e84e9b, #f87171);
  color: #fff;
  font-size: 12px;
  cursor: pointer;
  overflow: hidden;
}

.es-rte__swatch-custom i {
  position: relative;
  pointer-events: none;
  filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.75));
}

.es-rte__swatch-custom:hover,
.es-rte__swatch-custom:focus-within {
  border-color: #fff;
  transform: scale(1.08);
}

/* เส้นคั่นหน้ากลุ่ม "สีที่ใช้ล่าสุด + สีอิสระ" (2026-09-30) — สูงเท่าวงสี ขนาดเดียวกับเส้นคั่นในแถบเครื่องมือ */
.es-rte__palette-sep {
  flex: 0 0 auto;
  width: 1px;
  height: 24px;
  margin: 0 2px;
  background: rgba(var(--text-primary-rgb), 0.2);
}

.es-rte__picker {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
}

/* บอกว่าสีอิสระที่เพิ่งใส่จะถูกปรับบนธีมไหน — ขึ้นใต้แถบเครื่องมือ 6 วิแล้วหายเอง (rich-editor.js showColorNote) */
.es-rte__colornote {
  margin: 0;
  padding: 8px 12px;
  border-left: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  border-right: 1.5px solid rgba(var(--text-primary-rgb), 0.12);
  background: #000;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-secondary);
}

.es-rte__colornote[hidden] {
  display: none;
}

.es-rte__colornote::before {
  content: "\f05a";
  margin-right: 6px;
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
  color: var(--stat-warning, #f59e0b);
}

/* ฟอร์มสินค้า: หัวข้อ "รูปสินค้า" + ปุ่ม PREVIEW บรรทัดเดียวกัน (2026-09-21)
   `.product-section-title` ของ design กว้าง 100% → ต้องปล่อยให้หดได้ ไม่งั้นปุ่มตกบรรทัด */
.es-section-head.es-product-head > .product-section-title {
  width: auto;
  margin: 0;
}

.es-section-head.es-product-head {
  margin: 16px 0 8px;
}

/* ฟอร์มเป็น flex คอลัมน์จัดกลาง → แถวหัวข้อหดเหลือกว้างเท่าเนื้อหาแล้วลอยกลางจอ (ผู้ใช้ทัก 2026-09-21)
   ต้องกางเต็มความกว้าง หัวข้อจึงชิดซ้ายและปุ่ม PREVIEW ชิดขวาได้ */
.add-new-product-wrapper > .es-section-head {
  align-self: stretch;
  width: 100%;
}

/* ปีที่สร้างผลงาน: ช่องพิมพ์ + ปุ่มลูกศรเลือกปีขวามือ (2026-09-21)
   <select> โปร่งใสกว้างเท่าปุ่มลูกศร วางทับ — แตะแล้วได้ตัวเลือกของเครื่อง */
.es-year-combo {
  position: relative;
  flex: 1 1 auto; /* .input-wrapper เป็น flex — ไม่ใส่แล้วหดเหลือกว้างเท่าเนื้อหา */
  width: 100%;
}

.es-year-combo > .form-input {
  padding-right: 56px;
}

.input-wrapper .es-year-combo > .es-year-combo__pick {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 52px !important; /* กฎ select ทั่วไปของฟอร์มตั้ง width:100% */
  min-width: 0;
  padding: 0;
  opacity: 0;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.es-year-combo__icon {
  position: absolute;
  top: 50%;
  right: 22px;
  transform: translateY(-50%);
  color: var(--text-secondary);
  font-size: 12px;
  pointer-events: none;
}

.es-year-combo:hover .es-year-combo__icon,
.es-year-combo__pick:focus-visible + .es-year-combo__icon {
  color: var(--grad-1);
}

/* ============================================================
   แกลเลอรีหน้าสินค้า: ช่วงที่ FlexSlider กำลังเริ่ม (ผู้ใช้แจ้ง 2026-09-22 "เหมือนแสดงรูปใหญ่ original ก่อนแว๊บนึง")
   วัดจริง: FlexSlider ตั้ง wrapper `width:400%` ก่อน แล้วค่อยใส่ความกว้างให้แต่ละสไลด์ ~0.7 วินาทีให้หลัง
   ระหว่างนั้นสไลด์กว้างเท่า wrapper → รูป 1,843px · แกลเลอรีสูง 3,809px (สไลด์ซ้อนกันแนวตั้ง)
   แก้: ให้กรอบ .flex-viewport เป็น container แล้วสไลด์กว้าง 100cqw (= กว้างเท่ากรอบ) + ลอยเรียงแนวนอนตั้งแต่แรก
   พอ FlexSlider ใส่ width แบบ inline ของมันเองก็ชนะกฎนี้ไปตามปกติ
   🔴 ต้องตรงกับก้อนเดียวกันใน es_marketplace_gallery_critical_css() (inc/woocommerce.php)
   ============================================================ */
.woocommerce-product-gallery .flex-viewport {
  container-type: inline-size;
}

.woocommerce-product-gallery .flex-viewport .woocommerce-product-gallery__image {
  width: 100cqw;
  float: left;
}

/* ============================================================
   คำบรรยายสินค้า: หัวข้อ h1–h6 + รายการจุด/ตัวเลข (ผู้ใช้สั่ง 2026-09-22)
   ชุดเดียวกันทั้งกล่องพิมพ์ (.es-rte__area) และหน้าสินค้า (.product-description__body) — เห็นใน editor = เห็นหน้าจริง
   ⚠️ reset ทั้งเว็บ (`* { margin:0; padding:0 }`) ลบระยะเยื้องรายการ/ขนาดหัวข้อทิ้ง ต้องประกาศเองทั้งหมด
   ⚠️ `.product-description .description-header h2` (หัว "INFORMATION") อยู่นอก __body — ไม่โดนกฎนี้
   ============================================================ */
.es-rte__area h1, .product-description__body h1,
.es-rte__area h2, .product-description__body h2,
.es-rte__area h3, .product-description__body h3,
.es-rte__area h4, .product-description__body h4,
.es-rte__area h5, .product-description__body h5,
.es-rte__area h6, .product-description__body h6 {
  margin: 0.5em 0 0.2em;
  color: var(--text-primary);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.02em;
  text-transform: none;
}

.es-rte__area h1, .product-description__body h1 { font-size: 24px; }
.es-rte__area h2, .product-description__body h2 { font-size: 21px; }
.es-rte__area h3, .product-description__body h3 { font-size: 18px; }
.es-rte__area h4, .product-description__body h4 { font-size: 16px; }
.es-rte__area h5, .product-description__body h5 { font-size: 15px; }
.es-rte__area h6, .product-description__body h6 { font-size: 14px; }

.es-rte__area > :first-child,
.product-description__body > :first-child {
  margin-top: 0;
}

.es-rte__area ul, .product-description__body ul,
.es-rte__area ol, .product-description__body ol {
  margin: 0;
  padding-left: 1.6em;
}

.es-rte__area ul, .product-description__body ul { list-style: disc; }
.es-rte__area ol, .product-description__body ol { list-style: decimal; }

.es-rte__area li, .product-description__body li {
  font-size: 14px;
  line-height: 1.8;
  color: var(--text-secondary);
  letter-spacing: 0.02em;
}

/* 🔴 style.css ของ Dokan มี `.dokan-dashboard .dokan-dashboard-content ul li { list-style: none }` (0,3,2)
   → จุดของรายการในกล่องพิมพ์หาย (ผู้ใช้แจ้ง 2026-09-22) ส่วนหน้าสินค้าไม่โดน · ต้องเจาะจงกว่าแล้วให้ li เอาชนิดจุดจาก ul/ol */
.dokan-dashboard .dokan-dashboard-content .es-rte__area ul li,
.dokan-dashboard .dokan-dashboard-content .es-rte__area ol li {
  list-style: inherit;
}

.es-rte__area li::marker, .product-description__body li::marker {
  color: var(--grad-1);
}

/* ปุ่มชนิดย่อหน้า + แผงเลือก (2026-09-22) — แผงของเราเอง ไม่ใช่รายการ <select> สีขาวของระบบ (ผู้ใช้ขอให้เข้าธีม)
   แต่ละตัวเลือกแสดงด้วยขนาด/สีจริงของหัวข้อนั้น = เห็นก่อนเลือกว่าจะออกมาหน้าตาแบบไหน */
.es-rte__bar .es-rte__btn.es-rte__blockbtn {
  width: auto;
  gap: 8px;
  padding: 0 10px 0 12px;
  border: 1px solid rgba(var(--text-primary-rgb), 0.14);
  font-family: var(--font);
  font-size: 12px;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.es-rte__blockbtn .fa-chevron-down {
  font-size: 10px;
  transition: transform 0.2s;
}

.es-rte__blockbtn[aria-expanded="true"] .fa-chevron-down {
  transform: rotate(180deg);
}

.es-rte__pop.es-rte__blockpop {
  flex-direction: column;
  align-items: stretch;
  gap: 2px;
  padding: 6px;
}

.es-rte__blockopt {
  display: block;
  width: 100%;
  padding: 6px 12px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--text-primary);
  font-family: var(--font);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.02em;
  text-align: left;
  cursor: pointer;
}

.es-rte__blockopt:hover,
.es-rte__blockopt:focus-visible {
  background: rgba(var(--grad-1-rgb), 0.14);
  outline: none;
}

.es-rte__blockopt[aria-selected="true"] {
  background: rgba(var(--grad-1-rgb), 0.22);
  color: var(--grad-1);
}

/* ขนาดตรงกับหัวข้อในคำบรรยาย (ชุดข้างบน) */
.es-rte__blockopt--p  { font-size: 14px; font-weight: 400; color: var(--text-secondary); }
.es-rte__blockopt--h1 { font-size: 24px; }
.es-rte__blockopt--h2 { font-size: 21px; }
.es-rte__blockopt--h3 { font-size: 18px; }
.es-rte__blockopt--h4 { font-size: 16px; }
.es-rte__blockopt--h5 { font-size: 15px; }
.es-rte__blockopt--h6 { font-size: 14px; }

/* แถวหัวข้อ "รายละเอียดสินค้า" + ปุ่ม PREVIEW ชิดขวา (2026-09-22) — ตัวนับ (n/5,000) ยังต่อท้ายป้ายเหมือนเดิม */
.es-field-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px 12px;
}

.es-field-head > .es-store-preview-btn {
  margin-left: auto;
  font-size: 11px;
  white-space: nowrap;
}

/* ============================================================
   ระยะระหว่างเนื้อหาชิ้นสุดท้ายกับท้ายเว็บ — เท่ากันทั้งเว็บ (ผู้ใช้แจ้งซ้ำ 2026-09-22 "แก้แค่หน้ารายละเอียดสินค้า หน้าอื่นยังห่าง")
   รอบ 21 ก.ย. ลดแค่ `.app-footer` (margin 48→16 + padding 20→8) ซึ่งมีผลทุกหน้าจริง แต่หลายหน้ามีช่องว่างของตัวเองซ้อนอยู่
   — ค่าจาก design เดิมที่ใส่ไว้กันแถบเมนูล่างบัง ซึ่งตอนนี้ .app-footer.has-bottom-nav / .has-bottom-menu เว้นที่ให้เองแล้ว
   วัดจริง (ระยะจากเนื้อหาสุดท้ายถึงลิงก์กฎ): หน้าสินค้า 29 · หน้าร้าน 112 · หน้ากฎ/ติดต่อ 93 · บัญชีของฉัน 131 · แก้ไขบัญชี/ตั้งค่าร้าน 104–179 · แดชบอร์ดร้าน 92–104
   ⚠️ แก้ที่นี่เท่านั้น ห้ามแก้ styles.css (เก็บไว้เทียบ prototype) · หน้าที่เนื้อหาสั้นยังดันท้ายเว็บไปติดล่างจอเหมือนเดิม (flex-grow ของ .site-main)
   ============================================================ */
.template-main {
  padding-bottom: 0;          /* styles.css 40px — หน้ากฎ/ติดต่อ/หน้าทั่วไป */
}

/* หน้าแรก (หน้า shop ที่ตั้งเป็นหน้าแรก) เป็น is_page() จึงได้ .template-main + padding-top 20px ติดมา
   ตอนยังไม่มีแถบหมวดหมู่ การ์ดเลยเริ่มต่ำกว่าหน้า /shop/ 20px (ผู้ใช้สั่ง 2026-10-12 ให้ชิดหัวเว็บ)
   มีแถบหมวดหมู่เมื่อไรระยะ 20px กลับมาเอง */
body.es-root-page .site-main.template-main:not(:has(> .product-category)) {
  padding-top: 0;
}

/* หน้า shop (หน้าแรก + /shop/) ขยับขึ้นอีก 4px ให้ชิดหัวเว็บ (ผู้ใช้สั่ง 2026-10-12 "ยังชิดไม่พอ" ลอง −5 · −2 แล้วลงตัวที่ −4) */
body.woocommerce-shop #primary {
  margin-top: -4px;
}

.store-tab-panel {
  padding-bottom: 0;          /* store.css 60px — แท็บในแดชบอร์ดร้าน */
}

.store-products {
  padding-bottom: 0;          /* store-profile.css 80px — หน้าร้าน */
}

.edit-profile-wrapper {
  margin-bottom: 0 !important; /* styles.css 80px !important — แก้ไขบัญชี · ตั้งค่าร้าน */
}

.es-vendor-empty {
  padding-bottom: 16px;       /* 48px — กล่อง "ยังไม่มี…" มักเป็นของชิ้นสุดท้ายของหน้า */
}

/* รอบ 2 (22 ก.ย. ผู้ใช้แจ้ง "หน้าโปรไฟล์ผู้ซื้อเปิดในมือถือดูห่างเกิน") — รอบแรกวัดแต่บัญชีที่ไม่มีคำสั่งซื้อจึงหลุด
   วัดที่ 390px: โปรไฟล์ที่มีคำสั่งซื้อ 84 · ฟอร์มเพิ่ม/แก้สินค้า 104 · shop 75 */
.order-card-list {
  padding-bottom: 0;          /* ข้างบนไฟล์นี้เอง 60px — รายการคำสั่งซื้อในหน้าโปรไฟล์ */
}

.add-new-product-wrapper {
  margin-bottom: 0 !important; /* add-new-product.css 80px !important — ฟอร์มเพิ่ม/แก้สินค้า */
}

.product-list {
  margin-bottom: 0;           /* product.css 50px — ตัวโหลดเพิ่ม (.product-loader) มีระยะของตัวเองอยู่แล้ว */
}

.woocommerce form.register.create-store-wrapper,
.woocommerce-account form.register.create-store-wrapper {
  margin-bottom: 0;           /* ข้างบนไฟล์นี้ 80px — หน้าเปิดร้าน */
}

/* ============================================================
   ปุ่ม = ไอคอน + ข้อความอังกฤษ ทั้งเว็บ (ผู้ใช้สั่ง 2026-09-22 — ไล่เก็บปุ่มที่ตกหล่น)
   ปุ่มเหล่านี้เดิมมีแต่ตัวหนังสือ จึงยังไม่ได้จัดไอคอนให้อยู่บรรทัดเดียวกับข้อความ
   ⚠️ EDIT PROFILE · EDIT STORE · BACK TO HOME (404) ตั้งใจไม่มีไอคอน — ผู้ใช้สั่งไว้ก่อนหน้า
   ============================================================ */
.btn-submit,
.es-product-submit,
.es-gate__btn,
.btn-return-plain {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.tab-btn,
.btn-apply-coupon,
.pruduct-buttons .btn-buy-now,
.es-change-confirm__reject,
.es-vendor-empty .btn-edit-store,
.woocommerce-info a.button.wc-forward,
.woocommerce-message a.button.wc-forward {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.btn-submit i,
.es-product-submit i,
.es-gate__btn i,
.tab-btn i,
.btn-apply-coupon i,
.btn-buy-now i {
  flex: 0 0 auto;
  font-size: 0.9em;
}

/* ปุ่มยืนยันอีเมลของ WooCommerce — HTML มาจากปลั๊กอิน ใส่ไอคอนด้วย CSS (inc/email-verify.php) */
.woocommerce-info a.button.wc-forward[href*="wc_send_verification"]::before {
  content: "\f0e0";
  font-family: "Font Awesome 6 Free";
  font-weight: 900;
  font-size: 0.9em;
}

/* ประโยคยินยอมเหนือปุ่ม I AGREE (template-parts/terms-gate.php) */
.es-gate__consent {
  margin: 0 0 10px;
  font-size: 12px;
  line-height: 1.6;
  text-align: center;
  color: var(--text-secondary);
}

/* แท็บประเภทร้าน 3 อัน (INDIVIDUAL · ARTIST · GALLERY) — จอแคบไอคอนขึ้นเหนือตัวหนังสือ
   วัดที่ 360px: แบบบรรทัดเดียว INDIVIDUAL ล้นแท็บ (กว้างได้แค่ 88px) */
@media (max-width: 480px) {
  .create-store-wrapper .tab-switcher .tab-btn {
    min-width: 0;
    flex-direction: column;
    gap: 3px;
    padding: 7px 4px;
    font-size: 11px;
    letter-spacing: 0.03em;
    line-height: 1.2;
  }
}

/* ช่องจังหวัดค้นหาได้ (assets/js/state-select.js) — Dokan style.css ดันกล่องรายการลง 32px ในแดชบอร์ดร้าน
   ถอดเฉพาะของช่องนี้ ไม่แตะ select2 ตัวอื่นของ Dokan */
.select2-container--open .es-state-dropdown.select2-dropdown--below,
.select2-container--open .es-state-dropdown.select2-dropdown--above {
  margin-top: 0;
}

/* กรอบฟ้าตอนโฟกัสช่องพิมพ์ค้นหา = ring ของ Tailwind forms ใน Dokan (แดชบอร์ดร้าน) — ให้ตรงกับหน้าแก้ไขโปรไฟล์ */
.es-state-dropdown .select2-search__field:focus {
  box-shadow: none;
}

/* ── หัวข้อ "การแสดงผล" ในหน้าแก้ไขโปรไฟล์ — สวิตช์โหมดสว่าง/มืด (2026-09-25 · inc/theme-mode.php) ──
   ข้อความซ้าย สวิตช์ชิดขวา · จอแคบสวิตช์ยังอยู่บรรทัดเดียวกัน (ป้ายสั้น) */
.es-theme-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin: 4px 0 8px;
}

.es-theme-row__text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.es-theme-row__title {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-primary);
}

.es-theme-switch .es-switch__label {
  min-width: 86px;
}

/* ── ปุ่มคู่ DARK | LIGHT (ทีม UI ขอ 2026-09-26 · แทนสวิตช์ด้านบนซึ่งเก็บไว้ใช้คืน) ──
   กรอบแคปซูลเส้นบาง · ตัวที่เลือกมีขอบไล่สีแบรนด์ (ไส้โปร่ง = พื้นเดียวกับกรอบ)
   ขอบวาดด้วย ::before + mask ตัดไส้ · หนา 2px โหมดมืด / 3px โหมดสว่าง (theme-light.css ข้อ 14) */
.es-theme-seg {
  display: inline-flex;
  flex-shrink: 0;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--border-inactive);
  border-radius: var(--radius-btn);
  background: var(--bg-primary);
}

.es-theme-seg__btn {
  --es-seg-ring: 2px;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 92px;
  padding: 9px 14px;
  border: 0;
  border-radius: var(--radius-btn);
  background: transparent;
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  font-family: var(--font);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.10em;
  line-height: 1.2;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 0.2s, box-shadow 0.3s;
}

.es-theme-seg__btn i {
  font-size: 14px;
}

.es-theme-seg__btn::before {
  content: '';
  position: absolute;
  inset: 0;
  padding: var(--es-seg-ring);
  border-radius: inherit;
  background: var(--gradient);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  opacity: 0;
  transition: opacity 0.25s;
  pointer-events: none;
}

.es-theme-seg__btn[aria-pressed="true"]::before {
  opacity: 1;
}

.es-theme-seg__btn[aria-pressed="false"]:hover {
  background: rgba(var(--text-primary-rgb), 0.06);
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
}

.es-theme-seg__btn[aria-pressed="true"]:active {
  box-shadow:
    0 0 12px 3px rgba(var(--grad-1-rgb), 0.28),
    0 0 16px 4px rgba(var(--grad-4-rgb), 0.20);
}

.es-theme-seg__btn:focus-visible {
  outline: 2px solid var(--grad-4);
  outline-offset: 2px;
}

/* มือถือ: "สีของธีม" อยู่บรรทัดบน ปุ่มคู่เต็มความกว้างบรรทัดล่าง ปุ่มละครึ่ง (ผู้ใช้สั่ง 2026-09-26) */
@media (max-width: 768px) {
  .es-theme-row:has(.es-theme-seg) {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }

  .es-theme-seg {
    display: flex;
    width: 100%;
  }

  .es-theme-seg__btn {
    flex: 1 1 0;
    min-width: 0;
  }
}

/* ลิงก์สลับโหมดท้ายเว็บ — ไอคอนเล็กนำหน้า (inc/theme-mode.php) */
.app-footer__links a i {
  margin-right: 1px;
  font-size: 10px;
}

/* ── ดึงหน้าเลยขอบบน (overscroll / rubber-band ของ Safari · Chrome บน Mac · iOS) — ผู้ใช้แจ้ง 2026-09-25 ──
   หัวเว็บเป็น sticky จึงถูกลากลงมาพร้อมเนื้อหา เหลือช่องว่างเหนือหัวเว็บที่ทะลุเห็นภาพพื้นหลัง
   → พื้นสีเดียวกับหัวเว็บยื่นขึ้นไปเหนือขอบบน 100vh (มองไม่เห็นตอนปกติ เพราะอยู่นอกจอ)
   ดึงลงมาเท่าไรก็ถูกบังเท่านั้น ทั้งสองโหมด (สีมาจาก --bg-header ของแต่ละโหมด) */
.app-header::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: 100vh;
  background: var(--bg-header);
  pointer-events: none;
}

/* ── ไอคอนแชท SVG ในปุ่มกลางแถบเมนูล่าง (2026-09-25 · footer.php) — ทั้งสองโหมด ──
   สัดส่วน viewBox 40×34 · กว้างราวครึ่งหนึ่งของปุ่มตามรูปตัวอย่าง (รอบแรกเล็กไป ผู้ใช้แจ้ง) · สีกล่องตาม currentColor ของปุ่ม */
.bnav-btn .es-chat-icon {
  display: block;
  width: 34px;
  height: 29px;
}

.bottom-nav-container--menu .bnav-btn .es-chat-icon {
  width: 38px;
  height: 32px;
  transform: translateY(3px); /* หางอยู่ล่าง — ดันลงให้ตัวกล่อง (ไม่รวมหาง) อยู่กลางปุ่ม */
}

/* ── ชื่อสินค้าบนการ์ด (หน้า shop / ผลค้นหา / สินค้าแนะนำ) เป็นตัวหนา — ทั้งสองโหมด (ผู้ใช้สั่ง 2026-09-25 ตาม UI ตัวอย่าง) ──
   product.css ตั้ง 400 · ยังตัดที่ 2 บรรทัดเหมือนเดิม (ตัวหนากว้างขึ้นเล็กน้อย ชื่อยาวอาจถูกตัดเร็วขึ้นไม่กี่ตัวอักษร) */
.product-card .product-title {
  font-weight: 700;
}

/* ── ตัวเลขแจ้งเตือนบนแท็บที่ไม่ได้เลือก ต้องไม่จาง — ทั้งสองโหมด (ผู้ใช้สั่ง 2026-09-25) ──
   เดิมจางทั้งกล่องไอคอน (opacity .3) ตราแดงที่อยู่ในกล่องจึงจางตาม
   → ย้ายความจางไปที่พื้นกล่อง (สีเดียวกัน alpha .3) + ตัวไอคอน · หน้าตาแท็บเหมือนเดิม ตราแดงชัดเต็ม */
.nav-tabs-item:not(.active) .nav-tabs-icon,
.store-tab-nav-item:not(.active) .store-tab-nav-icon {
  opacity: 1;
  background: rgba(var(--bg-primary-rgb), 0.3);
}

.nav-tabs-item:not(.active) .nav-tabs-icon > i,
.store-tab-nav-item:not(.active) .store-tab-nav-icon > i {
  opacity: 0.3;
}

/* ── แท็บที่เลือกเปลี่ยนแบบจาง ไม่ตัดฉับ (ผู้ใช้แจ้ง 2026-10-12: สลับแท็บรัว ๆ กล่องขาวกะพริบ) ──
   scripts.js ย้าย .active ไปแท็บที่แตะทันทีบนหน้าเดิม → กล่องขาวค่อย ๆ ย้ายไปก่อนหน้าใหม่มาถึง */
.nav-tabs-icon {
  transition: background-color 0.15s ease, box-shadow 0.25s ease, transform 0.2s ease;
}

.nav-tabs-icon > i {
  transition: color 0.15s ease, opacity 0.15s ease;
}

.nav-tabs--sub .nav-tabs-list .nav-tabs-item,
.nav-tabs--sub .nav-tabs-list .nav-tabs-item a {
  transition: background-color 0.15s ease, color 0.15s ease;
}

@media (prefers-reduced-motion: reduce) {
  .nav-tabs-icon,
  .nav-tabs-icon > i,
  .nav-tabs--sub .nav-tabs-list .nav-tabs-item,
  .nav-tabs--sub .nav-tabs-list .nav-tabs-item a {
    transition: none;
  }
}

/* ── ตัวเลขแจ้งเตือนเป็นสีขาวเสมอ แม้ชี้เมาส์ที่ปุ่มแม่ — ทั้งสองโหมด (ผู้ใช้แจ้ง 2026-09-25: โหมดสว่างชี้แล้วเลขกลายเป็นดำ) ──
   กฎ hover ของปุ่ม (a[class*='btn']:hover ฯลฯ) ตั้ง -webkit-text-fill-color: var(--text-primary) ที่ปุ่ม
   ซึ่งสืบทอดลงมาถึงตรา — โหมดมืดเป็นขาวจึงไม่มีใครเห็น */
.es-noti-badge,
.es-noti-badge--inline,
.nav-tabs-count,
.store-tab-nav-count,
.cart-count-badge,
.es-ticket__badge {
  color: #fff;
  -webkit-text-fill-color: #fff;
}

/* ── โลโก้ธนาคาร (ฟอนต์ thbanks) เป็นกล่องสี่เหลี่ยมจัตุรัส มุมมนเล็กน้อย โลโก้อยู่กลาง — ทุกจุด ทั้งสองโหมด (ผู้ใช้สั่ง 2026-09-25) ──
   เดิมพื้นสีธนาคารชิดขอบตัวอักษรพอดี (ไม่มีระยะรอบโลโก้) · ขนาดคิดเป็น em จึงตามขนาดไอคอนเดิมของแต่ละจุด
   กล่อง 1.4em · โลโก้ 0.9em (≈ 64% ของกล่อง) · โลโก้ขาว (โหมดสว่างตั้งใน theme-light.css ข้อ 15)
   ⚠️ พร้อมเพย์ใช้ fa-qrcode ไม่ใช่ thbanks — ไม่โดนกฎนี้ */
i.thbanks {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.4em;
  height: 1.4em;
  border-radius: 0.28em;
  line-height: 1;
  vertical-align: middle;
  flex: 0 0 auto;
  overflow: hidden;
}

i.thbanks::before {
  font-size: 0.9em;
}

/* ในรายการเลือกธนาคาร (icon-select) กล่องเดิมตรึง 20px/ตัวอักษร 18px — ย่อตัวอักษรให้กล่องใหม่ยังสูงเท่าแถว */
.icon-select__icon--font.thbanks {
  width: 1.4em;
  height: 1.4em;
  font-size: 15px;
}

/* ── ปุ่มกลับหน้า Market (ซ้ายล่างหน้าโปรไฟล์/แดชบอร์ดร้าน · ปุ่มบนหัวเว็บ) ใช้ไอคอน SVG ตัวเดียวกับ Market ในแถบเมนูล่าง ──
   (ผู้ใช้สั่ง 2026-09-25 · เดิม fa-shop + fa-location-dot ซ้อนกัน) · สีตาม currentColor ของปุ่ม ทั้งสองโหมด */
.btn-bottom-shop .bnav-icon,
.btn-shop .bnav-icon {
  display: block;
  width: 22px;
  height: 22px;
}

.btn-shop .bnav-icon {
  width: 19px;
  height: 19px;
}

/* ── สีตัวหนังสือที่ผู้ขายเลือกในคำบรรยายสินค้า — ทั้งสองธีม (ผู้ใช้สั่ง 2026-09-30) ──
   inc/rich-text.php es_marketplace_rte_theme_colors() แปลง style="color:…" เป็นสีคู่ --es-tc-d / --es-tc-l
   ที่ตัดกับพื้นธีมนั้นได้ ≥ 4.5:1 · ธีมสว่างเลือก --es-tc-l ใน theme-light.css
   !important แทนความแรงของ style ในแท็กเดิม (สีที่ผู้ขายเลือกเคยชนะกฎของหน้าทุกตัว) */
.es-tc {
  color: var(--es-tc-d) !important;
}

/* ── แถบนำทางหน้ารายละเอียดคำสั่งซื้อ (2026-10-01 · template-parts/order-breadcrumb.php) — ทั้งสองธีม ──
   Marketplace / Customer Profile (หรือ Store Profile) / ORDER-xxx · ใต้หัวเว็บ เหนือกล่อง "คำสั่งซื้อ"
   ตัวคั่น "/" วาดด้วย ::after ของรายการก่อนหน้า · ยาวเกินจอมือถือ = ตัดบรรทัดได้ */
.es-breadcrumb {
  margin: 0 0 12px; /* เท่าระยะระหว่างการ์ด (.payment-order-header margin-bottom 12px) */
  padding: 10px 14px; /* ทุกจอเท่ามือถือ (ผู้ใช้สั่ง 2026-10-02 — จอแคบเปลี่ยนแค่ข้อความ ขนาดห้ามกระโดด) */
  border-radius: 12px;
  background: var(--bg-primary); /* สีเดียวกับการ์ด .payment-order-header ข้างล่าง — ธีมสว่างขาว (ผู้ใช้สั่ง 2026-10-01) */
}

/* กล่องถัดไปมี margin-top ของตัวเอง (แถบนับเวลา 16px) — กล่องแม่เป็น flex ระยะไม่ยุบรวม ได้ช่อง 28–32px ห่างกว่าการ์ดอื่น */
.es-breadcrumb + .payment-timer,
.es-breadcrumb + .payment-order-header {
  margin-top: 0;
}

.es-breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 0;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 12px;
  line-height: 1.5;
  text-transform: uppercase; /* MARKETPLACE / CUSTOMER PROFILE / ORDER-xxx (ผู้ใช้สั่ง 2026-10-01) */
  letter-spacing: 0; /* ผู้ใช้แจ้ง "ตัวหนังสือดูห่าง ๆ" — ไม่เว้นระยะตัวอักษรเพิ่ม */
}

.es-breadcrumb__item {
  display: inline-flex;
  align-items: center;
  min-width: 0;
  color: var(--text-secondary);
}

/* ตัวคั่น "/" ติดท้ายช่องก่อนหน้า (::after) — จอแคบตกบรรทัดแล้ว "/" ค้างท้ายบรรทัดแรก ไม่ไปขึ้นหน้าบรรทัดใหม่
   ระยะรอบ "/" 7px ทุกจอ (ผู้ใช้สั่ง 2026-10-02 ให้ห่างขึ้นจาก 6px · แล้วให้ทุกจอเท่ามือถือ) */
.es-breadcrumb__item:not(:last-child)::after {
  content: "/";
  margin: 0 7px;
  color: rgba(var(--text-primary-rgb), 0.35);
}

.es-breadcrumb__link,
.es-breadcrumb__current {
  display: inline-flex;
  align-items: center;
  gap: 3px; /* ไอคอนติดชื่อ (ผู้ใช้สั่ง 2026-10-02 · เดิม 6px) */
}

/* ก่อนชี้ = เทาอ่อนกว่าตัวหนังสือรอง · ชี้ = เข้มขึ้น + ขีดเส้นใต้ (ผู้ใช้สั่ง 2026-10-01 — แทนสีรุ้ง)
   🔴 ต้องปิดกฎกลาง `a:hover` ของ styles.css ที่ทาไล่สีรุ้งให้ทุกลิงก์ (background + ตัวหนังสือโปร่งใส) */
.es-breadcrumb__link {
  color: rgba(var(--text-primary-rgb), 0.6); /* รอบ 2: .45 อ่อนไป ผู้ใช้ขอเข้มขึ้น */
  text-decoration: none;
  transition: color 0.2s ease;
}

/* ไอคอนหน้าแต่ละช่อง — SVG แถบเมนูล่าง (fill=currentColor) กับ Font Awesome ขนาดเท่ากัน · สีตามตัวหนังสือ */
.es-breadcrumb__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  font-size: 12px;
  line-height: 1;
}

.es-breadcrumb__icon svg {
  display: block;
  width: 14px;
  height: 14px;
}

.es-breadcrumb .es-breadcrumb__link:hover,
.es-breadcrumb .es-breadcrumb__link:focus-visible {
  color: var(--text-primary);
  background: none;
  -webkit-text-fill-color: currentColor;
  animation: none;
  text-decoration: none;
}

/* เส้นใต้เฉพาะตัวหนังสือ ไม่ลากผ่านไอคอน/ช่องว่าง (ผู้ใช้สั่ง 2026-10-02) — ใส่ที่ป้ายชื่อ ไม่ใช่ที่ <a> (ใส่ที่ <a> แล้วลามถึงไอคอน) */
.es-breadcrumb .es-breadcrumb__link:hover :is(.es-breadcrumb__full, .es-breadcrumb__short),
.es-breadcrumb .es-breadcrumb__link:focus-visible :is(.es-breadcrumb__full, .es-breadcrumb__short) {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ชื่อย่อบนจอแคบ (2026-10-02 ผู้ใช้สั่ง) — MARKETPLACE → MARKET · CUSTOMER/STORE PROFILE → PROFILE
   สลับด้วย display:none อย่างเดียว — ตัวที่ซ่อนหลุดจากโปรแกรมอ่านหน้าจอเอง (ห้ามใส่ aria-hidden ไม่งั้นจอแคบอ่านไม่เจอชื่อ) */
.es-breadcrumb__short {
  display: none;
}

@media (max-width: 768px) {
  .es-breadcrumb__full {
    display: none;
  }

  .es-breadcrumb__short {
    display: inline;
  }
}

.es-breadcrumb__current {
  font-weight: 600;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

/* ── กล่อง "คุณยังไม่ได้บันทึกบัญชีรับเงินคืน" ในหน้าคำขอของผู้ซื้อ (2026-10-02 · woocommerce/myaccount/returns.php) ──
   กล่องเหลืองของ design (.return-status-box.warning) + ปุ่มขอบไล่สีชิดซ้าย ไม่ยืดเต็มกล่อง */
.return-status-box.es-need-bank {
  margin-bottom: 14px;
}

.return-status-box.es-need-bank p + p {
  margin-top: 6px;
}

.return-status-box.es-need-bank strong i {
  margin-right: 4px;
  color: rgb(245, 158, 11);
}

a.order-tracking-btn.es-need-bank__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  margin-top: 12px;
  padding-inline: 18px;
}

/* ============================================================
   หน้าการเงินร้าน — การ์ดยอดเงินที่ถอนได้ + สรุปภาพรวมรายได้ + กล่องขอถอนเงิน
   ผู้ใช้สั่ง 2026-10-03 · ตามแบบจากทีม UI · แทนการ์ด 4 ใบเดิม (dokan/withdraw/withdraw-dashboard.php)
   ธีมสว่างอยู่ใน theme-light.css (:root[data-theme="light"] .es-fin-…)
   ============================================================ */
.es-fin-hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding: 22px 20px 20px;
  border: 2px solid transparent;
  border-radius: 22px;
  background:
    linear-gradient(135deg, rgba(var(--bg-header-rgb), .96), rgba(24, 16, 64, .96)) padding-box,
    var(--gradient) border-box;
  box-shadow: 0 0 18px rgba(var(--grad-2-rgb), .28), 0 0 34px rgba(var(--grad-4-rgb), .14);
}

.es-fin-hero__ghost {
  position: absolute;
  right: 18px;
  top: 22px;
  z-index: -1;
  font-size: 104px;
  line-height: 1;
  /* กระเป๋าแบบเส้นขอบโปร่งตามแบบ — FA ชุดฟรีไม่มีกระเป๋าแบบเส้น จึงใช้ขอบตัวอักษรแทน */
  color: transparent;
  -webkit-text-stroke: 2.5px rgba(var(--grad-3-rgb), .55);
  opacity: .7;
  pointer-events: none;
}

.es-fin-hero__top {
  display: flex;
  align-items: center;
  gap: 16px;
  min-width: 0;
}

.es-fin-hero__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 18px;
  background: linear-gradient(135deg, var(--grad-2), #6d28d9 70%, var(--grad-3));
  color: #fff;
  font-size: 28px;
}

.es-fin-hero__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.es-fin-hero__label {
  font-size: 18px;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: .02em;
}

.es-fin-hero__amount {
  margin: 2px 0;
  font-size: clamp(30px, 8vw, 42px);
  font-weight: 800;
  line-height: 1.15;
  color: var(--stat-success);
  letter-spacing: .01em;
  overflow-wrap: anywhere;
}

.es-fin-hero__amount--bad {
  color: var(--stat-error);
}

.es-fin-hero__sub {
  font-size: 14px;
  color: var(--text-secondary);
}

/* ปุ่มเต็มแถบ ไล่สีแบรนด์ ตัวหนังสือขาว (กฎ: ปุ่มไล่สีต้องตัวหนังสือขาว)
   ปรับรอบ 2 (ผู้ใช้สั่ง 2026-10-03): เล็กลง ตัวบางลง · ชี้แล้วสีวิ่ง
   ภาพพื้นกว้าง 200% ไล่ชมพู→ฟ้า→ชมพู แล้วเลื่อน 200% ต่อรอบ = วนต่อกันไม่มีรอยสะดุด */
a.es-fin-hero__btn,
.es-fin-hero__btn {
  margin-top: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 42px;
  padding: 9px 16px;
  border-radius: 14px;
  background: linear-gradient(90deg,
    var(--grad-1) 0%, var(--grad-2) 17.5%, var(--grad-3) 37.5%, var(--grad-4) 50%,
    var(--grad-3) 62.5%, var(--grad-2) 82.5%, var(--grad-1) 100%);
  background-size: 200% 100%;
  background-position: 0% 50%;
  color: #fff !important;
  -webkit-text-fill-color: #fff;
  text-decoration: none;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: .14em;
  box-shadow: none;
  transition: transform .2s;
}

.es-fin-hero__btn::before,
.es-fin-hero__btn::after {
  content: none !important;
}

/* 🔴 ต้องหนักกว่ากฎกลาง a[class*='btn']:hover / :focus (0,2,1) ที่ล้างพื้นไล่สี + ปิดแอนิเมชันของปุ่มลิงก์ทุกตัว
   และ a:hover (styles.css) ที่ตั้ง background-clip: text — เลยต้องเขียน a.… และสั่งพื้นกลับครบทุกค่า */
a.es-fin-hero__btn:hover,
a.es-fin-hero__btn:focus,
a.es-fin-hero__btn:focus-visible {
  color: #fff;
  -webkit-text-fill-color: #fff;
  background-image: linear-gradient(90deg,
    var(--grad-1) 0%, var(--grad-2) 17.5%, var(--grad-3) 37.5%, var(--grad-4) 50%,
    var(--grad-3) 62.5%, var(--grad-2) 82.5%, var(--grad-1) 100%);
  background-size: 200% 100%;
  -webkit-background-clip: border-box;
  background-clip: border-box;
}

a.es-fin-hero__btn:hover,
a.es-fin-hero__btn:focus-visible {
  animation: es-fin-btn-run 1.6s linear infinite;
}

a.es-fin-hero__btn:hover i,
a.es-fin-hero__btn:focus i {
  color: #fff;
  -webkit-text-fill-color: #fff;
}

.es-fin-hero__btn:active {
  transform: scale(.985);
}

.es-fin-hero__btn i {
  font-size: 13px;
  color: #fff;
  -webkit-text-fill-color: #fff;
}

@keyframes es-fin-btn-run {
  from { background-position: 0% 50%; }
  to   { background-position: 200% 50%; }
}

/* จอสัมผัสค้างสถานะ hover หลังแตะ — ไม่วิ่งค้าง (กฎเดียวกับปุ่มแชท 2 ต.ค.) · ผู้ที่ตั้งลดการเคลื่อนไหวก็ไม่วิ่ง */
@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) {
  a.es-fin-hero__btn:hover,
  a.es-fin-hero__btn:focus-visible {
    animation: none;
  }
}

/* สรุปภาพรวมรายได้ — ขนาดเท่ากล่อง "รายได้สุทธิอยู่ที่ไหนบ้าง" (หัวข้อ 16px + ไอคอนชมพู · ตัวเลข 16px) ผู้ใช้สั่งรอบ 2 */
.es-fin-overview__title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 8px;
  font-size: 16px;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: .04em;
}

.es-fin-overview__title i {
  color: var(--grad-1);
  font-size: 16px;
}

.es-fin-overview__card {
  padding: 0 16px;
  border: 1px solid rgba(var(--text-primary-rgb), .1);
  border-radius: 12px;
  background: rgba(var(--text-primary-rgb), .04);
}

.es-fin-overview__row {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
}

.es-fin-overview__row + .es-fin-overview__row {
  border-top: 1px solid rgba(var(--text-primary-rgb), .08);
}

.es-fin-overview__icon {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  font-size: 16px;
}

.es-fin-overview__icon--sales { color: var(--stat-success); }
.es-fin-overview__icon--net { color: #8b5cf6; }

/* วงกลมขอบแดง + ขีดลบ (FA 6.0 ไม่มีวงกลมแบบเส้นในชุดฟรี) */
.es-fin-overview__icon--fee i {
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--stat-error);
  border-radius: 50%;
  color: var(--stat-error);
  font-size: 8px;
}

.es-fin-overview__label {
  font-size: 13px;
  color: var(--text-secondary);
  letter-spacing: .04em;
  min-width: 0;
}

.es-fin-overview__value {
  font-size: 16px;
  font-weight: 700;
  color: var(--text-primary);
  white-space: nowrap;
  letter-spacing: .04em;
}

.es-fin-overview__value--fee,
.es-fin-overview__value--bad {
  color: var(--stat-error);
}

.es-fin-overview__row--total .es-fin-overview__label {
  font-weight: 700;
  color: var(--text-primary);
}

.es-fin-overview__hint {
  margin: 8px 2px 0;
}

/* เว้นจากหัวข้อ "รายได้สุทธิอยู่ที่ไหนบ้าง" ข้างล่าง (ผู้ใช้สั่ง 2026-10-03) — ช่องห่างของ panel 12px ไม่พอ */
.es-fin-overview {
  margin-bottom: 16px;
}

/* กล่องขอถอนเงิน — เนื้อในคือกล่องเดิม ถอดพื้น/ระยะของกล่องหน้าเพจออก */
.es-withdraw-modal__box {
  max-width: 440px;
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  text-align: left;
}

.es-withdraw-modal .store-finance-withdraw-form {
  margin: 0;
  padding: 0;
  background: none;
}

.es-withdraw-modal .store-finance-withdraw-form h3 {
  justify-content: center;
  margin: 0 0 18px;
}

/* ปุ่มยืนยัน + CLOSE อยู่แถวเดียวกัน ใช้ .avatar-cropper__actions ชุดเดียวกับกล่องบัญชีรับเงิน (2026-10-03) */
.es-withdraw-modal__actions {
  margin-top: 14px;
}

@media (max-width: 480px) {
  .es-fin-hero {
    padding: 18px 16px 16px;
    border-radius: 18px;
  }

  .es-fin-hero__icon {
    width: 56px;
    height: 56px;
    border-radius: 16px;
    font-size: 24px;
  }

  .es-fin-hero__label { font-size: 16px; }
  .es-fin-hero__sub { font-size: 13px; }
  .es-fin-hero__ghost { font-size: 66px; right: 10px; top: 12px; opacity: .45; }
}

/* =========================================================================
 * ข้อความแนะนำเว็บท้ายหน้าแรก ใต้ตะแกรงผลงาน (SEO)
 * es_marketplace_home_intro() ใน inc/woocommerce.php
 * ใช้ตัวแปรสีของธีม ธีมสว่างเปลี่ยนตามเอง
 * ====================================================================== */
.es-home-title {
  margin: 4px 0 6px;
  font-size: clamp(20px, 4.4vw, 26px);
  line-height: 1.35;
  font-weight: 700;
  color: var(--text-primary);
  text-wrap: pretty;
}

.es-home-intro {
  max-width: 760px;
  margin: 28px auto 0;
  text-align: center;
}

.es-home-intro__title {
  margin: 12px 0 8px;
  font-size: 16px;
  line-height: 1.5;
  font-weight: 700;
  color: var(--text-primary);
  text-wrap: pretty;
}

.es-home-intro__lead {
  margin: 0 0 8px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-secondary);
  text-wrap: pretty;
}

.es-home-intro__more > summary {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
  list-style: none;
}

.es-home-intro__more > summary:hover {
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.es-home-intro__sub {
  margin: 14px 0 0;
  font-size: 14px;
  line-height: 1.5;
  font-weight: 700;
  color: var(--text-primary);
}

.es-home-intro__more > summary::-webkit-details-marker {
  display: none;
}

.es-home-intro__more > summary::after {
  content: '\25BE';
  transition: transform 0.2s ease;
}

.es-home-intro__more[open] > summary::after {
  transform: rotate(180deg);
}

.es-home-intro__more[open] {
  text-align: left;
  padding: 12px 16px;
  border: 1px solid rgba(var(--grad-1-rgb), 0.25);
  border-radius: 12px;
  background: rgba(var(--grad-1-rgb), 0.07);
}

.es-home-intro__more p,
.es-home-intro__faq dd {
  margin: 8px 0 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.es-home-intro__faq {
  margin: 4px 0 0;
}

.es-home-intro__faq dt {
  margin-top: 12px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-primary);
}

.es-home-intro__faq dd {
  margin-left: 0;
}

.es-home-intro__cta a {
  font-size: 13.5px;
  color: var(--grad-1);
  text-decoration: underline;
}

.es-home-intro__cta a:hover {
  color: var(--grad-1);
  -webkit-text-fill-color: var(--grad-1);
  background: none;
}

/* ── ฟอร์มแก้ไขโปรไฟล์ · ตั้งค่าร้าน · เพิ่ม/แก้ไขสินค้า · เปิดร้าน กว้างเท่าหน้าอื่น (ผู้ใช้สั่ง 2026-10-15) ──
   design ตั้ง max-width 800px ไว้ที่จอ ≥769px ขณะที่หน้าอื่นกว้างตาม .page-fixs-wrapper (1024px)
   `body` นำหน้าเพื่อชนะไฟล์ CSS ของแต่ละหน้าที่โหลดทีหลัง (add-new-product.css · store.css · create-store.css) */
@media (min-width: 769px) {
  body .edit-profile-wrapper,
  body .add-new-product-wrapper,
  body .create-store-wrapper,
  body.woocommerce-account form.register.create-store-wrapper {
    max-width: none;
  }
}

/* ── ฟอร์มเพิ่ม/แก้ไขสินค้า บนจอคอม: รูปปก + แกลเลอรีขนาดพอดี (ผู้ใช้สั่ง 2026-10-15 หลังขยายฟอร์มเป็น 1024px) ──
   เดิมรูปปกจำกัด 166px แต่ตารางแกลเลอรี 3 ช่องยืดเต็มที่เหลือ → ช่องละ ~242px ใหญ่เกินและไม่สัมพันธ์กับรูปปก
   ใหม่: แกลเลอรี 3 ช่อง × 2 แถว (ผู้ใช้สั่ง · เดิมลอง 4×2 แล้วดูเบี้ยว) · รูปปก = สี่เหลี่ยมสูงเท่าแกลเลอรี 2 แถวพอดี
   ขนาดช่อง `--es-gall-tile` · ช่องไฟ 10px (ตรงกับ add-new-product.css ที่จอ ≥769px)
   🔴 มือถือ (≤768px) ใช้สูตรอีกชุดข้างบนไฟล์นี้ (รูปปก = 2 ช่องของตาราง 3 คอลัมน์) ไม่แตะ */
@media (min-width: 769px) {
  .product-images-row {
    /* แถวกว้าง = จอ − 160px (ระยะขอบหน้า + ฟอร์ม + กล่องเทา) · ใช้ 5 ช่อง + ช่องไฟ 46px · เผื่อแถบเลื่อน → −240px · สูงสุด 160px */
    --es-gall-tile: min(160px, calc((100vw - 240px) / 5));
    justify-content: flex-start;
  }

  .product-images-row .trade-item-cover-box-wrap {
    width: auto;
    max-width: none;
  }

  .product-images-row .trade-item-cover-box-wrap .trade-item-cover-box {
    width: calc(var(--es-gall-tile) * 2 + 10px);
  }

  .product-images-row .trade-item-gall-box-wrap {
    flex: 0 0 auto;
  }

  .product-images-row .gall-grid {
    grid-template-columns: repeat(3, var(--es-gall-tile));
    gap: 10px;
  }
}


/* หมายเหตุ + การ์ด "ระบบจะคิดเป็นพัสดุไซส์ …" ในฟอร์มเพิ่ม/แก้ไขสินค้า ชิดซ้ายเต็มความกว้าง
   ฟอร์มเป็น flex column `align-items: center` ของที่แคบกว่าฟอร์มจึงลอยกลาง (ผู้ใช้ทัก 2026-10-15) */
.add-new-product-wrapper > .es-form-note,
.add-new-product-wrapper > .es-ship-size {
  align-self: stretch;
}

/* เนื้อหาข้างในการ์ดไซส์ยืดเต็มที่เหลือข้างป้ายไซส์ → ตารางค่าส่ง (เส้นประ + ราคา) ชิดขวาสุด */
.es-vendor-product-form .es-ship-size__body {
  flex: 1 1 auto;
}
