/* ============================================================
   pm-utilities.css — ตัวช่วยชั้นบนสุดของคาสเคด (C-7)
   ที่มา: docs/design.md §5.4, §8.1, §8.4 · F-2, F-7
   ⛔ ห้ามมีค่า hex (B-1) · ⛔ ระยะทุกค่ามาจาก --s1…--s8 (§8.1)
   เก็บไว้เท่าที่มีที่ใช้จริง — ไม่สร้าง utility ดักไว้ล่วงหน้า
   ============================================================ */

/* ---- a11y ---- */
/* ซ่อนจากสายตาแต่ screen reader ยังอ่านได้ — ห้ามใช้ display:none */
.pm-visually-hidden{
  position:absolute; width:1px; height:1px;
  padding:0; margin:-1px; overflow:hidden;
  clip-path:inset(50%); white-space:nowrap; border:0;
}
/* skip link — โผล่เมื่อ focus (F-2) */
.pm-skip-link{
  position:absolute; left:var(--s2); top:calc(var(--s2) * -4);
  z-index:100;
  display:inline-flex; align-items:center; min-height:44px;
  padding:0 var(--s3);
  background:var(--color-surface); color:var(--color-ink);
  border:1px solid var(--color-line-strong); border-radius:var(--radius);
  font-size:var(--fs-small); font-weight:600; text-decoration:none;
}
.pm-skip-link:focus{ top:var(--s2); }

/* ---- ขนาดข้อความตามสเกล §5.4 ----
   ⚠️ ห้ามลด body / small / meta / label ตามหน้าจอ (B-4 วัดที่ 375px)
   เล็กที่สุดในระบบคือ --fs-label 12.5px — ไม่มีอะไรต่ำกว่านี้ */
.pm-text-deck{  font-size:var(--fs-deck);  line-height:1.62; color:var(--color-ink-body); }
.pm-text-body{  font-size:var(--fs-body);  line-height:1.65; color:var(--color-ink-body); }
.pm-text-long{  font-size:var(--fs-body-long); line-height:1.78; color:var(--color-ink-body); }
.pm-text-small{ font-size:var(--fs-small); line-height:1.55; color:var(--color-ink-body); }
.pm-text-meta{  font-size:var(--fs-meta);  line-height:1.45; color:var(--color-ink-muted); }

/* ---- สีตัวอักษรตามบทบาท (§3.1) ----
   ห้ามใช้ --color-accent เป็นสีเนื้อความ และห้ามเป็นพื้นปุ่มหลัก (B-2) */
.pm-ink{       color:var(--color-ink); }
.pm-ink-body{  color:var(--color-ink-body); }
.pm-ink-muted{ color:var(--color-ink-muted); }
.pm-ink-accent{ color:var(--color-accent); }   /* เฉพาะ accent 1 จุดต่อหน้า (B-2 · 10%) */

/* ---- พื้น (§3.1) ---- */
.pm-bg-paper{   background:var(--color-paper); }
.pm-bg-surface{ background:var(--color-surface); }

/* ---- ระยะห่างตามสเกล §8.1 — ห้ามใช้ค่าที่ไม่อยู่ในสเกล ---- */
.pm-mt-1{ margin-top:var(--s1); } .pm-mt-2{ margin-top:var(--s2); }
.pm-mt-3{ margin-top:var(--s3); } .pm-mt-4{ margin-top:var(--s4); }
.pm-mt-5{ margin-top:var(--s5); } .pm-mt-6{ margin-top:var(--s6); }
.pm-mb-1{ margin-bottom:var(--s1); } .pm-mb-2{ margin-bottom:var(--s2); }
.pm-mb-3{ margin-bottom:var(--s3); } .pm-mb-4{ margin-bottom:var(--s4); }
.pm-mb-5{ margin-bottom:var(--s5); } .pm-mb-6{ margin-bottom:var(--s6); }

/* ---- stack: ระยะห่างสม่ำเสมอระหว่างลูกโดยไม่ต้องใส่ margin รายตัว ---- */
.pm-stack{ display:flex; flex-direction:column; }
.pm-stack--1{ gap:var(--s1); } .pm-stack--2{ gap:var(--s2); }
.pm-stack--3{ gap:var(--s3); } .pm-stack--4{ gap:var(--s4); }
.pm-stack--5{ gap:var(--s5); }

/* ---- แถวแนวนอน · ระยะระหว่างของที่กดได้ ≥ 8px (F-3) ---- */
.pm-row{ display:flex; flex-wrap:wrap; align-items:center; gap:var(--s2); }
.pm-row--tight{ gap:var(--s1); }   /* 8px — ขั้นต่ำที่ F-3 ยอม */
/* 🔴 เพิ่ม 14 ก.ย. 2026 (รอบ 9) — เดิม banner-promotion.php เขียนคลาสนี้ไว้ในมาร์กอัป
   ตั้งแต่รอบ 7 แต่ **ไม่เคยมีกฎอยู่จริงในไฟล์ใด** แถวปุ่มจึงตกไปที่ flex-start
   ผล: ทุกอย่างในสไลด์ที่ 2 อยู่กึ่งกลาง ยกเว้นแถวปุ่มที่ชิดซ้าย = "ไม่สมส่วน"
   บทเรียน: คลาสที่ไม่มีกฎจะ **เงียบ** ไม่มี error ให้เห็น — ต้องเทียบ
   `grep -rho "pm-[a-z]*--[a-z]*" template-parts/` กับกฎในไฟล์ css ทุกครั้งที่เพิ่ม modifier */
.pm-row--center{ justify-content:center; }

/* ============================================================
   สเกลข้อความเมื่ออยู่บนพื้นเข้ม — แก้บั๊กที่พบจริงเมื่อ 11 ก.ย. 2026
   อาการ: .pm-text-small{color:--color-ink-body} ตั้งสีที่ตัว <p> เอง
          พื้นเข้มตั้งสีที่ตัว "พ่อ" → สีที่ตัวเองชนะสีที่สืบทอดมาเสมอ
          ผล: --color-ink-body บนพื้น --color-night = 1.50:1 อ่านไม่ออก (F-1 ตก)
          (ไม่เขียนค่า hex ตรงนี้ แม้จะเป็นคอมเมนต์ — เงื่อนไขผ่าน B-1 คือ grep ทั้งไฟล์)
   ใช้ :where() ให้ scope มีน้ำหนัก 0 — ได้ (0,1,0) เท่ากับตัว utility เอง
   แต่มาทีหลังในลำดับไฟล์จึงชนะ · และยัง "แพ้" ทุก override ที่เจาะจงกว่า
   (เช่น .pm-card--soft .pm-text-small) ตามที่ควรเป็น
   ============================================================ */
:where(.pm-band--night,.pm-band--brand,.pm-card--night,.on-night,.on-brand) .pm-text-deck,
:where(.pm-band--night,.pm-band--brand,.pm-card--night,.on-night,.on-brand) .pm-text-body,
:where(.pm-band--night,.pm-band--brand,.pm-card--night,.on-night,.on-brand) .pm-text-long,
:where(.pm-band--night,.pm-band--brand,.pm-card--night,.on-night,.on-brand) .pm-text-small,
:where(.pm-band--night,.pm-band--brand,.pm-card--night,.on-night,.on-brand) .pm-text-meta,
:where(.pm-band--night,.pm-band--brand,.pm-card--night,.on-night,.on-brand) .pm-ink-muted,
:where(.pm-band--night,.pm-band--brand,.pm-card--night,.on-night,.on-brand) .pm-ink-body{
  color:var(--color-on-night-2);      /* 7.71 บน night ✅ */
}
:where(.pm-band--night,.pm-band--brand,.pm-card--night,.on-night,.on-brand) .pm-ink{
  color:var(--color-on-night);        /* 12.59 ✅ */
}

/* =============================================================================
   คืนฟอนต์ของธีมให้กลับมาใช้จริง — เพิ่ม 15 ก.ย. 2026 (รอบที่ 8)
   คำสั่งเจ้าของงาน: "เช็ค font ด้วยนะ เหมือนจะไม่เหมือนกันด้วยนะ" — และมันไม่เหมือนกันจริง

   🔴 อาการที่วัดได้บน staging ก่อนแก้ (ทุกค่าเป็น computed style ของจริง):
        h1 · h2 · .pm-prodcard__name        → Cormorant Garamond
        .pm-prodcard__name > a              → **DM Sans**   ← หัวการ์ดกับลิงก์ในหัวการ์ดคนละฟอนต์
        body · .pm-text-body · .pm-chip · .pm-btn · .pm-slide__title · .pm-banner__cardtitle
        · .pm-foot__word · .pm-prodcard__cat → DM Sans
        .pm-prodcard__now                   → Instrument Serif  ← **ที่เดียวในหน้าที่ได้ฟอนต์จริง**

   🔴 ต้นเหตุ — **ไม่ใช่ที่ธีม** ธีมถูกต้องทุกอย่าง:
        `<style id="wp-custom-css">` (Appearance → Additional CSS · 41,220 ตัวอักษร · `!important` 729 จุด)
        เปิดหัวไฟล์ด้วยบล็อกชื่อ "01. GLOBAL FONT OVERRIDE" ซึ่งมีแค่สองกฎ แต่กินทั้งเว็บ:
            h1,h2,h3,h4,h5,h6                                   { font-family:'Cormorant Garamond',serif !important }
            body,p,li,td,th,label,input,textarea,select,button,a { font-family:'DM Sans',sans-serif !important }
        และ **ฟอนต์สองตัวนั้นไม่ได้ถูกโหลดเลย** เพราะ B-5 ถอด Google Fonts ออกไปแล้ว (14 ก.ย.)
        → เบราว์เซอร์ตกไปใช้ serif/sans-serif ของระบบคนละตัวกันในแต่ละที่ = อาการที่เจ้าของงานเห็น
        ยืนยันว่าฟอนต์ของเราโหลดสำเร็จจริง: `document.fonts` รายงาน
        `Instrument Serif 400 loaded` และ `Hanken Grotesk 100 900 loaded` — มีแต่ไม่มีใครได้ใช้

   ── ทำไมแก้ด้วย !important ตรงนี้ แทนที่จะไปลบ Additional CSS ทิ้ง ───────────
   C-7 ยอมให้ใช้ `!important` เพื่อทับสไตล์ที่มาจากนอกธีม **และต้องมีคอมเมนต์เหตุผล** — นี่คือคอมเมนต์นั้น
   ⛔ ห้ามไปลบ/แก้ `wp_custom_css` เพื่อแก้เรื่องนี้ — 41KB ก้อนนั้นยังคุมหน้าหน้าแรก Elementor (8074)
      และหน้า WooCommerce อยู่ · ลบเมื่อไรหน้าพวกนั้นเปลี่ยนทันทีโดยไม่มีใครสั่ง (= หนี้ 17 ต้องเคาะแยก)
   ⛔ ทุก selector ที่นี่ **ต้องขึ้นต้นด้วย .pm-header / .pm-home / .pm-footer เสมอ**
      เพื่อให้ผลอยู่ในขอบเขตของธีมเราเท่านั้น และเพื่อให้ชนะ h1/body ของก้อนนั้นด้วยความจำเพาะ
      (`.pm-home h1` = 0,1,1 ชนะ `h1` = 0,0,1 · ทั้งคู่ `!important` จึงตัดกันที่ความจำเพาะ)
   ⛔ ลำดับสองบล็อกข้างล่างสลับไม่ได้ — บล็อกหัวเรื่องต้องมาทีหลังเสมอ
   ✅ วันที่หนี้ 17 ถูกเคลียร์ ให้ลบทั้งบล็อกนี้ทิ้งได้เลย ธีมจะถูกต้องด้วยตัวเองอยู่แล้ว

   ── 🔴 แก้ 22 ก.ย. 2026 — ข้อความข้างบนนี้ล้าหลังไปแล้วสองจุด ────────────────────
   อ่านย่อหน้าข้างบนแล้วอย่าเพิ่งทำตาม · รายงาน docs/report-custom-css-section01-2026-09-22.md

   (1) **ตัวเลขผิด** — ก้อนที่ทำงานอยู่จริง **ไม่ใช่ post 1389 (41,220 ตัวอักษร)** อีกต่อไป
       วันที่ 17 ก.ย. 2026 มันถูกคัดลอกไปเป็น **post `custom_css` ID 9271** (`post_title` = `bajaar-child`)
       ขนาด 32,302 ตัวอักษร · 1389 กลายเป็นของธีมแม่ที่ **ไม่ถูกเรียกใช้แล้ว**
       (`wp_get_custom_css_post()` คืน 9271 เพราะ stylesheet ปัจจุบันคือ `bajaar-child`)

   (2) **§01 ถูกตัดออกแล้วเมื่อ 22 ก.ย. 2026** ตามคำสั่งเจ้าของงาน — คือการ "เคาะแยก"
       ที่ ⛔ ข้างบนเรียกร้องไว้พอดี · หลังตัดแล้ว **ทั้งบล็อกนี้กลายเป็นของซ้ำซ้อน**
       (มันตั้งค่าเดียวกับที่ pm-base.css ตั้งอยู่แล้ว เพียงแต่มี `!important` ติดมา)

   ⛔ **ยังไม่ลบทิ้งในรอบ 22 ก.ย. โดยตั้งใจ** — รอบนั้นแก้ที่ Additional CSS อย่างเดียว
      การลบบล็อกนี้ไปพร้อมกันคือการเปลี่ยนสองอย่างในครั้งเดียว ทำให้แยกไม่ออกว่าอะไรทำให้อะไรเปลี่ยน
      👉 การลบเป็น **สไลซ์ถัดไป** · ขอบเขตของมันเขียนไว้ที่ §7 ของรายงาน 22 ก.ย.
   ⛔ ⛔ ข้างบนที่เขียนว่า "ห้ามไปลบ/แก้ `wp_custom_css`" ใช้กับ **§01 ไม่ได้อีกแล้ว**
      (ทำไปแล้วและตรวจผ่าน) แต่ **ยังใช้กับ §02–§12 อยู่ทุกตัวอักษร** — หมวดพวกนั้นยังคุม
      หน้า blog / archive / sidebar / my-account / login ที่ยังไม่ถูกเขียนใหม่
   ============================================================================= */

/* 1) ฟอนต์เนื้อความ — ไล่ตามรายการ selector ของกฎที่มาทับ ทีละตัว */
.pm-header,.pm-home,.pm-footer,
.pm-header p,.pm-header a,.pm-header li,.pm-header button,.pm-header input,.pm-header label,.pm-header select,.pm-header textarea,
.pm-home p,.pm-home a,.pm-home li,.pm-home td,.pm-home th,.pm-home label,.pm-home input,.pm-home textarea,.pm-home select,.pm-home button,
.pm-footer p,.pm-footer a,.pm-footer li,.pm-footer button,.pm-footer input,.pm-footer label,.pm-footer select,.pm-footer textarea,
/* 🔴 เพิ่ม .pm-shop 16 ก.ย. 2026 — หน้า Shop ใช้ <main class="pm-shop"> ซึ่งไม่อยู่ในรายการนี้มาก่อน
   จึงหลุดออกนอกเกราะ แล้วโดน "01. GLOBAL FONT OVERRIDE" ของ Additional CSS ทับเต็ม ๆ
   วัดจริงบน staging ก่อนแก้: h1 → Cormorant Garamond · .pm-prodcard__name a → DM Sans
   ⛔ เทมเพลตใหม่ทุกตัวที่เพิ่มเข้ามาหลังจากนี้ **ต้องมาเพิ่มคลาสตัวเองที่นี่ด้วย**
      ไม่งั้นจะเจออาการเดียวกันโดยไม่มีอะไรฟ้อง — ธีมถูกหมด แต่หน้าเพี้ยน */
/* 🔴 แก้ 17 ก.ย. 2026 (รอบผูก template เข้ากับ page จริง) — **เพิ่ม `.pm-shop` เปล่า ๆ**
   ของเดิมมีแต่ selector ลูก (`.pm-shop p` ฯลฯ) **ไม่มีตัว <main> เอง** ต่างจาก .pm-home/.pm-cart
   ผลคือ `main.pm-shop` สืบฟอนต์ DM Sans มาจาก `body` ของ Additional CSS §01 ตรง ๆ
   แล้ว **ทุก element ที่ไม่ได้อยู่ในรายการลูก (div, span, strong, figcaption) ก็สืบตามไปหมด**
   วัดจริงบน staging หลังผูก template: `main.pm-shop` = DM Sans · `.pm-card` = DM Sans
   ⛔ เห็นได้เฉพาะตอนหน้านี้ถูก render จริงเท่านั้น — ไฟล์ preview ไม่มี Additional CSS จึงดูปกติเสมอ */
.pm-shop,
.pm-shop p,.pm-shop a,.pm-shop li,.pm-shop td,.pm-shop th,.pm-shop label,.pm-shop input,.pm-shop textarea,.pm-shop select,.pm-shop button,
.pm-shop div,.pm-shop span,.pm-shop strong,.pm-shop em,.pm-shop figcaption,.pm-shop dt,.pm-shop dd,
/* 🔴 เพิ่ม .pm-cart + .pm-minicart 16 ก.ย. 2026 (รอบ 🛒)
   .pm-cart      = <main> ของ template-cart-case-a.php
   .pm-minicart  = ลิ้นชักตะกร้า ซึ่งอยู่ **นอก** <main> และอยู่ทุกหน้าของเว็บ
      → ถ้าไม่ใส่ที่นี่ ลิ้นชักจะได้ฟอนต์ของ Additional CSS ทุกหน้า แม้หน้าอื่นจะถูกต้อง
   ⛔ เทมเพลตใหม่ทุกตัวหลังจากนี้ต้องมาเพิ่มคลาสตัวเองที่บล็อกนี้และบล็อกข้างล่าง
      ไม่งั้นธีมถูกหมดแต่หน้าเพี้ยน โดยไม่มีอะไรฟ้อง (บทเรียนหน้า Shop · changelog 16 ก.ย. รอบ 3) */
.pm-cart,.pm-minicart,.pm-checkout,
.pm-cart p,.pm-cart a,.pm-cart li,.pm-cart td,.pm-cart th,.pm-cart label,.pm-cart input,.pm-cart textarea,.pm-cart select,.pm-cart button,
.pm-minicart p,.pm-minicart a,.pm-minicart li,.pm-minicart span,.pm-minicart dt,.pm-minicart dd,.pm-minicart label,.pm-minicart input,.pm-minicart button,
.pm-checkout p,.pm-checkout a,.pm-checkout li,.pm-checkout td,.pm-checkout th,.pm-checkout label,.pm-checkout input,.pm-checkout textarea,.pm-checkout select,.pm-checkout button,
.pm-checkout abbr,.pm-checkout strong,.pm-checkout .select2-container,
/* 🔴 เพิ่ม .pm-product 18 ก.ย. 2026 (รอบหน้าสินค้าเดี่ยว) — คู่กับบล็อก 2 ข้างล่าง
   เขียนตัว <main> เปล่า ๆ ไว้ด้วยตั้งแต่แรก ตามบทเรียนของหน้า Shop 17 ก.ย.
   (มีแต่ selector ลูกไม่พอ — <main> เองจะสืบ DM Sans มาจาก `body` ของ Additional CSS §01)
   ⛔ เทมเพลตใหม่ทุกตัวหลังจากนี้ต้องมาเพิ่มคลาสตัวเองที่บล็อกนี้และบล็อกข้างล่าง */
.pm-product,
.pm-product p,.pm-product a,.pm-product li,.pm-product td,.pm-product th,.pm-product label,
.pm-product input,.pm-product textarea,.pm-product select,.pm-product button,
.pm-product div,.pm-product span,.pm-product strong,.pm-product em,.pm-product figcaption,
.pm-product dt,.pm-product dd,.pm-product caption,
/* 🔴 เพิ่ม .pm-login 24 ก.ย. 2026 (หน้า Sign in / Create account · ในเครื่อง) — คู่กับบล็อก 2
   <main> ของ template-account-case-a.php · ช่อง captcha ของปลั๊กอินอยู่ในนี้ด้วยจึงเขียน div/span */
.pm-login,
.pm-login p,.pm-login a,.pm-login li,.pm-login label,.pm-login input,.pm-login button,
.pm-login div,.pm-login span,.pm-login strong,.pm-login em{
  font-family:var(--font-body) !important;
}

/* 2) ฟอนต์หัวเรื่อง — หัวข้อจริง + องค์ประกอบที่ธีมตั้งใจให้เป็นตัวเด่น
      ทุกตัวที่มีลูกเป็น <a> ต้องเขียน `... a` คู่ไว้ด้วย ไม่งั้นบล็อก 1 จะดึงลูกกลับไปเป็นฟอนต์เนื้อความ
      — ซึ่งคืออาการเดิมเป๊ะ: หัวการ์ดเป็นเซริฟ แต่ตัวอักษรที่เห็นจริงเป็นซานส์ */
.pm-header h1,.pm-header h2,.pm-header h3,.pm-header h4,.pm-header h5,.pm-header h6,
.pm-home h1,.pm-home h2,.pm-home h3,.pm-home h4,.pm-home h5,.pm-home h6,
.pm-footer h1,.pm-footer h2,.pm-footer h3,.pm-footer h4,.pm-footer h5,.pm-footer h6,
.pm-home h1 a,.pm-home h2 a,.pm-home h3 a,.pm-home h4 a,.pm-home h5 a,.pm-home h6 a,
.pm-footer h2 a,.pm-footer h3 a,
.pm-home blockquote,
.pm-home .pm-card__title,.pm-home .pm-card__title a,
.pm-home .pm-slide__title,.pm-home .pm-slide__setprice,
.pm-home .pm-slide__goaltitle,.pm-home .pm-slide__goaltitle a,
.pm-home .pm-slide__num,
.pm-home .pm-slide__readtitle,.pm-home .pm-slide__readtitle a,
.pm-home .pm-banner__cardtitle,
.pm-home .pm-prodcard__name,.pm-home .pm-prodcard__name a,
.pm-home .pm-prodcard__now,.pm-home .pm-prodcard__moretitle,
.pm-home .pm-ritual__now,.pm-home .pm-layer__priceval,
.pm-home .pm-ordinal,
.pm-header .pm-brand__word,.pm-footer .pm-foot__word,
/* 🔴 เพิ่ม .pm-shop 16 ก.ย. 2026 — คู่กับบล็อก 1 ข้างบน
   ⛔ ตัวที่มีลูกเป็น <a> ต้องเขียน `... a` คู่ไว้เสมอ ไม่งั้นบล็อก 1 จะดึงลูกกลับไปเป็นฟอนต์เนื้อความ
      (อาการเดิมเป๊ะ: หัวการ์ดเป็นเซริฟ แต่ตัวอักษรที่เห็นจริงเป็นซานส์) */
.pm-shop h1,.pm-shop h2,.pm-shop h3,.pm-shop h4,.pm-shop h5,.pm-shop h6,
.pm-shop h1 a,.pm-shop h2 a,.pm-shop h3 a,.pm-shop h4 a,.pm-shop h5 a,.pm-shop h6 a,
.pm-shop .pm-card__title,.pm-shop .pm-card__title a,
.pm-shop .pm-prodcard__name,.pm-shop .pm-prodcard__name a,
.pm-shop .pm-prodcard__now,
.pm-shop .pm-shoprange__name,
/* 🔴 เพิ่ม .pm-cart + .pm-minicart 16 ก.ย. 2026 — คู่กับบล็อก 1 ข้างบน
   รายการนี้คือ "ตัวอักษรที่ต้องเป็น serif" ของสองหน้าจอนี้: หัวเรื่อง ชื่อสินค้าในรายการ
   ยอดรวม และหัวลิ้นชัก · ⛔ ห้ามใส่ selector กว้าง ๆ อย่าง .pm-cart span ที่นี่
   จะลาก meta ของ variation กับราคาต่อหน่วยไปเป็น serif ด้วย */
.pm-cart h1,.pm-cart h2,.pm-cart h3,.pm-cart h4,.pm-cart h5,.pm-cart h6,
.pm-cart h1 a,.pm-cart h2 a,.pm-cart h3 a,.pm-cart h4 a,.pm-cart h5 a,.pm-cart h6 a,
.pm-cart .pm-cartline .product-name a,
.pm-cart .pm-cart__emptytitle,
.pm-cart .pm-summary__total td,
.pm-cart .pm-prodcard__name,.pm-cart .pm-prodcard__name a,
.pm-minicart .pm-minicart__title,
.pm-minicart .pm-minicart__emptytitle,
.pm-minicart .pm-minicart__total .amount,
.pm-checkout h1,.pm-checkout h2,.pm-checkout h3,.pm-checkout h4,.pm-checkout h5,.pm-checkout h6,
.pm-checkout h1 a,.pm-checkout h2 a,.pm-checkout h3 a,.pm-checkout h4 a,.pm-checkout h5 a,.pm-checkout h6 a,
.pm-checkout .pm-review__total td,
/* 🔴 เพิ่ม .pm-product 18 ก.ย. 2026 — คู่กับบล็อก 1 ข้างบน
   ⛔ ตัวที่มีลูกเป็น <a> ต้องเขียน `... a` คู่ไว้เสมอ ไม่งั้นบล็อก 1 จะดึงลูกกลับไปเป็นฟอนต์เนื้อความ
   ⛔ ห้ามใส่ selector กว้าง ๆ อย่าง `.pm-product span` ที่นี่ — จะลาก SKU/แท็ก/ป้ายสเปกไปเป็น serif ด้วย
   🔴 `.pm-rawnote__body` **ไม่อยู่ในรายการนี้โดยตั้งใจ** — เนื้อหาดิบที่ยังไม่ผ่านต้องดูเป็น
      "ของที่ยกมา" ไม่ใช่ของที่ออกแบบแล้ว (ดู 14.7 ใน pm-components.css) */
.pm-product h1,.pm-product h2,.pm-product h3,.pm-product h4,.pm-product h5,.pm-product h6,
.pm-product h1 a,.pm-product h2 a,.pm-product h3 a,.pm-product h4 a,.pm-product h5 a,.pm-product h6 a,
.pm-product .pm-card__title,.pm-product .pm-card__title a,
.pm-product .pm-prodcard__name,.pm-product .pm-prodcard__name a,
.pm-product .pm-prodcard__now,
.pm-product .pm-pdp__amount,
.pm-product .pm-specs__val,
/* 🔴 เพิ่ม .pm-login 24 ก.ย. 2026 — H1 เท่านั้น (H2 ในหน้าเป็น screen-reader-text) */
.pm-login h1{
  font-family:var(--font-display) !important;
}

/* 🔴 **ไม่ต้องมีข้อยกเว้นสำหรับ `.pm-rawnote__body` แล้ว** — หัวข้อในเนื้อหาดิบถูกลดชั้น
   เป็น `<p class="pm-rawnote__h">` ตั้งแต่ฝั่ง PHP (pm_product_demote_headings())
   จึงเข้าเงื่อนไข `.pm-product p` ของบล็อก 1 และได้ฟอนต์เนื้อความอยู่แล้ว
   ⛔ ถ้าวันหนึ่งมีคนถอดการลดชั้นออก ต้องกลับมาเขียนข้อยกเว้นที่นี่ ไม่งั้นหัวข้อของเนื้อหาเก่า
      จะกลายเป็น Instrument Serif ซึ่งทำให้ก้อนที่ยังไม่ผ่านดูเหมือนเนื้อหาที่ออกแบบแล้ว */

/* 🔴 ข้อยกเว้นที่ต้องเขียนคืน — `.pm-checkout__cardtitle--toggle` เป็น <h3> ที่ครอบ
   checkbox "Ship to a different address?" อยู่ (โครงนี้มาจาก WooCommerce ห้ามรื้อ ดู
   woocommerce/checkout/form-shipping.php) ตัว <span> ข้างในเป็น **ข้อความของ control**
   ไม่ใช่หัวเรื่อง จึงต้องเป็นฟอนต์เนื้อความ ไม่งั้นได้ serif กลางฟอร์มโดยไม่ตั้งใจ
   ⛔ อย่าแก้ด้วยการถอด h3 ออกจากบล็อกข้างบน — h3 ใบอื่นในหน้านี้เป็นหัวการ์ดจริง ๆ */
.pm-checkout .pm-checkout__cardtitle--toggle span{
  font-family:var(--font-body) !important;
}

/* 🔴 ข้อยกเว้นของหน้าขอบคุณ (8 ต.ค. 2026) — `.pm-ty__label` เป็น <h2> เพื่อโครงหัวเรื่อง (a11y)
   แต่หน้าตาตามแบบคือ **ป้ายตัวพิมพ์ใหญ่ฟอนต์เนื้อความ** ("SHIPPING TO" · "PAID WITH")
   บล็อกหัวเรื่องข้างบนบังคับ serif ด้วย !important → ต้องเขียนคืนด้วย !important ที่ขอบเขตแคบสุด
   วัดบนหน้าจริงก่อนแก้: Instrument Serif 12.5px · รายงาน docs/report-thank-you-2026-10-08.md */
.pm-checkout .pm-ty__label{
  font-family:var(--font-body) !important;
}
/* กลับกัน: หัวขั้นของไทม์ไลน์เป็น <p> (ไม่ใช่หัวเรื่อง) แต่แบบเป็น Instrument Serif 24px
   บล็อกเนื้อความ `.pm-checkout p` บังคับซานส์ด้วย !important → เขียนคืนที่คลาสเดียว */
.pm-checkout .pm-ty__steptitle{
  font-family:var(--font-display) !important;
}


/* ============================================================
   ล็อกการเลื่อนของหน้าเบื้องหลังระหว่างลิ้นชักตะกร้าเปิด (16 ก.ย. 2026)
   🔴 ใส่ที่ <html> ไม่ใช่ <body> — iOS Safari ไม่หยุดเลื่อนถ้าใส่ที่ body อย่างเดียว
   ⛔ คลาสนี้ถูกเติม/ถอดโดย pm-minicart.js เท่านั้น · ไม่มี JS = ไม่มีวันถูกเติม
   ============================================================ */
.pm-noscroll{ overflow:hidden; }

/* ============================================================
   `.screen-reader-text` — คลาสของ WooCommerce/WordPress ที่ **เราไม่ได้เป็นเจ้าของ**
   (16 ก.ย. 2026 · รอบ 🛒)

   🔴 ทำไมต้องประกาศเอง ทั้งที่ WooCommerce มีกฎนี้อยู่แล้ว:
      woocommerce_quantity_input() พ่น <label class="screen-reader-text"> ออกมาเสมอ
      ถ้าวันไหน CSS ของ WooCommerce ถูก dequeue หรือโหลดไม่ทัน ป้ายนั้นจะ **โผล่เป็นข้อความจริง**
      กลางช่องจำนวน ("Breast Capsules 60 capsules quantity") — เจอจริงตอนตรวจ preview 16 ก.ย.
      ซึ่งไม่มี CSS ของ WooCommerce โหลดอยู่
   ⛔ ห้ามแก้ด้วย display:none — screen reader จะอ่านไม่เจอ แล้วช่องจำนวนจะไม่มี label (F-5)
      ต้องซ่อนด้วยวิธีเดียวกับ .pm-visually-hidden เท่านั้น
   ============================================================ */
.pm-cart .screen-reader-text,
.pm-minicart .screen-reader-text,
.pm-login .screen-reader-text{   /* เพิ่ม 24 ก.ย. — H2 ของแผง + ป้าย Required ใน woocommerce/myaccount/*.php */
  position:absolute !important;   /* ทับกฎของ WooCommerce ที่มาจากนอกธีม — C-7 อนุญาตพร้อมเหตุผล */
  width:1px; height:1px;
  padding:0; margin:-1px;
  overflow:hidden; clip-path:inset(50%);
  white-space:nowrap; border:0;
}

/* ───────────────────────────────────────────────────────────────────────────
   ข้อยกเว้นฟอนต์ของ h5/h6 — เพิ่ม 21 ก.ย. 2026 (รอบแท็บหน้าสินค้า)
   แผน: docs/plan-product-tabs-2026-09-21.md §3.4

   🔴 บล็อก `.pm-product h1,…,.pm-product h6 { font-family:var(--font-display) !important }`
      ข้างบนลาก **h5 กับ h6 ไปเป็นเซริฟด้วย** ซึ่งขัด design.md §5.3 ตรง ๆ —
      §5.3 กำหนดว่า h5 = Hanken Grotesk 600 17px · h6 = Hanken Grotesk 600 14px uppercase
      และเขียนเหตุผลไว้ชัดว่า **จุดตัดระหว่าง serif กับ sans อยู่ที่ 18px**
   ⚠️ ที่ผ่านมายังไม่มีอาการเพราะหน้าสินค้าไม่เคยมี h5/h6 สักตัว —
      สัญญา .pm-prose (pm-components.css บล็อก 15) ทำให้มีตั้งแต่รอบนี้
   ✅ specificity เท่ากับบล็อกเดิม (0,2,0) + มาทีหลัง → ชนะตามลำดับคาสเคด ไม่ต้องเพิ่มน้ำหนัก
   ⛔ ห้ามแก้ด้วยการถอด h5/h6 ออกจากบล็อกเดิม — บล็อกนั้นใช้ร่วมกับ .pm-shop/.pm-cart/.pm-checkout

   🔴 หนี้ที่ยังไม่แก้ (อยู่นอกขอบเขตคำสั่งรอบนี้): `.pm-shop` `.pm-cart` `.pm-checkout`
      มีบั๊กเดียวกันรออยู่ — วันที่หน้าพวกนั้นมี h5/h6 จริงต้องมาเพิ่มที่นี่
   ─────────────────────────────────────────────────────────────────────────── */
.pm-product h5,.pm-product h6,
.pm-product h5 a,.pm-product h6 a{
  font-family:var(--font-body) !important;
}

/* ───────────────────────────────────────────────────────────────────────────
   ตัวอักษรที่ซ้อนอยู่ **ในหัวเรื่อง** — เพิ่ม 21 ก.ย. 2026 (รอบที่สอง)

   🔴 อาการที่เจอตอนเอาเนื้อหาจริงมาวางในรูปแบบใหม่:
      หัวข้อ "Features:" · "Benefit:" · "Active Ingredients:" · "Directions:" · "Warning:"
      ของสินค้า 2421 เขียนมาเป็น `<h2><b><strong>Features:</strong></b></h2>`
      → บล็อก 1 ข้างบน (`.pm-product strong` = ฟอนต์เนื้อความ !important) ชนะตัว <strong>
        ที่อยู่ **ข้างใน** หัวเรื่อง → หัวข้อทั้งหมดกลายเป็นซานส์ตัวหนา ทั้งที่ <h3> เป็นเซริฟ
      อาการนี้เห็นเฉพาะกับเนื้อหาจริง — ตัวอย่างที่เขียนเองไม่มี <strong> ครอบหัวข้อจึงไม่โผล่

   ✅ h1–h4 เป็นเซริฟ → ลูกที่เป็น strong/b/em/i/a/span ต้องเป็นเซริฟตาม
   ⛔ **ห้ามเติม h5/h6 เข้ามาในรายการนี้** — สองชั้นนั้นเป็น Hanken Grotesk 600 ตาม
      design.md §5.3 (จุดตัด serif/sans อยู่ที่ 18px) ลูกของมันต้องเป็นซานส์เหมือนกัน
   ⚠️ `.pm-shop` `.pm-cart` `.pm-checkout` มีอาการเดียวกันรออยู่ถ้าหัวเรื่องของหน้าเหล่านั้น
      มีเนื้อหาที่คนเขียนใส่ <strong> มา — ยังไม่แก้ในรอบนี้ (อยู่นอกขอบเขตคำสั่ง)
   ─────────────────────────────────────────────────────────────────────────── */
.pm-product :is(h1,h2,h3,h4) :is(strong,b,em,i,a,span){
  font-family:var(--font-display) !important;
}

/* ───────────────────────────────────────────────────────────────────────────
   คะแนนเฉลี่ยในแท็บ Reviews — เพิ่ม 21 ก.ย. 2026
   🔴 `.pm-reviews__avg` เป็น <p> จึงโดนบล็อก 1 (`.pm-product p` = ฟอนต์เนื้อความ !important)
      ลากไปเป็นซานส์ ทั้งที่ pm-components บล็อก 17 ตั้งไว้เป็น --font-display
      อาการเดียวกับ `.pm-pdp__amount` และ `.pm-specs__val` ที่เคยต้องมาเพิ่มที่นี่มาแล้ว
   ⛔ ห้ามแก้ด้วยการเปลี่ยน <p> เป็น <span> ในเทมเพลต — มันเป็นประโยคเดี่ยวของตัวเอง
   ─────────────────────────────────────────────────────────────────────────── */
.pm-product .pm-reviews__avg{
  font-family:var(--font-display) !important;
}
