/* ⛔ ไฟล์นี้ถูกสร้างด้วย tools/build_webstore.py — ห้ามแก้ที่นี่
   แก้ที่ docs/mockups/store/app.css แล้วรันสคริปต์ใหม่
   (แก้ตรงนี้จะหายทั้งหมดในบิลด์ครั้งถัดไป) */
/* ═══════════════════════════════════════════════════════════════════════
   HaruShop — ระบบดีไซน์กลาง (โลกเดียว มืดตลอด ตั้งใจ)
   สีแบรนด์มาจากเว็บเดิม HaruShop-Website: ถ่านอมแดง + ember + ทอง

   สีมีหน้าที่ตายตัว
     ember  = แบรนด์ · ปุ่มหลัก · เส้นเน้น       ทอง = ราคา · ป้ายคุ้ม
     เขียว  = สถานะสำเร็จ/ใช้งานอยู่ "เท่านั้น"   ฟ้า = ข้อมูล/สถานะสด
     แดงอ่อน = ผิดพลาด

   ⛔⛤ --ember (#FF3B3B) ใช้เป็น "พื้นปุ่ม" ไม่ได้ — ขาวบนแดงนี้ได้ 3.4:1
      ไม่ผ่าน WCAG AA · พื้นปุ่มต้องใช้ --ember-btn (#C81E1E → 5.3:1)
   ═══════════════════════════════════════════════════════════════════════ */

/* ── ฟอนต์จากเครื่องเรา (⛔ ห้ามพึ่ง CDN — กฎเดิมของโครงการ) ──
   ⛤ 2026-09-01 วัดจริงแล้วพบว่าเว็บพึ่ง Google Fonts ล้วน ๆ
      บล็อกโดเมนกูเกิล ⇒ โหลดฟอนต์ได้ 0 ตัว ตกไปฟอนต์ระบบทั้งเว็บ
      และ "ตัวสำรองในเครื่อง" ที่ program-ui.css อ้างไว้ก็ 404 มาตลอด
      (ทั้งไฟล์ไม่มีจริง และ CSP font-src ไม่มี 'self')
   ⚠ IBM Plex Mono ยังไม่มีไฟล์ในเครื่อง จึงยังดึงจากกูเกิลอยู่ตัวเดียว
     — เป็นฟอนต์ตัวเลข/รหัส ถ้าโหลดไม่ขึ้นจะตกไป monospace ของระบบ
     ซึ่งอ่านออกปกติ ไม่กระทบข้อความไทยที่เป็นเนื้อหาหลัก */
@font-face{font-family:'Anuphan'; font-style:normal; font-weight:300 700;
  font-display:swap; src:url('/web/fonts/anuphan-thai.woff2') format('woff2');
  unicode-range:U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC}
@font-face{font-family:'Anuphan'; font-style:normal; font-weight:300 700;
  font-display:swap; src:url('/web/fonts/anuphan-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Anuphan'; font-style:normal; font-weight:300 700;
  font-display:swap; src:url('/web/fonts/anuphan-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Space Grotesk'; font-style:normal; font-weight:500 700;
  font-display:swap; src:url('/web/fonts/space-grotesk-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Space Grotesk'; font-style:normal; font-weight:500 700;
  font-display:swap;
  src:url('/web/fonts/space-grotesk-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}

:root{
  /* ⛔⛤ เจ้าของแจ้ง 2026-08-31: "กดแท็ปเลื่อนมีหน้าต่างสีขาว"
     เมนูของ <select> · ตัวเลือกวันที่ · แถบเลื่อน · ช่องกรอก ถูกวาดโดย
     เบราว์เซอร์เอง ไม่ใช่ CSS ของเรา ⇒ ไม่ประกาศไว้ = วาดเป็นธีมสว่างเสมอ
     แม้ทั้งหน้าจะเป็นสีดำ · โปรแกรมจริงประกาศไว้แล้ว (webui/shared/tokens.css)
     แต่เว็บร้านไม่เคยมี ⇒ ประกาศให้ตรงกัน */
  color-scheme: dark;
  /* ── พื้น: กราไฟต์เกือบดำ เย็นกว่าเดิมเล็กน้อย ── */
  --bg:#07070A;
  --bg-soft:#0C0C11;
  --surface:#12121A;
  --glass:rgba(255,255,255,.035);
  --glass-2:rgba(255,255,255,.06);
  --line:rgba(255,255,255,.08);
  --line-2:rgba(255,45,70,.24);

  /* ── ตัวอักษร ── */
  --tx:#F5F3F6;
  --tx2:#B9B2BE;
  --tx3:#9A93A1;         /* ⛔ อย่าทำให้เข้มกว่านี้ — 12.5px บนการ์ดจะหลุด WCAG AA */

  /* ── แบรนด์ ── */
  --ember:#FF2D46;        /* เส้น ไอคอน ตัวอักษรบนพื้นมืด — ห้ามเป็นพื้นปุ่ม */
  --ember-btn:#C4152B;    /* พื้นปุ่มหลัก (ขาวบนนี้ผ่าน AA) */
  --ember-lit:#FF7C8B;    /* ขอบโฟกัส · ไอคอน · ตัวอักษรเน้น */
  --ember-deep:#7A0B18;
  --gold:#FFC24D;         /* ราคา · ป้ายคุ้มสุด */
  --ok:#7FE07F;           /* สำเร็จ / ใช้งานอยู่ เท่านั้น */
  /* ⚠ ฟ้าใช้เฉพาะ "สถานะเชิงเทคนิค" (กำลังทำงาน · จำนวนวัน · ค่าที่วัดได้)
     ห้ามเอาไปใช้เป็นสีตกแต่งทั่วไป ไม่งั้นความหมายจะเจือจนอ่านไม่ออก */
  --info:#5FD0E8;
  --warn:#E0A877;
  --bad:#FF6B5A;

  /* ── ชื่อเดิมที่โค้ดยังเรียกอยู่ (ชี้มาที่โทเคนใหม่) ── */
  --vio:var(--ember-btn);
  --vio-lit:var(--ember-lit);
  --money:var(--ok);
  --cyan:var(--info);
  --rose:var(--bad);

  /* ── ระยะ · มุม · เงา · จังหวะ ── */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px;
  --sp-5:24px; --sp-6:32px; --sp-7:48px; --sp-8:64px;
  --r:16px;
  --r-sm:10px;
  --r-lg:22px;
  --maxw:1280px;          /* ความกว้างเนื้อหาอ่านสบาย */
  --maxw-wide:1560px;     /* ความกว้างของงานภาพ/กริดการ์ด บนจอใหญ่ */
  --shadow:0 2px 4px rgba(0,0,0,.34), 0 12px 34px rgba(0,0,0,.46);
  --shadow-hi:0 4px 10px rgba(0,0,0,.40), 0 22px 54px rgba(0,0,0,.56);
  --ease:cubic-bezier(.2,.7,.3,1);
  --t-fast:150ms;
  --t:220ms;
  --t-slow:300ms;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth; -webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--bg); color:var(--tx);
  font-family:"Anuphan","IBM Plex Sans Thai",system-ui,sans-serif;
  /* พื้นหลัง: แสงแดงจุดเดียวด้านบน — ตารางกับเกรนอยู่ที่ ::before/::after
     ⚠ ห้ามใช้รูปภาพ ทุกอย่างวาดด้วย CSS ล้วน โหลดเร็วและผ่าน CSP */
  background-image:
    radial-gradient(64% 42% at 50% -8%, rgba(255,45,70,.13), transparent 70%);
  background-attachment:fixed;
  font-size:15px; line-height:1.7; -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
a{color:inherit; text-decoration:none}
button{font:inherit; color:inherit; cursor:pointer; background:none; border:0}
img,svg{display:block; max-width:100%}
:focus-visible{outline:2px solid var(--vio-lit); outline-offset:3px; border-radius:8px}
[hidden]{display:none !important}
.wrap{max-width:var(--maxw); margin:0 auto; padding:0 20px}
/* ⚠ ใช้กับงานภาพที่ต้องการพื้นที่กว้างกว่าเนื้อความ (หน้าต่างโปรแกรม) */
.wrap.wide{max-width:var(--maxw-wide)}
@media(min-width:900px){ .wrap{padding:0 32px} }

/* ══════════════ จอใหญ่: ไม่ให้เหลือขอบดำเป็นแถบกว้าง ══
   ⛔⛤ เจ้าของแจ้งว่า "เว็บไม่เต็มจอ มีขอบดำข้าง ๆ เหมือนโดนตัด"
      วัดจริงบนจอ 1905px: เนื้อหากว้าง 1280 ⇒ ว่างข้างละ 313px = 33% ของจอ
      พื้นหลังดำสนิททั้งแถบ จึงเห็นเป็นขอบดำชัด ๆ
   ⚠ ยืดเป็น 100% ไม่ได้ — บรรทัดตัวอักษรยาวเกิน ~90 ตัวจะอ่านยาก ตาหาบรรทัด
     ถัดไปไม่เจอ ⇒ ขยายเฉพาะ "หัวเว็บ · ฮีโร่ · กริดการ์ด · ท้ายเว็บ" ที่เป็นงานภาพ
     ส่วนย่อหน้ายาว ๆ ตรึงความกว้างอ่านสบายไว้เท่าเดิม */
@media(min-width:1500px){
  header.top > .wrap,
  .hero > .wrap,
  /* ⛔⛤ 2026-09-13 · หัวหน้าของหน้าย่อย (ดูโปรแกรม · คู่มือ · สินค้า ·
     กระเป๋าเงิน) ไม่เคยอยู่ในรายการนี้ ⇒ บนจอกว้าง หัวหน้ากว้าง 1280
     แต่เนื้อหาข้างล่างกว้าง 1560 ⇒ ขอบซ้ายไม่ตรงกัน เห็นชัดว่าเยื้อง */
  .prog-hero > .wrap,
  .gdhero > .wrap,
  .plhero > .wrap,
  .wlhero > .wrap,
  .sec > .wrap,
  .foot > .wrap{max-width:var(--maxw-wide)}
  .sechead p, .hero .sub, .lead, .pdbody{max-width:78ch}
}
@media(min-width:1800px){
  header.top > .wrap,
  .hero > .wrap,
  .prog-hero > .wrap,
  .gdhero > .wrap,
  .plhero > .wrap,
  .wlhero > .wrap,
  .sec > .wrap,
  .foot > .wrap{max-width:1680px}
}

/* ── ตัวอักษร ── */
.grad{
  background:linear-gradient(178deg,#FFFFFF 6%,#D3B7B1 100%);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
h1,h2,h3{margin:0; letter-spacing:-.015em; text-wrap:balance;
  font-family:"Space Grotesk","Anuphan",system-ui,sans-serif}
.eyebrow{
  font-family:"IBM Plex Mono",monospace; font-size:11px; letter-spacing:.18em;
  text-transform:uppercase; color:var(--vio-lit);
}
.lead{color:var(--tx2); font-size:15px; margin:10px 0 0}
.mono{font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums}

/* ── แถบโหลดบนสุด ── */
.loadbar{position:fixed; top:0; left:0; height:2px; width:0; z-index:120;
  background:linear-gradient(90deg,var(--ember),var(--gold)); box-shadow:0 0 12px var(--ember);
  transition:width .25s ease, opacity .3s ease; opacity:0}
.loadbar.on{opacity:1}

/* ── หัวเว็บ ── */
.top{position:sticky; top:var(--toolsH,0px); z-index:80;
  background:rgba(7,8,11,.72); backdrop-filter:blur(18px) saturate(140%);
  border-bottom:1px solid var(--line)}
.top .wrap{display:flex; align-items:center; gap:28px; min-height:68px}
.brand{display:flex; align-items:center; gap:11px; font-weight:600; font-size:17px; letter-spacing:-.01em}
.brand .mk{width:30px; height:30px; border-radius:9px; flex:none;
  background:linear-gradient(140deg,var(--ember),var(--ember-deep)); display:grid; place-items:center;
  box-shadow:0 4px 14px rgba(108,90,224,.45)}
.top nav{display:none; gap:26px; font-size:14.5px; color:var(--tx2)}
@media(min-width:900px){ .top nav{display:flex} }
.top nav a{padding:8px 0; border-bottom:2px solid transparent; transition:color .18s,border-color .18s}
.top nav a:hover{color:var(--tx)}
.top nav a.on{color:var(--tx); border-bottom-color:var(--vio-lit)}
.top .sp{flex:1}
.chipacct{display:flex; align-items:center; gap:10px; min-height:44px;
  background:var(--glass-2); border:1px solid var(--line); border-radius:999px;
  padding:5px 16px 5px 5px; transition:border-color .18s, background .18s}
.chipacct:hover{border-color:var(--line-2); background:rgba(255,255,255,.08)}
/* ⛔⛤ เดิมบรรทัดนี้เขียน background เป็นไล่สีม่วงตายตัว
   `.chipacct .av` เจาะจงกว่า `.av-ember` ⇒ **สีที่ลูกค้าเลือกไม่มีวันขึ้นที่มุมขวา**
   (หน้าโปรไฟล์เปลี่ยนสีได้ แต่มุมขวาม่วงอยู่อย่างนั้น ดูเหมือนบันทึกไม่ติด)
   ⇒ เหลือแค่ background-color เป็นสีพื้นตอนยังไม่มีคลาสสี ส่วนไล่สีของแต่ละสี
     เป็น background-image ซึ่งไม่มีใครทับ จึงขึ้นได้ตามที่เลือกจริง */
.chipacct .av{width:32px; height:32px; border-radius:50%; flex:none;
  background-color:#22203C; border:1px solid var(--line-2)}
.chipacct b{font-size:13.5px; font-weight:500}

/* ── ปุ่ม ── */
.btn{display:inline-flex; align-items:center; justify-content:center; gap:8px;
  min-height:46px; padding:0 22px; border-radius:12px; font-size:15px; font-weight:500;
  border:1px solid var(--line-2); background:var(--glass-2); color:var(--tx);
  transition:border-color .18s, background .18s, transform .12s, filter .18s}
.btn:hover{border-color:var(--vio-lit); background:rgba(255,255,255,.08)}
.btn:active{transform:translateY(1px)}
.btn.primary{background:var(--ember-btn); border-color:var(--ember-btn); color:#fff;
  font-weight:600; box-shadow:0 6px 20px rgba(200,30,30,.34)}
.btn.primary:hover{filter:brightness(1.12); background:var(--ember-btn)}
.btn.sm{min-height:40px; padding:0 15px; font-size:13.5px; border-radius:10px}
/* ⛤ ปุ่มจาง — สำหรับทางที่ "มีให้เลือก แต่ไม่ใช่สิ่งที่อยากให้กด"
   เช่น ยกเลิกคำสั่งซื้อ · กันกดพลาดตอนรีบ และไม่แย่งสายตาปุ่มหลัก
   ⚠ ยังต้องสูง 40px ตามเกณฑ์พื้นที่นิ้วสัมผัส ห้ามย่อกว่านี้
   ⛔⛤ 2026-09-11: `ghost` คือชื่อเดียวกันของปุ่มแบบนี้ที่หน้าหลังร้าน (รื้อ 09-11)
     เรียกใช้ — ทั้งใน HTML และผ่าน adBtn/adLink ใน app.js — แต่ไม่เคยมีใครเขียนกฎให้
     ⇒ ปุ่มรีเฟรช/ลิงก์ในหน้าแอดมินทุกหน้าออกมาเป็นปุ่มเปล่า ๆ ของ .btn ล้วน
     รับชื่อนี้เป็นชื่อพ้องเสียเลย (ตั้งใต้ .btn ไม่ใช่คลาสสั้นลอย ๆ ที่จะรั่วไปทั้งเว็บ) */
.btn.quiet,.btn.ghost{background:transparent; border-color:var(--line); color:var(--tx3);
  font-weight:500; min-height:40px; padding:0 15px; font-size:13.5px}
.btn.quiet:hover,.btn.ghost:hover{color:var(--tx2); border-color:var(--line-2);
  background:var(--glass)}
.btn.block{width:100%}
.btn[disabled]{opacity:.5; cursor:not-allowed}

/* ── การ์ดกระจก ── */
.glass{background:var(--glass); border:1px solid var(--line); border-radius:var(--r);
  box-shadow:var(--shadow); backdrop-filter:blur(6px)}

/* ── หน้าแรก · ฮีโร่ ── */
.hero{position:relative; padding:64px 0 52px; text-align:center; overflow:hidden}
.hero::before{content:""; position:absolute; left:50%; top:-260px; width:900px; height:520px;
  translate:-50% 0; pointer-events:none;
  background:radial-gradient(closest-side, rgba(108,90,224,.28), transparent 72%)}
.hero::after{content:""; position:absolute; inset:0; pointer-events:none;
  background:
    radial-gradient(closest-side at 12% 30%, rgba(84,200,240,.10), transparent 70%),
    radial-gradient(closest-side at 88% 20%, rgba(244,85,110,.08), transparent 70%)}
.hero > *{position:relative; z-index:1}
.live{display:inline-flex; align-items:center; gap:9px; border:1px solid var(--line);
  background:var(--glass); border-radius:999px; padding:6px 16px; font-size:12.5px;
  color:var(--tx2); font-family:"IBM Plex Mono",monospace}
.dot{width:7px; height:7px; border-radius:50%; background:var(--money);
  box-shadow:0 0 10px var(--money); animation:bp 2.4s ease-in-out infinite}
@keyframes bp{0%,100%{opacity:1}50%{opacity:.3}}
.hero h1{font-size:clamp(34px,6vw,58px); font-weight:700; line-height:1.16; margin:22px 0 0}
.hero .sub{color:var(--tx2); font-size:clamp(15px,1.9vw,18px); margin:16px auto 0; max-width:52ch}
.hero .cta{display:flex; gap:12px; justify-content:center; margin-top:30px; flex-wrap:wrap}

/* พิสูจน์ตัวตน */
.proof{display:flex; align-items:center; justify-content:center; gap:16px; margin-top:30px; flex-wrap:wrap}
.faces{display:flex}
.faces i{width:34px; height:34px; border-radius:50%; border:2px solid var(--bg); margin-left:-11px; display:block}
.faces i:first-child{margin-left:0}
.f1{background:linear-gradient(140deg,#7C6BF5,#4B3FA8)}
.f2{background:linear-gradient(140deg,#54C8F0,#2A6B87)}
.f3{background:linear-gradient(140deg,#F4556E,#8C2438)}
.f4{background:linear-gradient(140deg,#E9B949,#8A6A18)}
.f5{background:linear-gradient(140deg,#3FD68A,#1B6D45)}
.stars{display:flex; gap:3px; color:var(--gold)}
.proof .txt{font-size:13.5px; color:var(--tx2)}
.proof .txt b{color:var(--tx); font-weight:600}

/* แถบตัวเลข */
.stats{display:grid; grid-template-columns:repeat(2,1fr); gap:12px; margin-top:44px}
@media(min-width:820px){ .stats{grid-template-columns:repeat(4,1fr)} }
.stat{padding:18px 20px}
.stat b{display:block; font-family:"IBM Plex Mono",monospace; font-size:26px; font-weight:600;
  font-variant-numeric:tabular-nums; letter-spacing:-.02em}
.stat span{font-size:12.5px; color:var(--tx3)}
.stat.c b{color:var(--cyan)}
.stat.g b{color:var(--money)}

/* ── หัวข้อหมวด ── */
.sec{padding:68px 0}
.sec.tight{padding-top:0}
.sechead{display:flex; align-items:flex-end; justify-content:space-between; gap:20px;
  margin-bottom:26px; flex-wrap:wrap}
.sechead h2{font-size:clamp(24px,3.2vw,32px); font-weight:700; margin-top:8px}
.sechead p{margin:8px 0 0; color:var(--tx2); font-size:14.5px; max-width:52ch}
.sechead .ico{display:inline-flex; align-items:center; gap:11px}
.sechead .ico span{width:36px; height:36px; border-radius:11px; display:grid; place-items:center;
  background:var(--glass-2); border:1px solid var(--line); color:var(--vio-lit)}

/* ── ตะแกรง ── */
.grid{display:grid; gap:18px; grid-template-columns:1fr}
@media(min-width:640px){ .grid.two,.grid.three{grid-template-columns:repeat(2,1fr)} }
@media(min-width:1000px){ .grid.three{grid-template-columns:repeat(3,1fr)} }
/* ⚠ เคยเขียน class="grid four" ทั้งที่ยังไม่มีกฎ .four ⇒ ตกเป็นคอลัมน์เดียว
   การ์ด 4 ใบยืดเป็นแถบยาว 939px เห็นเป็นช่องว่างดำทั้งจอ */
@media(min-width:640px){ .grid.four{grid-template-columns:repeat(2,1fr)} }
@media(min-width:1100px){ .grid.four{grid-template-columns:repeat(4,1fr)} }

/* ── การ์ดเหตุผล ── */
.why{padding:26px 24px}
.why .ic{width:44px; height:44px; border-radius:13px; display:grid; place-items:center;
  background:linear-gradient(150deg,rgba(108,90,224,.30),rgba(84,200,240,.14));
  border:1px solid var(--line-2); color:var(--vio-lit); margin-bottom:16px}
.why h3{font-size:17px; font-weight:600; margin-bottom:8px}
.why p{margin:0; font-size:14px; color:var(--tx2)}

/* ── การ์ดสินค้า ── */
.card{display:flex; flex-direction:column; overflow:hidden; padding:12px;
  transition:transform .22s cubic-bezier(.2,.7,.3,1), border-color .22s, box-shadow .22s;
  animation:rise .5s cubic-bezier(.2,.8,.3,1) both}
.card:hover{transform:translateY(-4px); border-color:var(--line-2); box-shadow:var(--shadow-hi)}
.card:nth-child(2){animation-delay:.07s}
.card:nth-child(3){animation-delay:.14s}
@keyframes rise{from{opacity:0; transform:translateY(16px) scale(.985)} to{opacity:1; transform:none}}
.art{position:relative; aspect-ratio:1/1; border-radius:11px; overflow:hidden; background:#0A0B14}
.art svg{width:100%; height:100%}
.card:hover .art svg{transform:scale(1.03)}
.art svg{transition:transform .5s cubic-bezier(.2,.7,.3,1)}
.ribbon{position:absolute; top:11px; right:11px; font-size:11.5px; font-weight:600;
  padding:5px 12px; border-radius:999px; color:#fff; background:var(--rose);
  box-shadow:0 6px 18px rgba(244,85,110,.42); letter-spacing:.01em}
.ribbon.hot{background:var(--ember-btn); box-shadow:0 6px 18px rgba(200,30,30,.45)}
.ribbon.soon{background:rgba(12,14,22,.82); border:1px solid var(--line-2); color:var(--tx2); box-shadow:none}
.cbody{padding:15px 6px 6px; display:flex; flex-direction:column; gap:9px; flex:1}
.ctitle{display:flex; align-items:center; gap:9px; font-size:16.5px; font-weight:600; line-height:1.4}
.ctitle .ki{color:var(--vio-lit); flex:none}
.cdesc{margin:0; font-size:13.5px; color:var(--tx3); line-height:1.65}
.crow{display:flex; align-items:baseline; gap:12px; margin-top:auto; padding-top:4px; flex-wrap:wrap}
.price{font-size:24px; font-weight:700; color:var(--gold); font-variant-numeric:tabular-nums; letter-spacing:-.02em}
.price small{font-size:14px; font-weight:500; color:var(--tx3)}
.stock{display:inline-flex; align-items:center; gap:6px; font-size:12.5px; color:var(--tx3);
  font-family:"IBM Plex Mono",monospace}
.noprice{font-size:14.5px; color:var(--tx3)}
.card .btn{margin-top:4px}

/* การ์ดหมวด */
.cat .cbody{gap:5px}
.catmeta{display:inline-flex; align-items:center; gap:7px; font-size:12.5px; color:var(--tx3);
  font-family:"IBM Plex Mono",monospace}

/* ── รีวิว ── */
.rev{padding:24px}
.rev .q{font-size:14.5px; color:var(--tx2); margin:0 0 18px; line-height:1.75}
.rev .who{display:flex; align-items:center; gap:12px}
.rev .who i{width:38px; height:38px; border-radius:50%; flex:none}
.rev .who b{display:block; font-size:14px; font-weight:600}
.rev .who span{font-size:12px; color:var(--tx3)}
.rev .stars{margin-bottom:14px}

/* ── คำถามที่พบบ่อย ── */
.faq{border:1px solid var(--line); border-radius:var(--r); overflow:hidden; background:var(--glass)}
.faq details{border-bottom:1px solid var(--line)}
.faq details:last-child{border-bottom:0}
.faq summary{cursor:pointer; padding:18px 22px; font-weight:500; font-size:15px;
  display:flex; align-items:center; gap:12px; list-style:none; transition:background .18s}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{background:rgba(255,255,255,.03)}
.faq summary::after{content:"+"; margin-left:auto; color:var(--vio-lit);
  font-family:"IBM Plex Mono",monospace; font-size:18px; transition:transform .2s}
.faq details[open] summary::after{transform:rotate(45deg)}
.faq p{margin:0; padding:0 22px 20px; color:var(--tx2); font-size:14px; max-width:74ch}

/* ── หน้าคลังคีย์ ── */
.pagehead{padding:38px 0 0}
.pagehead h1{font-size:clamp(26px,4vw,38px); font-weight:700; margin-top:8px}
.acct{display:flex; align-items:center; gap:14px; margin:24px 0 0; flex-wrap:wrap}
/* ⚠ ห้ามใส่ background แบบ shorthand ตรงนี้ — ทับตัวแปรไล่สีของ [class*="av-"]
   (ดูหมายเหตุที่ .av-ember) · ให้เหลือแค่สีพื้นตอนยังไม่มีคลาสสี */
.acct .big{width:52px; height:52px; border-radius:15px; flex:none;
  background-color:#22203C; border:1px solid var(--line-2);
  display:grid; place-items:center; color:#fff; font-weight:700; font-size:19px;
  background-position:center}
.acct .who b{display:block; font-size:16px; font-weight:600}
.acct .who span{font-size:13px; color:var(--tx3)}
.acct .sp{flex:1}
.tiles{display:grid; grid-template-columns:repeat(3,1fr); gap:12px; margin-top:26px}
.tile{padding:16px 18px}
.tile b{display:block; font-family:"IBM Plex Mono",monospace; font-size:23px; font-weight:600}
.tile span{font-size:12px; color:var(--tx3)}
.tile.g b{color:var(--money)}
.tile.c b{color:var(--cyan)}
.vgrid{display:grid; gap:18px; margin-top:22px}
@media(min-width:980px){ .vgrid{grid-template-columns:1.6fr 1fr; align-items:start} }
#keylist{display:grid; gap:16px}

.keycard{position:relative; padding:22px; overflow:hidden}
.keycard::before{content:""; position:absolute; left:0; right:0; top:0; height:2px;
  background:linear-gradient(90deg,var(--ember),var(--gold))}
.keytop{display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:16px}
.tag{display:inline-flex; align-items:center; gap:7px; font-size:11.5px; font-weight:600;
  letter-spacing:.04em; padding:5px 12px; border-radius:999px;
  border:1px solid var(--line-2); color:var(--tx2)}
.tag.on{color:var(--money); border-color:rgba(63,214,138,.38); background:rgba(63,214,138,.10)}
.tag.off{color:var(--tx3)}
/* 📱 ป้ายฝั่งบนการ์ดคีย์ (2026-09-13)
   ⛔⛤ ต้องอ่านได้จากตัวอักษรด้วย ไม่ใช่พึ่งสีอย่างเดียว — คนตาบอดสีต้องแยกออก
   ⚠ สองสีนี้ต้องไม่ชนกับความหมายเดิม: เขียว=ใช้งานอยู่ · ทอง=ราคา
     ⇒ คอมใช้ฟ้า (สถานะเชิงเทคนิค) · มือถือใช้ม่วง ซึ่งยังไม่ถูกใช้ที่ไหน */
.plat{display:inline-flex; align-items:center; gap:6px; flex:none;
  font-family:"IBM Plex Mono",monospace; font-size:11.5px; font-weight:600;
  letter-spacing:.05em; padding:5px 11px; border-radius:999px; border:1px solid}
.plat.pc{color:var(--cyan); border-color:rgba(95,208,232,.42)}
.plat.android{color:#B08CFF; border-color:rgba(176,140,255,.45)}
/* 🏷 ชื่อเล่นคีย์ที่ลูกค้าตั้งเอง (2026-09-13) */
.nick{display:inline-flex; align-items:baseline; gap:6px; font-size:13.5px;
  color:var(--tx2); min-width:0}
.nick b{font-weight:500; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  max-width:16ch}
.nick button{background:none; border:0; padding:0; cursor:pointer; font:inherit;
  font-size:12px; color:var(--tx3); text-decoration:underline dotted;
  text-underline-offset:3px}
.nick button:hover{color:var(--tx2)}
.keyval{font-family:"IBM Plex Mono",monospace; font-size:19px; letter-spacing:.06em; margin-left:auto}
.meter{height:6px; border-radius:999px; background:rgba(255,255,255,.07); overflow:hidden; margin:6px 0 10px}
.meter i{display:block; height:100%; background:linear-gradient(90deg,var(--gold),var(--ember))}
.mrow{display:flex; justify-content:space-between; gap:12px; font-size:12.5px; color:var(--tx3);
  font-family:"IBM Plex Mono",monospace; flex-wrap:wrap}
.kg{display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin:20px 0}
@media(min-width:560px){ .kg{grid-template-columns:repeat(4,1fr)} }
.kcell{background:rgba(255,255,255,.035); border:1px solid var(--line); border-radius:12px; padding:13px 15px}
.kcell b{display:block; font-family:"IBM Plex Mono",monospace; font-size:15.5px; font-weight:600;
  font-variant-numeric:tabular-nums; overflow:hidden; text-overflow:ellipsis}
.kcell span{font-size:11.5px; color:var(--tx3)}
.kacts{display:flex; gap:9px; flex-wrap:wrap}
.side{padding:22px}
.side h3{font-size:16.5px; font-weight:600; margin-bottom:6px}
.side .ver{font-family:"IBM Plex Mono",monospace; font-size:12.5px; color:var(--tx3); margin-bottom:18px}
.side .btn{margin-bottom:9px}
.hashline{font-family:"IBM Plex Mono",monospace; font-size:10.5px; color:var(--tx3);
  border-top:1px solid var(--line); padding-top:14px; margin-top:14px; word-break:break-all; line-height:1.7}
.hint{font-size:13px; color:var(--tx3); margin:12px 0 0; line-height:1.7}
.hint.bad{color:var(--rose)}
.empty{padding:38px 24px; text-align:center}
.empty h3{font-size:17px; font-weight:600; margin-bottom:8px}
.empty p{margin:0 auto; color:var(--tx3); font-size:14px; max-width:44ch}

/* ── ฟอร์ม ── */
.field{display:block; margin-bottom:14px}
.field span{display:block; font-size:13px; color:var(--tx2); margin-bottom:7px}
.input{width:100%; min-height:48px; padding:0 16px; border-radius:12px;
  background:rgba(255,255,255,.04); border:1px solid var(--line); color:var(--tx);
  font-size:14.5px; transition:border-color .18s, background .18s}
.input::placeholder{color:var(--tx3)}
.input:focus{border-color:var(--vio-lit); background:rgba(255,255,255,.06); outline:none}
.authgrid{display:grid; gap:18px; margin-top:24px}
@media(min-width:880px){ .authgrid{grid-template-columns:1fr 1fr; align-items:start} }
.pane{padding:26px}
.pane h2{font-size:19px; font-weight:600; margin-bottom:6px}
.pane > p.lead{margin-bottom:20px; font-size:14px}
.divider{display:flex; align-items:center; gap:14px; margin:20px 0; color:var(--tx3); font-size:12.5px}
.divider::before,.divider::after{content:""; flex:1; height:1px; background:var(--line)}

/* ── แถบเตือนในหน้า ── */
.notice{display:flex; align-items:center; gap:14px; margin-top:18px; padding:15px 18px;
  border:1px solid rgba(233,185,73,.34); background:rgba(233,185,73,.07);
  border-radius:var(--r); flex-wrap:wrap}
.notice .ic{color:var(--gold); flex:none}
.notice b{display:block; font-size:14.5px}
.notice p{margin:2px 0 0; font-size:13px; color:var(--tx2)}
.notice .btn{margin-left:auto}
.sep{height:1px; background:var(--line); margin:20px 0}
.linky{font-size:13px; color:var(--vio-lit); padding:6px 0; text-decoration:underline;
  text-underline-offset:3px}
.linky:hover{color:var(--tx)}

/* ── ป้ายแจ้งเตือนลอย ── */
#toasts{position:fixed; right:18px; bottom:92px; z-index:110; display:grid; gap:10px;
  max-width:min(360px, calc(100vw - 36px))}
@media(min-width:900px){ #toasts{bottom:24px} }
.toast{display:flex; align-items:flex-start; gap:11px; padding:13px 16px; border-radius:13px;
  background:rgba(14,16,26,.94); border:1px solid var(--line-2); box-shadow:var(--shadow-hi);
  font-size:13.5px; animation:slidein .28s cubic-bezier(.2,.8,.3,1) both}
@keyframes slidein{from{opacity:0; transform:translateX(18px)} to{opacity:1; transform:none}}
.toast .bar{width:3px; align-self:stretch; border-radius:2px; background:var(--money); flex:none}
.toast.bad .bar{background:var(--rose)}
/* ⚠ "สำเร็จบางส่วน" ไม่ใช่สำเร็จ และไม่ใช่ล้มเหลว — ต้องอ่านออกว่าเป็นคนละอย่าง
   เช่น สร้างสินค้าผ่านแต่รูปอัปไม่ผ่าน */
.toast.warn .bar{background:var(--warn)}
.toast.info .bar{background:var(--cyan)}

/* ── ป้ายประวัติซื้อล่าสุด ── */
/* ⛔⛤ 2026-09-01 กฎ 44px ของโครงการเอง — ตรวจแล้วมีลิงก์หลุดกฎอยู่จริง
   ("ไปหน้ากระเป๋าเงิน" 22px · "เงื่อนไขการใช้งาน" 29px · เส้นทาง 35px)
   ⚠ ขยายเฉพาะ "พื้นที่กด" ไม่ขยับตัวอักษรหรือระยะห่างของแถว
     (ใช้ inline-flex + min-height ⇒ กล่องโตขึ้นแต่บรรทัดยังชิดเหมือนเดิม)
   ⚠ เฉพาะจอที่กดด้วยนิ้วเท่านั้น — บนเดสก์ท็อปเมาส์แม่นอยู่แล้ว ไม่ต้องดันระยะ */
@media (hover:none) and (pointer:coarse){
  .crumb a, .crumbs a, .foot a, .slink, .navlink{
    display:inline-flex; align-items:center; min-height:44px}
  /* ⛤ 2026-09-13: ลิงก์เส้นทางสูง 44px แล้วก็จริง แต่ **กว้างแค่ 30-38px**
     (คำสั้นอย่าง "สินค้า" / "คลังคีย์") ⇒ นิ้วยังกดพลาดไปโดนตัวข้าง ๆ ได้
     ⚠ ขยายด้วย padding แล้วหักคืนด้วย margin ติดลบ ⇒ พื้นที่กดโตขึ้น
       แต่ตัวอักษรกับระยะห่างในแถวยังอยู่ที่เดิมเป๊ะ */
  .crumb a, .crumbs a{padding-inline:7px; margin-inline:-7px}
}
/* ⚠ ลิงก์ที่แทรกอยู่กลางย่อหน้า (.linky) **ตั้งใจไม่ขยาย**
   กฎ 44px มีไว้สำหรับปุ่ม/เมนูที่ยืนเดี่ยว ๆ · ถ้าไปดันลิงก์กลางประโยคด้วย
   บรรทัดจะถ่างออกจนอ่านยาก และย่อหน้าจะดูพัง — แลกไม่คุ้ม
   คนที่กดพลาดยังกดใหม่ได้ทันที ต่างจากปุ่มยืนเดี่ยวที่พลาดแล้วไปโดนของข้าง ๆ */

/* ⛔⛤ 2026-09-02 (B14) ป้าย "เพิ่งซื้อ" เป็น position:fixed ⇒ ลอยทับเนื้อหา
   ท้ายหน้าจริง ⇒ กันพื้นที่ท้ายหน้าเท่ากับแถบแนวตั้งที่ป้ายกินจริง
   (startTicker() ใน app.js วัดจากของจริงแล้วตั้งค่าให้ ไม่ใช่เลขเดา)
   ⚠ 2026-09-11 กฎนี้เคยหายไปตอน 0017153 — เหลือแต่ฝั่ง JS ที่ตั้งค่าทิ้งไว้
     โดยไม่มีใครอ่าน แล้วมีคนมาแปะ padding-bottom:150px ไว้ "ก่อน" กฎ .foot
     ตัวจริง ซึ่งถูกกฎท้ายไฟล์ทับทิ้งทั้งอัน ⇒ ป้ายทับข้อความลิขสิทธิ์มาตลอด
     ⇒ ห้ามแก้ด้วยเลขตายอีก และห้ามวางกฎ .foot ไว้ก่อนกฎ .foot ตัวหลัก */
:root{--ticker-space:0px}
.ticker{position:fixed; left:16px; bottom:92px; z-index:105;
  display:flex; align-items:center; gap:11px; padding:10px 12px 10px 10px;
  background:rgba(14,16,26,.94); backdrop-filter:blur(14px);
  border:1px solid var(--line-2); border-radius:14px; box-shadow:var(--shadow-hi);
  max-width:min(320px, calc(100vw - 32px)); animation:tkin .35s cubic-bezier(.2,.8,.3,1) both}
@media(min-width:900px){ .ticker{bottom:20px} }
@keyframes tkin{from{opacity:0; transform:translateX(-18px)} to{opacity:1; transform:none}}
/* ⛤ 2026-09-01: เดิมเป็นวงกลมแดงเปล่า ๆ ไม่มีอะไรข้างในเลย
   ⇒ ดูเหมือนรูปโหลดไม่ขึ้นมากกว่าจะเป็นดีไซน์ (เจ้าของเห็นจากคลิป)
   ⚠ ใส่รูปลูกค้าจริงไม่ได้ (ข้อมูลส่วนตัว) ⇒ ใช้สัญลักษณ์คนกลาง ๆ แทน
   ⚠ ฝัง SVG เป็น mask ไม่ใช่ background-image เพื่อให้สีตามธีมได้ */
.ticker .tav{width:34px; height:34px; border-radius:11px; flex:none;
  background:linear-gradient(140deg,var(--ember-deep),var(--ember));
  position:relative}
.ticker .tav::after{content:""; position:absolute; inset:0; opacity:.82;
  background:#fff;
  -webkit-mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='12' cy='7' r='4'/%3E%3C/svg%3E") center/17px 17px no-repeat;
  mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='12' cy='7' r='4'/%3E%3C/svg%3E") center/17px 17px no-repeat}
.ticker .tbody{min-width:0}
.ticker b{display:block; font-size:13px; font-weight:500; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis}
.ticker span{font-size:11.5px; color:var(--tx3); font-family:"IBM Plex Mono",monospace}
/* ⛔⛤ วัดจริง 2026-09-03: ป้ายลอยไปทับ "ปุ่ม" ในหน้าสินค้าจนกดไม่ได้
   (elementFromPoint ตรงกลางปุ่มคืนตัวป้าย ไม่ใช่ปุ่ม) — ลูกค้ากดการ์ดสินค้า
   แล้วโดนป้ายกินไปเฉย ๆ โดยไม่มีอะไรบอก
   ⇒ ตัวป้ายเป็นของ "อ่านอย่างเดียว" ⇒ ให้นิ้วทะลุผ่านไปหาของข้างล่างได้
     เหลือแค่ปุ่มปิดที่รับการกดจริง */
.ticker{pointer-events:none}
.ticker .tx{pointer-events:auto; margin-left:4px; color:var(--tx3);
  padding:6px; border-radius:8px; flex:none}
.ticker .tx:hover{color:var(--tx)}

/* ══ ปุ่ม ☰ + แผงเมนูเลื่อนขึ้นจากล่าง ══
   ⛤ มีไว้เพราะเมนูหลักถูกซ่อนตั้งแต่ต่ำกว่า 1180px ⇒ มือถือเข้าไม่ถึงสักหัวข้อ
   ⚠ จุดตัดต้องเท่ากับที่ซ่อนเมนูเป๊ะ (1180) ไม่งั้นมีช่วงที่ไม่มีทั้งสองอย่าง
      หรือมีทั้งสองอย่างพร้อมกัน */
.navbtn{display:none}
@media(max-width:1180px){ .navbtn{display:grid} }

.sheetwrap{position:fixed; inset:0; z-index:130; display:flex;
  align-items:flex-end}
.sheetbg{position:absolute; inset:0; background:rgba(0,0,0,.62);
  animation:shfade .2s ease both}
.sheetin{position:relative; width:100%; background:var(--surface);
  border-top:1px solid var(--line); border-radius:22px 22px 0 0;
  padding:10px 14px calc(18px + env(safe-area-inset-bottom));
  box-shadow:0 -18px 50px rgba(0,0,0,.6);
  animation:shup .26s cubic-bezier(.2,.8,.3,1) both;
  max-height:82vh; overflow-y:auto}
@keyframes shfade{from{opacity:0} to{opacity:1}}
@keyframes shup{from{transform:translateY(100%)} to{transform:none}}
.grab{display:block; width:42px; height:4px; border-radius:9px;
  background:var(--line); margin:0 auto 10px}
.sheetnav{display:grid}
/* ⛔ 52px ไม่ใช่เลขสวย ๆ — เป็นเป้าแตะขั้นต่ำ 44px บวกระยะกันกดพลาด */
.sheetnav a{display:flex; align-items:center; gap:12px; min-height:52px;
  padding:0 6px; color:var(--tx); font-size:15px;
  border-bottom:1px solid var(--line)}
.sheetnav a:last-child{border-bottom:0}
.sheetnav a.on{color:var(--ember-lit); font-weight:600}
.sheetnav a .sdot{width:7px; height:7px; border-radius:50%; flex:none;
  background:var(--ember); opacity:0}
.sheetnav a.on .sdot{opacity:1}
@media(prefers-reduced-motion:reduce){
  :root:not(.hs-on) .sheetbg,:root:not(.hs-on) .sheetin{animation:none}
}
.hs-off .sheetbg,.hs-off .sheetin{animation:none}

/* ── เมนูล่างบนมือถือ ── */
.bottomnav{position:fixed; left:0; right:0; bottom:0; z-index:100;
  display:grid; grid-template-columns:repeat(5,1fr);   /* ⚠ ต้องเท่าจำนวนปุ่มจริง ไม่งั้นตกแถวสองทับเนื้อหา */
  background:rgba(9,10,16,.92); backdrop-filter:blur(18px);
  border-top:1px solid var(--line); padding-bottom:env(safe-area-inset-bottom)}
@media(min-width:900px){ .bottomnav{display:none} }
.bottomnav a{display:grid; place-items:center; gap:4px; padding:9px 0 8px;
  font-size:11px; color:var(--tx3); transition:color .18s}
.bottomnav a.on{color:var(--vio-lit)}

/* ── ท้ายเว็บ ── */
/* ── แถบหัวบนจอมือถือจริง ──
   ⛔⛤ เจอ 2026-09-03: ชิปบัญชีกว้าง 144px ⇒ แถบหัวยาวถึง 414px
      บนจอ 320/360/390 มันล้นออกนอกจอ ชิปโดนตัดครึ่ง
   ⚠ ที่ไม่มีใครเห็นมาก่อน เพราะ **ด่านตรวจหัวเว็บเริ่มวัดที่ 768px**
     และตัววัดชั่วคราวตั้ง isMobile:true ซึ่งบังคับความกว้าง CSS เป็น 414
     เสมอไม่ว่าสั่งกี่พิกเซล ⇒ "วัดจอ 320" จริง ๆ คือวัด 414 มาตลอด
   ⇒ จอแคบเหลือแค่รูปโปรไฟล์ (ยังกดเข้าเมนูบัญชีได้เหมือนเดิม)
     ชื่อกับลูกศรไปโผล่ในเมนูที่กดเข้าไปอยู่แล้ว */
.bnm{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
@media(max-width:479px){
  .chipacct{padding:5px; gap:0}
  .chipacct > :not(.av){display:none}
  /* ⛔ ห้ามย่อปุ่มกลมให้เล็กกว่า 44px เพื่อให้พอดี — นั่นคือเป้าแตะขั้นต่ำ
     ที่ต้องรักษาไว้ · ย่อ "ระยะห่าง" กับ "ชิปบัญชี" แทน
     ⚠ กฎย่อแถบหัวเว็บของจอแคบอยู่ **ท้ายไฟล์** (ค้นคำว่า "แถบหัวเว็บจอแคบ")
       เพราะต้องอยู่หลังบล็อก max-width:760px ไม่งั้นถูกทับ */
}
@media(max-width:359px){
  .brand{font-size:14px}
  .brand .mk{width:26px; height:26px}
}

/* ── เป้าแตะบนอุปกรณ์ที่ใช้นิ้ว ──
   ⛤ กฎเดิมของโปรเจกต์ (บรรทัด ~458) ยกเว้นลิงก์กลางประโยคไว้ ถูกแล้ว —
      แต่สองอันนี้เป็นลิงก์ "ยืนเดี่ยว" ที่กดพลาดแล้วไปโดนของข้าง ๆ
      · .slink ปุ่มลัดในการ์ดขั้นตอน สูงแค่ 22px
      · เบรดครัมบ์ "หน้าแรก" สูง 35px
   ⚠ ใช้ pointer:coarse ไม่ใช่ความกว้างจอ — จอกว้างที่เป็นทัชสกรีนก็ต้องได้
     และคอมที่ย่อหน้าต่างแคบแต่ใช้เมาส์ ไม่ต้องถ่างจนย่อหน้าดูพัง */
/* ⚠ นับหน้าต่างแคบ (≤900) เป็นบริบทนิ้วด้วย — โน้ตบุ๊กจอสัมผัสกับแท็บเล็ต
   ที่รายงานว่ามีเมาส์ก็มีอยู่จริง และสองอันนี้เป็นปุ่มยืนเดี่ยว ไม่ใช่
   ลิงก์กลางย่อหน้า จึงไม่เข้าข้อยกเว้นของกฎเดิม */
@media (pointer:coarse), (max-width:900px){
  .steps3 .slink{margin-top:6px; min-height:44px; display:inline-flex;
    align-items:center}
  .crumb a{min-height:44px; display:inline-flex; align-items:center}
  /* ⛤ 2026-09-13: สูง 44px แล้วก็จริง แต่ **กว้างแค่ 30-38px** สำหรับคำสั้น
     อย่าง "สินค้า" / "คลังคีย์" ⇒ นิ้วยังกดพลาดไปโดนตัวข้าง ๆ ได้
     ⚠ ขยายด้วย padding แล้วหักคืนด้วย margin ติดลบ ⇒ พื้นที่กดโตขึ้น
       แต่ตัวอักษรกับระยะห่างในแถวอยู่ที่เดิมเป๊ะ
     ⚠ ต้องอยู่ในบล็อกนี้ ไม่ใช่บล็อก (hover:none) and (pointer:coarse)
       — ตัววัดจอมือถือใช้ hasTouch อย่างเดียว ซึ่งไม่ทำให้ hover:none ติด */
  .crumb a, .crumbs a{padding-inline:8px; margin-inline:-8px}
  /* ⛤ 2026-09-13 รอบ 9 · เส้นทางของหลังร้านเพิ่งกลายเป็นลิงก์จริง
     ⇒ ต้องได้เป้าแตะเท่ากับเส้นทางฝั่งหน้าร้าน ไม่งั้นสูงแค่ 27px */
  .adcrumb a{min-height:44px; display:inline-flex; align-items:center;
    padding-inline:8px; margin-inline:-8px}
  /* ⛔ ปุ่ม "ปุ่มลัด" ไม่มีประโยชน์บนเครื่องที่ไม่มีคีย์บอร์ด ⇒ ซ่อนไปเลย
     ดีกว่าถ่างให้ได้ขนาดนิ้วแล้วเบียดแถบบนจนของที่ใช้จริงไม่มีที่
     ⛔⛤ ต้องเขียน `.iconbtn.adkeys` ไม่ใช่ `.adkeys` เฉย ๆ — `.iconbtn.sm`
        มีน้ำหนักสองคลาส กฎคลาสเดียวแพ้เสมอ (คำสั่งในมีเดียไม่เพิ่มน้ำหนักให้)
        เคยพลาดกฎเดียวกันนี้มาแล้วกับ `.btn` */
  .iconbtn.adkeys{display:none}
  /* ป้ายปุ่มลัดในปุ่มค้นหาก็เช่นกัน — กินที่โดยไม่มีใครกดได้ */
  .adsearch kbd{display:none}
  /* ⛔⛤ แถบบนของหลังร้านไม่ตัดบรรทัด (flex ไม่ wrap) ⇒ ของที่เพิ่มเข้ามา
     ดันเกินขอบจอแคบแล้วทั้งหน้าเลื่อนซ้ายขวาได้
     ⇒ จอแคบเก็บไว้เฉพาะของที่ไม่มีทางอื่น: เมนู · เส้นทาง · ค้นหา · โหลดใหม่ · บัญชี
       "หน้าร้าน" ยังไปได้จากรางเมนูและเมนูบัญชี จึงตัดออกจากแถบบนได้ */
  .btn.adstore{display:none}
  /* เส้นทางต้องไม่ถูกบีบจนเป้าแตะแคบกว่านิ้ว — ให้ชื่อหน้าเป็นตัวที่ยอมหด */
  .adcrumb{min-width:0; overflow:hidden}
  .adcrumb a{flex:none}
  .adcrumb b{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
}

/* ⛔⛤ จอ ≤520 · แถบบนของหลังร้านไม่ตัดบรรทัด ⇒ ของเกินขอบแล้วทั้งหน้าเลื่อนได้
   ⇒ เหลือแต่ไอคอน: ชื่อหน้ายังอ่านได้จากรางเมนูที่เน้นอยู่ และจากหัวเรื่องของหน้า */
@media(max-width:520px){
  .adcrumb span, .adcrumb b{display:none}
  /* ⚠ จำกัดขอบเขตไว้ที่แถบบนของหลังร้านเท่านั้น — `.btn .lb` ลอย ๆ จะไป
     ซ่อนป้ายในปุ่มของหน้าร้านทั้งเว็บด้วย */
  .adtopbar .btn .lb{display:none}
  /* เหลือแต่ไอคอนแล้วต้องยังกว้างพอนิ้ว — ไม่งั้นได้ปุ่ม 36px ที่กดพลาดตลอด */
  .adtopbar .btn.sm{padding-inline:10px; min-width:44px; justify-content:center}
}

/* ══ ปรับให้พอดีมือถือแต่ละขนาด (วัดจริง 320 / 360 / 390 / 430 / 768 / 900) ══ */

/* ── ป้าย "เพิ่งซื้อ" ──
   ⛔⛤ เดิมเป็นกล่องลอยกว้าง 320px กลางฝั่งซ้าย ⇒ บนจอ 390 มันทับการ์ดสินค้า
      และหน้าต่างโปรแกรมพอดี (เจ้าของเห็นจากภาพหน้าจอ)
   ⇒ จอแคบ: เป็นแถบบางเต็มความกว้าง "เหนือเมนูล่าง" — บังพื้นที่น้อยลงมาก
     และอ่านออกว่าเป็นของระบบ ไม่ใช่ของที่หลุดมาทับ */
@media(max-width:899px){
  .ticker{left:9px; right:9px; max-width:none; border-radius:999px;
    padding:8px 10px; gap:9px;
    bottom:calc(78px + env(safe-area-inset-bottom))}
  .ticker .tav{width:27px; height:27px; border-radius:999px}
  .ticker .tav::after{-webkit-mask-size:14px 14px; mask-size:14px 14px}
  .ticker b{font-size:12px}
  .ticker span{font-size:10px}
}
/* ⛔⛤ 2026-09-11 ตรงนี้เคยมี @media(min-width:900px){ .foot{padding-bottom:150px} }
   ซึ่ง **ไม่เคยมีผล** เพราะกฎ .foot ตัวจริงอยู่ท้ายไฟล์ (บรรทัดหลังกว่า
   น้ำหนักเท่ากัน) แล้วตั้ง padding-bottom:44px ทับทิ้ง
   ⇒ ย้ายไปแก้ที่กฎ .foot ตัวจริงด้วย max(…, var(--ticker-space)) แทน */

/* ── การ์ดสินค้าบนมือถือ: รูปเล็กซ้าย เนื้อหาขวา ──
   ⛔⛤ ของเดิมรูปเป็นสี่เหลี่ยมจัตุรัสเต็มความกว้าง ⇒ จอ 390 เห็นได้ **ใบเดียว**
      ต่อหนึ่งหน้าจอ · เลือกของเทียบกันไม่ได้เลยถ้าไม่เลื่อนไปมา
   ⚠ ใช้ min-width:0 ทุกคอลัมน์ ไม่งั้นข้อความยาวดันกริดจนล้นจอ */
@media(max-width:659px){
  .card{display:grid; grid-template-columns:96px minmax(0,1fr); gap:12px;
    align-items:start; padding:11px}
  .art{aspect-ratio:1; border-radius:10px}
  .ribbon{top:6px; right:6px; font-size:10px; padding:3px 8px}
  .cbody{padding:0; gap:5px; min-width:0}
  .cbody p{font-size:12.5px; line-height:1.55}
  .ctitle{font-size:14.5px}
  .card:hover{transform:none}
}
@media(max-width:399px){
  .card{grid-template-columns:78px minmax(0,1fr); gap:10px}
  .ctitle{font-size:13.5px}
}

/* ── ท้ายเว็บ: 4 กลุ่มลิงก์เรียงลงมาเป็นแถวเดียว = 551px บนมือถือ ──
   ⇒ จับคู่เป็น 2 คอลัมน์ ลิงก์ทุกอันยังอยู่ครบ แค่ไม่ยาวเป็นหางว่าว */
@media(max-width:759px){
  .fgrid{grid-template-columns:1fr 1fr; gap:22px 18px}
  .fgrid > :first-child{grid-column:1 / -1}
  .fgrid ul{gap:8px; font-size:13.5px}
  .foot{padding:34px 0 96px; margin-top:40px}
}

/* ── สี่ขั้นตอน + การ์ดจุดขาย: บนมือถือเรียงเป็น "แถวนอน" ──
   ⛔⛤ เคยคิดจะทำ 2×2 แต่วัดแล้วไม่เข้าท่า: จอ 390 แบ่งสองคอลัมน์เหลือ
      คอลัมน์ละ ~178px ⇒ ข้อความไทยตกบรรทัดละ ~14 ตัวอักษร สูงกว่าเดิมอีก
   ⇒ เลขอยู่ซ้าย เนื้อหาอยู่ขวา (ท่าเดียวกับการ์ดสินค้า) อ่านไวและเตี้ยลงจริง
   ⚠ minmax(0,1fr) เสมอ — ไม่งั้นคำยาว ๆ ดันกริดจนล้นจอ */
@media(max-width:659px){
  .steps3{gap:10px}
  .steps3 .s{display:grid; grid-template-columns:38px minmax(0,1fr);
    gap:12px; padding:14px 15px; align-items:start}
  .steps3 .s .num{margin:0; grid-row:1 / span 3}
  .steps3 .s h3{font-size:15px; margin-bottom:4px}
  .steps3 .s p{font-size:13px}

  .trust{gap:10px}
  .trust .t{display:grid; grid-template-columns:26px minmax(0,1fr); gap:12px;
    padding:13px 15px; align-items:start}
  .trust .t svg{grid-row:1 / span 2; margin-top:2px}
}

/* ⚠ ระยะล่าง = ค่าเดิม หรือพื้นที่ที่ป้าย "เพิ่งซื้อ" กินอยู่ อันไหนมากกว่า
   (บวกกันตรง ๆ ไม่ได้ — วันที่ป้ายไม่โผล่จะเหลือช่องว่างเปล่า ๆ ท้ายหน้า) */
.foot{border-top:1px solid var(--line); margin-top:56px;
  padding:44px 0 max(96px, var(--ticker-space)); background:var(--bg-soft)}
@media(min-width:900px){ .foot{padding-bottom:max(44px, var(--ticker-space))} }
.fgrid{display:grid; gap:30px}
@media(min-width:760px){ .fgrid{grid-template-columns:1.6fr 1fr 1fr 1fr} }
.fgrid h4{font-family:"IBM Plex Mono",monospace; font-size:10.5px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--tx3); margin:0 0 14px; font-weight:400}
.fgrid ul{list-style:none; margin:0; padding:0; display:grid; gap:10px; font-size:14px; color:var(--tx2)}
.fgrid a:hover{color:var(--tx)}
.fabout{font-size:13.5px; color:var(--tx3); margin:14px 0 0; max-width:40ch}
.fbot{border-top:1px solid var(--line); margin-top:34px; padding-top:22px;
  display:flex; gap:16px; flex-wrap:wrap; font-size:12.5px; color:var(--tx3)}
.fbot .sp{flex:1}

/* ── บันทึกงานออกแบบ ── */
.notes{background:var(--bg); padding:44px 0 80px; border-top:1px solid var(--line)}
.notes h2{font-size:21px; font-weight:600; margin-bottom:8px}
.ng{display:grid; gap:14px; margin-top:24px}
@media(min-width:760px){ .ng{grid-template-columns:repeat(2,1fr)} }
.nn{border:1px solid var(--line); border-radius:14px; padding:18px 20px; background:var(--glass)}
.nn b{display:block; font-size:14.5px; font-weight:600; margin-bottom:6px}
.nn p{margin:0; font-size:13.5px; color:var(--tx2)}
.warnbox{margin-top:20px; border:1px solid rgba(233,185,73,.34); background:rgba(233,185,73,.07);
  border-radius:14px; padding:18px 20px; font-size:13.5px; color:var(--tx2)}
.warnbox b{color:var(--gold)}
/* ⚠ :root:not(.hs-on) = ยกเว้นให้เฉพาะคนที่กด ?motion=on เอง */
@media (prefers-reduced-motion:reduce){
  :root:not(.hs-on) *{animation:none !important; transition:none !important}}


/* ── เบรดครัมบ์ (หน้าแยกกันจึงต้องบอกว่าอยู่ตรงไหน) ── */
.crumb{display:flex; align-items:center; gap:9px; padding:22px 0 0;
  font-size:13px; color:var(--tx3); flex-wrap:wrap}
.crumb a{color:var(--tx2); border-bottom:1px solid transparent; padding-bottom:1px}
.crumb a:hover{color:var(--tx); border-bottom-color:var(--line-2)}
.crumb b{color:var(--tx); font-weight:500}

/* การ์ดหมวดกดได้ทั้งใบ */
a.card{color:inherit}
a.card:focus-visible{outline:2px solid var(--vio-lit); outline-offset:3px}

/* ตัวเลขขั้นตอนในหน้าคู่มือ */
.why .ic b{font-family:"IBM Plex Mono",monospace; font-size:18px; font-weight:600;
  color:var(--vio-lit)}

/* ── ข้ามไปเนื้อหา (แป้น Tab ครั้งแรกต้องเจออันนี้) ── */
.skip{position:absolute; left:-9999px; top:0; z-index:200;
  background:var(--ember-btn); color:#fff; padding:12px 18px; border-radius:0 0 12px 0;
  font-weight:600}
.skip:focus{left:0}

/* ── ป้ายความน่าเชื่อถือ ── */
.trust{display:grid; gap:12px; grid-template-columns:1fr; margin-top:34px}
@media(min-width:640px){ .trust{grid-template-columns:repeat(2,1fr)} }
@media(min-width:1024px){ .trust{grid-template-columns:repeat(4,1fr)} }
.trust .t{display:flex; align-items:flex-start; gap:12px; padding:16px 18px; text-align:left}
.trust .t svg{color:var(--ember-lit); flex:none; margin-top:2px}
.trust .t b{display:block; font-size:14.5px; font-weight:600}
.trust .t span{font-size:12.5px; color:var(--tx3); line-height:1.6}

/* ── ขั้นตอนการทำงาน ── */
.steps3{display:grid; gap:16px; counter-reset:s}
@media(min-width:820px){ .steps3{grid-template-columns:repeat(3,1fr)} }
.steps3 .s{position:relative; padding:24px 22px}
.steps3 .s .num{display:inline-grid; place-items:center; width:38px; height:38px;
  border-radius:12px; background:rgba(255,59,59,.12); border:1px solid var(--line-2);
  color:var(--ember-lit); font-family:"IBM Plex Mono",monospace; font-weight:600;
  margin-bottom:14px}
.steps3 .s h3{font-size:16.5px; font-weight:600; margin-bottom:7px}
.steps3 .s p{margin:0; font-size:13.5px; color:var(--tx2)}

/* ── ช่องรหัสผ่านที่กดดูได้ ── */
.pw{position:relative}
.pw .input{padding-right:52px}
.pw button{position:absolute; right:8px; top:50%; translate:0 -50%; width:36px; height:36px;
  display:grid; place-items:center; border-radius:9px; color:var(--tx3)}
.pw button:hover{color:var(--tx); background:rgba(255,255,255,.06)}

/* ── ข้อความผิดใต้ช่องกรอก ── */
.input.bad{border-color:var(--bad)}
.err{display:block; font-size:12.5px; color:var(--bad); margin-top:6px; min-height:0}

/* ── โครงร่างตอนกำลังโหลด ── */
@keyframes sk{0%{opacity:.45}50%{opacity:.85}100%{opacity:.45}}
/* ⚠ เดิมโครงร่างขึ้นทันทีที่เปิดหน้า ⇒ โหลดเร็ว ๆ ก็ยังเห็นแวบหนึ่งทุกครั้ง
   รีเฟรชรัว ๆ เลยเห็นเป็นของจาง ๆ กะพริบไม่หยุด · หน่วงให้โผล่หลัง 220ms
   ถ้าข้อมูลมาก่อนก็ถูกลบไปแล้ว ลูกค้าจะไม่เห็นอะไรกะพริบเลย */
.sk{background:rgba(255,255,255,.06); border-radius:8px;
  animation:skin .12s linear 0.22s both, sk 1.3s ease-in-out 0.22s infinite}
@keyframes skin{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){ .sk{animation:none} }

/* ── ปุ่มหลักบนแถบเมนู — จอแคบซ่อนไว้ เพราะมีเมนูล่างกับปุ่มในหน้าอยู่แล้ว ── */
.topcta{display:none}
@media(min-width:900px){ .topcta{display:inline-flex} }

/* ── สไปรต์ภาพปก: ต้องไม่กินที่ในหน้า ── */
.sprite{position:absolute; width:0; height:0; overflow:hidden}

/* ═══════════ หน้าสินค้า: แถบกรอง · โครงร่างระหว่างโหลด ═══════════ */
.vh{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0);
  clip-path:inset(50%); white-space:nowrap}

.filters{display:flex; gap:14px; align-items:center; flex-wrap:wrap; margin:26px 0 20px}
.chips{display:flex; gap:8px; flex-wrap:wrap}
.chip{min-height:40px; padding:0 16px; border-radius:999px; font-size:14px;
  border:1px solid var(--line); background:var(--glass); color:var(--tx2);
  transition:border-color var(--t) var(--ease), color var(--t) var(--ease),
             background var(--t) var(--ease)}
.chip:hover{color:var(--tx); border-color:var(--line-2)}
.chip[aria-pressed="true"]{background:rgba(255,59,59,.14); border-color:var(--ember);
  color:var(--tx); font-weight:600}
/* จำนวนใบในแต่ละตัวกรองของคลังคีย์ (2026-09-13) */
.chip .c{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--tx3);
  margin-left:7px}
.chip[aria-pressed="true"] .c{color:var(--tx2)}
.search{position:relative; display:flex; align-items:center; margin-left:auto; min-width:220px}
.search svg{position:absolute; left:14px; color:var(--tx3); pointer-events:none}
.search .input{padding-left:42px; min-height:40px}
@media(max-width:640px){ .search{margin-left:0; width:100%} }

.sk-line{height:12px; margin:10px 0}
.sk-art{aspect-ratio:1/1; border-radius:11px}
.w20{width:20%} .w40{width:40%} .w60{width:60%} .w90{width:90%}
.sk-row{display:grid; grid-template-columns:2fr 1fr 1fr; gap:14px; padding:16px 18px;
  border-bottom:1px solid var(--line)}

.empty-box{padding:40px 24px; text-align:center}
.empty-box h3{font-size:17px; font-weight:600; margin-bottom:8px}
.empty-box p{margin:0 auto 16px; color:var(--tx3); font-size:14px; max-width:44ch}

/* การ์ดสินค้าในแคตตาล็อก */
.card .pmeta{display:flex; gap:8px; flex-wrap:wrap; margin-top:2px}
.pill{font-size:12px; padding:4px 10px; border-radius:999px; border:1px solid var(--line);
  color:var(--tx2); background:var(--glass)}
.pill.soon{color:var(--warn); border-color:rgba(224,168,119,.34)}
.pill.gold{color:var(--gold); border-color:rgba(255,194,77,.34)}

/* ═══════════ หน้ารายละเอียดสินค้า ═══════════ */
.pdhead{display:grid; gap:24px; padding:26px 0 0}
@media(min-width:900px){ .pdhead{grid-template-columns:minmax(0,420px) 1fr; align-items:start} }
.pdart{padding:12px; border-radius:var(--r-lg)}
.pdart svg{width:100%; height:auto; border-radius:12px; display:block}
.pdinfo h1{font-size:clamp(26px,4vw,40px); margin:10px 0 0}
.pdbody{color:var(--tx2); font-size:14.5px; margin:14px 0 0; max-width:60ch}
.pdfrom{display:flex; align-items:baseline; gap:10px; margin:22px 0 0}
.from-label{font-size:13px; color:var(--tx3)}
.pdfrom .price{font-size:30px}

/* ตารางเปรียบเทียบแพ็ก */
.pktable{border:1px solid var(--line); border-radius:var(--r); overflow:hidden;
  background:var(--glass)}
.pkrow{display:grid; gap:12px; align-items:center; padding:16px 18px;
  border-bottom:1px solid var(--line); grid-template-columns:1fr}
@media(min-width:760px){ .pkrow{grid-template-columns:1.6fr .8fr auto} }
.pkrow:last-child{border-bottom:0}
.pkrow.best{background:rgba(255,59,59,.06)}
.pkname{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.pkname b{font-size:16px; font-weight:600}
.pksub{display:block; font-size:12.5px; color:var(--tx3); margin-top:3px}
.pkprice{display:flex; align-items:baseline; gap:8px}
.pkprice .price{font-size:22px}
.pkprice small{font-size:12px; color:var(--tx3); font-family:"IBM Plex Mono",monospace}
.pkrow .btn{justify-self:stretch}
@media(min-width:760px){ .pkrow .btn{justify-self:end; min-width:150px} }
.pkrow.off{opacity:.6}

/* รายการติ๊ก + ขั้นตอน */
.pane h2{font-size:18px; font-weight:600; margin-bottom:14px}
.ticks{list-style:none; margin:0; padding:0; display:grid; gap:11px; font-size:14px;
  color:var(--tx2)}
.ticks li{display:grid; grid-template-columns:18px 1fr; gap:11px; align-items:start}
.ticks li::before{content:""; width:16px; height:16px; margin-top:3px; border-radius:5px;
  background:rgba(127,224,127,.16); border:1px solid rgba(127,224,127,.4)}
.steps-ol{margin:0; padding-left:20px; display:grid; gap:10px; font-size:14px;
  color:var(--tx2)}
.steps-ol li::marker{color:var(--ember-lit); font-family:"IBM Plex Mono",monospace}

/* ═══════════════════════════════════ หน้าเช็คเอาต์ · หน้าคำสั่งซื้อ ══ */

/* แถบบอกว่าตอนนี้อยู่ขั้นไหน — ⛔ สถานะต้องบอกด้วย "รูป" ไม่ใช่สีอย่างเดียว
   (ตัวเลขในวงกลม + ขีดเชื่อม) คนตาบอดสีต้องอ่านออกเท่ากัน */
.flow{list-style:none; margin:18px 0 0; padding:0; display:flex; flex-wrap:wrap;
  gap:6px 4px; align-items:center; font-size:12.5px; color:var(--tx3)}
.flow li{display:flex; align-items:center; gap:8px; padding:5px 12px 5px 5px;
  border:1px solid var(--line); border-radius:999px; background:var(--glass)}
.flow li b{display:grid; place-items:center; width:22px; height:22px; border-radius:999px;
  background:rgba(255,255,255,.06); border:1px solid var(--line);
  font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--tx3)}
.flow li.now{color:var(--tx); border-color:var(--line-2)}
.flow li.now b{background:var(--ember-btn); border-color:transparent; color:#fff}
.flow li.done{color:var(--tx2)}
.flow li.done b{background:rgba(127,224,127,.14); border-color:rgba(127,224,127,.42);
  color:var(--ok)}

/* แถวสรุปยอด */
.sumrow{display:flex; align-items:baseline; justify-content:space-between; gap:14px;
  padding:9px 0; font-size:13.5px; color:var(--tx3); border-bottom:1px solid var(--line)}
.sumrow b{color:var(--tx2); font-weight:600; font-variant-numeric:tabular-nums}
.sumrow.total{border-bottom:0; padding-top:14px; font-size:14.5px; color:var(--tx2)}
.sumrow.total b{font-size:23px}

/* ตัวเพิ่ม-ลดจำนวน — ปุ่มแตะได้จริงบนมือถือ (44px) */
.qty{display:flex; align-items:center; gap:10px; margin:16px 0 18px;
  font-size:13px; color:var(--tx3)}
.qty span{margin-right:auto}
.qbtn.qbtn{min-width:44px; min-height:44px; padding:0; display:grid; place-items:center;
  font-size:19px; line-height:1; font-family:"IBM Plex Mono",monospace}
.qnum{min-width:38px; text-align:center; font-family:"IBM Plex Mono",monospace;
  font-size:17px; color:var(--tx); font-variant-numeric:tabular-nums}

/* ป้ายสถานะเพิ่มเติมของคำสั่งซื้อ */
.tag.wait{color:var(--gold); border-color:rgba(255,194,77,.38);
  background:rgba(255,194,77,.10)}
.tag.dead{color:var(--tx3); border-color:var(--line); background:rgba(255,255,255,.03)}

/* แถวสินค้าในใบคำสั่งซื้อ — ใช้โครงเดียวกับตารางแพ็กเกจ แต่ไม่มีปุ่ม
   ⚠ ต้องอยู่ในสื่อจอกว้างเท่านั้น จอ 375 ให้ซ้อนบรรทัดเหมือนแถวปกติ
     ไม่งั้นชื่อแพ็กยาว ๆ กับราคาจะเบียดกันจนอ่านไม่ออก */
@media(min-width:760px){ .pkrow.plain{grid-template-columns:1fr auto} }

/* รายการคำสั่งซื้อย่อในหน้าคลัง */
.odrow{display:grid; gap:4px; padding:12px 0; border-bottom:1px solid var(--line);
  text-decoration:none; color:inherit}
.odrow:last-of-type{border-bottom:0}
.odrow:hover{background:rgba(255,255,255,.02)}
.odtop{display:flex; align-items:center; justify-content:space-between; gap:10px}
.odtop .price{font-size:15px}
.odsub{font-size:12.5px; color:var(--tx3); line-height:1.6}
.odsub.mono{font-family:"IBM Plex Mono",monospace; font-size:11px}

/* ⛔⛤ 2026-09-11 ผิวของหลังร้านรุ่นเก่า (.adnav .adtiles .adlog .adrow .adpick
   .sortbar .pagebar .adwallet .adsub .kindrow) ถูกลบทิ้งพร้อมกับโค้ดที่เรียกมัน
   — หน้าหลังร้านใช้ผิวชุดใหม่ (.adshell/.adtbl/.adstrip/...) ทั้งหมดแล้ว
   ⚠ .adcard .admeta .adacts .adedit .adimgs ยังอยู่ เพราะหน้าฝั่งลูกค้า
     กับกล่องแก้สินค้ายังใช้ของเดิม */
.adlist{display:grid; gap:12px; margin-top:20px}
.adcard{padding:18px}
.adtop{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.adtop .keyval{font-size:14px}
.admeta{display:flex; gap:6px 16px; flex-wrap:wrap; margin-top:8px; font-size:12.5px;
  color:var(--tx3)}
.adacts{display:flex; gap:9px; flex-wrap:wrap; margin-top:14px}
.linkbox{font-family:"IBM Plex Mono",monospace; font-size:11px; color:var(--tx2);
  background:rgba(255,255,255,.04); border:1px solid var(--line);
  border-radius:var(--r-sm); padding:10px 12px; margin:10px 0; word-break:break-all}


/* ════════════════════════════════════════════════════════════════════
   ชั้นหน้าตาใหม่ 2026-08-31 — ต่อทับของเดิม ไม่ได้รื้อทิ้ง
   ════════════════════════════════════════════════════════════════════ */

/* ── ผิวพื้น: ตารางละเอียด + เกรนบาง ๆ ──
   ⚠ ทั้งคู่ position:fixed + pointer-events:none + z-index:0
     เนื้อหาอยู่ใน .wrap ซึ่ง position:relative อยู่แล้ว จึงลอยอยู่เหนือเสมอ */
body::before{
  content:""; position:fixed; inset:0; pointer-events:none; z-index:0; opacity:.5;
  background:
    linear-gradient(var(--line) 1px, transparent 1px) 0 0/64px 64px,
    linear-gradient(90deg, var(--line) 1px, transparent 1px) 0 0/64px 64px;
  /* ⚠ เดิมหน้ากากแคบ 80% ⇒ กริดหายก่อนถึงขอบจอ ทำให้ขอบข้างเป็นดำตัน
     บนจอกว้าง ๆ ยิ่งเห็นชัด — ขยายให้ลามถึงขอบ */
  -webkit-mask-image:radial-gradient(ellipse 120% 62% at 50% 0%, #000 0%, transparent 82%);
          mask-image:radial-gradient(ellipse 120% 62% at 50% 0%, #000 0%, transparent 82%);
}
body::after{
  content:""; position:fixed; inset:0; pointer-events:none; z-index:0; opacity:.045;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence baseFrequency='.9' numOctaves='3'/></filter><rect width='120' height='120' filter='url(%23n)'/></svg>");
}
.wrap{position:relative; z-index:1}

/* ── ปุ่ม: ยกขึ้นตอนชี้ + เงาแดงบนปุ่มหลัก ── */
.btn{border-radius:999px; font-weight:600;
  transition:transform var(--t) var(--ease), border-color var(--t) var(--ease),
    background var(--t) var(--ease), box-shadow var(--t) var(--ease)}
.btn:hover{transform:translateY(-2px); border-color:var(--line-2)}
.btn:active{transform:translateY(0)}
.btn.primary{background:linear-gradient(180deg,#E01F38,var(--ember-btn));
  box-shadow:0 8px 22px rgba(196,21,43,.32)}
.btn.primary:hover{filter:none; box-shadow:0 12px 30px rgba(196,21,43,.44)}
.btn.sm{border-radius:999px}
.btn[disabled]{transform:none !important; box-shadow:none}

/* ── กระจก: ขอบบนเรืองแดงจาง ๆ ── */
.glass{background:linear-gradient(165deg,var(--surface),var(--bg-soft));
  backdrop-filter:blur(8px)}
/* css-dupe-ok: ตั้ง position:relative ให้กล่องทุกชนิดเพื่อรองรับเส้นเรือง
   ::after ด้านล่าง — ค่าตรงกับกฎเฉพาะของ .keycard ไม่ได้ทับให้เพี้ยน */
.card,.pane,.side,.keycard,.adcard{position:relative}
.card::after,.pane::after,.keycard::after{
  content:""; position:absolute; inset:0 0 auto 0; height:1px; pointer-events:none;
  background:linear-gradient(90deg,transparent,var(--ember),transparent); opacity:.42}
.card{transition:transform var(--t-slow) var(--ease), border-color var(--t-slow) var(--ease),
  box-shadow var(--t-slow) var(--ease)}
.card:hover{transform:translateY(-5px); border-color:var(--line-2); box-shadow:var(--shadow-hi)}

/* ── หัวเว็บ ── */
header.top{background:rgba(7,7,10,.78); backdrop-filter:blur(14px)}
header.top nav a{border-radius:9px; transition:color var(--t-fast) var(--ease),
  background var(--t-fast) var(--ease)}
.mk{box-shadow:0 0 18px rgba(255,45,70,.4)}

/* ── ฮีโร่แบบสองคอลัมน์ ── */
.hero{text-align:left; padding:72px 0 80px}
.hero::before{
  left:50%; top:-30%; width:1100px; height:640px; translate:-50% 0;
  background:radial-gradient(ellipse at 50% 40%, rgba(255,45,70,.20), transparent 62%);
  filter:blur(22px); will-change:transform}
.hero::after{background:none}
.hgrid{display:grid; gap:44px; align-items:center}
@media(min-width:1000px){ .hgrid:not(.solo){grid-template-columns:1.02fr .98fr} }
/* ⚠ hero คอลัมน์เดียว — ข้อความยาวเกิน 70ch อ่านยาก ต้องคุมความกว้าง */
.hgrid.solo{max-width:62ch}
.hgrid.solo .sub{max-width:54ch}
.hero h1{margin:20px 0 14px}
.hero .sub{margin:0; max-width:52ch}
.hero .cta{justify-content:flex-start; margin-top:26px}
.hspec{display:flex; flex-wrap:wrap; gap:8px 22px; margin-top:22px; font-size:12.5px;
  color:var(--tx3); font-family:"IBM Plex Mono",monospace}
.hspec b{color:var(--info); font-weight:500}

/* ── ภาพจำลองหน้าจอโปรแกรม (วาดเอง ไม่ใช่ภาพจากเกม) ── */
.shot{border-radius:var(--r-lg); border:1px solid var(--line); overflow:hidden;
  background:linear-gradient(160deg,var(--surface),var(--bg-soft));
  box-shadow:0 30px 70px rgba(0,0,0,.6); will-change:transform}
.shotbar{display:flex; align-items:center; gap:7px; padding:12px 15px;
  border-bottom:1px solid var(--line); background:rgba(255,255,255,.02)}
.shotbar i{width:9px; height:9px; border-radius:99px; background:#2E2E38; display:block}
.shotbar b{margin-left:8px; font-size:12px; color:var(--tx3); font-weight:500;
  font-family:"IBM Plex Mono",monospace}
.shotbody{padding:16px; display:grid; gap:12px}
.srow{display:grid; grid-template-columns:1fr auto; gap:12px; align-items:center;
  padding:12px 14px; border-radius:var(--r-sm); border:1px solid var(--line);
  background:var(--glass)}
.srow .n{font-size:13.5px; font-weight:600}
.srow .s{font-size:11.5px; color:var(--tx3); font-family:"IBM Plex Mono",monospace}
.spark{height:64px; border-radius:var(--r-sm); border:1px solid var(--line);
  background:var(--glass); padding:10px 12px; display:flex; align-items:flex-end; gap:4px}
.spark i{flex:1; border-radius:3px 3px 0 0; display:block;
  background:linear-gradient(180deg,var(--ember),rgba(255,45,70,.18))}
.tag.tech{color:var(--info); border-color:rgba(95,208,232,.34);
  background:rgba(95,208,232,.08)}

/* ── แถวปุ่มชุมชน ── */
.commrow{display:flex; flex-wrap:wrap; gap:11px; margin-top:16px}
.commcard{display:grid; gap:14px; padding:24px; border-radius:var(--r-lg);
  border:1px solid var(--line); background:linear-gradient(165deg,var(--surface),var(--bg-soft))}
@media(min-width:820px){ .commcard{grid-template-columns:1fr auto; align-items:center} }
.commcard h3{font-size:19px}
.commcard p{color:var(--tx3); font-size:13.5px; margin-top:6px; max-width:56ch}

/* ══════════════════ หน้าคู่มือใช้งาน (2026-09-13 รอบ 10) ══════════════════
   ⛔⛤ ชื่อคลาสขึ้นต้น gd ทุกตัว — เช็คแล้วว่าไม่ชนของเดิมสักชื่อ
      (ชื่อสั้น ๆ อย่าง .steps/.video เคยรั่วข้ามหน้ามาแล้วหลายรอบ)
   ⚠ แอนิเมชันทุกตัวในบล็อกนี้ "มีจุดจบ" หรือเกิดตอนชี้เท่านั้น
      ⛔ ห้ามมีอันไหนวนไม่จบ — หน้าคู่มือถูกเปิดค้างไว้ระหว่างทำตามทีละขั้น
   ⚠ กฎลดการเคลื่อนไหวรวมอยู่ที่บล็อก prefers-reduced-motion ด้านบนแล้ว
      (`*{animation:none!important;transition:none!important}`) ⇒ ที่นี่ไม่ต้องซ้ำ */
.gdhero{position:relative; overflow:hidden; padding:30px 0 8px;
  border-bottom:1px solid var(--line)}
/* แสงพื้นหลัง — ตกแต่งล้วน ไม่ขยับ ไม่กินซีพียู กดไม่โดน อ่านไม่เจอ */
.gdglow{position:absolute; inset:-30% -10% auto -10%; height:520px;
  pointer-events:none; filter:blur(70px); opacity:.5}
.gdglow i{position:absolute; display:block; border-radius:50%}
.gdglow .g1{left:4%; top:8%; width:420px; height:420px;
  background:radial-gradient(circle,rgba(255,45,70,.34),transparent 68%)}
.gdglow .g2{right:2%; top:22%; width:360px; height:360px;
  background:radial-gradient(circle,rgba(122,11,24,.42),transparent 70%)}
/* ⚠ ห้ามคุมความกว้างที่ตัวพ่อ — แถวตัวเลขสามช่องจะถูกบีบจนตกบรรทัด
   ⇒ คุมเฉพาะย่อหน้าที่ต้องอ่านเป็นบรรทัดสั้น (หัวเรื่อง + คำโปรย) */
.gdhead{position:relative; padding:26px 0 34px}
.gdhead h1{font-size:clamp(28px,4.6vw,46px); font-weight:700; line-height:1.14;
  letter-spacing:-.02em; margin-top:10px; max-width:22ch}
.gdhead .lead{max-width:56ch}
.gdhero .cta{display:flex; gap:12px; flex-wrap:wrap; margin-top:24px}
/* สามตัวเลขใต้หัวเรื่อง — เส้นคั่นระหว่างช่อง อ่านเป็นชุดเดียว */
.gdfacts{display:flex; flex-wrap:wrap; gap:0 26px; margin-top:26px}
.gdfacts span{display:grid; gap:2px; padding:10px 26px 10px 0;
  border-right:1px solid var(--line)}
.gdfacts span:last-child{border-right:0; padding-right:0}
.gdfacts b{font-size:17px; font-weight:600; color:var(--tx)}
.gdfacts small{font-size:12px; color:var(--tx3)}

/* ── คลิป ── ⛔ ก่อนกดไม่มีคำขอไปหา YouTube เลย (ไม่มีรูปปกจากภายนอกด้วย)
   ⇒ ฉากหลังเป็นไล่เฉดของเราเอง ไม่ใช่ภาพ thumbnail */
/* ⚠ ไม่ปล่อยให้กว้างเต็ม .wrap — 16:9 ที่ 1200px สูง 675px กินทั้งจอ
   จนเลื่อนผ่านแล้วไม่เห็นว่ามีอะไรต่อ ⇒ คุมไว้แล้ววางกลาง */
.gdvideo{position:relative; aspect-ratio:16/9; border-radius:var(--r-lg);
  overflow:hidden; border:1px solid var(--line-2); display:grid;
  place-items:center; cursor:pointer; max-width:960px; margin:0 auto;
  background:radial-gradient(120% 90% at 50% 0%,rgba(255,45,70,.22),transparent 62%),
    linear-gradient(165deg,var(--surface),#0A0A0E)}
/* ตารางบาง ๆ ให้พื้นหลังมีเนื้อ ไม่ใช่กล่องดำเปล่า ๆ (ไม่ใช่ภาพ ไม่โหลดอะไรเพิ่ม) */
.gdvideo::before{content:""; position:absolute; inset:0; pointer-events:none;
  opacity:.5; -webkit-mask-image:radial-gradient(70% 60% at 50% 45%,#000,transparent);
  mask-image:radial-gradient(70% 60% at 50% 45%,#000,transparent);
  background-image:linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);
  background-size:52px 52px}
.gdvideo::after{content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(180deg,transparent 52%,rgba(0,0,0,.72))}
.gdvideo.on::before{display:none}
.gdvideo iframe{position:absolute; inset:0; width:100%; height:100%; border:0}
/* ⛔⛤ 2026-09-13 · เจ้าของเจอเอง: "กดดูคลิปแล้ว แต่แดง ๆ ยังขึ้นกลางจอ"
   ของที่ต้องหายตอนคลิปขึ้นมีสี่อย่าง ไม่ใช่สอง — ลืมปุ่มเล่นกับพื้นหลังของเราเอง
   ⚠ ปุ่มเล่นไม่ได้แค่ "ดูเกะกะ" — มันอยู่ z-index สูงกว่าคลิป จึงกินการกด
     กลางจอไปด้วย ⇒ กดหยุด/เล่นตรงกลางคลิปไม่ติดเลย
   ⚠ ต้อง display:none ไม่ใช่ opacity:0 — จาง ๆ แต่ยังกินการกดอยู่เหมือนเดิม */
.gdvideo.on{cursor:default; border-color:var(--line); background:#000}
.gdvideo.on::after,
.gdvideo.on .gdvmeta,
.gdvideo.on .gdplay{display:none}
.gdplay{position:relative; z-index:2; width:86px; height:86px; border-radius:50%;
  border:0; cursor:pointer; display:grid; place-items:center; color:#fff;
  background:var(--ember-btn); box-shadow:0 16px 44px rgba(255,45,70,.4);
  transition:transform var(--t) var(--ease), box-shadow var(--t) var(--ease)}
.gdplay svg{width:34px; height:34px; margin-left:5px}
/* วงแหวนขยาย — เกิดตอนชี้/โฟกัสเท่านั้น ไม่วนเองตอนอยู่เฉย ๆ */
.gdplay .ring{position:absolute; inset:-10px; border-radius:50%;
  border:1px solid rgba(255,45,70,.55); opacity:0; transform:scale(.86);
  transition:opacity var(--t) var(--ease), transform var(--t) var(--ease)}
.gdvideo:hover .gdplay,.gdplay:focus-visible{transform:scale(1.07);
  box-shadow:0 20px 54px rgba(255,45,70,.55)}
.gdvideo:hover .gdplay .ring,.gdplay:focus-visible .ring{opacity:1; transform:scale(1)}
.gdvmeta{position:absolute; left:0; right:0; bottom:0; z-index:2; display:grid;
  gap:3px; padding:18px 22px}
.gdvmeta b{font-size:15.5px; font-weight:600}
.gdvmeta span{font-size:12px; color:var(--tx3)}
.gdchap{display:flex; align-items:center; gap:9px; flex-wrap:wrap; margin-top:14px;
  max-width:960px; margin-left:auto; margin-right:auto}
.gdchap .sp{flex:1}

/* ── สามขั้น ── รางซ้ายเป็นเส้นต่อเนื่อง เติมสีตอนขั้นนั้นโผล่เข้าจอ */
.gdsteps{display:grid; gap:0; margin:0; padding:0; list-style:none}
.gdstep{position:relative; display:grid; grid-template-columns:26px 44px minmax(0,1fr);
  gap:0 16px; padding:0 0 30px}
.gdstep:last-child{padding-bottom:0}
.gdrail{position:relative; grid-column:1; justify-self:center; width:3px;
  background:rgba(255,255,255,.11); border-radius:3px}
.gdrail i{position:absolute; inset:0 0 auto 0; height:0; border-radius:3px;
  background:linear-gradient(180deg,var(--ember),rgba(255,45,70,.16));
  box-shadow:0 0 12px rgba(255,45,70,.45);
  transition:height 900ms var(--ease)}
.gdstep.lit .gdrail i{height:100%}
.gdrail.last{background:transparent}
.gdstep .num{grid-column:2; width:44px; height:44px; border-radius:14px;
  display:grid; place-items:center; font-family:"IBM Plex Mono",monospace;
  font-size:19px; font-weight:600; color:var(--tx3);
  border:1px solid var(--line); background:var(--bg-soft);
  transition:color var(--t) var(--ease), border-color var(--t) var(--ease),
    box-shadow var(--t) var(--ease), background var(--t) var(--ease)}
.gdstep.lit .num{color:#fff; border-color:transparent;
  background:linear-gradient(160deg,var(--ember),var(--ember-deep));
  box-shadow:0 10px 26px rgba(255,45,70,.34)}
.gdstep .bd{grid-column:3; padding-bottom:6px}
.gdstep h3{font-size:19px; font-weight:600; margin:9px 0 8px}
.gdstep>.bd>p{margin:0; color:var(--tx2); font-size:14.5px; max-width:66ch}
.gdul{margin:12px 0 0; padding:0; list-style:none; display:grid; gap:7px}
.gdul li{position:relative; padding-left:19px; font-size:13.5px; color:var(--tx3)}
.gdul li::before{content:""; position:absolute; left:4px; top:8px; width:5px;
  height:5px; border-radius:50%; background:var(--ember)}
/* บรรทัด "ถ้าทำถูกจะเห็นอะไร" — ตัวเดียวที่เป็นกรอบเขียว ให้ตากวาดเจอทันที */
.gdok{margin:14px 0 0 !important; padding:10px 14px; border-radius:var(--r-sm);
  font-size:13.5px; color:var(--tx2) !important;
  border:1px solid rgba(127,224,127,.26); background:rgba(127,224,127,.06)}
.gdok b{color:var(--ok); font-weight:600}
.gdacts{display:flex; gap:9px; flex-wrap:wrap; margin-top:14px}

/* ── การ์ดสี่ใบ ── */
.gdreqs{margin-top:4px}
.gdreq .ic{width:44px; height:44px; border-radius:13px; display:grid;
  place-items:center; margin-bottom:14px; color:var(--ember-lit);
  border:1px solid var(--line-2); background:rgba(255,45,70,.08)}
.gdreq{padding:24px 22px; transition:transform var(--t) var(--ease),
  border-color var(--t) var(--ease)}
.gdreq:hover{transform:translateY(-3px); border-color:var(--line-2)}
.gdreq h3{font-size:16px; font-weight:600; margin-bottom:7px}
.gdreq p{margin:0; font-size:13.5px; color:var(--tx2)}

/* ── ทางลัดไปต่อ ── */
.gdnexts{margin-top:4px}
.gdnext{display:grid; gap:5px; padding:20px 22px; text-decoration:none;
  color:var(--tx); position:relative;
  transition:transform var(--t) var(--ease), border-color var(--t) var(--ease)}
.gdnext:hover{transform:translateY(-3px); border-color:var(--line-2)}
.gdnext b{font-size:15.5px; font-weight:600}
.gdnext span{font-size:12.5px; color:var(--tx3)}
.gdnext em{position:absolute; right:20px; top:19px; font-style:normal;
  color:var(--tx3); transition:transform var(--t) var(--ease), color var(--t) var(--ease)}
.gdnext:hover em{transform:translateX(4px); color:var(--ember-lit)}

/* ── ช่องค้นในคำถามที่เจอบ่อย ── */
.gdfhead .sp{flex:1}
.gdsearch{display:flex; align-items:center; gap:9px; padding:0 14px; min-height:42px;
  border:1px solid var(--line); border-radius:999px; background:var(--glass);
  color:var(--tx3); min-width:min(320px,100%);
  transition:border-color var(--t-fast) var(--ease)}
.gdsearch:focus-within{border-color:var(--line-2)}
.gdsearch input{flex:1; min-width:0; border:0; background:none; color:var(--tx);
  font:inherit; font-size:13.5px; outline:none}
.gdfaq details[hidden]{display:none}
.gdempty{margin:14px 2px 0; font-size:13.5px; color:var(--tx3)}

/* ══════════ หน้าสินค้า · หน้ากระเป๋าเงิน · หน้าดูโปรแกรม (2026-09-13 รอบ 11) ══
   ⛔⛤ ชื่อคลาสขึ้นต้น pl (product list) / wl (wallet) / pg (program)
      เช็คแล้วว่าไม่ชนของเดิมสักชื่อ
   ⚠ แอนิเมชันทุกตัว "มีจุดจบ" หรือเกิดตอนชี้เท่านั้น — ทุกหน้าถูกเปิดค้างได้ */

/* ── หัวหน้าแบบมีแสง (ใช้ร่วมกันหน้าสินค้า + หน้ากระเป๋าเงิน) ── */
.plhero,.wlhero{position:relative; overflow:hidden; padding:22px 0 4px}
.plglow{position:absolute; inset:-40% -10% auto -10%; height:480px;
  pointer-events:none; filter:blur(72px); opacity:.46}
.plglow i{position:absolute; display:block; border-radius:50%}
.plglow .g1{left:2%; top:10%; width:400px; height:400px;
  background:radial-gradient(circle,rgba(255,45,70,.32),transparent 68%)}
.plglow .g2{right:6%; top:26%; width:340px; height:340px;
  background:radial-gradient(circle,rgba(122,11,24,.4),transparent 70%)}
.plhead{position:relative; padding:22px 0 26px}
.plhead h1{font-size:clamp(28px,4.4vw,44px); font-weight:700; line-height:1.14;
  letter-spacing:-.02em; margin-top:10px; max-width:20ch}
.plhead .lead{max-width:58ch}

/* ── การ์ดสินค้า ── ⛔⛤ ร้านมีของแค่ 2 ชิ้น ⇒ การ์ดต้องใหญ่พอที่จะ "เต็มหน้า"
   ไม่งั้นเหลือพื้นดำครึ่งจอ อ่านแล้วเหมือนของหมด */
.plcards{gap:22px}
.plcards .card{overflow:hidden; transition:transform var(--t) var(--ease),
  border-color var(--t) var(--ease), box-shadow var(--t) var(--ease)}
.plcards .card:hover{transform:translateY(-5px); border-color:var(--line-2);
  box-shadow:0 24px 60px rgba(0,0,0,.5)}
.plcards .art{position:relative}
/* ไล่เฉดล่างของภาพ — ตัวหนังสือใต้ภาพอ่านง่ายขึ้นโดยไม่ต้องใส่กล่องทึบ */
.plcards .art::after{content:""; position:absolute; inset:auto 0 0 0; height:46%;
  pointer-events:none;
  background:linear-gradient(180deg,transparent,rgba(10,10,14,.85))}
.plcards .art img{transition:transform 700ms var(--ease)}
.plcards .card:hover .art img{transform:scale(1.045)}
.plcards .crow{display:flex; align-items:baseline; gap:9px; margin-top:14px;
  padding-top:14px; border-top:1px solid var(--line)}
/* ลูกศรท้ายการ์ด — บอกว่ากดได้ โดยไม่ต้องมีปุ่มจริงมาแย่งพื้นที่ */
.plcards .crow::after{content:"→"; margin-left:auto; color:var(--tx3);
  transition:transform var(--t) var(--ease), color var(--t) var(--ease)}
.plcards .card:hover .crow::after{transform:translateX(5px); color:var(--ember-lit)}

/* ── ตารางเทียบ PC / มือถือ ── */
.plcmp{display:grid; grid-template-columns:minmax(120px,.9fr) 1fr 1fr;
  border:1px solid var(--line); border-radius:var(--r-lg); overflow:hidden;
  background:var(--glass); font-size:13.5px}
.plcmp>div{padding:13px 16px; border-bottom:1px solid var(--line)}
.plcmp>div:nth-child(3n){border-right:0}
.plcmp>div:nth-last-child(-n+3){border-bottom:0}
.plcmp .hd{background:var(--bg-soft); display:grid; gap:2px; align-content:center}
.plcmp .hd b{font-size:14.5px; font-weight:600}
.plcmp .hd span{font-size:11.5px; color:var(--tx3)}
.plcmp .rk{color:var(--tx3); background:rgba(255,255,255,.018)}
.plcmp .rv{color:var(--tx2)}
.plcmp .rv.good{color:var(--tx)}
/* ⛤ จุดเขียวหน้าข้อที่เป็นจุดแข็ง — บอกด้วยรูปทรง ไม่ใช่สีอย่างเดียว */
.plcmp .rv.good::before{content:"✓ "; color:var(--ok); font-weight:600}
@media(max-width:760px){
  .plcmp{grid-template-columns:1fr 1fr}
  .plcmp .hd:first-child{display:none}
  .plcmp .rk{grid-column:1/-1; background:var(--bg-soft); color:var(--tx2);
    font-weight:600; font-size:12.5px}
}

/* ── แถบความมั่นใจ 4 ช่อง ── */
.pltrust{display:grid; gap:18px; grid-template-columns:1fr;
  border:1px solid var(--line); border-radius:var(--r-lg); padding:24px;
  background:linear-gradient(165deg,var(--surface),var(--bg-soft))}
@media(min-width:700px){ .pltrust{grid-template-columns:repeat(2,1fr)} }
@media(min-width:1080px){ .pltrust{grid-template-columns:repeat(4,1fr)} }
.pltrust>div{display:grid; gap:5px; align-content:start}
.pltrust .ic{width:38px; height:38px; border-radius:11px; display:grid;
  place-items:center; margin-bottom:6px; color:var(--ember-lit);
  border:1px solid var(--line-2); background:rgba(255,45,70,.08)}
.pltrust b{font-size:14.5px; font-weight:600}
.pltrust span:not(.ic){font-size:12.5px; color:var(--tx3); line-height:1.65}

/* ── การ์ดยอดเงินในกระเป๋า ── */
.walletcard.wlbal{align-items:center}
.wlbal .amt{font-size:clamp(38px,6vw,56px)}
/* ⛔⛤ `.wc-side` เดิมเป็น flex:0 0 auto ⇒ ความกว้างเท่าของข้างใน
   พอใส่ปุ่มเติมด่วน 4 ปุ่มเข้าไป มันยื่นพ้นการ์ดบนจอ 320-360
   ⇒ ให้ยุบลงมาเป็นแถวของตัวเองและหดได้
   ⛔⛤ ต้องเขียน `.walletcard.wlbal .wc-side` (สามคลาส) ไม่ใช่ `.wlbal .wc-side`
      กฎเดิม `.walletcard .wc-side{flex:0 0 auto}` มีน้ำหนักเท่ากันแต่อยู่
      **ท้ายไฟล์กว่า** ⇒ มันชนะ · กับดักเดียวกับ `.btn.sm` ที่เจอมาแล้ว */
.walletcard.wlbal .wc-side{flex:1 1 240px; min-width:0}
.wlquick{display:flex; gap:8px; flex-wrap:wrap; justify-content:flex-end;
  margin-bottom:10px}
.wlquick .btn{font-variant-numeric:tabular-nums}
.wlbal .wc-side .btn.block{width:100%}
@media(max-width:820px){ .wlquick{justify-content:flex-start} }

/* ══════════════ ศูนย์ช่วยเหลือ (2026-09-13 รอบ 12) ══════════════
   ⛤ หน้านี้คนเปิดมาตอน "กำลังหงุดหงิด" ⇒ ของชิ้นแรกต้องเป็นช่องค้น
      และทุกใบต้องมีทางไปทำต่อ ไม่ใช่อ่านจบแล้วจบกัน */
.hlhero{position:relative; overflow:hidden; padding:22px 0 4px}
.hlsearch{display:flex; align-items:center; gap:12px; margin-top:26px;
  padding:0 18px; min-height:58px; max-width:620px;
  border:1px solid var(--line); border-radius:999px; color:var(--tx3);
  background:rgba(0,0,0,.34);
  transition:border-color var(--t) var(--ease), box-shadow var(--t) var(--ease)}
.hlsearch:focus-within{border-color:var(--line-2);
  box-shadow:0 0 0 4px rgba(255,45,70,.1)}
.hlsearch input{flex:1; min-width:0; border:0; background:none; color:var(--tx);
  font:inherit; font-size:15px; outline:none}
.hlclear{border:0; background:var(--glass-2); color:var(--tx2); cursor:pointer;
  width:26px; height:26px; border-radius:999px; flex:none; font-size:12px;
  line-height:1; display:grid; place-items:center}
.hlclear:hover{background:var(--glass); color:var(--tx)}
.hlcount{margin:12px 2px 0; font-size:12.5px; color:var(--tx3); min-height:18px}

/* ── การ์ดอาการ ── */
.hlgrid{display:grid; gap:16px; grid-template-columns:1fr}
@media(min-width:700px){ .hlgrid{grid-template-columns:repeat(2,1fr)} }
@media(min-width:1080px){ .hlgrid{grid-template-columns:repeat(3,1fr)} }
.hlcard{display:grid; gap:7px; align-content:start; padding:22px;
  text-decoration:none; color:var(--tx);
  transition:transform var(--t) var(--ease), border-color var(--t) var(--ease),
    box-shadow var(--t) var(--ease)}
.hlcard:hover{transform:translateY(-4px); border-color:var(--line-2);
  box-shadow:0 20px 44px rgba(0,0,0,.42)}
.hlcard .ic{width:40px; height:40px; border-radius:12px; display:grid;
  place-items:center; margin-bottom:6px; color:var(--ember-lit);
  border:1px solid var(--line-2); background:rgba(255,45,70,.08);
  transition:transform var(--t) var(--ease)}
.hlcard:hover .ic{transform:scale(1.06)}
.hlcard b{font-size:15.5px; font-weight:600; line-height:1.4}
.hlcard>span:not(.ic){font-size:13px; color:var(--tx3); line-height:1.7}
.hlcard em{font-style:normal; font-size:12.5px; color:var(--ember-lit);
  margin-top:6px; transition:transform var(--t) var(--ease)}
.hlcard:hover em{transform:translateX(4px)}
.hlcard[hidden]{display:none}

/* ── ชิปหมวด + คำถาม ── */
.hlcats{display:flex; gap:7px; flex-wrap:wrap}
.hlfaq details[hidden]{display:none}
.hlnone{margin:14px 2px 0; font-size:13.5px; color:var(--tx3)}

/* ── ยังไม่หาย ── ⛔ ไม่ใช่การ์ด "ทักแอดมิน" ซ้ำกับส่วนท้ายเว็บ
   ฝั่งขวาคือของที่ส่วนท้ายไม่มี: บอกว่าต้องเตรียมอะไรมาก่อนทัก */
.hlcta{display:grid; gap:22px; grid-template-columns:1fr; padding:26px;
  border:1px solid var(--line); border-radius:var(--r-lg);
  background:linear-gradient(165deg,var(--surface),var(--bg-soft))}
@media(min-width:900px){ .hlcta{grid-template-columns:1.15fr .85fr; gap:34px} }
.hlcta h2{font-size:clamp(20px,2.6vw,26px); margin-top:6px}
.hlcta .tx>p{margin:10px 0 0; font-size:13.5px; color:var(--tx3); max-width:52ch}
.hlprep{border:1px solid var(--line); border-radius:var(--r);
  padding:18px 20px; background:rgba(0,0,0,.26)}
.hlprep>b{display:block; font-size:13.5px; font-weight:600; margin-bottom:12px}
.hlprep ol{list-style:none; margin:0; padding:0; display:grid; gap:10px}
.hlprep li{display:grid; grid-template-columns:22px 1fr; gap:11px;
  align-items:start; font-size:13px; color:var(--tx2)}
.hlprep li span{width:22px; height:22px; border-radius:7px; display:grid;
  place-items:center; font-family:"IBM Plex Mono",monospace; font-size:11.5px;
  font-weight:600; color:var(--ember-lit);
  border:1px solid var(--line-2); background:rgba(255,45,70,.08)}
.hlprep>p{margin:14px 0 0; font-size:12px; color:var(--tx3); line-height:1.7}

/* ── หน้าดูโปรแกรม ── การ์ดตัวเลขกับแท็บให้อ่านเป็นชุดเดียวกับหน้าอื่น ── */
.pstats>div{transition:transform var(--t) var(--ease),
  border-color var(--t) var(--ease)}
.pstats>div:hover{transform:translateY(-3px); border-color:var(--line-2)}
/* ⛤ ช่องที่กำลังเปิดอยู่ต้องเด่นกว่าช่องอื่นชัด ๆ ไม่ใช่ต่างกันนิดเดียว */
.ptab.on{box-shadow:0 10px 26px rgba(255,45,70,.22)}
/* สลับหมวดแล้วเนื้อหาเลื่อนเข้ามา — จบใน 260ms ไม่วน
   ⛔⛤ ห้ามตั้งชื่อคลาสว่า `swap` เฉย ๆ — ชื่อนั้นถูกใช้แล้ว (ข้อความ "สลับ"
      ใต้ฟอร์มเข้าสู่ระบบ ซึ่งมี text-align:center) ⇒ ติดเข้าไปแล้วเนื้อหา
      ทั้งแผงหมวดกลายเป็นจัดกลาง · ตัวตรวจไม่จับให้เพราะกฎไม่ได้ประกาศซ้ำ
      และคลาสก็มีกฎรองรับอยู่แล้ว ⇒ ก่อนตั้งชื่อคลาสใหม่ต้อง grep ทุกครั้ง */
.pdetail.pdswap{animation:pgswap 260ms var(--ease) both}
@keyframes pgswap{from{opacity:0; transform:translateY(8px)} to{opacity:1; transform:none}}

@media(max-width:760px){
  .gdstep{grid-template-columns:20px 38px minmax(0,1fr); gap:0 12px}
  .gdstep .num{width:38px; height:38px; font-size:17px; border-radius:12px}
  .gdplay{width:66px; height:66px}
  .gdplay svg{width:26px; height:26px}
  .gdvmeta{padding:14px 16px}
  .gdfacts span{padding-right:18px}
}

/* ── หน้าบัญชี (เข้าสู่ระบบ · สมัครสมาชิก) ── */
.authbox{max-width:470px; margin:0 auto}
.authbox .pane{padding:28px}
.authbox h1{font-size:clamp(26px,4vw,34px)}
.field span{font-size:12.5px; color:var(--tx3)}
.input{border-radius:var(--r-sm); background:rgba(0,0,0,.35);
  transition:border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease)}
.input:focus{outline:none; border-color:var(--ember);
  box-shadow:0 0 0 3px rgba(255,45,70,.16)}
.swap{text-align:center; font-size:13.5px; color:var(--tx3); margin-top:18px}
.swap a{color:var(--ember-lit); font-weight:600}
.okmark{color:var(--ok)} .badmark{color:var(--bad)}

/* ── ท้ายเว็บ ── */
.foot{background:linear-gradient(180deg,transparent,rgba(255,45,70,.035))}

/* ── การเคลื่อนไหว: เผยทีละส่วนตอนเลื่อนถึง ──
   ⛔⛤ ถ้า IntersectionObserver ไม่ทำงาน (เบราว์เซอร์เก่า/สคริปต์พัง)
      ของที่ opacity:0 จะหายถาวร = อ่านไม่ได้ ซื้อไม่ได้
      จึงตั้ง .rise ให้ "มองเห็นตามปกติ" ไว้ก่อน แล้วให้ JS เติม .anim เอง
      ⇒ ไม่มี JS = เห็นทุกอย่าง · มี JS = ได้แอนิเมชัน */
.rise.anim{opacity:0; transform:translateY(16px)}
.rise.anim.in{opacity:1; transform:none;
  transition:opacity 620ms var(--ease), transform 620ms var(--ease)}

@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  /* ⚠ :root:not(.hs-on) = ยกเว้นให้เฉพาะคนที่กด ?motion=on เอง */
  :root:not(.hs-on) *,:root:not(.hs-on) *::before,:root:not(.hs-on) *::after{
    animation-duration:1ms !important; animation-iteration-count:1 !important;
    transition-duration:1ms !important}
  :root:not(.hs-on) .rise.anim{opacity:1 !important; transform:none !important}
  :root:not(.hs-on) .hero::before{display:none}
  .btn:hover,.card:hover{transform:none}
}


/* ── รายละเอียดหน้าบัญชี ── */
.opt{font-style:normal; color:var(--tx3); font-weight:400; font-size:11.5px}
.authbox .hashline{margin-top:18px}
@media(max-width:900px){ .hidesm{display:none} }

/* ── เป้าแตะ ──
   ⛔ ปุ่มเล็กต้องยังแตะได้จริง — เดิม .btn.sm สูง 40px ต่ำกว่าเกณฑ์ 44px
   (ของที่เหลือแยกไปอยู่ในกฎจอแคบท้ายไฟล์ เพราะจอกว้างขนาดเดิมสวยกว่า) */
.btn.sm{min-height:44px}

/* ── หัวเว็บบนจอแคบ ──
   ⛔⛤ เดิมยัดปุ่มชุมชน+Discord+เลือกแพ็กเกจ+ชิปบัญชี ลงแถวเดียว
      จอ 375 ดันชิปบัญชีตกขอบขวา และปุ่มเหลือแต่วงกลมเปล่าเพราะข้อความถูกซ่อน
      ⇒ จอแคบเก็บแค่ แบรนด์ + ชิปบัญชี · ปุ่มชุมชน/Discord ยังอยู่ครบใน
        ฮีโร่ ท้ายเว็บ และหน้าช่วยเหลือ ซึ่งกดถึงได้เหมือนกัน */
@media(max-width:760px){
  header.top .j-line,
  header.top .j-discord,
  header.top .topcta{display:none}
  header .wrap{gap:10px}
}

/* ═══════════════════════════════ เมนูบัญชี · แจ้งเตือน · โปรไฟล์ · กระเป๋า ══ */
.acctwrap{position:relative; display:flex; align-items:center; gap:8px}
.iconbtn{position:relative; display:grid; place-items:center; width:44px; height:44px;
  border-radius:999px; border:1px solid var(--line); background:var(--glass);
  color:var(--tx2); cursor:pointer;
  transition:border-color var(--t) var(--ease), color var(--t) var(--ease)}
.iconbtn:hover{border-color:var(--line-2); color:var(--tx)}
/* ปุ่มภาพเคลื่อนไหวตอนเปิดอยู่ — ต้องดูออกโดยไม่ต้องพึ่งสีอย่างเดียว
   (เพิ่มเส้นขอบเข้ม + จุดเรืองข้างใน ไม่ใช่แค่เปลี่ยนเฉดสี) */
#motionbtn[aria-pressed="true"]{border-color:rgba(255,45,70,.55);
  color:var(--ember-lit); box-shadow:0 0 0 1px rgba(255,45,70,.18) inset}
.iconbtn .dot{position:absolute; top:9px; right:10px; width:8px; height:8px;
  border-radius:99px; background:var(--ember); border:2px solid var(--bg)}

.acctmenu{position:absolute; right:0; top:calc(100% + 10px); width:252px; z-index:60;
  border-radius:var(--r); border:1px solid var(--line); overflow:hidden;
  background:linear-gradient(165deg,var(--surface),var(--bg-soft));
  box-shadow:var(--shadow-hi)}
.acctmenu.wide{width:320px; max-height:420px; overflow-y:auto}
.acctmenu .mhead{display:flex; gap:11px; align-items:center; padding:14px 16px;
  border-bottom:1px solid var(--line)}
/* ⛔⛤ เคยไม่มีกฎไหนตั้งขนาดให้รูปในหัวเมนูเลย (คำนวณออกมาเป็น auto)
   ⇒ วงกลมยืดผิดรูปจนดูเหมือนโดนตัดครึ่ง (เจ้าของทัก 2026-08-31
     "กางแท็บโปรไฟล์แต่เห็นไม่ครบ")
   ⚠ .chipacct .av ตั้ง 32px ไว้ แต่เจาะจงเฉพาะชิปมุมขวา ไม่ครอบมาถึงในเมนู */
.acctmenu .mhead .av{width:40px; height:40px; flex:none; border-radius:50%;
  border:1px solid var(--line-2); background-color:#22203C;
  display:grid; place-items:center; color:#fff; font-weight:700; font-size:15px}
.acctmenu .mhead > div{min-width:0}
.acctmenu .mhead b{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.acctmenu .mhead b{display:block; font-size:14px}
.acctmenu .mhead span{font-size:11.5px; color:var(--tx3);
  font-family:"IBM Plex Mono",monospace}
.acctmenu a,.acctmenu > button{display:flex; align-items:center; gap:10px; width:100%;
  padding:11px 16px; font-size:13.5px; color:var(--tx2); text-align:left;
  background:none; border:0; cursor:pointer; min-height:44px; text-decoration:none}
.acctmenu a:hover,.acctmenu > button:hover{background:var(--glass-2); color:var(--tx)}
.acctmenu .sepline{height:1px; background:var(--line); margin:4px 0}
.acctmenu .danger{color:var(--bad)}
.acctmenu .bal{margin-left:auto; font-family:"IBM Plex Mono",monospace;
  color:var(--gold); font-size:12.5px}
@media(max-width:520px){ .acctmenu{width:min(88vw,300px)} .acctmenu.wide{width:min(92vw,340px)} }

/* แถวแจ้งเตือน */
.ntrow{display:grid; gap:3px; padding:12px 16px; border-bottom:1px solid var(--line);
  text-decoration:none; color:inherit}
.ntrow:last-child{border-bottom:0}
.ntrow:hover{background:var(--glass-2)}
.ntrow b{font-size:13px; display:flex; align-items:center; gap:8px}
.ntrow b i{width:7px; height:7px; border-radius:99px; background:var(--ember);
  display:block; flex:none}
.ntrow span{font-size:12px; color:var(--tx3); line-height:1.6}
.ntrow .t{font-size:10.5px; color:var(--tx3); font-family:"IBM Plex Mono",monospace}

/* รูปโปรไฟล์ */
.chipacct .av,.acctmenu .av{background-size:cover; background-position:center;
  display:grid; place-items:center; font-weight:700; color:#fff; font-size:13px}
.avpick{display:flex; gap:16px; align-items:center; flex-wrap:wrap; margin:16px 0 10px}
.avbig{width:88px; height:88px; border-radius:50%; flex:none; display:grid;
  place-items:center; font-size:32px; font-weight:700; color:#fff;
  border:1px solid var(--line-2); background-size:cover; background-position:center}
.avgrid{display:flex; gap:9px; flex-wrap:wrap}
.avgrid button{width:44px; height:44px; border-radius:50%; border:1px solid var(--line);
  cursor:pointer; transition:transform var(--t) var(--ease), box-shadow var(--t) var(--ease)}
.avgrid button:hover{transform:translateY(-2px)}
.avgrid button[aria-pressed="true"]{border-color:var(--ember);
  box-shadow:0 0 0 3px rgba(255,45,70,.26)}
/* ⛔⛤ สีพื้นต้องเป็น "ตัวแปรสองสี" ไม่ใช่ background: linear-gradient(...) ตรง ๆ
   เพราะ JS วาดลายประจำตัวลง background-image แบบ inline ซึ่งชนะทุกกฎ
   ⇒ ถ้าสีพื้นมาจาก shorthand background ลายจะทับไล่สีจนหายเกลี้ยง
   ตอนนี้: ลายอยู่ชั้นบน · ไล่สีอยู่ชั้นล่าง · ทั้งคู่อยู่ใน background-image
   ของ .av เอง JS จึงแค่ตั้งค่าตัวแปร --av-pat ไม่ต้องไปแตะ background */
.av-ember{--av1:#E01F38; --av2:#5A0A14}
.av-cyan{--av1:#5FD0E8; --av2:#17515F}
.av-gold{--av1:#FFC24D; --av2:#6B4A0F}
.av-green{--av1:#7FE07F; --av2:#1E5A2A}
.av-violet{--av1:#B08CFF; --av2:#3A2470}
.av-slate{--av1:#8A8F98; --av2:#33363B}
[class*="av-"]{
  background-image:var(--av-pat,none),
    linear-gradient(140deg,var(--av1,#E01F38),var(--av2,#5A0A14));
  background-size:100% 100%, cover;
  background-repeat:no-repeat, no-repeat}

/* กระเป๋าเงิน */
.walletcard{padding:26px; border-radius:var(--r-lg); border:1px solid var(--line-2);
  background:linear-gradient(150deg,rgba(255,45,70,.12),var(--bg-soft) 62%);
  position:relative; overflow:hidden; margin-bottom:16px}
.walletcard::after{content:""; position:absolute; right:-40px; top:-40px; width:220px;
  height:220px; border-radius:50%; pointer-events:none;
  background:radial-gradient(closest-side,rgba(255,45,70,.20),transparent)}
.walletcard > *{position:relative}
.walletcard .amt{font-family:"Space Grotesk",sans-serif; font-size:clamp(34px,7vw,46px);
  font-weight:700; color:var(--gold); letter-spacing:-.02em; line-height:1.1;
  font-variant-numeric:tabular-nums}
.ledger{display:grid; gap:0}
.lrow{display:grid; grid-template-columns:1fr auto; gap:12px; padding:12px 0;
  border-bottom:1px solid var(--line); font-size:13.5px; align-items:center}
.lrow:last-child{border-bottom:0}
.lrow .s{font-size:11.5px; color:var(--tx3); font-family:"IBM Plex Mono",monospace;
  word-break:break-all}
.lrow .plus{color:var(--ok); font-family:"IBM Plex Mono",monospace; font-weight:600}
.lrow .minus{color:var(--tx2); font-family:"IBM Plex Mono",monospace; font-weight:600}
.topupline{display:grid; gap:2px; padding:10px 0; border-bottom:1px solid var(--line);
  font-size:12.5px}
.topupline:last-child{border-bottom:0}

/* ช่องคูปอง + แถบจ่ายด้วยกระเป๋า */
.couponrow{display:grid; grid-template-columns:1fr auto; gap:10px; align-items:end;
  margin:16px 0 4px}
.couponrow .field{margin:0}
.sumrow.save b{color:var(--ok)}
/* ══════════════════════════ กล่องชำระเงินหน้าใบสั่งซื้อ (รื้อใหม่ 2026-09-02) ══
   ⛔⛤ ปัญหาเดิมที่รื้อทิ้ง
     · ปุ่มแดง 2 ใบบนจอเดียว ("ไปเติมเงิน" กับ "ทักแอดมินในดิสคอร์ด")
       ปุ่มแดงแปลว่า "กดอันนี้" มีสองใบเมื่อไหร่ ความหมายหายทันที
     · เรื่องทักแอดมินพูดซ้ำ 2 ที่ (กล่องเตือน + ปุ่ม)
     · ยอดที่ต้องจ่ายอยู่คนละกล่องกับปุ่มจ่าย ต้องกวาดตาหา
     · เวลาหมดอายุอยู่แถบขวา คนละสายตากับปุ่ม — สำคัญขึ้นมากหลังแก้ B4
       เพราะตอนนี้ใบที่ค้าง "กันสต๊อก" ไว้จริง
   ⚠ กติกาที่ต้องรักษาไว้: **ปุ่มแดงได้ใบเดียวต่อสถานะ**
     (มีเทสคุมใน test_order_pay_ui_2026_09_02.py) */

/* ── หัวกล่อง: ยอดที่ต้องชำระ ── */
.duehead{display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; margin:0;
  padding-bottom:15px; border-bottom:1px solid var(--line); margin-bottom:17px}
.duehead .lab{font-size:13.5px; color:var(--tx3); font-weight:400}
.duehead .amt{margin-left:auto; font-size:29px; font-weight:700;
  color:var(--gold); letter-spacing:-.5px; font-family:"IBM Plex Mono",monospace}

/* ── การ์ดวิธีจ่าย ── */
.method{display:flex; gap:14px; align-items:center; flex-wrap:wrap;
  padding:15px 16px; border-radius:var(--r); border:1px solid var(--line);
  background:var(--glass)}
/* ⚠ สีบอกสถานะ ห้ามใช้สีเดียวสื่อความหมายอย่างเดียว — ข้อความในการ์ดบอกซ้ำเสมอ */
.method.short{border-color:rgba(255,194,77,.3); background:rgba(255,194,77,.05)}
.method.ready{border-color:rgba(127,224,127,.28); background:rgba(127,224,127,.05)}
/* ⛤ ไอคอนต้องเป็น SVG จากชุดเดียวกับทั้งเว็บ ไม่ใช่อีโมจิ
   (อีโมจิให้ระบบปฏิบัติการวาดเอง — คนละสไตล์กับเว็บ และบนวินโดวส์
    👛 ออกมาเป็นก้อนสีชมพูอ่านไม่ออก · เห็นจากภาพหน้าจอตอนตรวจ 2026-09-02)
   ⛔⛤ สัญลักษณ์ใน icons.svg **ไม่ได้ตั้ง fill/stroke ไว้เอง** — ตั้งใจให้
      รับมาจากที่ใช้งาน · โปรแกรมเดสก์ท็อปตั้งไว้ในสไตล์ฐานของมัน แต่หน้าร้าน
      ไม่เคยใช้ชุดนี้เลยไม่มีกฎรองรับ ⇒ ไม่ตั้ง = เส้นกลายเป็นพื้นทึบสีดำ
      (เจอจากภาพหน้าจอ: ไอคอนออกมาเป็นวงกลมทึบ) */
.mic svg, .clock .cic{fill:none; stroke:currentColor; stroke-width:1.8;
  stroke-linecap:round; stroke-linejoin:round}
.method .mic{width:40px; height:40px; flex:none; border-radius:12px; display:grid;
  place-items:center; background:var(--glass-2); border:1px solid var(--line);
  color:var(--tx2)}
.method .mic svg{width:19px; height:19px}
.method .mtxt{min-width:0; flex:1 1 180px}
.method .mtxt b{display:block; font-size:14.5px; font-weight:600}
.method .mtxt span{display:block; font-size:12.5px; color:var(--tx3); margin-top:2px}
.method .btn{margin-left:auto; flex:none}
@media(max-width:560px){ .method .btn{margin-left:0; width:100%} }

.gapline{margin:14px 0 0; font-size:13px; color:var(--tx2); line-height:1.7}
.gapline b{color:var(--gold); font-family:"IBM Plex Mono",monospace}
.gapline.soft{color:var(--tx3)}

/* ── นาฬิกาหมดอายุ ── */
.clock{display:flex; align-items:center; gap:9px; margin:16px 0 0;
  font-size:12.8px; color:var(--tx3); line-height:1.7}
.clock b{color:var(--tx2); font-weight:600; font-family:"IBM Plex Mono",monospace}
.clock .cic{width:15px; height:15px; flex:none}
/* เหลือน้อย = เปลี่ยนทั้งสีและถ้อยคำ (ดู app.js) ไม่ใช่เปลี่ยนสีอย่างเดียว */
.clock.hot{color:var(--ember-lit)}
.clock.hot b{color:var(--ember-lit)}

/* ── ขั้นตอนแบบพับเก็บ ── */
details.how{margin-top:17px; border-top:1px solid var(--line); padding-top:15px}
details.how > summary{cursor:pointer; font-size:13.5px; color:var(--tx2);
  list-style:none; display:flex; align-items:center; gap:8px; font-weight:500;
  min-height:32px}
details.how > summary::-webkit-details-marker{display:none}
details.how > summary::before{content:"▸"; color:var(--tx3); font-size:11px}
details.how[open] > summary::before{content:"▾"}
details.how > summary:focus-visible{outline:2px solid var(--ember-lit);
  outline-offset:3px; border-radius:6px}
details.how .steps-ol{margin-top:12px; font-size:13px; gap:7px}

/* ── แถวท้ายกล่อง: ทางช่วยเหลือ + ยกเลิก ── */
.payfoot{margin-top:17px; padding-top:15px; border-top:1px solid var(--line);
  display:flex; gap:12px; align-items:center; flex-wrap:wrap}
.payfoot p{margin:0; font-size:12.5px; color:var(--tx3); flex:1 1 250px;
  line-height:1.7}
.payfoot .btn{margin-left:auto}

/* ── กล่องข้อความตามสถานะ (แทน .ver ยาว ๆ ที่อ่านไม่ออกว่าดีหรือร้าย) ── */
.msgbox{display:flex; gap:13px; align-items:flex-start; padding:15px 17px;
  border-radius:var(--r); font-size:13.2px; line-height:1.75;
  border:1px solid var(--line); background:var(--glass); color:var(--tx3)}
.msgbox .mic{flex:none; display:grid; place-items:center; width:20px; height:20px;
  margin-top:1px; color:currentColor}
.msgbox .mic svg{width:19px; height:19px}
.msgbox.bad .mic{color:var(--ember-lit)}
.msgbox.good .mic{color:var(--ok)}
.msgbox.info .mic{color:var(--info)}
.msgbox b{color:var(--tx)}
.msgbox.bad{border-color:rgba(255,45,70,.32); background:rgba(255,45,70,.07);
  color:var(--tx2)}
.msgbox.good{border-color:rgba(127,224,127,.26); background:rgba(127,224,127,.05);
  color:var(--tx2)}
.msgbox.info{border-color:rgba(95,208,232,.24); background:rgba(95,208,232,.05);
  color:var(--tx2)}
/* ⛔ ประโยคห้ามพลาด (เช่น "อย่ากดจ่ายซ้ำ") ต้องเด่นกว่าตัวหนาธรรมดา */
.msgbox .no{color:var(--ember-lit); font-weight:700}

/* กรอบทั้งใบเปลี่ยนตามความหมาย — ผู้ใช้เห็นตั้งแต่ยังไม่ทันอ่าน */
.pane.iswarn{border-color:rgba(255,45,70,.3)}
.pane.isgood{border-color:rgba(127,224,127,.24)}

/* ── แถบฟีเจอร์จริงจากตัวโปรแกรม ── */
.featnav{display:flex; flex-wrap:wrap; gap:8px; margin:20px 0 4px}
.featgrid{display:grid; gap:14px; margin-top:18px}
@media(min-width:700px){ .featgrid{grid-template-columns:repeat(2,1fr)} }
@media(min-width:1060px){ .featgrid{grid-template-columns:repeat(4,1fr)} }
.feat{padding:18px; border-radius:var(--r); border:1px solid var(--line);
  background:linear-gradient(165deg,var(--surface),var(--bg-soft)); position:relative;
  transition:transform var(--t-slow) var(--ease), border-color var(--t-slow) var(--ease),
    box-shadow var(--t-slow) var(--ease)}
.feat:hover{transform:translateY(-4px); border-color:var(--line-2);
  box-shadow:var(--shadow-hi)}
.feat .ic{width:40px; height:40px; border-radius:12px; display:grid; place-items:center;
  font-size:20px; background:rgba(255,45,70,.12); border:1px solid var(--line-2);
  margin-bottom:12px}
.feat h3{font-size:15.5px; margin-bottom:6px}
.feat p{font-size:12.5px; color:var(--tx3); line-height:1.75}
.feat .chips2{display:flex; flex-wrap:wrap; gap:6px; margin-top:11px}
.feat .chips2 span{font-size:10.5px; padding:4px 9px; border-radius:999px;
  border:1px solid var(--line); color:var(--tx3); font-family:"IBM Plex Mono",monospace}
/* เข้าเวทีทีละใบตอนสลับหมวด — สั้นและไม่ขวางการอ่าน */
/* ⚠ .pop เป็นของกลาง — ใช้กับอะไรก็ได้ที่ JS สร้างทีหลังแล้วอยากให้ไล่โผล่
   เคยผูกไว้กับ .feat อย่างเดียว ⇒ ที่อื่นตั้ง animationDelay ไว้แต่ไม่มีอะไรวิ่ง */
.pop{animation:featpop 320ms var(--ease) both}
@keyframes featpop{from{opacity:0; transform:translateY(10px)} to{opacity:1; transform:none}}
@media (prefers-reduced-motion: reduce){ .pop{animation:none} }

/* ฟอร์มสร้างคูปองในหลังร้าน */
.cpgrid{display:grid; gap:12px; margin-bottom:14px}
@media(min-width:680px){ .cpgrid{grid-template-columns:repeat(2,1fr)} }
@media(min-width:1000px){ .cpgrid{grid-template-columns:repeat(4,1fr)} }
select.input{appearance:none; -webkit-appearance:none; cursor:pointer}

/* ── หัวเว็บ: ของเยอะขึ้นแล้ว (เมนู + ปุ่มชุมชน + Discord + กระดิ่ง + ชิปบัญชี) ──
   ⛔⛤ เดิมจุดตัดตั้งไว้ตอนยังมีของน้อย พอเพิ่มปุ่มแล้วคำในเมนูตัดบรรทัดกลางหัวเว็บ
      แก้สองอย่าง: ห้ามคำในเมนูตัดบรรทัดเด็ดขาด และเลื่อนจุดตัดให้กว้างขึ้น
      ของที่ถูกซ่อนยังกดถึงได้จากแถบล่าง ฮีโร่ ท้ายเว็บ และเมนูบัญชี */
header.top nav a{white-space:nowrap}
/* ⛤ 2026-09-13 · จุดตัดเดิม 1180 ตั้งไว้ตอนปุ่มชุมชน/Discord ยังเป็นปุ่มยาว
   พอเหลือแต่ไอคอนแล้ว แถวเมนูลงมาได้ถึง ~1150 โดยไม่เบียด
   (วัดจริงที่ 1181: เหลือที่ว่าง 37px) ⇒ ต่ำกว่านั้นค่อยพับเป็นปุ่มสามขีด */
@media(max-width:1149px){ header.top nav{display:none} }
/* ⛔⛤ ปุ่มบนหัวห้ามตัดบรรทัด — flex บีบให้เล็กลงได้ก่อนที่จะซ่อนตัวไหน
   ⇒ "เลือกแพ็กเกจ" เคยตกเป็น 2 บรรทัดที่ 1280px (ปุ่มหลักดูพัง)
   แถวเมนูเป็นชิ้นเดียวที่ยอมให้ยืดหดได้ ที่เหลือคงขนาดจริงเสมอ */
header.top .btn, header.top .brand, header.top .acctwrap{
  flex:0 0 auto; white-space:nowrap}
/* ⛔⛤ 2026-09-13 (เจ้าของแจ้ง: "ตัวหนังสือซ้อนกัน ตรงมุมบนเป็นหนัก")
   เดิมตั้งใจให้แถวเมนูเป็นชิ้นที่ "ยืดหดได้" (min-width:0) เพื่อให้ทุกอย่าง
   อยู่ในแถวเดียว · แต่ลิงก์ในเมนูเป็น white-space:nowrap ⇒ พอกล่องเมนูถูกบีบ
   ต่ำกว่าเนื้อหา **ตัวอักษรล้นออกนอกกล่องโดยที่กล่องไม่รู้ตัว**
   ⇒ คำในเมนูไปทับปุ่มชุมชน/Discord ตั้งแต่ราว 1181-1460px (จอโน้ตบุ๊กส่วนใหญ่)
   ⇒ **ห้ามให้อะไรในแถบหัวเว็บหดต่ำกว่าเนื้อหาเด็ดขาด** · ที่ว่างไม่พอเมื่อไหร่
     ให้ "ซ่อนของที่มีทางอื่นเข้าถึงได้" แทน ไม่ใช่บีบให้เล็กลง
   ลำดับความสำคัญของร้าน: แบรนด์ > เมนู > ปุ่มเลือกแพ็กเกจ > ชิปบัญชี >
     ไอคอน > ปุ่มชุมชน/Discord (สองอันหลังมีอยู่ในฮีโร่ · ท้ายเว็บ · หน้าช่วยเหลือ) */
header.top nav{flex:0 0 auto; min-width:auto}
/* ⛔ ปุ่มไอคอนก็ห้ามหด — เดิมไม่อยู่ในรายการข้างบน ⇒ ถูกบีบเหลือ 24px
   (ต่ำกว่าเกณฑ์เป้าแตะ 44px และเป็นตัวที่ทำให้แถวดู "เบียด") */
header.top .iconbtn{flex:0 0 auto}
/* ⛔⛤ แถบหัวเว็บถูกคุมความกว้างไว้ที่ 1280 เหมือนย่อหน้าเนื้อความ
   ทั้งที่มันเป็น "แถบเครื่องมือ" ไม่ใช่ตัวอักษรที่ต้องคุมความยาวบรรทัด
   ⇒ จอ 1340-1499 มีที่ว่างข้าง ๆ อีกข้างละ ~110px แต่ของในแถบกลับเบียดกันเอง
     (นี่คือสาเหตุที่จอโน้ตบุ๊กเจอหนักสุด) ⇒ ให้กว้างได้ตั้งแต่ต้น */
/* ⚠ ต้องอยู่ในมีเดีย ไม่งั้นไปทับกฎจอ ≥1800 ที่ตั้งไว้ 1680 (กฎท้ายไฟล์ชนะ) */
@media(max-width:1799px){ header.top > .wrap{max-width:var(--maxw-wide)} }
/* ระยะห่างหดตามจอ — ได้คืนมาเกือบ 100px ที่จอ 1280 โดยไม่ต้องซ่อนอะไรเพิ่ม */
header.top .wrap{gap:clamp(14px,1.5vw,28px)}
header.top nav{gap:clamp(15px,1.5vw,26px)}
/* ⛔⛤ ปุ่มชุมชน/Discord บนหัวเว็บ **เหลือแต่ไอคอนเสมอ** ทุกความกว้าง
   เหตุผล: สองปุ่มนี้กินรวมกัน ~282px และเป็นตัวที่ทำให้แถวแตกทุกรอบ ·
   ไอคอนไลน์กับดิสคอร์ดเป็นสัญลักษณ์ที่คนจำได้อยู่แล้ว · และทั้งสองปุ่มมีแบบ
   เต็มคำอยู่ในฮีโร่ · ท้ายเว็บ · หน้าช่วยเหลือ ⇒ ไม่มีใครหาไม่เจอ
   ⚠ ต้องซ่อนแบบ "มองไม่เห็นแต่ยังอ่านออก" ไม่ใช่ display:none —
     display:none ทำให้ปุ่มไม่เหลือชื่อให้โปรแกรมอ่านหน้าจอเลย (มีแต่ไอคอน) */
header.top .j-line .hidesm,
header.top .j-discord .hidesm{position:absolute; width:1px; height:1px;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap}
@media(max-width:1340px){ header.top .j-line{display:none} }
@media(max-width:1260px){ header.top .j-discord{display:none} }
@media(max-width:860px){ header.top .topcta{display:none} }

/* ── กล่องซ้อนหน้า (แทน prompt/alert ของเบราว์เซอร์) ── */
/* ⛔⛤ ชั้นซ้อนเดิม 90 อยู่ "ใต้" แถบล่าง(100) ป้ายซื้อล่าสุด(105) และข้อความเด้ง(110)
   ⇒ บนมือถือกล่องถูกของพวกนี้ทับ · ต้องสูงกว่าทุกอันยกเว้นแถบโหลด(120)
   ⚠ ตัวกล่องยังต้องเป็นลูกของ body ด้วย ไม่งั้นชั้นซ้อนถูกขังอยู่ใน .wrap */
.modalwrap{position:fixed; inset:0; z-index:115; display:grid; place-items:center;
  padding:20px; background:rgba(4,4,6,.72); backdrop-filter:blur(6px);
  animation:mfade 180ms var(--ease)}
@keyframes mfade{from{opacity:0} to{opacity:1}}
.modalcard{width:min(460px,100%); max-height:88vh; overflow-y:auto;
  border-radius:var(--r-lg); border:1px solid var(--line-2);
  background:linear-gradient(165deg,var(--surface),var(--bg-soft));
  box-shadow:var(--shadow-hi); animation:mrise 220ms var(--ease)}
@keyframes mrise{from{opacity:0; transform:translateY(14px) scale(.98)} to{opacity:1}}
.modalhead{display:flex; align-items:center; gap:12px; padding:18px 20px;
  border-bottom:1px solid var(--line)}
.modalhead h2{font-size:18px; margin:0}
.modalhead .iconbtn{margin-left:auto}
.iconbtn.sm{width:36px; height:36px}
.modalbody{padding:20px}
/* ⛔⛤ พบ 2026-08-31 ตอนไล่เก็บรายละเอียด: กล่องยืนยัน 16 กล่องทั่วเว็บ
   เขียนข้อความหลายบรรทัดด้วย 
 (เช่น "ยอดจะเปลี่ยนจาก X เป็น Y" ขึ้นบรรทัดใหม่)
   แต่ HTML ยุบขึ้นบรรทัดใหม่เป็นเว้นวรรคเสมอ ⇒ ทุกกล่องออกมาเป็นพืดเดียวยาวเหยียด
   ⚠ ไม่มีเทสไหนจับได้ เพราะตัวหนังสือ "อยู่ครบ" ทุกตัว แค่อ่านไม่รู้เรื่อง
   ⇒ pre-line = เคารพการขึ้นบรรทัด แต่ยังตัดคำตามความกว้างปกติ
      (pre ธรรมดาจะทำให้ข้อความยาวล้นขอบกล่อง) */
.modalbody > .ver{white-space:pre-line; line-height:1.75; margin-bottom:14px}

/* ══ กล่องเลือกแพ็ก "ต่ออายุคีย์ใบนี้" (2026-09-13) ══
   ⛔⛤ แถบล็อกฝั่งต้องอยู่บนสุดของกล่องเสมอ — ลูกค้าต้องเห็นก่อนเลือกว่า
      เวลาที่ซื้อรอบนี้จะเข้าคีย์ใบไหนและฝั่งไหน (บักเงิน 2026-09-03) */
.lockbar{display:flex; flex-direction:column; gap:3px; margin-bottom:14px;
  padding:12px 14px; border-radius:12px; border:1px solid var(--line-2);
  background:rgba(255,45,70,.06); font-size:13px; line-height:1.6}
.lockbar b{font-size:13.5px}
.lockbar span{color:var(--tx3); font-size:12.5px}
.pickgrid{display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:9px; margin-bottom:14px}
.pickitem{display:flex; flex-direction:column; gap:3px; text-align:left;
  cursor:pointer; padding:12px 13px; border-radius:12px; color:var(--tx);
  border:1px solid var(--line); background:rgba(255,255,255,.035);
  transition:border-color .16s var(--ease), background .16s var(--ease)}
.pickitem:hover{border-color:var(--line-2); background:rgba(255,255,255,.06)}
.pickitem b{font-size:14.5px; font-weight:600}
.pickitem .price{font-family:"IBM Plex Mono",monospace; font-size:15px; color:var(--gold)}
.pickitem small{font-size:11.5px; color:var(--tx3)}
.amtpick{display:flex; flex-wrap:wrap; gap:8px; margin:14px 0}
.amtpick button{padding:9px 15px; min-height:44px; border-radius:999px;
  border:1px solid var(--line); background:var(--glass); color:var(--tx2);
  cursor:pointer; font:inherit; font-size:13.5px;
  font-family:"IBM Plex Mono",monospace}
.amtpick button:hover{border-color:var(--line-2); color:var(--tx)}
.amtpick button[aria-pressed="true"]{border-color:var(--ember); color:var(--tx);
  background:rgba(255,45,70,.10)}
@media (prefers-reduced-motion: reduce){
  .modalwrap,.modalcard{animation:none}
}

/* ── ชิปบัญชีมุมขวาบน: บอกให้รู้ว่ากดได้ ── */
.chipacct{cursor:pointer; transition:border-color var(--t) var(--ease),
  background var(--t) var(--ease), transform var(--t) var(--ease)}
.chipacct:hover{border-color:var(--line-2); background:var(--glass-2);
  transform:translateY(-1px)}
.chipacct .caret{color:var(--tx3); transition:transform var(--t) var(--ease)}
.chipacct[aria-expanded="true"]{border-color:var(--line-2); background:var(--glass-2)}
.chipacct[aria-expanded="true"] .caret{transform:rotate(180deg)}
.chipacct .av{box-shadow:0 0 0 1px var(--line)}

/* ── คีย์ที่ซ่อนไว้ ── */
.hkrow{display:flex; align-items:center; gap:10px; padding:10px 0;
  border-bottom:1px solid var(--line); font-size:12.5px}
.hkrow:last-child{border-bottom:0}
.hkrow .m{font-family:"IBM Plex Mono",monospace; color:var(--tx3);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.hkrow button{margin-left:auto; flex:none}

/* ── QR พร้อมเพย์ในกล่องเติมเงิน ── */
.qrbox{display:grid; justify-items:center; gap:10px; margin:16px 0 4px;
  padding:16px; border-radius:var(--r); border:1px solid var(--line);
  background:rgba(255,255,255,.03)}
.qrimg{width:min(220px,60vw); height:auto; border-radius:10px; display:block;
  background:#fff; padding:6px}
.qrbox .hint{text-align:center; margin:0}

/* ── ตัวเลขเงิน: อ่านง่ายและเรียงหลักตรงกันทุกที่ ──
   ⛤ ใช้ตัวเลขความกว้างเท่ากัน (tabular) + ไม่ให้ตัดบรรทัดกลางจำนวน
   ⚠ Space Grotesk ไม่มีเลขไทยและช่องไฟ ฿ แคบ ⇒ ระบุ ฿ ให้ห่างขึ้นเล็กน้อย */
.price,.amt,.sumrow b,.lrow .plus,.lrow .minus,.walletcard .amt{
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1;
  white-space:nowrap; letter-spacing:.01em}
.walletcard .amt{font-family:"Space Grotesk","IBM Plex Mono",monospace;
  font-weight:700; letter-spacing:-.015em; text-shadow:0 2px 18px rgba(255,194,77,.22)}
.acctmenu .bal{font-variant-numeric:tabular-nums; letter-spacing:.02em}

/* ── การ์ดสินค้าเล็กลง (เจ้าของสั่ง 2026-08-31: ของเดิมใหญ่เกินไป) ──
   ⛤ ตัวการคือภาพปกสัดส่วน 1:1 ซึ่งบนจอกว้างสูงเท่าความกว้างการ์ด (~570px)
     ลดเป็น 16:10 แล้วให้เรียง 3 ใบบนจอกว้าง ⇒ เห็นสินค้าได้มากขึ้นในหน้าจอเดียว
   ⚠ ไม่แตะ .art ของหน้ารายละเอียดสินค้า (.pdart) ซึ่งต้องการภาพใหญ่ */
#catalog .art{aspect-ratio:16/10}
#catalog .art svg{width:74%; height:74%; margin:auto}
/* ⛔⛤ 2026-09-13 · เดิมบังคับ 3 คอลัมน์ที่ ≥1000 และ 4 คอลัมน์ที่ ≥1400
   ⇒ ร้านที่มีสินค้าแค่ 2 ชิ้น (ตอนนี้จริง ๆ ก็มีเท่านี้) ได้การ์ดเล็กสองใบ
     กองอยู่มุมซ้าย เหลือพื้นดำว่างครึ่งจอ — เจ้าของเห็นแล้วบอกว่าเหมือนของหมด
   ⇒ auto-fit ยุบช่องที่ไม่มีการ์ดทิ้งเอง ⇒ มีกี่ใบก็เต็มความกว้างเสมอ
     (2 ใบ = ใหญ่เต็มครึ่งจอ · 8 ใบ = 4 คอลัมน์เหมือนเดิม) */
@media(min-width:1000px){
  #catalog.grid.two{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
}
#catalog .ctitle{font-size:17px}
#catalog .cdesc{font-size:12.5px; line-height:1.65}
#catalog .card{padding:10px}

/* ── หน้าไม่เจอ (404) ── */
.nfhead{padding-top:64px}
.nfacts{margin-top:26px; flex-wrap:wrap}
.nfgrid{display:grid; gap:14px}
@media(min-width:720px){ .nfgrid{grid-template-columns:repeat(2,1fr)} }
.nfcard{text-decoration:none; display:block}
.nfcard h2{margin:0 0 6px}
.nfcard .ver{margin:0}

/* ══════════════ หัวเว็บบนจอ 375 ล้นออกขวา (วัดจริง 2026-08-31) ══
   ⛔⛤ ระยะห่าง 28px ระหว่างของในหัวเว็บถูกออกแบบไว้สำหรับจอกว้าง
      พอเหลือแค่ แบรนด์ + กระดิ่ง + ชิปบัญชี บนจอ 375 ยังรวมกันได้ 370px
      ในกล่องที่กว้าง 335 ⇒ ชิปบัญชีล้นออกไป 15px ทั้งหน้าเลื่อนซ้ายขวาได้
      (เมนูล่างพลอยกว้าง 391 ตามไปด้วย เพราะหน้าเลื่อนได้แล้ว)
   ⚠ ชื่อผู้ใช้ยาวได้ถึง 20 ตัว ⇒ ต้องตัดด้วยจุดไข่ปลา ไม่ใช่ตั้งความกว้างตายตัว
   ⚠ กระดิ่งกว้างแค่ 14px = เป้าแตะเล็กเกินเกณฑ์ ทั้งที่สูงพอ */
@media(max-width:760px){
  header.top .wrap{gap:12px; padding-left:16px; padding-right:16px}
  header.top .brand{flex:none}
  header.top .iconbtn{min-width:44px; min-height:44px}
  .acctwrap{min-width:0; flex:1 1 auto; justify-content:flex-end}
  .chipacct{min-width:0; max-width:100%}
  .chipacct b{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
              min-width:0}
  .bottomnav{max-width:100vw; overflow:hidden}
}

/* ══ แถบหัวเว็บจอแคบ (2026-09-13) ══
   ⛔⛤ บล็อกนี้ **ต้องอยู่หลัง** บล็อก max-width:760px ข้างบนเสมอ
      กฎข้างบนตั้ง `header.top .brand{flex:none}` และ `gap:12px` ไว้
      ซึ่งเจาะจงเท่ากันเป๊ะ ⇒ ตัวที่อยู่ท้ายไฟล์กว่าเป็นฝ่ายชนะ
      เคยเขียนไว้ที่บล็อก max-width:479px (บรรทัด ~586) แล้วไม่มีผลเลย
      ⇒ จอ 320px แถบหัวล้นออกไป 32px ทุกหน้าเมื่อล็อกอินอยู่
   ⚠ ห้ามย่อปุ่มกลมให้เล็กกว่า 44px — ย่อ "ชื่อร้าน" กับ "ระยะห่าง" แทน */
@media(max-width:479px){
  header.top .wrap{gap:7px; padding-left:11px; padding-right:11px}
  header.top .brand{flex:0 1 auto; min-width:0; gap:7px; white-space:nowrap}
  header.top .brand .bnm{min-width:0; flex:0 1 auto}
}
@media(max-width:359px){
  /* จอเล็กสุดที่ยังต้องใช้งานได้ — ชื่อร้านยอมให้หายไปเหลือแต่โลโก้
     ⚠ ลิงก์ยังมีข้อความอยู่ในโค้ด โปรแกรมอ่านหน้าจอจึงยังอ่านชื่อร้านได้
     ⛔ เหลือแต่โลโก้แล้วลิงก์กว้างแค่ 33px ⇒ ต่ำกว่าเป้าแตะขั้นต่ำ
        ต้องบังคับกว้าง 44px คืน ไม่งั้นแก้บั๊กหนึ่งไปสร้างอีกบั๊กหนึ่ง */
  header.top .brand .bnm{width:0; opacity:0}
  header.top .brand{min-width:44px; justify-content:center; gap:0}
}

/* ══════════════ เป้าแตะบนมือถือ (วัดในเบราว์เซอร์จริง 2026-08-31) ══
   ⛔ วัดจากจอ 375px แล้วพบว่าตัวกรอง/ช่องค้นหา/ปุ่มปิดแถบข่าวยังต่ำกว่า 44px
      นิ้วโป้งพลาดง่ายและกดโดนของข้าง ๆ · บนจอกว้างขนาดเดิมสวยกว่าจึงแยกกฎ
   ⚠ ปุ่มปิดแถบข่าวเดิม 25px = เล็กกว่าครึ่งหนึ่งของเกณฑ์ */
@media(max-width:760px){

  /* ⚠ ลิงก์ตัวหนังสือที่ "ทำหน้าที่เป็นปุ่ม" ก็ต้องแตะได้จริง
     (ลืมรหัสผ่าน / สมัครสมาชิก — วัดได้ 66x34 บนจอ 320) */
}

/* ══════════════ เป้าแตะสำหรับ "จอที่ใช้นิ้ว" ══
   ⛔⛤ เดิมกฎพวกนี้อยู่ในบล็อก 760px ⇒ **แท็บเล็ตแนวตั้ง (768px) หลุดหมด**
      ทั้งที่เป็นจอสัมผัสเต็มตัว · วัดด้วยตัวกวาดอัตโนมัติแล้วเจอ 8 จุดที่ 768
   ⚠ แยกจากบล็อกจัดวางโดยตั้งใจ — กฎจัดวาง (ซ่อนเมนู ฯลฯ) ใช้เกณฑ์คนละตัว
     กับกฎ "นิ้วต้องกดโดน" จึงต้องไม่ผูกอยู่ในบล็อกเดียวกัน */
@media(max-width:900px){
  /* ⛔⛤ สามอันนี้เคยอยู่ในบล็อก 760 ⇒ แท็บเล็ต 768 หลุด
     ⚠⚠ เครื่องทดสอบในเครื่อง **ซ่อนแถบข่าวไว้** (ไม่มีประวัติซื้อในฐานชั่วคราว)
        ตัวกวาดจึงไม่เห็นปุ่มปิด 25px เลยผ่านหมด — ไปเจอตอนกวาดเครื่องจริง
        ⇒ บทเรียน: กล่องทรายที่ข้อมูลไม่ครบ ซ่อนบั๊กได้ ต้องกวาดของจริงด้วย */
  .ticker .tx{min-width:44px; min-height:44px; padding:0;
              display:inline-grid; place-items:center}
  header.top .brand{min-height:44px; display:inline-flex; align-items:center}
  /* ⛤ 2026-09-13: เดิมเขียน `padding:6px 0` (ตัวย่อ) ซึ่ง **ล้าง padding
     แนวนอนที่ตั้งไว้ในบล็อกก่อนหน้าทิ้ง** ⇒ พื้นที่กดกว้างแค่ 30px สำหรับคำสั้น
     ⚠ กฎนี้อยู่ท้ายไฟล์กว่า จึงเป็นฝ่ายชนะเสมอ — ต้องเขียนแยกแกนให้ครบที่นี่
       (เจอตอนกวาดจอมือถือ 2026-09-13 · รูปแบบเดียวกับ .pdhead และ gap หัวเว็บ) */
  .crumb a{display:inline-block; padding-block:6px; padding-inline:8px;
    margin-inline:-8px}
  .chip{min-height:44px}
  .search .input{min-height:44px}
  .authbox a, .authbox .linky, .field + a, .formfoot a{display:inline-flex;
    align-items:center; min-height:44px}
  /* ⚠ ลิงก์ท้ายเว็บสูงแค่ 18px — กดพลาดไปโดนบรรทัดข้างเคียงตลอด
     (ยอมให้แถวห่างขึ้นบนจอสัมผัส ส่วนจอกว้างคงความกระชับไว้เหมือนเดิม) */
  .fgrid ul{gap:2px}
  .fgrid ul a{display:flex; align-items:center; min-height:44px}
  /* ⚠ ปุ่มลืมตาดูรหัสผ่านซ่อนอยู่ในช่องกรอก เดิม 36px — ขยายเป็น 44
     แล้วขยับช่องว่างขวาของช่องกรอกตามเพื่อไม่ให้ตัวอักษรวิ่งไปทับปุ่ม */
  .pw button{width:44px; height:44px; right:4px}
  .pw .input{padding-right:56px}
}

/* ── ปุ่มบนใบขอเติมเงิน ── */
.tuacts{margin-top:10px; gap:8px; flex-wrap:wrap}
.tuacts .btn{flex:1 1 auto; min-width:120px}
.topupline + .topupline{margin-top:14px; padding-top:14px;
  border-top:1px solid var(--line)}

/* ── ตัวเลขบนกระดิ่ง ──
   ⚠ ต้องอ่านออกแม้เลขสองหลัก และห้ามดันปุ่มให้ขยับ (ลอยทับมุมขวาบน) */
.bellnum{position:absolute; top:2px; right:2px; min-width:17px; height:17px;
  padding:0 4px; border-radius:999px; background:var(--ember); color:#fff;
  font-size:10.5px; font-weight:700; line-height:17px; text-align:center;
  font-variant-numeric:tabular-nums; pointer-events:none;
  box-shadow:0 0 0 2px var(--bg)}
/* css-dupe-ok: ค่าเดียวกับกฎหลักของ .iconbtn — ประกาศซ้ำตรงนี้เพื่อให้
   เห็นชัดว่า .bellnum ข้างบนต้องมีตัวยึดตำแหน่ง ไม่ได้เปลี่ยนพฤติกรรมอะไร */
.iconbtn{position:relative}

/* ── ป้ายใต้ภาพจำลองหน้าจอโปรแกรม ──
   ⛔ ต้องอ่านออกจริง ไม่ใช่ซ่อนจนไม่มีใครเห็น — เป็นคำชี้แจงว่าไม่ใช่ภาพจริง */
.shotwrap{margin:0; display:grid; gap:10px}
/* ⛔⛤ 38ch แคบเกินไปสำหรับข้อความไทย 2-3 บรรทัด — ใต้หน้าต่างโปรแกรม
   กว้าง 1,100px แต่คำบรรยายถูกบีบเป็นเสาแคบกลางจอ ตัดบรรทัดกลางคำ
   ดูเหมือนหน้าเว็บพัง (เจ้าของแจ้งจากคลิป 2026-09-01)
   ⚠ แต่กว้างเกินก็อ่านยาก — 62ch คือช่วงที่อ่านสบายสำหรับข้อความยาว
   ⚠ ห้ามใช้ % หรือ vw: บนจอแคบจะกว้างกว่ากล่องแม่ ⇒ ใช้ ch คู่กับ 100% */
.shotcap{font-size:12px; line-height:1.7; color:var(--tx3); text-align:center;
  max-width:min(62ch, 100%); margin:0 auto}
/* ขั้นตอนซื้อ 4 ขั้น — จอกว้างเรียงสี่ จอกลางเรียงสอง */
@media(min-width:640px){ .steps3.four{grid-template-columns:repeat(2,1fr)} }
@media(min-width:1080px){ .steps3.four{grid-template-columns:repeat(4,1fr)} }
.steps3 .slink{display:inline-block; margin-top:10px; font-size:13px;
  color:var(--ember-lit); text-decoration:none; font-weight:600}
.steps3 .slink:hover{text-decoration:underline}

/* ── บรรทัดเตือน "รอแอดมินส่งมอบ" ในหน้าคำสั่งซื้อ ── */
.warnline{margin-top:10px; padding:12px 14px; border-radius:var(--r-sm);
  border:1px solid rgba(255,194,77,.28); background:rgba(255,194,77,.07);
  color:var(--tx2)}

/* ══════════════ หน้าต่างโปรแกรม (ภาพจำลอง) ══
   ⛔ วาดด้วย CSS ล้วน ไม่มีภาพจากตัวเกม ไม่มีไฟล์ให้โหลดเพิ่มสักไฟล์
   ⚠ ห้ามใส่แอนิเมชันวนไม่จบ — หน้าแรกเปิดค้างไว้ทั้งวัน จะกินซีพียูเครื่องลูกค้า
     (จุดสถานะใช้แค่ไล่สีนิ่ง ๆ ไม่กะพริบ) */
.shottabs{display:flex; gap:6px; padding:9px 14px; overflow-x:auto;
  border-bottom:1px solid var(--line); background:rgba(255,255,255,.015);
  scrollbar-width:none}
.shottabs::-webkit-scrollbar{display:none}
.shottabs span{flex:none; font-size:11.5px; padding:5px 11px; border-radius:999px;
  border:1px solid var(--line); color:var(--tx3); white-space:nowrap}
.shottabs span.on{color:var(--tx); border-color:rgba(255,45,70,.4);
  background:rgba(255,45,70,.1)}
.shottabs span.more{border-color:transparent; color:var(--tx3); opacity:.75}

.shotgrid{display:grid; grid-template-columns:repeat(3,1fr); gap:10px}
.scell{padding:11px 12px; border-radius:var(--r-sm); border:1px solid var(--line);
  background:var(--glass); display:grid; gap:2px; min-width:0}
.scell .k{font-size:10.5px; color:var(--tx3); letter-spacing:.02em}
.scell .v{font-size:19px; font-weight:700; font-variant-numeric:tabular-nums;
  font-family:"IBM Plex Mono",monospace; line-height:1.15}
.scell .u{font-size:10px; color:var(--tx3); opacity:.85;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}

.shotlog{display:grid; gap:6px; padding:11px 12px; border-radius:var(--r-sm);
  border:1px solid var(--line); background:rgba(0,0,0,.28)}
.shotlog .lg{display:grid; grid-template-columns:auto 1fr; gap:9px;
  align-items:baseline; font-size:11.5px; min-width:0}
.shotlog .t{font-family:"IBM Plex Mono",monospace; color:var(--tx3); font-size:10.5px}
.shotlog .d{color:var(--tx2); overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap}
.shotlog .d.ok{color:var(--ok)}
.shotlog .d.warn{color:var(--warn)}

.shotfoot{display:flex; flex-wrap:wrap; gap:6px}
.chipx{font-size:11px; padding:4px 9px; border-radius:999px;
  border:1px solid var(--line); color:var(--tx2); background:var(--glass)}
.chipx.more{color:var(--tx3); border-style:dashed}

/* จุดสถานะ "กำลังทำงาน" — จุดนิ่ง ไม่ใช่ไฟกะพริบ */
.tag.dotlive::before{content:""; width:6px; height:6px; border-radius:99px;
  background:var(--ok); display:inline-block; margin-right:6px;
  box-shadow:0 0 0 3px color-mix(in oklab,var(--ok) 18%, transparent)}

@media(max-width:520px){
  .shotgrid{grid-template-columns:1fr 1fr}
  .scell:last-child{grid-column:1 / -1}
}
/* ⚠ จอ 320 แถบแท็บแน่นมาก — ตัดคำใบ้ท้ายแถวออก เหลือแท็บจอที่จำเป็นจริง */
@media(max-width:380px){ .shottabs span.more{display:none} }

.pill.warn{border-color:rgba(255,194,77,.34); color:var(--warn);
  background:rgba(255,194,77,.08)}



/* ══════════════ แสงขอบจอ ══
   ⛤ จอ 2560 ยังไงก็เหลือขอบ — ขอบนั้นต้อง "ดูตั้งใจ" ไม่ใช่ดำตัน
   ⚠ position:fixed + pointer-events:none + ไม่มีแอนิเมชันวนไม่จบ
     (หน้าแรกเปิดค้างทั้งวัน ของที่วิ่งตลอดกินซีพียูเครื่องลูกค้า) */
@media(min-width:1500px){
  .hero::after{
    content:""; position:absolute; inset:0; pointer-events:none; z-index:0;
    background:
      radial-gradient(48% 70% at 0% 40%, rgba(255,45,70,.07), transparent 70%),
      radial-gradient(48% 70% at 100% 40%, rgba(95,208,232,.05), transparent 70%);
  }
}


/* ══════════════ ช่องล่อกันบอท ══
   ⛔⛤ ห้ามใช้ display:none หรือ visibility:hidden — บอทที่เขียนดี ๆ ข้ามช่อง
      ที่ซ่อนด้วยสองอย่างนั้นได้ · ต้อง "อยู่ในหน้าจริง แต่คนมองไม่เห็น"
   ⚠ คู่กับ tabindex="-1" + aria-hidden ในตัว HTML เพื่อไม่ให้คนที่ใช้คีย์บอร์ด
     หรือโปรแกรมอ่านหน้าจอหลงมากรอก */
.trapfield{position:absolute; left:-9999px; top:auto; width:1px; height:1px;
  overflow:hidden}
.cfbox{margin:14px 0 0; min-height:0}
.cfbox:not([hidden]){min-height:68px}

/* ══════════════ หน้า "ดูโปรแกรม" ══
   ⚠ ภาพจำลองหน้าจอวาดด้วย CSS ล้วน — ไม่มีไฟล์ภาพให้โหลดเพิ่ม
     และไม่มีภาพจากตัวเกม (เลี่ยงเรื่องลิขสิทธิ์)
   ⛔⛤ เคยพลาด: เขียนบล็อกนี้ด้วยชื่อโทเคนที่คิดเอง (--acc --card --fg --dim)
      ทั้งห้าตัวไม่มีใน :root เลย · หน้าเว็บ "ดูเหมือนใช้ได้" เพราะสีตกทอด
      จากพ่อแม่มาบัง แต่ตัวเลขหัวหน้าหายไปทั้งแถว (พื้นไล่สีกลายเป็น none
      บนตัวอักษรโปร่งใส) ⇒ ใช้เฉพาะโทเคนที่มีจริง และมีด่าน
      tools/check_css_tokens.py คอยจับ */
.prog-hero{padding:38px 0 10px; position:relative; overflow:hidden}
.prog-hero::before{content:""; position:absolute; inset:-30% -10% auto -10%;
  height:420px; pointer-events:none;
  background:
    radial-gradient(ellipse 60% 70% at 22% 0%,
      color-mix(in oklab,var(--ember) 18%, transparent), transparent 70%),
    radial-gradient(ellipse 50% 60% at 82% 10%,
      color-mix(in oklab,var(--ember-deep) 34%, transparent), transparent 70%);
  filter:blur(26px); opacity:.6}
/* ⛤ 2026-09-13 · ต้องมีระยะห่างจากเส้นทางด้านบน — ของเดิมป้าย "ภายในโปรแกรม"
   ไปติดบรรทัดเส้นทางจนอ่านเหมือนหลุดบรรทัดเดียวกัน */
.phead{position:relative; max-width:74ch; margin-top:18px}
/* ⚠ ใช้สเกลเดียวกับ .pdinfo h1 — ห้ามตั้งขนาดใหม่รายหน้า
   (ด่าน tools/design_audit.js ยอมให้ H1 มีได้ 4 ขนาดทั้งเว็บ) */
.phead h1{margin:6px 0 10px; font-size:clamp(26px,4vw,40px); line-height:1.15}
.phead .lead{color:var(--tx2); font-size:16px; line-height:1.75; max-width:66ch}

.pstats{display:flex; flex-wrap:wrap; gap:10px; margin:22px 0 4px}
.pstats>div{flex:1 1 150px; min-width:132px; padding:13px 15px;
  border:1px solid var(--line); border-radius:var(--r);
  background:color-mix(in oklab,var(--surface) 78%, transparent)}
.pstats b{display:block; font-size:26px; line-height:1.1;
  font-variant-numeric:tabular-nums;
  background-image:linear-gradient(120deg,var(--tx),var(--ember-lit));
  -webkit-background-clip:text; background-clip:text; color:transparent}
.pstats span{display:block; margin-top:3px; font-size:12.5px; color:var(--tx3)}

/* แถวหมวด — เลื่อนข้างได้บนจอแคบ ไม่ดันหน้าให้ล้น */
.ptabs{display:flex; gap:8px; overflow-x:auto; padding:2px 2px 10px;
  scrollbar-width:thin; -webkit-overflow-scrolling:touch}
.ptab{flex:0 0 auto; display:inline-flex; align-items:center; gap:7px;
  padding:9px 14px; min-height:40px; border-radius:999px; cursor:pointer;
  border:1px solid var(--line); background:var(--surface); color:var(--tx2);
  font:inherit; font-size:13.5px; white-space:nowrap;
  transition:border-color var(--t) var(--ease), color var(--t) var(--ease),
    background var(--t) var(--ease), transform var(--t) var(--ease)}
.ptab .ic{font-size:15px; line-height:1}
.ptab:hover{color:var(--tx);
  border-color:color-mix(in oklab,var(--ember) 42%, var(--line))}
.ptab.on{color:var(--tx); border-color:var(--line-2); transform:translateY(-1px);
  background:linear-gradient(120deg,
    color-mix(in oklab,var(--ember-deep) 46%, var(--surface)),
    var(--surface));
  box-shadow:0 6px 20px -13px var(--ember)}

/* ⛤ 2026-09-02 ถอดแผงภาพจำลองข้างหมวดออกแล้ว (เจ้าของจะทำคลิปสอนแทน)
   ⇒ เหลือกล่องเดียว ต้องกินเต็มความกว้าง ไม่งั้นค้างอยู่ครึ่งซ้ายแล้วขวาโล่ง */
.pgrid{display:grid; grid-template-columns:minmax(0,1fr);
  gap:18px; align-items:start; margin-top:6px}
.pdetail{padding:20px 22px; border-radius:var(--r-lg)}
/* ⛔⛤ 2026-09-13: คลาสนี้เคยชื่อ `.pdhead` ซึ่งชนกับหัวหน้ารายละเอียดสินค้า
   (product.html ใช้ `.pdhead` เป็นกริด 2 คอลัมน์ที่ยุบเป็น 1 คอลัมน์บนมือถือ)
   กฎตัวนี้อยู่ท้ายไฟล์กว่า ⇒ ชนะ ⇒ **หน้าสินค้าบนมือถือถูกบังคับเป็นแถวนอน
   ตลอดเวลา** ตัวหนังสือเลยถูกบีบเหลือ 2-3 คำต่อบรรทัด (เจ้าของส่งภาพมา)
   ⚠ คลาสในไฟล์นี้ใช้ร่วมกันทั้งเว็บ — ชื่อสั้นต้องไม่ซ้ำเด็ดขาด */
.pdehead{display:flex; align-items:center; gap:11px; margin-bottom:8px}
.pdicon{width:38px; height:38px; flex:0 0 38px; border-radius:12px;
  display:grid; place-items:center; font-size:19px;
  border:1px solid var(--line);
  background:color-mix(in oklab,var(--ember-deep) 30%, var(--surface))}
.pdetail h3{margin:0; font-size:19px}
.pdetail .ver{margin:0 0 14px; line-height:1.7}

@media(max-width:900px){
  .pgrid{grid-template-columns:1fr}
  .ptab{min-height:44px; padding:11px 15px}
}

/* ══════════════ หน้ารวมสินค้าแยกกลุ่มตามชนิด ══
   ⚠ ขึ้นหัวข้อเฉพาะตอนมีมากกว่าหนึ่งชนิด (ดู renderCatalog)
     หัวข้อลอยเดี่ยว ๆ เหนือกลุ่มเดียวอ่านแล้วงงกว่าไม่มี */
#catalog.bykind{display:block}
.kindhead{display:flex; align-items:baseline; gap:10px; margin:26px 0 14px;
  font-size:17px}
.kindhead:first-child{margin-top:4px}
.kindnum{font-size:12.5px; font-weight:400; color:var(--tx3)}
.kindgrid{display:grid; gap:18px; grid-template-columns:1fr}
@media(min-width:640px){ .kindgrid{grid-template-columns:repeat(2,1fr)} }
@media(min-width:1000px){ .kindgrid{grid-template-columns:repeat(3,1fr)} }
@media(min-width:1400px){ .kindgrid{grid-template-columns:repeat(4,1fr)} }
.pill.kindpill{border-color:var(--line-2);
  color:var(--ember-lit); background:color-mix(in oklab,var(--ember-deep) 22%,
    transparent)}

/* ── ชุดรูปโปรไฟล์ให้เลือก ──
   ⚠ รูปวาดด้วย currentColor ⇒ สีตัวอักษรต้องขาวเสมอ ไม่งั้นรูปจมพื้น */
.avicons{display:flex; flex-wrap:wrap; gap:9px; margin:14px 0 8px}
.aviconbtn{width:46px; height:46px; border-radius:14px; flex:none;
  display:grid; place-items:center; color:#fff; cursor:pointer;
  border:1px solid var(--line);
  transition:transform var(--t) var(--ease), box-shadow var(--t) var(--ease),
    border-color var(--t) var(--ease)}
.aviconbtn:hover{transform:translateY(-2px)}
.aviconbtn[aria-pressed="true"]{border-color:var(--ember);
  box-shadow:0 0 0 3px color-mix(in oklab,var(--ember) 26%, transparent)}
.avletter{font-size:16px; font-weight:700}
/* ⚠ รูปในวงกลมโปรไฟล์ต้องอยู่กลางพอดี — .av เป็น grid อยู่แล้ว */
.av svg,.avbig svg,.acct .big svg{display:block}
@media(max-width:900px){ .aviconbtn{width:48px; height:48px} }

/* ── หน้าฝากขายกับเรา ──
   ⚠ ขั้นตอนเป็น "ลำดับจริง" (คุย → ตกลง → ขึ้นหน้า → เปิดขาย)
     เลขจึงมีความหมาย ไม่ใช่ของตกแต่ง */
.pnsteps{list-style:none; counter-reset:pn; margin:0; padding:0;
  display:grid; gap:12px}
.pnsteps li{counter-increment:pn; position:relative; padding:16px 18px 16px 60px;
  border:1px solid var(--line); border-radius:var(--r); background:var(--glass)}
.pnsteps li::before{content:counter(pn); position:absolute; left:18px; top:16px;
  width:28px; height:28px; border-radius:9px; display:grid; place-items:center;
  font-size:13px; font-weight:700; color:#fff;
  background:linear-gradient(140deg,var(--ember-btn),var(--ember-deep))}
.pnsteps li b{display:block; font-size:15px; margin-bottom:3px}
.pnsteps li span{font-size:13.5px; color:var(--tx2); line-height:1.7}
@media(min-width:900px){ .pnsteps{grid-template-columns:1fr 1fr} }

/* ══════════════ ชั้นตกแต่งรอบสุดท้าย ══
   ⛤ เจ้าของสั่ง 2026-08-31: "เพิ่มอนิเมะชั่นหรือฟังชั่นลูกเล่นต่าง ๆ"
   ⚠ ทุกอย่างในบล็อกนี้ต้อง "มีประโยชน์" ไม่ใช่ขยับเพื่อขยับ —
     บอกว่ากดได้ · บอกว่ากำลังโหลด · บอกว่าอันไหนสำคัญ
   ⚠ ทุกตัวเคารพ prefers-reduced-motion ผ่านกฎรวมที่บรรทัด 445 อยู่แล้ว
     (`*{animation:none !important; transition:none !important}`) */

/* ── การ์ดยกตัวตอนชี้ — บอกว่ากดได้ ──
   ⚠ ใช้ translate3d ให้ GPU ทำ ไม่บังคับคำนวณ layout ใหม่ */
.card.cat,.glass.feat,.glass.why,.glass.t{
  transition:transform var(--t) var(--ease), border-color var(--t) var(--ease),
    box-shadow var(--t) var(--ease)}
.card.cat:hover{transform:translate3d(0,-4px,0);
  border-color:var(--line-2); box-shadow:var(--shadow-hi)}
.glass.feat:hover,.glass.why:hover{transform:translate3d(0,-2px,0);
  border-color:color-mix(in oklab,var(--ember) 30%, var(--line))}

/* ── ปุ่มหลักมีประกายวิ่งผ่านตอนชี้ ──
   ⚠ ทำเฉพาะปุ่มหลัก ปุ่มธรรมดาไม่ต้อง ไม่งั้นทั้งหน้าวิบวับจนลายตา */
.btn.primary{position:relative; overflow:hidden}
.btn.primary::after{content:""; position:absolute; inset:0;
  background:linear-gradient(105deg,transparent 38%,
    rgba(255,255,255,.22) 50%,transparent 62%);
  transform:translateX(-120%); pointer-events:none}
.btn.primary:hover::after{transform:translateX(120%);
  transition:transform 620ms var(--ease)}

/* ── ตัวเลขสำคัญนับขึ้นตอนโผล่ (JS เป็นคนขยับ) ── */
.countup{font-variant-numeric:tabular-nums}

/* ── แถบความคืบหน้าการอ่านหน้ายาว ──
   ⚠ ขึ้นเฉพาะหน้าที่ยาวจริง (JS ตัดสินจากความสูง) */
.readbar{position:fixed; left:0; top:0; height:2px; z-index:120;
  width:0; pointer-events:none;
  background:linear-gradient(90deg,var(--ember),var(--gold))}

/* ── ปุ่มกลับขึ้นบน ── */
.totop{position:fixed; right:18px; bottom:calc(18px + env(safe-area-inset-bottom));
  width:44px; height:44px; border-radius:50%; z-index:110;
  display:grid; place-items:center; cursor:pointer;
  border:1px solid var(--line); background:var(--surface); color:var(--tx2);
  opacity:0; transform:translateY(10px); pointer-events:none;
  transition:opacity var(--t) var(--ease), transform var(--t) var(--ease)}
.totop.on{opacity:1; transform:none; pointer-events:auto}
.totop:hover{color:var(--tx); border-color:var(--line-2)}
/* ⚠ มือถือมีแถบเมนูล่างอยู่แล้ว ต้องยกขึ้นไม่ให้ทับ */
@media(max-width:900px){ .totop{bottom:calc(76px + env(safe-area-inset-bottom))} }

/* ── ไฮไลต์หัวข้อที่เพิ่งกระโดดมาจากลิงก์ #anchor ── */
:target{scroll-margin-top:88px}
.jumped{animation:jump 1.4s var(--ease)}
@keyframes jump{
  0%{box-shadow:0 0 0 0 color-mix(in oklab,var(--ember) 46%, transparent)}
  100%{box-shadow:0 0 0 14px transparent}}
@media (prefers-reduced-motion: reduce){ .jumped{animation:none} }

/* รูปสินค้าจริง — เต็มกรอบเสมอ ไม่ว่าสัดส่วนไฟล์จะเพี้ยนแค่ไหน
   ⚠ object-fit:cover ครอบให้พอดี · ของสำคัญควรอยู่กลางรูป
     (เว้นขอบว่างรอบตัวหลัก 8% ตามที่บอกเจ้าของไว้) */
.art .artimg,.pdart .artimg{width:100%; height:100%; object-fit:cover;
  display:block; border-radius:inherit}
.pdart .artimg{aspect-ratio:1/1; border-radius:12px}

/* ══════════════ หน้ากระเป๋าเงิน — โครงใหม่ ══
   ⛤ เจ้าของสั่ง 2026-08-31: "ทำหน้าเติมเงินใหม่ทั้งหมด · ตรงซองอั่งเปา
      หายากเกินไป ทำให้อยู่ที่เดียวกัน"
   ⇒ วิธีเติมเงินทุกทางเป็นการ์ดขนาดเท่ากันในแถวเดียว ไม่มีทางไหนถูกซ่อน
     ท้ายคอลัมน์ข้างจนหาไม่เจอ */
.walletcard{display:flex; align-items:center; gap:22px; flex-wrap:wrap;
  margin-bottom:0}
.walletcard .wc-main{flex:1 1 260px; min-width:0}
.walletcard .wc-side{flex:0 0 auto}
.walletcard .ver{margin:6px 0 0}

.paygrid{display:grid; gap:16px; grid-template-columns:1fr}
@media(min-width:820px){ .paygrid{grid-template-columns:1fr 1fr} }
.payway{padding:20px 22px; display:flex; flex-direction:column; gap:14px}
/* ⚠ ทางที่ปิดอยู่ต้องดูจางลง แต่ยังอ่านออก — ซ่อนไปเลยลูกค้าจะไม่รู้ว่ามีทางนี้ */
.payway.off{opacity:.62}
.pw-head{display:flex; align-items:flex-start; gap:12px}
.pw-head > div{flex:1; min-width:0}
.pw-head h3{margin:0; font-size:17px}
.pw-head p{margin:2px 0 0; font-size:12.5px; color:var(--tx3)}
.pw-ic{width:42px; height:42px; flex:none; border-radius:13px; display:grid;
  place-items:center; font-size:20px; border:1px solid var(--line);
  background:color-mix(in oklab,var(--ember-deep) 24%, var(--surface))}
.paysteps{list-style:none; counter-reset:pw; margin:0; padding:0;
  display:grid; gap:9px}
.paysteps li{counter-increment:pw; position:relative; padding-left:30px;
  font-size:13.5px; line-height:1.65; color:var(--tx2)}
.paysteps li::before{content:counter(pw); position:absolute; left:0; top:1px;
  width:20px; height:20px; border-radius:7px; display:grid; place-items:center;
  font-size:11px; font-weight:700; color:var(--tx);
  border:1px solid var(--line-2);
  background:color-mix(in oklab,var(--ember-deep) 30%, transparent)}
.payway .btn.block{margin-top:auto}
.payway .field{margin-top:2px}

.wlgrid{display:grid; gap:16px; grid-template-columns:1fr}
@media(min-width:900px){ .wlgrid{grid-template-columns:1.25fr .75fr} }
.wlgrid .pane h2{font-size:18px; margin:0 0 12px}

/* ⛔⛤ หน้าบูสในตัวอย่างเคยอ้างรูปแม่แบบจากตัวเกม (templates/*.png)
   พาธใช้ไม่ได้บนเว็บ ⇒ รูปไม่ขึ้น กรอบยุบ layout เละ
   และเป็นภาพจากตัวเกมซึ่งห้ามเอาขึ้นเว็บสาธารณะอยู่แล้ว
   ⇒ ตัวสกัดแทนด้วย <span> ว่าง · ตรงนี้ให้ขนาดและผิวคืน layout จะได้ไม่พัง */
.pw .power-game-icon{display:block; width:38px; height:38px; margin:0 auto 6px;
  border-radius:10px; border:1px solid var(--line);
  background:radial-gradient(circle at 50% 35%,
    color-mix(in oklab,var(--ember) 26%, transparent), transparent 70%),
    var(--glass-2)}

.btn.danger{border-color:color-mix(in oklab,var(--bad) 46%, var(--line));
  color:var(--bad)}
.btn.danger:hover{background:color-mix(in oklab,var(--bad) 14%, transparent)}

/* ══ หลังร้าน: แก้สินค้าและรูป ══ */
.adedit{display:grid; gap:8px; margin:12px 0;
  grid-template-columns:1fr}
@media(min-width:820px){
  .adedit{grid-template-columns:1.3fr 1.7fr auto auto; align-items:center}
}
.adedit .input{min-height:40px}
.adimgs{display:grid; gap:12px; grid-template-columns:1fr 1fr; margin:6px 0 12px}
.adimg{border:1px solid var(--line); border-radius:12px; padding:10px;
  display:grid; gap:6px; background:var(--glass); text-align:center}
.adimg b{font-size:12.5px}
.adimg .ver{font-size:11px; margin:0}
/* ⚠ กรอบตัวอย่างต้องสูงคงที่ ไม่งั้นการ์ดกระโดดตอนรูปโหลดเสร็จ */
.adthumb{aspect-ratio:16/10; border-radius:9px; overflow:hidden;
  background:rgba(0,0,0,.35); display:grid; place-items:center}
.adthumb img{width:100%; height:100%; object-fit:cover; display:block}
/* ⛔⛤ 2026-09-13: เคยชื่อ `.pkprice` ซึ่งชนกับราคาในแถวแพ็กหน้าสินค้า
   (จัดชิดเส้นฐาน gap 8) ⇒ กฎตัวนี้อยู่ท้ายกว่าเลยชนะทั้งเว็บ */
.orprice{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
@media(max-width:640px){ .adimgs{grid-template-columns:1fr} }

/* ── ตัวเลือกในเมนู <select> ──
   ⚠ เบราว์เซอร์วาดเมนูนี้เอง แต่งได้จำกัด · color-scheme ข้างบนทำงานหลัก
     ส่วนตรงนี้บังคับสีอีกชั้นสำหรับเบราว์เซอร์ที่ยอมให้แต่ง */
select.input option{background:var(--surface); color:var(--tx)}
select.input option:checked{background:var(--ember-deep)}
/* ลูกศรของ select — appearance:none ทำให้ลูกศรเดิมหาย ต้องวาดเอง */
select.input{padding-right:34px;
  background-image:linear-gradient(45deg,transparent 50%,var(--tx3) 50%),
    linear-gradient(135deg,var(--tx3) 50%,transparent 50%);
  background-position:calc(100% - 18px) calc(50% + 2px),
    calc(100% - 13px) calc(50% + 2px);
  background-size:5px 5px, 5px 5px; background-repeat:no-repeat}

/* ══════════════ หลังร้าน — ฟอร์มและปุ่มลบ ══
   ⛤ เจ้าของสั่ง 2026-08-31: "เพิ่มให้ลบแพ็กเกจหรืออื่น ๆ ได้ด้วย" +
     "เพิ่มสินค้าใหม่ตอนนี้เหมือนจะใช้ไม่ได้จริง" ⇒ ฟอร์มจริงกล่องเดียว */

/* กล่องฟอร์มกว้างกว่ากล่องยืนยันธรรมดา — มีหลายช่องต้องกรอก */
.modalcard.wide{width:min(560px,100%)}

/* แถวเลือกไฟล์รูปในฟอร์ม */
.filepick{display:flex; gap:10px; align-items:center; flex-wrap:wrap;
  margin-top:8px}
.filepick .ver{font-size:13px; color:var(--tx3);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:100%}

/* ⛤ ข้อความผิดพลาดของฟอร์ม — อยู่ในกล่อง ไม่ใช่ toast ที่หายไปใน 3 วิ
   คนจะได้อ่านทันขณะกำลังแก้ช่องที่ผิด */
.formmsg{margin:4px 0 0; padding:10px 12px; border-radius:10px;
  font-size:13.5px; line-height:1.65; color:var(--bad);
  border:1px solid color-mix(in oklab,var(--bad) 40%, var(--line));
  background:color-mix(in oklab,var(--bad) 10%, transparent)}

/* ปุ่มเพิ่ม/ลบ อยู่คนละฝั่ง — กันกดผิดใบ */
.kacts.spread{justify-content:space-between; width:100%}

/* แถวราคาในหลังร้านมีปุ่มมากกว่าฝั่งลูกค้าหนึ่งใบ */
@media(min-width:760px){
  .pkrow.adm{grid-template-columns:1.5fr .75fr auto auto}
  .pkrow.adm .btn{min-width:0; justify-self:end}
}

/* ═══════════════════════════════════════════════════════════════════════
   หลังร้านรุ่นใหม่ (2026-09-11)
   ───────────────────────────────────────────────────────────────────────
   ⛔⛤ ทำไมต้องรื้อ: ของเดิมวางทุกอย่างเป็น "การ์ดใบใหญ่เรียงลงมา" —
      หน้าแรกเป็นการ์ดตัวเลข 8 ใบขนาดเท่ากันเป๊ะ ⇒ ทุกใบสำคัญเท่ากัน
      แปลว่าไม่มีใบไหนสำคัญ · หน้าคำสั่งซื้อ 1 จอเห็นได้ 4 ใบ และของในแต่ละใบ
      อยู่คนละตำแหน่ง ⇒ กวาดตาเทียบข้ามใบไม่ได้เลย
      เจ้าของแจ้งตรง ๆ ว่า "มองดูยากมาก ดูไม่ออกเลย"

   หลักที่ใช้แทน
     1. งานค้างที่ต้องมือมาก่อนตัวเลขสวย ๆ เสมอ
     2. ของที่เป็นรายการ = ตาราง คอลัมน์ตรงกันทุกแถว หัวตารางติดขอบบน
     3. ตัวเลขเงินชิดขวา + ฟอนต์ตัวเลขความกว้างเท่ากัน ⇒ หลักตรงกันทุกแถว
     4. สื่อสถานะด้วย "รูปทรง + คำ" ไม่ใช่สีอย่างเดียว
     5. ชื่อคอลัมน์เขียนเป็นคำที่แอดมินพูดจริง ไม่ใช่ชื่อฟิลด์ในฐาน
   ═══════════════════════════════════════════════════════════════════════ */
:root{
  --adrail:244px;
  --adline:rgba(255,255,255,.075);
  --adsurf:#111119;
  --adsurf-2:#16161F;
  --adhead:#0F0F17;
  --adline-hi:rgba(255,255,255,.16);
}

/* ── โครง ── */
.adminbody{background:var(--bg)}
.adshell{display:grid; grid-template-columns:var(--adrail) minmax(0,1fr);
  min-height:100vh}
.adbody{min-width:0; display:flex; flex-direction:column}

/* ── รางเมนู ── */
.adrail{position:sticky; top:0; height:100vh; overflow:auto; z-index:40;
  background:linear-gradient(180deg,#0B0B12,#08080C);
  border-right:1px solid var(--adline);
  padding:16px 12px 20px; display:flex; flex-direction:column; gap:3px}
.adbrand{display:flex; align-items:center; gap:10px; padding:4px 8px 14px;
  color:var(--tx); text-decoration:none}
.adbrand .mk{border-radius:9px}
.adbrand b{font-size:15px; font-weight:600; display:block; line-height:1.25}
.adbrand small{font-size:10.5px; color:var(--tx3); letter-spacing:.14em;
  text-transform:uppercase; font-family:"IBM Plex Mono",monospace}
.adgrp{font-size:10.5px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--tx3); padding:16px 10px 6px; font-weight:600}
.aditem{display:flex; align-items:center; gap:10px; padding:9px 10px;
  border-radius:10px; color:var(--tx2); font-size:13.5px; text-decoration:none;
  position:relative; transition:background var(--t-fast) var(--ease),
  color var(--t-fast) var(--ease)}
.aditem svg{width:17px; height:17px; flex:none; opacity:.72}
.aditem .lb{min-width:0}
.aditem:hover{background:var(--glass); color:var(--tx)}
/* ⛔ ใช้ aria-current ไม่ใช่ .on — markNav() ติด .on ให้ทุกลิงก์ที่เป็น
   "ต้นทางของที่อยู่ปัจจุบัน" ⇒ /web/admin จะสว่างค้างทุกหน้าย่อย */
.aditem[aria-current="page"]{color:var(--tx); font-weight:600;
  background:linear-gradient(90deg,rgba(255,45,70,.16),rgba(255,45,70,.03))}
.aditem[aria-current="page"] svg{opacity:1; color:var(--ember-lit)}
.aditem[aria-current="page"]::before{content:""; position:absolute; left:-12px;
  top:8px; bottom:8px; width:3px; border-radius:0 3px 3px 0; background:var(--ember)}
.adcnt{margin-left:auto; font-family:"IBM Plex Mono",monospace; font-size:11px;
  font-weight:600; padding:1px 7px; border-radius:999px; background:var(--glass-2);
  color:var(--tx2); font-variant-numeric:tabular-nums}
.adcnt.hot{background:rgba(255,45,70,.2); color:#FFB3BC;
  box-shadow:inset 0 0 0 1px rgba(255,45,70,.36)}
.adfoot{margin-top:auto; padding:14px 10px 0; border-top:1px solid var(--adline);
  display:flex; flex-direction:column; gap:8px; font-size:11.5px; color:var(--tx3)}
.adback{color:var(--tx2); text-decoration:none; font-size:12.5px}
.adback:hover{color:var(--tx)}
.adsync{display:flex; align-items:center; gap:7px}
.livedot{width:7px; height:7px; border-radius:999px; background:var(--ok);
  box-shadow:0 0 0 3px rgba(127,224,127,.16); flex:none}
.livedot.stale{background:var(--warn); box-shadow:0 0 0 3px rgba(224,168,119,.16)}

/* ── แถบบน ── */
/* ⛔ ชื่อคลาสต้องไม่ใช่ .adtop — ชื่อนั้นเป็นหัวการ์ดของหน้าฝั่งลูกค้าอยู่แล้ว
   (มี flex-wrap:wrap ติดมาด้วย) ⇒ ใช้ชื่อของตัวเองจะได้ไม่รับของแถมเงียบ ๆ */
.adtopbar{position:sticky; top:0; z-index:30; display:flex; align-items:center;
  gap:12px; padding:12px 24px; border-bottom:1px solid var(--adline);
  background:rgba(7,7,10,.88); backdrop-filter:blur(14px)}
.adcrumb{font-size:12.5px; color:var(--tx3); display:flex; align-items:center;
  gap:7px; margin:0}
.adcrumb b{color:var(--tx); font-weight:500}
/* ⛔⛤ เส้นทางที่หน้าตาเหมือนกดได้ ต้องกดได้จริง — ของเดิมเป็นข้อความเปล่า
   กดแล้วได้แค่ลากคลุมตัวอักษร (เจ้าของแจ้งเอง 2026-09-13) */
.adcrumb a{color:var(--tx3); text-decoration:none; border-radius:7px;
  padding:3px 6px; margin:-3px -6px;
  transition:color var(--t-fast) var(--ease), background var(--t-fast) var(--ease)}
.adcrumb a:hover{color:var(--tx); background:var(--glass)}
.adstore svg{opacity:.8}
.adsearch svg{opacity:.8}
.adsearch kbd{font-family:"IBM Plex Mono",monospace; font-size:10px; color:var(--tx3);
  border:1px solid var(--adline); border-radius:5px; padding:1px 5px; margin-left:8px;
  background:var(--glass)}
.adkeys{font-family:"IBM Plex Mono",monospace; font-weight:600; color:var(--tx3)}

/* ══ ช่องค้นหาเดียวของหลังร้าน (Ctrl+K) ══
   ⛔ กล่องนี้แขวนที่ <body> เสมอ — เป็นลูกของแผงที่ overflow:hidden เมื่อไหร่
      รายการจะโดนตัดหายทันที (เคยโดนมาแล้วกับเมนูในการ์ดคีย์) */
.palwrap{align-items:flex-start}
.palcard{width:min(620px,100%); margin-top:12vh; max-height:74vh; display:flex;
  flex-direction:column; overflow:hidden}
.palhead{padding:14px 16px; border-bottom:1px solid var(--line)}
.palhead input{width:100%}
.pallist{overflow-y:auto; padding:8px; display:flex; flex-direction:column; gap:2px}
.palrow{display:flex; align-items:center; gap:12px; width:100%; text-align:left;
  background:transparent; border:0; border-radius:10px; padding:9px 11px;
  color:var(--tx2); cursor:pointer; font:inherit}
.palrow .t{min-width:0; display:grid}
.palrow .t b{font-size:13.5px; font-weight:600; color:var(--tx);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.palrow .t span{font-size:11.5px; color:var(--tx3)}
.palrow .k{margin-left:auto; font-size:10.5px; color:var(--tx3); flex:none;
  border:1px solid var(--adline); border-radius:999px; padding:2px 9px}
.palrow.on{background:linear-gradient(90deg,rgba(255,45,70,.16),rgba(255,45,70,.04))}
.palrow.on .t b{color:#fff}
.palfoot{padding:10px 16px; border-top:1px solid var(--line); font-size:11.5px;
  color:var(--tx3)}
.adrailbtn{display:none}
.adrailbg{position:fixed; inset:0; z-index:39; background:rgba(0,0,0,.55)}

/* ── หน้า ── */
.adpage{padding:24px 24px 72px; max-width:1620px; width:100%}
.adhead{display:flex; align-items:flex-end; gap:16px; flex-wrap:wrap;
  margin-bottom:20px}
.adhead h1{font-size:24px; font-weight:600; letter-spacing:-.015em; margin:0}
.adlead{font-size:12.5px; color:var(--tx3); margin:4px 0 0; max-width:76ch}
.adstack{display:grid; gap:16px}
.adcols{display:grid; gap:16px; grid-template-columns:minmax(0,1.5fr) minmax(0,1fr)}
.adcols.even{grid-template-columns:repeat(2,minmax(0,1fr))}
.adcols.start{align-items:start}

/* ── กล่องเนื้อหา ── */
.adpanel{background:var(--adsurf); border:1px solid var(--adline);
  border-radius:14px; overflow:hidden}
.adpanel>header{display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:12px 16px; border-bottom:1px solid var(--adline)}
.adpanel>header h2{font-size:14.5px; font-weight:600; margin:0}
.adwhy{font-size:12px; color:var(--tx3)}
.adnote{font-size:12px; color:var(--tx3); padding:0 16px 14px; margin:0}
/* ══ แท็บแยกกองงานในหลังร้าน (2026-09-13) ══
   ⛔⛤ เจ้าของเปิดหน้าเงินแล้วเห็นใบปนกันจนแยกไม่ออกว่าใบไหนต้องทำอะไร
      ⇒ กองที่เป็น "งานจริง" ต้องเด่นกว่ากองอื่นชัดเจน ไม่ใช่แท็บเท่ากันหมด */
.adtabs{display:flex; gap:8px; flex-wrap:wrap; padding:14px 16px;
  border-bottom:1px solid var(--line)}
.adtab{min-height:34px; padding:0 14px; border-radius:999px; font-size:13.5px;
  border:1px solid transparent; background:transparent; color:var(--tx3);
  cursor:pointer; display:inline-flex; align-items:center;
  transition:color var(--t) var(--ease), background var(--t) var(--ease)}
.adtab:hover{color:var(--tx2)}
.adtab[aria-selected="true"]{color:var(--tx); background:var(--glass);
  border-color:var(--line)}
.adtab .c{font-family:"IBM Plex Mono",monospace; font-size:11.5px; margin-left:7px;
  padding:1px 7px; border-radius:999px; background:rgba(255,255,255,.09)}
.adtab[data-hot="1"] .c{background:var(--ember); color:#fff}
/* ══ การ์ด "งานเดียวของหน้านี้" (2026-09-13 รอบ 2) ══
   ⛔⛤ เจ้าของแจ้งว่าหลังร้านดูแล้วงง ⇒ ทุกหน้าต้องตอบคำถามเดียว
      "ตอนนี้ต้องทำอะไร" · ตัวเลขใหญ่ที่สุดในหน้า = จำนวนงานค้าง
      เป็น 0 ต้องเปลี่ยนเป็นโทนเขียวและบอกว่าว่างแล้ว ไม่ใช่ปล่อยให้ตารางเปล่าตอบแทน */
.adjob{display:flex; align-items:center; gap:18px; flex-wrap:wrap; padding:18px 22px;
  border-radius:var(--r); margin-bottom:14px;
  border:1px solid rgba(63,214,138,.28); background:rgba(63,214,138,.06)}
.adjob.hot{border-color:var(--line-2); background:rgba(255,59,59,.07)}
.adjob .big{font-family:"IBM Plex Mono",monospace; font-size:36px; font-weight:600;
  line-height:1; font-variant-numeric:tabular-nums; color:var(--money)}
.adjob.hot .big{color:var(--vio-lit)}
.adjob .t{min-width:0}
.adjob .t b{display:block; font-size:15.5px; font-weight:600}
.adjob .t span{font-size:13px; color:var(--tx3)}
.adjobmini{display:flex; gap:26px; flex-wrap:wrap; padding:0 4px 16px; margin-bottom:14px;
  border-bottom:1px solid var(--line)}
.adjobmini div{min-width:110px}
.adjobmini b{display:block; font-size:19px; font-weight:600;
  font-variant-numeric:tabular-nums}
.adjobmini span{font-size:11.5px; color:var(--tx3)}
.adjobmini .g b{color:var(--money)} .adjobmini .y b{color:var(--gold)}
.adjobmini .m b{color:var(--tx2)}

/* ══ ลิ้นชักรายละเอียด — ปุ่มที่ย้อนไม่ได้อยู่ในนี้เท่านั้น ══ */
.drawerwrap{place-items:stretch; justify-content:flex-end}
.drawercard{width:min(540px,100%); height:100%; max-height:100%; overflow-y:auto;
  background:var(--surface); border:0; border-left:1px solid var(--line-2);
  border-radius:0; display:flex; flex-direction:column}
.drawercard .modalhead{position:sticky; top:0; background:var(--surface); z-index:2}
.drbox{border:1px solid var(--line); border-radius:12px; padding:14px 16px;
  margin-bottom:14px}
.drbox h3{font-size:13.5px; font-weight:500; color:var(--tx3); margin-bottom:9px}
.drbox.danger{border-color:var(--line-2); background:rgba(255,59,59,.05)}
.drbox.danger h3{color:var(--vio-lit)}
.drbox.danger .adfine{margin-bottom:12px; display:block}
.drkv{display:grid; grid-template-columns:auto 1fr; gap:5px 16px; font-size:13.5px;
  margin:0}
.drkv dt{color:var(--tx3)}
.drkv dd{margin:0; color:var(--tx2); min-width:0; overflow-wrap:anywhere}


/* ══ แถวแพ็กในหน้าสินค้า (2026-09-13 รอบ 3) ══
   ⛔⛤ ของเดิมเป็นตาราง 8 คอลัมน์ ⇒ ต้องกวาดตาข้ามคอลัมน์ถึงจะรู้ว่าแพ็กไหนทำเงิน
      ของใหม่วางแถบสัดส่วนรายได้ไว้กลางแถว เห็นจากหางตาได้เลย */
.adpacks{display:flex; flex-direction:column}
.adpack{display:grid; gap:14px; align-items:center; padding:12px 18px; cursor:pointer;
  border-bottom:1px solid var(--line); grid-template-columns:1fr;
  transition:background .16s var(--ease)}
@media(min-width:820px){
  .adpack{grid-template-columns:minmax(0,1.35fr) 96px minmax(100px,1.1fr) 158px auto}
}
.adpack:last-child{border-bottom:0}
.adpack:hover{background:rgba(255,255,255,.035)}
.adpack.off{opacity:.55}
.adpack .nm{font-size:14.5px; font-weight:500}
.adpack .tg{display:flex; gap:6px; flex-wrap:wrap; margin:4px 0 2px}
.adpack .pc{text-align:right}
.adpack .pc b{display:block; font-family:"IBM Plex Mono",monospace; font-size:15px;
  font-weight:600; color:var(--gold); font-variant-numeric:tabular-nums}
.adpack .pc span{font-size:10.5px; color:var(--tx3)}
.adpack .rv span{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--tx3)}
.adpack .lm{font-size:11.5px; color:var(--tx3); line-height:1.6}
.adpack .lm b{color:var(--tx2); font-weight:500; font-family:"IBM Plex Mono",monospace}
/* แถบสัดส่วนรายได้ — เทียบกับแพ็กที่ทำเงินมากสุดของทั้งร้าน */
/* ⛔⛤ 2026-09-13: เคยชื่อ `.adbar` ซึ่งชนกับแถบกรวยคนเข้าเว็บ (สูง 30px
   ใช้ position:absolute) ที่อยู่ท้ายไฟล์กว่า ⇒ **แถบสัดส่วนรายได้ในหน้าสินค้า
   ถูกวาดเป็นแถบสูง 30px ผิดรูปมาตลอด** โดยไม่มีอะไรฟ้อง ⇒ แยกชื่อออก */
.adrev{height:6px; border-radius:999px; background:rgba(255,255,255,.07);
  overflow:hidden; margin-bottom:5px}
.adrev i{display:block; height:100%; border-radius:999px;
  background:linear-gradient(90deg,rgba(255,59,59,.45),var(--vio))}
.adprodf{padding:11px 18px; display:flex; gap:9px; flex-wrap:wrap; align-items:center;
  background:rgba(0,0,0,.18); border-top:1px solid var(--line)}
.adprodf .t{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--tx3)}

/* ══ บันทึกกิจกรรม — หัววันติดขอบบน + แถวที่อ่านออกจากหางตา ══ */
.addaybar{position:sticky; top:0; z-index:3; display:flex; align-items:center; gap:9px;
  padding:10px 4px 9px; margin-top:6px;
  background:linear-gradient(180deg,var(--bg) 68%,rgba(0,0,0,0));
  font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--tx3)}
.addaybar b{font-family:"Anuphan",sans-serif; font-size:13.5px; font-weight:600;
  color:var(--tx2)}
.addaybar .ln{flex:1; height:1px; background:var(--line)}
.adev{display:grid; grid-template-columns:52px 26px 1fr auto; gap:12px; align-items:center;
  padding:9px 12px 9px 10px; border-radius:10px; cursor:pointer;
  border-left:3px solid transparent; transition:background .14s var(--ease)}
.adev:hover{background:rgba(255,255,255,.04)}
/* ⛤ สิ่งที่ผิดปกติต้องเด่นกว่าของปกติ — เห็นจากหางตาโดยไม่ต้องอ่าน */
.adev.risk{border-left-color:var(--rose); background:rgba(255,107,90,.05)}
.adev.admin{border-left-color:var(--vio)}
.adev .tm{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--tx3);
  text-align:right; font-variant-numeric:tabular-nums}
.adev .tx{min-width:0; font-size:13.5px; line-height:1.5}
.adev .tx b{font-weight:500}
.adev .tx em{font-style:normal; color:var(--tx3); font-size:12.5px}
/* ⛤ รหัสดิบยังอยู่ (ไล่บั๊กต้องใช้) แต่ไม่บังประโยคจริง — โผล่ตอนชี้เมาส์ */
.adev .raw{font-family:"IBM Plex Mono",monospace; font-size:10.5px; color:var(--tx3);
  opacity:0; transition:opacity .14s var(--ease); white-space:nowrap}
.adev:hover .raw, .adev:focus-visible .raw{opacity:.75}

/* จำนวนกำกับบนชิปตัวกรองของหลังร้าน */
.adchip .c{font-family:"IBM Plex Mono",monospace; font-size:11px; margin-left:7px;
  padding:1px 7px; border-radius:999px; background:rgba(255,255,255,.09);
  color:var(--tx3)}
.adchip.on .c{color:var(--tx2)}
.adchip[data-hot="1"] .c{background:var(--rose); color:#fff}

/* กล่องเตือนในลิ้นชัก — โทนส้ม ไม่ใช่แดง เพราะเป็น "ควรรู้" ไม่ใช่ "อันตราย" */
.drbox.tip{border-color:rgba(224,168,119,.32); background:rgba(224,168,119,.05)}
.drbox.tip h3{color:var(--warn)}
.drbox h3 .adtag{margin-left:8px}

/* หัวกองของใบค้างที่จัดกลุ่มตามลูกค้า */
.adgrp td{background:rgba(255,255,255,.035); font-family:"IBM Plex Mono",monospace;
  font-size:12px; color:var(--tx3); padding:9px 16px}
.adwarn{display:flex; gap:10px; align-items:flex-start; padding:11px 16px;
  font-size:12.5px; color:#F0C199; background:rgba(224,168,119,.07);
  border-bottom:1px solid rgba(224,168,119,.2)}
.adwarn.last{border-bottom:0; border-top:1px solid var(--adline)}
.adwarn.cool{color:#95E2F2; background:rgba(95,208,232,.06);
  border-color:rgba(95,208,232,.2)}
.adwarn svg{width:16px; height:16px; flex:none; margin-top:2px}
.adempty{padding:26px 16px; text-align:center; color:var(--tx3); font-size:13px}

/* ── แถบตัวเลข: แผ่นเดียวแบ่งด้วยเส้นผม (ไม่ใช่การ์ดแยกใบ) ── */
/* ⚠ 158px แคบไปจริงตอนเปิดใช้ — บรรทัดล่างของแต่ละช่องตัดคำเป็น 5 บรรทัด
   จนช่องสูงเกือบ 250px · 200px ทำให้ได้ 4-6 ช่องต่อแถวบนจอทำงานจริง
   และบรรทัดล่างจบใน 2 บรรทัด */
.adstrip{display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  background:var(--adsurf); border:1px solid var(--adline); border-radius:14px;
  overflow:hidden}
.adstrip>div{padding:13px 16px; border-right:1px solid var(--adline);
  display:flex; flex-direction:column; gap:3px; min-width:0}
.adstrip>div:last-child{border-right:0}
.adstrip .lab{font-size:11.5px; color:var(--tx3)}
.adstrip .val{font-size:22px; font-weight:600; line-height:1.2;
  font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums;
  letter-spacing:-.03em}
.adstrip .val.money{color:var(--gold)}
.adstrip .val.good{color:var(--ok)}
.adstrip .val.warn{color:var(--warn)}
.adstrip .val.bad{color:#FF9BA6}
.adstrip .val.info{color:var(--info)}
/* ⛔⛤ ห้ามตั้งชื่อคลาสว่า foot ที่นี่ — .foot คือ 'ส่วนท้ายเว็บ' ของหน้าร้าน
   ซึ่งมีกฎแบบไม่จำกัดพ่อแม่ (padding 44px 0 96px + เส้นบน + พื้นหลัง)
   ⇒ บรรทัดล่างของทุกช่องตัวเลขจะสูง 158px และมีเส้นขีดกลางช่อง
   (เจอตอนเปิดดูจริง 2026-09-11 — ตัวเลขถูกดันห่างจากคำอธิบายครึ่งจอ) */
.adstrip .fnote{font-size:11.5px; color:var(--tx3); line-height:1.45}
.adstrip.inside{border:0; border-radius:0}
.adstrip.inside+.adstrip.inside{border-top:1px solid var(--adline)}
.up{color:var(--ok)}
.down{color:var(--bad)}

/* ── คิวงานที่ต้องทำ ── */
.adtodo{display:flex; align-items:center; gap:13px; padding:13px 16px;
  border-bottom:1px solid var(--adline); flex-wrap:wrap}
.adtodo:last-child{border-bottom:0}
.adtodo .ic{width:34px; height:34px; border-radius:10px; display:grid;
  place-items:center; flex:none}
.adtodo .ic svg{width:17px; height:17px}
.adtodo .tx{min-width:190px; flex:1}
.adtodo .t{font-size:13.5px; font-weight:500}
.adtodo .d{font-size:12px; color:var(--tx3)}
.adtodo .n{font-family:"IBM Plex Mono",monospace; font-size:19px; font-weight:600;
  font-variant-numeric:tabular-nums; margin-left:auto}
.adtodo.hot .ic{background:rgba(255,45,70,.15); color:#FF9BA6}
.adtodo.hot .n{color:#FF9BA6}
.adtodo.warn .ic{background:rgba(224,168,119,.14); color:var(--warn)}
.adtodo.warn .n{color:var(--warn)}
.adtodo.calm .ic{background:var(--glass-2); color:var(--tx3)}
.adtodo.calm .n{color:var(--tx3)}

/* ── ป้ายสถานะ: รูปทรง + คำ ไม่ใช่สีอย่างเดียว ── */
.adtag{display:inline-flex; align-items:center; gap:5px; font-size:11.5px;
  font-weight:600; padding:2px 9px 2px 7px; border-radius:999px; white-space:nowrap;
  background:var(--glass-2); color:var(--tx2);
  box-shadow:inset 0 0 0 1px var(--adline)}
.adtag i{width:6px; height:6px; border-radius:999px; background:currentColor; flex:none}
.adtag.ok{background:rgba(127,224,127,.13); color:#9DEB9D;
  box-shadow:inset 0 0 0 1px rgba(127,224,127,.26)}
.adtag.warn{background:rgba(224,168,119,.14); color:#F0C199;
  box-shadow:inset 0 0 0 1px rgba(224,168,119,.3)}
.adtag.bad{background:rgba(255,107,90,.14); color:#FF9B8C;
  box-shadow:inset 0 0 0 1px rgba(255,107,90,.32)}
.adtag.info{background:rgba(95,208,232,.13); color:#95E2F2;
  box-shadow:inset 0 0 0 1px rgba(95,208,232,.26)}
.adtag.gold{background:rgba(255,194,77,.13); color:#FFD98A;
  box-shadow:inset 0 0 0 1px rgba(255,194,77,.26)}
.adtag.mute i{background:var(--tx3)}
.adtag.sq{border-radius:6px}

/* ── ตาราง ── */
/* ⛔⛤ overflow-x:auto ทำให้ overflow-y กลายเป็น auto ตามสเปก ⇒ กล่องตาราง
   กลายเป็น "พื้นที่เลื่อนของตัวเอง" และ sticky ของหัวตารางจะยึดกับกล่องนั้น
   ไม่ใช่กับหน้าจอ ⇒ เลื่อนหน้าลงแล้วหัวตารางหายไปเฉย ๆ (วัดจริงแล้วหายจริง)
   ⇒ จำกัดความสูงกล่องบนจอกว้าง ให้เลื่อนในตัวเอง หัวตารางจึงค้างได้จริง
   ⚠ บนจอแคบไม่ทำ — พื้นที่เลื่อนซ้อนสองชั้นทำให้ปัดพลาดตลอด */
.adtwrap{overflow-x:auto}
@media (min-width:1061px){
  .adtwrap{max-height:calc(100vh - 220px)}
}
table.adtbl{width:100%; border-collapse:collapse; font-size:13px}
table.adtbl thead th{position:sticky; top:0; z-index:2; background:var(--adhead);
  text-align:left; font-size:11px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--tx3); font-weight:600; padding:9px 14px; white-space:nowrap;
  border-bottom:1px solid var(--adline)}
table.adtbl th.r, table.adtbl td.r{text-align:right}
table.adtbl tbody td{padding:10px 14px; vertical-align:middle;
  border-bottom:1px solid rgba(255,255,255,.045)}
table.adtbl tbody tr:last-child td{border-bottom:0}
table.adtbl tbody tr{transition:background var(--t-fast) var(--ease)}
table.adtbl tbody tr:hover{background:rgba(255,255,255,.028)}
table.adtbl tbody tr.need td:first-child{box-shadow:inset 3px 0 0 var(--ember)}
table.adtbl tbody tr.dim{opacity:.62}
table.adtbl tbody tr.pick{cursor:pointer}
table.adtbl tbody tr.sel{background:rgba(255,45,70,.09)}
table.adtbl tbody tr.sel td:first-child{box-shadow:inset 3px 0 0 var(--ember-lit)}
td.money{font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums;
  text-align:right; font-weight:600}
td.mono, .admono{font-family:"IBM Plex Mono",monospace; font-size:12px;
  color:var(--tx2); font-variant-numeric:tabular-nums}
/* เลขใบกับวันที่ห้ามตัดบรรทัด — ตัดแล้วอ่านผิดใบได้ง่ายมากตอนกวาดตา */
td.mono{white-space:nowrap}
.adwho{display:flex; align-items:center; gap:9px; min-width:0}
.adwho .av{width:28px; height:28px; border-radius:999px; flex:none; display:grid;
  place-items:center; font-size:11.5px; font-weight:600; background:#241722;
  color:#E8C3CC}
.adwho .nm{font-weight:500}
.adfine{font-size:11.5px; color:var(--tx3)}
/* ⚠ margin-top:14px ของ .adacts รุ่นเก่า (ยังใช้กับการ์ดฝั่งลูกค้า) รั่วเข้ามา
   ทำให้ปุ่มในช่องตารางลอยต่ำกว่าข้อความในแถวเดียวกัน ⇒ ล้างที่นี่ให้ชัด */
/* ⛔⛤ 2026-09-13: เคยชื่อ `.adacts` ซึ่งชนกับปุ่มท้ายการ์ดใบเติมเงิน
   (บรรทัด ~921) ที่ต้องการ `margin-top` ⇒ กฎตัวนี้อยู่ท้ายกว่าเลยชนะ
   ทำให้ปุ่มท้ายการ์ดเสียระยะห่างด้านบนไปเงียบ ๆ ⇒ แยกชื่อออกจากกัน */
.adtacts{display:flex; gap:6px; justify-content:flex-end; flex-wrap:wrap; margin:0}
/* ⚠ ปุ่มในช่องจัดการห้ามตัดคำ — "ลองออกคีย์ใหม่" ตัดเป็นสองบรรทัดแล้วแถวสูงไม่เท่ากัน
   กวาดตาข้ามแถวไม่ได้ทันที (ปุ่มทั้งกลุ่มขึ้นบรรทัดใหม่ได้ แค่ตัวอักษรห้ามตัด) */
.adtacts .btn{white-space:nowrap}
.adtfoot{display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:10px 16px; border-top:1px solid var(--adline); font-size:12.5px;
  color:var(--tx3); background:#0E0E15}
.adextra{display:flex; align-items:center; gap:12px; flex-wrap:wrap}

/* ── ตัวกรอง ── */
.adfilters{display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  padding:11px 16px; border-bottom:1px solid var(--adline)}
.adchip{border:1px solid var(--adline); background:none; border-radius:999px;
  padding:5px 13px; font-size:12.5px; color:var(--tx2); cursor:pointer;
  display:inline-flex; align-items:center; gap:6px; min-height:32px}
.adchip:hover{border-color:var(--tx3); color:var(--tx)}
.adchip.on{background:var(--glass-2); color:var(--tx);
  border-color:var(--adline-hi); font-weight:600}
.adchip b{font-family:"IBM Plex Mono",monospace; font-size:11px; color:var(--tx3);
  font-weight:600}
.adchip.on b{color:var(--ember-lit)}
.adchip b.hot{color:#FF9BA6}
.adfind{display:flex; align-items:center; gap:7px; background:var(--bg-soft);
  border:1px solid var(--adline); border-radius:9px; padding:5px 11px;
  color:var(--tx3); min-width:240px}
.adfind input{background:none; border:0; outline:none; color:var(--tx);
  font:inherit; font-size:13px; width:100%; min-height:26px}
select.adsel{appearance:none; background:var(--bg-soft);
  border:1px solid var(--adline); border-radius:9px; color:var(--tx2);
  font:inherit; font-size:13px; padding:6px 11px; min-height:34px; cursor:pointer}

/* ── กราฟ ── */
.adchart{padding:14px 16px}
.adchart svg{width:100%; height:auto; display:block; overflow:visible}
.adlegend{display:flex; gap:16px; flex-wrap:wrap; font-size:12px; color:var(--tx3);
  padding:12px 16px 0}
.adlegend span{display:flex; align-items:center; gap:6px}
.adlegend i{width:9px; height:9px; border-radius:3px; display:inline-block}
.adlegend .k1 i{background:linear-gradient(180deg,#FF2D46,#8E1226)}
.adlegend .k2 i{background:linear-gradient(180deg,#95E2F2,#1E5C6B)}

/* ══ กราฟแท่งรุ่น 2 (2026-09-13) ══
   ⛔⛤ สีของกราฟอยู่ที่นี่ที่เดียว — ของเดิมเขียนรหัสสีติดไปกับทุกชิ้นใน JS
      ⇒ เปลี่ยนธีมทีต้องไล่แก้ในสคริปต์ และไม่มีทาง :hover ได้เลย
   ⚠ .adchartbox ต้อง position:relative — กล่องชี้วางตำแหน่งเทียบกล่องนี้ */
.adchartbox{position:relative}
.adchartbox .adgl{stroke:rgba(255,255,255,.08); stroke-width:1}
.adchartbox .adgl.soft{stroke:rgba(255,255,255,.035)}
.adchartbox .adax{fill:var(--tx3); font-size:10px;
  font-family:"IBM Plex Mono",monospace}
.adchartbox .adax.now{fill:var(--tx); font-weight:600}
.adchartbox .adtop{fill:#FFC8CE; font-size:10.5px; font-weight:600;
  font-family:"IBM Plex Mono",monospace}
.adchartbox .adavg{stroke:rgba(255,220,150,.45); stroke-width:1;
  stroke-dasharray:5 5}
.adchartbox .adavgl{fill:rgba(255,220,150,.75); font-size:9.5px;
  font-family:"IBM Plex Mono",monospace}
.adchartbox .adfoot2{fill:var(--tx3); font-size:10px; font-family:Anuphan,sans-serif}
.adchartbox .adcolbg{fill:transparent}
.adchartbox .adcol.lit .adcolbg{fill:rgba(255,255,255,.05)}
.adchartbox .adbar1{transition:filter .14s var(--ease)}
.adchartbox .adcol.lit .adbar1{filter:brightness(1.35)}
.adchartbox .adhit{cursor:crosshair}
/* กล่องชี้ — ลอยเหนือกราฟ ไม่กินการชี้ของตัวเอง (ไม่งั้นกะพริบไม่จบ) */
.adtip{position:absolute; top:2px; transform:translateX(-50%); pointer-events:none;
  background:rgba(14,14,19,.97); border:1px solid var(--line-2); border-radius:10px;
  padding:8px 11px; font-size:12px; color:var(--tx2); white-space:nowrap; z-index:5;
  box-shadow:0 10px 26px rgba(0,0,0,.5); display:grid; gap:2px}
.adtip b{color:var(--tx); font-size:12.5px; font-weight:600}
.adtip .v1{color:#FFB3BC; font-family:"IBM Plex Mono",monospace}
.adtip .v2{color:#95E2F2; font-family:"IBM Plex Mono",monospace}
.adtip .sub{color:var(--tx3)}

/* ── กรวยเส้นทาง ── */
/* ⚠ กรวยยาวเต็มจอกว้าง ๆ อ่านยากกว่าเดิม — ตาต้องกวาดไกลเกินไปกว่าจะถึงตัวเลข
   ⇒ จำกัดความกว้างไว้ แล้วปล่อยที่ว่างด้านขวาแทน */
.adfunnel{display:grid; gap:9px; padding:16px; max-width:940px}
.adstep{display:grid; grid-template-columns:150px minmax(0,1fr) auto;
  align-items:center; gap:14px}
.adstep .fl{font-size:12.5px; color:var(--tx2)}
.adbar{height:30px; border-radius:7px; background:var(--glass); overflow:hidden;
  position:relative}
.adbar i{position:absolute; inset:0 auto 0 0; border-radius:7px;
  background:linear-gradient(90deg,rgba(255,45,70,.75),rgba(255,124,139,.4))}
.adbar i.good{background:linear-gradient(90deg,#4E9E5E,#7FE07F)}
.adbar b{position:absolute; left:11px; top:0; line-height:30px; font-size:12.5px;
  font-weight:600; color:#fff; text-shadow:0 1px 3px rgba(0,0,0,.65);
  font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums}
.adpc{font-family:"IBM Plex Mono",monospace; font-size:12px; color:var(--tx3);
  min-width:74px; text-align:right; font-variant-numeric:tabular-nums}

/* ── บันทึกกิจกรรมแบบภาษาคน ── */
.adfeed{display:flex; flex-direction:column}
.adline{display:grid; grid-template-columns:60px 26px minmax(0,1fr) auto; gap:11px;
  align-items:center; padding:8px 16px; font-size:13px;
  border-bottom:1px solid rgba(255,255,255,.045)}
.adline:last-child{border-bottom:0}
.adline .tm{font-family:"IBM Plex Mono",monospace; font-size:11.5px;
  color:var(--tx3); font-variant-numeric:tabular-nums}
.adline .ic{width:26px; height:26px; border-radius:8px; display:grid;
  place-items:center; font-size:12px; font-weight:600}
.adline .ic.sale{background:rgba(127,224,127,.13); color:var(--ok)}
.adline .ic.people{background:rgba(95,208,232,.12); color:var(--info)}
.adline .ic.money{background:rgba(255,194,77,.12); color:var(--gold)}
.adline .ic.admin{background:rgba(255,45,70,.13); color:var(--ember-lit)}
.adline .ic.risk{background:rgba(255,107,90,.14); color:var(--bad)}
.adline .ic.other{background:var(--glass-2); color:var(--tx3)}
.adline .tx b{font-weight:600}
.adline .tx em{font-style:normal; color:var(--tx3)}
.adline .raw{font-family:"IBM Plex Mono",monospace; font-size:10.5px;
  color:#5F5966; white-space:nowrap}

/* ── หน้าลูกค้า: ตาราง + แผงข้าง ── */
.adsplit{display:grid; grid-template-columns:minmax(0,1fr) 380px; gap:16px;
  align-items:start}
.adside{position:sticky; top:76px}
.adsideh{display:flex; gap:12px; align-items:center; padding:16px;
  border-bottom:1px solid var(--adline)}
.adsideh .av{width:44px; height:44px; border-radius:999px; display:grid;
  place-items:center; background:#2A1A24; color:#EFC9D2; font-weight:600;
  font-size:16px; flex:none}
.adsideh .who{min-width:0}
.adsideh .who b{display:block; font-size:15px; font-weight:600}
.adtags{display:flex; gap:7px; flex-wrap:wrap; padding:12px 16px;
  border-bottom:1px solid var(--adline)}
.adkv{display:grid; grid-template-columns:auto minmax(0,1fr); gap:7px 14px;
  padding:13px 16px; font-size:12.5px; border-bottom:1px solid var(--adline);
  margin:0}
.adkv dt{color:var(--tx3)}
.adkv dd{margin:0; text-align:right; font-family:"IBM Plex Mono",monospace;
  font-variant-numeric:tabular-nums}
.adkv dd.txt{font-family:inherit}
.adminih{font-size:11px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--tx3); padding:13px 16px 7px; font-weight:600}
.admlist{padding:0 16px 14px; display:flex; flex-direction:column; gap:7px}
.admrow{display:flex; align-items:center; gap:9px; font-size:12.5px;
  padding:8px 11px; background:var(--bg-soft); border:1px solid var(--adline);
  border-radius:9px; flex-wrap:wrap}
.admrow.gone{opacity:.6}
.admrow code{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--tx2)}
.adsidebtns{display:flex; gap:7px; flex-wrap:wrap; padding:0 16px 16px}
/* บรรทัด "ยังมีอีก N" ท้ายรายการที่ถูกตัด — ต้องมีทุกที่ที่ตัดรายการ */
.admore{display:flex; align-items:center; gap:10px; font-size:11.5px;
  color:var(--tx3); padding:2px 2px 0}
.admore a{color:var(--tx2); text-decoration:none; margin-left:auto}
.admore a:hover{color:var(--tx); text-decoration:underline}

/* ── ใบขอเติมเงิน ── */
.adslip{display:grid; grid-template-columns:auto minmax(0,1fr) auto; gap:14px;
  align-items:center; padding:14px 16px; border-bottom:1px solid var(--adline)}
.adslip:last-child{border-bottom:0}
.adslip .amt{font-family:"IBM Plex Mono",monospace; font-size:17px; font-weight:600;
  font-variant-numeric:tabular-nums}
.adslip .row1{display:flex; align-items:center; gap:9px; flex-wrap:wrap}
.adslip .row2{font-size:12.5px; color:var(--tx2); margin-top:4px}
.adslip .row3{font-size:12px; color:var(--tx3); margin-top:2px}
.adface{width:44px; height:44px; border-radius:12px; display:grid; place-items:center;
  flex:none; background:#241722; color:#E8C3CC; font-weight:600; font-size:15px}

/* ── สินค้า ── */
.adprod{border-bottom:1px solid var(--adline)}
.adprod:last-child{border-bottom:0}
.adprodh{display:flex; align-items:center; gap:12px; padding:13px 16px;
  background:var(--adhead); flex-wrap:wrap}
.adprodh .cov{width:42px; height:42px; border-radius:10px; flex:none; display:grid;
  place-items:center; background:linear-gradient(150deg,#3A1216,#120A0C);
  box-shadow:inset 0 0 0 1px rgba(255,45,70,.28); font-size:17px; overflow:hidden}
.adprodh .cov img{width:100%; height:100%; object-fit:cover}
.adprodh .nm{font-weight:600; font-size:14px}

/* ── โครงจาง ๆ ตอนกำลังโหลด ── */
.adskel{padding:16px; display:grid; gap:9px}
.adskel i{display:block; height:12px; border-radius:6px; background:var(--glass-2)}
.adskel i.w40{width:40%}
.adskel i.w70{width:70%}

/* ── จอแคบ ── */
@media (max-width:1200px){
  .adcols, .adcols.even{grid-template-columns:minmax(0,1fr)}
  .adsplit{grid-template-columns:minmax(0,1fr)}
  .adside{position:static}
}
@media (max-width:1060px){
  .adshell{grid-template-columns:minmax(0,1fr)}
  /* ⛔ รางบนจอแคบต้องเป็นแผงที่เลื่อนเข้ามา ไม่ใช่แถวเมนูแนวนอนที่ต้องปัดหา
     — เมนูงาน 7 หัวข้อ ปัดหาแล้วพลาดง่ายตอนรีบ */
  .adrail{position:fixed; top:0; bottom:0; left:0; width:262px;
    transform:translateX(-105%); transition:transform var(--t) var(--ease)}
  .adrail.open{transform:none; box-shadow:var(--shadow-hi)}
  .adrailbtn{display:inline-flex}
  .adpage{padding:18px 14px 64px}
  .adtop{padding:10px 14px}
}
@media (max-width:720px){
  .adstep{grid-template-columns:112px minmax(0,1fr)}
  .adpc{grid-column:2; text-align:left; min-width:0}
  .adline{grid-template-columns:52px 24px minmax(0,1fr)}
  .adline .raw{display:none}
  .adslip{grid-template-columns:auto minmax(0,1fr)}
  .adslip .adacts{grid-column:1 / -1; justify-content:flex-start}
  .adhead h1{font-size:21px}
}
@media (prefers-reduced-motion:reduce){
  .adrail{transition:none}
}

/* ── เก็บรายละเอียดที่เจอตอนประกอบจริง (2026-09-11) ── */
/* กลุ่มชิปที่ซ้อนอยู่ในแถบตัวกรอง ต้องไม่มีขอบ/ระยะซ้อนอีกชั้น */
.adfilters .adfilters{padding:0; border:0; gap:6px}
/* ป้ายสีของกราฟเทียบสองค่า — ต้องเป็นคลาส ไม่ใช่ style ในแท็ก (CSP) */
.adlegend i.lg-visit{background:#C4152B}
.adlegend i.lg-signup{background:#5FD0E8}
/* หน้าบันทึกกิจกรรมย้อนหลังได้ 90 วัน ⇒ ช่องเวลาต้องกว้างพอใส่ "วันที่ + เวลา" */
#al-list .adline{grid-template-columns:118px 26px minmax(0,1fr) auto}
@media (max-width:720px){
  #al-list .adline{grid-template-columns:104px 24px minmax(0,1fr)}
}
/* ปุ่มในช่องราคา (ตารางสินค้า) วางต่อจากตัวเลขในบรรทัดใหม่ ไม่ดันคอลัมน์ */
td.money .btn{margin-top:6px}


/* ══════════════════════════════════════════════════════════════
   ตัวควบคุมที่ "เบราว์เซอร์วาดเอง" — ไม่ใช่ CSS ของเรา
   ⛔⛤ เจ้าของสั่ง 2026-08-31: "กดแท็ปเลื่อนมีหน้าต่างสีขาว
      ทำให้เป็นมือโปรเก็บรายละเอียดทุกจุดไม่ใช่แค่จุดนี้"
      ⇒ ไล่หาของประเภทเดียวกันทั้งเว็บ ไม่ใช่ปะเฉพาะจุดที่ถ่ายรูปมา
      พบ 6 จุดที่เป็นอาการเดียวกันและยังไม่เคยกันไว้เลย
   ⚠ ของพวกนี้ไม่โผล่ในเทสวัดความกว้างหรือเทสโทเคน เพราะมัน "ถูกต้อง"
     ทุกอย่างในสายตาโค้ด — ผิดแค่ตอนคนเห็นจริง ๆ
   ══════════════════════════════════════════════════════════════ */

/* ── 1) ช่องที่เบราว์เซอร์เติมรหัสให้อัตโนมัติ ──
   ⛔⛤ อาการหนักสุด: Chrome ทาพื้นช่องอีเมล/รหัสผ่านเป็น "ขาวอมฟ้า"
      พร้อมตัวหนังสือสีเข้ม ⇒ หน้าเข้าสู่ระบบมีกล่องขาวโพลนกลางธีมมืด
   ⚠ background ธรรมดาทับไม่ได้ Chrome ใช้สไตล์ระดับ UA
     วิธีเดียวที่ได้ผลจริงคือยืมเงาด้านในมาทาแทนพื้น */
input.input:-webkit-autofill,
input.input:-webkit-autofill:hover,
input.input:-webkit-autofill:focus,
textarea.input:-webkit-autofill,
select.input:-webkit-autofill{
  -webkit-text-fill-color:var(--tx);
  -webkit-box-shadow:0 0 0 100px var(--surface) inset;
  box-shadow:0 0 0 100px var(--surface) inset;
  caret-color:var(--tx);
  /* ⚠ ดีเลย์ยาว ๆ คือกลเม็ดมาตรฐาน — กันภาพวูบสีขาวหนึ่งเฟรมตอนโหลด */
  transition:background-color 100000s ease-in-out 0s}

/* ── 2) แถบเลือกข้อความ ──
   ค่าปริยายเป็นน้ำเงินสด อ่านไม่ออกบนพื้นมืด */
::selection{background:color-mix(in oklab,var(--ember) 42%, transparent);
  color:#fff}

/* ── 3) กล่องติ๊ก · ปุ่มกลม · แถบเลื่อน · แถบความคืบหน้า ──
   เบราว์เซอร์ทาด้วยสีประจำตัวเอง (ฟ้า) ⇒ ไม่เข้ากับทั้งเว็บ
   ⚠ หน้าต่างโปรแกรมที่ยกมาโชว์มีกล่องติ๊ก 23 อัน โดนหมดทุกอัน */
input[type="checkbox"],input[type="radio"],
input[type="range"],progress{accent-color:var(--ember)}

/* ── 4) ปุ่ม "เลือกไฟล์" ในช่องแนบไฟล์ ──
   ⛤ ใช้ที่แนบสลิปโอนเงินกับตั้งรูปโปรไฟล์ — สองจุดที่ลูกค้าเจอบ่อย */
input[type="file"]{color:var(--tx3); font:inherit; font-size:13px}
input[type="file"]::file-selector-button{
  font:inherit; font-size:13px; font-weight:600; cursor:pointer;
  margin-right:10px; padding:9px 14px; border-radius:10px;
  color:var(--tx); background:var(--surface);
  border:1px solid var(--line)}
input[type="file"]::file-selector-button:hover{
  border-color:color-mix(in oklab,var(--ember) 45%, var(--line))}

/* ── 5) กากบาทล้างคำค้นในช่องค้นหา ──
   ⚠ เบราว์เซอร์วาดเป็นสัญลักษณ์ทึบสีเข้ม ⇒ จมหายไปกับพื้นมืด
     ใช้ filter กลับสีแทน เพราะแต่งสีมันตรง ๆ ไม่ได้ */
input[type="search"]::-webkit-search-cancel-button{
  -webkit-appearance:none; appearance:none;
  width:15px; height:15px; cursor:pointer; opacity:.5;
  background:var(--tx2);
  -webkit-mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 4l8 8M12 4l-8 8' stroke='%23000' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 4l8 8M12 4l-8 8' stroke='%23000' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat}
input[type="search"]::-webkit-search-cancel-button:hover{opacity:1}

/* ── 6) ลูกศรขึ้นลงของช่องตัวเลข ──
   ⛤ หน้าเติมเงินและหน้าคูปองใช้ช่องตัวเลข 6 ช่อง
   ⚠ ลูกศรจิ๋วของเบราว์เซอร์เล็กกว่า 44px ⇒ กดยากบนมือถืออยู่แล้ว
     ซ่อนทิ้ง แล้วให้พิมพ์เอา (ทุกช่องมีปุ่ม -/+ ของเราเองอยู่แล้ว) */
input[type="number"]{-moz-appearance:textfield; appearance:textfield}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button{
  -webkit-appearance:none; appearance:none; margin:0}

/* ── 7) สามเหลี่ยมของ <details> ──
   ⛤ ใช้ในคำถามที่พบบ่อย 18 อันทั่วเว็บ */
details > summary{cursor:pointer}
details > summary::marker{color:var(--tx3)}
details > summary::-webkit-details-marker{color:var(--tx3)}

/* ── ช่องข้อความยาว ──
   ⚠ .input ตั้ง padding:0 16px ไว้สำหรับช่องบรรทัดเดียว
     ใส่กับ textarea ตรง ๆ ตัวหนังสือจะติดขอบบนสนิท
   ⚠ เบราว์เซอร์ตั้งฟอนต์ของ textarea เป็นฟอนต์ระบบเสมอ ไม่สืบทอดจาก body
     ⇒ ไม่บังคับ font-family เอง จะได้ฟอนต์คนละตัวกับทั้งเว็บ */
textarea.input{padding:14px 16px; line-height:1.75; font-family:inherit;
  resize:vertical; min-height:120px}
textarea.input.tall{min-height:168px}

/* ══ ไอคอนหัวเว็บเป็นโลโก้จริงแล้ว (2026-09-01) ══
   ⚠ กฎเดิมของ .brand .mk วาดพื้นหลังไล่สีให้กล่อง svg — พอเปลี่ยนเป็น <img>
     พื้นหลังนั้นจะโผล่เป็นขอบรอบโลโก้ (โลโก้มีพื้นดำในตัวอยู่แล้ว)
   ⇒ ทับด้วยกฎเฉพาะเมื่อเป็นรูป ไม่ไปแตะกล่อง svg ที่อื่นยังใช้อยู่ */
img.mk{background:none; border:0; box-shadow:none; padding:0;
  object-fit:contain; border-radius:9px}

/* ══════════════════════════════════════════════════════════════
   กล่องที่ JS เติมเนื้อหาทีหลัง — ระหว่างรอให้โชว์โครงจาง ๆ
   ⛔⛤ เจ้าของแจ้ง 2026-09-01: "ทุกแท็ปทุกหน้าเวลากดรี" เห็นภาพแปลก
      HTML จากเซิร์ฟเป็นโครงเปล่า (หน้าสินค้า 18 KB) เนื้อหามาจาก API
      ⇒ ทุกครั้งที่โหลดจะเห็น "หัวข้อลอยอยู่เหนือช่องว่าง" ก่อนเสมอ
        แล้วเนื้อหากระโดดเข้ามาดันหน้าเลื่อน
   ⚠ ใช้ :empty ไม่ใช่คลาสที่ JS ต้องมาถอด — เติมเนื้อหาปุ๊บโครงหายเอง
     ถ้าใช้คลาส แล้ว JS พังกลางทาง โครงจะค้างถาวรแทนที่จะเป็นแค่ว่าง
   ══════════════════════════════════════════════════════════════ */
/* ⛔⛤ ต้องมี :not([hidden]) — ของบางจุด (กล่องกันบอท · เส้นคั่น) ตั้ง hidden ไว้
   แล้วให้ JS ถอดตอนถึงเวลา · display:block ที่นี่จะไป **ทับ hidden**
   ⇒ ของที่ควรซ่อนจะโผล่ขึ้นมาเป็นแถบเทาลอย ๆ ทุกหน้า
   (เกือบพลาดตอนเขียนกฎนี้เอง 2026-09-01) */
[data-fill]:empty:not([hidden]){
  display:block;
  min-height:120px;
  border-radius:var(--r-sm, 12px);
  background:
    linear-gradient(100deg, transparent 20%,
      color-mix(in oklab, var(--tx3) 9%, transparent) 42%,
      transparent 64%) 0 0 / 220% 100% no-repeat,
    color-mix(in oklab, var(--tx3) 5%, transparent);
  animation:fillwait 1.25s linear infinite}
@keyframes fillwait{from{background-position:120% 0} to{background-position:-120% 0}}

/* ความสูงที่จองไว้ต่อจุด — ใกล้ของจริงแล้วหน้าจะไม่กระโดดตอนเนื้อหามา */
[data-fill="46"]:empty:not([hidden]){min-height:46px}
[data-fill="54"]:empty:not([hidden]){min-height:54px}
[data-fill="56"]:empty:not([hidden]){min-height:56px}
[data-fill="64"]:empty:not([hidden]){min-height:64px}
[data-fill="90"]:empty:not([hidden]){min-height:90px}
[data-fill="120"]:empty:not([hidden]){min-height:120px}
[data-fill="130"]:empty:not([hidden]){min-height:130px}
[data-fill="140"]:empty:not([hidden]){min-height:140px}
[data-fill="150"]:empty:not([hidden]){min-height:150px}
[data-fill="160"]:empty:not([hidden]){min-height:160px}
[data-fill="180"]:empty:not([hidden]){min-height:180px}
[data-fill="190"]:empty:not([hidden]){min-height:190px}
[data-fill="200"]:empty:not([hidden]){min-height:200px}
[data-fill="220"]:empty:not([hidden]){min-height:220px}
[data-fill="260"]:empty:not([hidden]){min-height:260px}
[data-fill="300"]:empty:not([hidden]){min-height:300px}
[data-fill="380"]:empty:not([hidden]){min-height:380px}
[data-fill="560"]:empty:not([hidden]){min-height:560px}

/* ⚠ คนที่ตั้งเครื่องให้ลดการเคลื่อนไหว ต้องไม่เห็นแถบวิ่ง — เหลือแค่พื้นจาง */
@media (prefers-reduced-motion: reduce){
  [data-fill]:empty:not([hidden]){animation:none; background:
    color-mix(in oklab, var(--tx3) 5%, transparent)}
}
[data-fill="78"]:empty:not([hidden]){min-height:78px}

/* ══════════════════════════════════════════════════════════════
   หน้าเลื่อนทั้งแผงตอนของโหลดเสร็จ (2026-09-01)
   ⛔⛤ การ์ด "ซองอั่งเปา" ซ่อนฟอร์มไว้ (#ap-box hidden) รอเซิร์ฟบอกว่า
      เปิดรับไหม · พอฟอร์มโผล่ การ์ดสูงขึ้น แล้วทุกอย่างข้างล่างเลื่อนลง
      ทั้งแผง ⇒ กดรีเฟรชถี่ ๆ เห็นหน้ากระตุก/ซ้อนตลอด
   ⇒ ระหว่างที่ยังไม่รู้คำตอบ ให้ฟอร์ม "กินที่แต่มองไม่เห็น"
     ⚠ จองด้วยความสูงของฟอร์มจริง ไม่ใช่ตัวเลขที่เดาเอง
       เพิ่มช่องกรอกทีหลังเมื่อไหร่ ที่จองก็ขยายตามเอง
   ⚠ visibility:hidden ไม่ใช่ opacity:0 — ต้องกดไม่ได้และคีย์บอร์ดข้ามไป
   ══════════════════════════════════════════════════════════════ */
#way-angpao:not([data-known]) #ap-box[hidden]{
  display:block; visibility:hidden}

/* ยอดเงินระหว่างรอตัวเลขจริง — แถบจาง ไม่ใช่ขีดลอย ๆ */
#wl-balance:empty{min-height:46px; max-width:180px}

/* ══════════════ หน้าแรก: หน้าต่างโปรแกรมเอียง 3 มิติ ══════════════
   ⛤ ยกหน้าตาจากเว็บต้นฉบับ (HaruShop-Website) มาเขียนด้วยโทเคนของร้าน
      ไม่พึ่ง Tailwind ไม่เพิ่มไฟล์นอกสักไฟล์
   ⛔ ทุกชื่อคลาสขึ้นต้น hs-/hw- เพราะชื่อสั้น ๆ ชนของเดิมเพียบ
      (.f1 .f2 .f3 .eyebrow .lead .pill .chip .grid มีกฎแบบไม่จำกัดพ่อแม่อยู่แล้ว)
   ⛔ วาดด้วย CSS ล้วน ไม่มีภาพจากตัวเกม — เป็นภาพจำลอง ไม่ใช่ภาพหน้าจอจริง */

/* ── แสงพื้นหลังแดง (เจ้าของว่าของเดิม "มืดไป ไม่แดงเหมือนต้นฉบับ") ── */
.hero .hs-glow{position:absolute; inset:0; z-index:0; overflow:hidden;
  pointer-events:none}
.hs-glow i{position:absolute; border-radius:50%; filter:blur(80px); display:block}
.hs-g1{top:-22rem; left:-10rem; width:52rem; height:52rem;
  background:radial-gradient(circle,rgba(255,45,70,.44),transparent 66%)}
.hs-g2{top:4%; right:-14rem; width:48rem; height:48rem;
  background:radial-gradient(circle,rgba(226,28,42,.40),transparent 66%)}
.hs-g3{bottom:-14rem; left:26%; width:40rem; height:40rem;
  background:radial-gradient(circle,rgba(255,150,95,.24),transparent 66%)}

/* ── กริดสองคอลัมน์เฉพาะหน้าแรก ──
   ⚠ ของเดิม .hgrid:not(.solo) = 1.02fr .98fr ซึ่งซ้ายกว้างกว่าขวา
      แต่ฝั่งขวาต้องอวดหน้าต่างโปรแกรม ⇒ กลับสัดส่วน */
@media(min-width:1060px){
  /* ⛔ ต้องมีที่ว่างด้านบนมากกว่าหน้าอื่น — ป้ายลอยอยู่เหนือขอบหน้าต่าง
     และ .hero{overflow:hidden} จะตัดทุกอย่างที่พ้นขอบบนทิ้งเงียบ ๆ
     ⚠ เฉพาะจอกว้าง — จอแคบซ่อนป้ายลอยอยู่แล้ว เว้นไว้ = ช่องว่างเปล่า */
  .hero.showcase{padding-top:112px}
  .hgrid.showcase{grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr)}
  /* ⛔ มาสคอตห้อยต่ำกว่าขอบล่างหน้าต่าง ~74px ⇒ คำชี้แจงต้องหลบให้พ้น
     ไม่งั้นตัวหนังสือทับตัวคุกกี้ (จอแคบไม่มีมาสคอต จึงไม่ต้องเว้น) */
  .hero.showcase .hs-note{margin-top:96px}
  /* ⚠ หัวเรื่องต้องอยู่ 2 บรรทัดเสมอแบบต้นฉบับ — 3 บรรทัดเมื่อไหร่พลังหาย
     ของเดิม 6vw กว้างเกินเมื่อคอลัมน์แคบลง ⇒ ผูกกับ vw ที่เล็กลง */
  .hero .hgrid.showcase h1{font-size:clamp(36px,4.15vw,54px); line-height:1.1}
}

/* ── ตัวหน้าต่าง ── */
.hs-wrap{position:relative; perspective:1600px}
/* ⛤ เจ้าของแจ้ง 2026-09-02: "จอโปรแกรมล้น" (จอ 1920 ตัวเลขขวาโดนตัด)
   วัดที่ 1280/1440/1600/1920/2560 แล้ว: 128% ล้น 4 จาก 5 · 114% ล้น 2
   ⇒ 108% คือค่ามากสุดที่ไม่ล้นสักจอ · ยังล้นกรอบคอลัมน์ตัวเองอยู่
     (ได้ความรู้สึก "หน้าต่างใหญ่" แบบต้นฉบับ แต่ไม่มีอะไรโดนตัดทิ้ง)
   ⚠ ด่านกวาดความกว้างมองไม่เห็น เพราะยกเว้นของที่อยู่ในกล่องตัดขอบ
     ⇒ มีด่านเฉพาะใน check_hero_showcase.js วัดขอบขวาเทียบขอบจอ */
.hs-win{position:relative; width:108%; transform-origin:left center;
  /* ⛔⛤ ห้ามตั้งชื่อตัวแปรว่า --tx/--ty — ชนโทเคนสีตัวอักษรของร้าน
     ⇒ calc องศาบวกกับ "สี" เป็นค่าใช้ไม่ได้ เบราว์เซอร์ทิ้ง transform
        ทั้งบรรทัดเงียบ ๆ หน้าต่างจะแบนสนิทโดยไม่มี error สักตัว
     ⚠ อย่าเขียนรหัสสีตัวอย่างตรงนี้ — ด่านตรวจสีดิบไม่ตัดคอมเมนต์ก่อนอ่าน */
  transform:rotateY(calc(-13deg + var(--hs-ty,0deg)))
    rotateX(calc(4deg + var(--hs-tx,0deg))) rotate(-1deg) scale(.94);
  transition:transform .25s cubic-bezier(.2,.7,.25,1);
  border-radius:16px; border:1px solid var(--line); overflow:hidden;
  background:linear-gradient(165deg,var(--surface),var(--bg-soft));
  box-shadow:0 40px 90px rgba(0,0,0,.72), 0 0 0 1px rgba(255,45,70,.10),
    0 0 90px rgba(255,45,70,.13)}

/* แถบหัวหน้าต่าง */
.hw-bar{display:flex; align-items:center; gap:9px; padding:9px 12px;
  border-bottom:1px solid var(--line); background:rgba(0,0,0,.34)}
.hw-name{display:flex; align-items:center; gap:8px; font-size:12.5px;
  font-weight:700; white-space:nowrap}
.hw-name i{width:19px; height:19px; border-radius:6px; display:grid;
  place-items:center; font-style:normal; font-size:9.5px; font-weight:800;
  background:var(--ember-btn); color:#fff}
.hw-ver{font-family:"IBM Plex Mono",monospace; font-size:10px; color:var(--tx3)}
.hw-sep{width:1px; height:15px; background:var(--line)}
.hw-page{font-size:11.5px; color:var(--tx2); display:flex; gap:6px;
  align-items:center; white-space:nowrap}
.hw-push{margin-left:auto}
.hw-chip{display:inline-flex; align-items:center; gap:5px; padding:4px 9px;
  border-radius:999px; border:1px solid var(--line); background:var(--glass);
  font-size:10.5px; color:var(--tx2); white-space:nowrap}
.hw-chip s{width:5px; height:5px; border-radius:50%; background:var(--ok);
  text-decoration:none}
.hw-chip.go{background:var(--ember-btn); border-color:var(--ember-btn);
  color:#fff; font-weight:700}
.hw-btns{display:flex; gap:9px; color:var(--tx3); font-size:10px;
  padding-left:4px}

/* ตัวเนื้อหน้าต่าง */
.hw-body{display:grid; grid-template-columns:146px 1fr; min-height:436px}
.hw-rail{border-right:1px solid var(--line); padding:12px 9px;
  background:rgba(0,0,0,.22)}
.hw-rail .grp{font-size:9.5px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--tx3); font-family:"IBM Plex Mono",monospace; padding:6px 8px 8px}
.hw-rail span.nav{display:flex; gap:8px; align-items:center; padding:8px 9px;
  border-radius:9px; color:var(--tx2); font-size:11.5px; margin-bottom:2px}
.hw-rail span.nav.on{background:rgba(255,45,70,.13); color:var(--tx);
  border:1px solid rgba(255,45,70,.24)}
.hw-rail span.nav b{display:block; font-weight:600}
.hw-rail span.nav small{display:block; font-size:9.5px; color:var(--tx3)}
.hw-rail span.nav i{font-style:normal; font-size:12px}

.hw-main{padding:14px}
.hw-head{display:flex; align-items:center; gap:12px; padding:13px 15px;
  border-radius:13px; margin-bottom:12px;
  border:1px solid rgba(127,224,127,.24); background:rgba(127,224,127,.06)}
.hw-head .mark{position:relative; width:34px; height:34px; border-radius:10px;
  display:grid; place-items:center; background:rgba(127,224,127,.14);
  color:var(--ok); font-size:15px}
/* วงแหวนหมุนรอบเครื่องหมายถูก — บอกว่า "กำลังทำงานอยู่" (ต้นฉบับ: ring-spin) */
.hw-head .mark::before{content:""; position:absolute; inset:-4px;
  border-radius:13px; pointer-events:none;
  border:1.5px dashed rgba(127,224,127,.5)}
@keyframes hsSpin{to{transform:rotate(360deg)}}
.hs-anim .hw-head .mark::before{animation:hsSpin 7s linear infinite}
.hw-head b{display:block; font-size:13.5px}
.hw-head small{display:block; font-size:10.5px; color:var(--tx3)}
.hw-big{margin-left:auto; text-align:right}
.hw-big b{font-size:22px; font-family:"IBM Plex Mono",monospace; color:var(--tx)}
.hw-big small{letter-spacing:.12em; text-transform:uppercase; font-size:9px}

.hw-tiles{display:grid; grid-template-columns:repeat(4,1fr); gap:9px;
  margin-bottom:12px}
.hw-tile{border:1px solid var(--line); border-radius:12px; padding:11px 12px;
  background:var(--glass)}
.hw-tile small{display:flex; align-items:center; gap:5px; font-size:9.5px;
  color:var(--tx3); margin-bottom:5px}
.hw-tile b{font-size:18px; font-family:"IBM Plex Mono",monospace; display:block}
.hw-tile u{display:block; text-decoration:none; font-size:9px;
  color:var(--tx3); margin-top:2px}

.hw-rows{display:grid; grid-template-columns:repeat(4,1fr); gap:9px;
  margin-bottom:12px}
.hw-row{border:1px solid var(--line); border-radius:11px; padding:9px 11px;
  background:var(--glass)}
.hw-row small{display:block; font-size:9px; color:var(--tx3);
  font-family:"IBM Plex Mono",monospace}
.hw-row b{font-size:11.5px; display:block; margin-top:2px}
.hw-row.r1 b{color:var(--ok)}   .hw-row.r2 b{color:var(--gold)}
.hw-row.r3 b{color:var(--info)} .hw-row.r4 b{color:var(--ember-lit)}

.hw-log{border:1px solid var(--line); border-radius:12px; overflow:hidden}
.hw-log .cap{display:flex; align-items:center; gap:8px; padding:7px 11px;
  border-bottom:1px solid var(--line); background:rgba(0,0,0,.3);
  font-family:"IBM Plex Mono",monospace; font-size:9.5px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--tx3)}
.hw-log .cap span{padding:2px 8px; border-radius:999px; background:var(--glass);
  color:var(--tx2); letter-spacing:0; text-transform:none}
.hw-log ul{margin:0; padding:8px 11px; list-style:none;
  font-family:"IBM Plex Mono",monospace; font-size:10px; color:var(--tx2)}
.hw-log li{padding:2.5px 0; display:flex; gap:9px; white-space:nowrap}
.hw-log .at{color:var(--tx3)} .hw-log .who{color:var(--ember-lit)}

/* ── ป้ายลอย ──
   ⛤ ต้องเด่นพอจะอ่านจากมุมตา — กรอบแดงเรือง + ตัวเลขใหญ่
   ⛔ ต้องลอยเหนือ/นอกหน้าต่าง ห้ามทับแถบหัวหรือเนื้อหา
      (หน้าต่างเอียง ⇒ ขอบบนลาด ต้องเผื่อระยะมากกว่ากล่องตรง ๆ)
   ⛔ และต้องไม่ชนแถบเมนูข้างบน — ช่องว่างระหว่างเมนูกับขอบหน้าต่างแคบ */
.hs-chip{position:absolute; z-index:4; padding:12px 18px; border-radius:15px;
  border:1px solid rgba(255,45,70,.42); background:rgba(14,7,10,.94);
  box-shadow:0 18px 44px rgba(0,0,0,.66), 0 0 26px rgba(255,45,70,.18),
    inset 0 1px 0 rgba(255,255,255,.06);
  backdrop-filter:blur(10px)}
.hs-chip small{display:block; font-family:"IBM Plex Mono",monospace;
  font-size:9.5px; letter-spacing:.2em; text-transform:uppercase;
  color:var(--ember-lit); margin-bottom:5px; opacity:.85}
.hs-chip b{font-family:"IBM Plex Mono",monospace; font-size:25px;
  font-weight:700; color:var(--tx); letter-spacing:-.5px; line-height:1.1;
  display:block; font-variant-numeric:tabular-nums}
.hs-chip b em{font-style:normal; font-size:11px; color:var(--tx3);
  margin-left:4px}
.hs-c1{top:-13%; left:8%}   .hs-c1 b{color:var(--ok)}
.hs-c2{top:-15%; right:19%} .hs-c2 b{color:var(--tx)}
.hs-c3{bottom:-9%; right:4%} .hs-c3 b{color:var(--gold)}

/* ── มาสคอต ──
   ⛤ ต้นฉบับ: คุกกี้ยืน "เกาะมุมล่างซ้ายของหน้าต่าง" ตัวคาบขอบหน้าต่างไว้
      ไม่ใช่ลอยอยู่ข้างล่างแยกกัน */
.hs-mascot{position:absolute; left:-7%; bottom:-14%; width:142px; z-index:6;
  pointer-events:none; filter:drop-shadow(0 18px 30px rgba(0,0,0,.75))}
.hs-mascot svg{width:100%; display:block}

/* ── คำชี้แจงใต้ภาพ (ห้ามหาย — เป็นภาพจำลอง ไม่ใช่ภาพหน้าจอจริง) ── */
.hs-note{margin:34px auto 0; font-size:11.5px; color:var(--tx3);
  text-align:center; max-width:min(62ch,100%)}

/* ══ จอแคบ: หน้าต่างโปรแกรมกลายเป็น "การ์ดแนวตั้ง" ══
   ⛔⛤ ของเดิมบังคับ min-width:760px แล้วให้เลื่อนซ้ายขวาเอา
      วัดจริงบนจอ 390: เห็นได้ครึ่งเดียว · หน้าแรกสูง 6,500px = 7.7 หน้าจอ
      และการปัดซ้ายขวาในหน้าที่เลื่อนลงอยู่ = ท่าที่นิ้วทำพร้อมกันไม่ได้
   ⇒ ไม่ย่อของเดิม แต่ **จัดใหม่ให้พอดีจอ**: ซ่อนเมนูซ้าย · ตัวเลข 2 คอลัมน์ ·
     จอเรียงลงมา · บันทึกเหลือ 3 บรรทัดล่าสุด แล้วมีลิงก์ไปหน้าเต็ม
   ⚠ ข้อมูลไม่หายสักอย่าง — ที่ตัดคือ "จำนวนบรรทัดที่โชว์" ไม่ใช่เนื้อหา */
@media(max-width:1059px){
  .hs-chip,.hs-mascot{display:none}
  /* ⛔ ก้อนแสงตั้งขนาดเป็น rem คงที่ (52rem = 832px) ⇒ บนจอ 320-390px
     มันยื่นพ้นขอบขวาจอ · ด่านกวาดความกว้างจับได้ ถึงหน้าจะไม่เลื่อน
     แนวนอนก็ตาม (เพราะ .hero{overflow:hidden} ตัดไว้)
     ⇒ ย่อให้พอดีจอ ไม่ใช่ไปแก้ด่าน */
  .hs-glow i{width:min(26rem,86vw); height:min(26rem,86vw)}
  .hs-g1{top:-6rem; left:-4rem}
  .hs-g2{top:22%; right:0}
  .hs-g3{bottom:-6rem; left:10%}

  .hs-wrap{overflow:visible; padding-bottom:0}
  .hs-win{transform:none; width:100%; min-width:0; transition:none;
    box-shadow:0 18px 44px rgba(0,0,0,.5)}
  .hs-note{text-align:left; margin-top:14px}

  /* แถบหัว: เหลือชื่อ+รุ่น+ปุ่มเริ่ม · ชิปที่เหลือเป็นของประดับบนจอเล็ก */
  .hw-page,.hw-btns,.hw-bar .hw-chip:not(.go){display:none}
  .hw-bar{padding:11px 12px}
  .hw-chip.go{margin-left:auto}

  /* เมนูซ้ายเป็นของสำหรับเมาส์ — บนจอเล็กกินที่ 146px โดยกดอะไรไม่ได้ */
  .hw-rail{display:none}
  .hw-body{display:block; min-height:0}
  .hw-main{padding:11px}

  .hw-head{padding:11px 12px; margin-bottom:10px}
  .hw-big{display:none}          /* เลขซ้ำกับการ์ด "รอบทั้งหมด" ข้างล่างพอดี */

  .hw-tiles{grid-template-columns:repeat(2,1fr); gap:8px; margin-bottom:10px}
  .hw-rows{grid-template-columns:1fr; gap:6px; margin-bottom:10px}
  /* จอเรียงลงมา: ชื่อซ้าย สถานะขวา อ่านจบในบรรทัดเดียว */
  .hw-row{display:flex; align-items:center; gap:9px; padding:10px 11px}
  .hw-row small{font-size:10px}
  .hw-row b{margin-top:0; margin-left:auto}

  /* ⚠ ตัดแค่ "จำนวนบรรทัดที่โชว์" — ของเต็มอยู่ที่ /web/program */
  .hw-log li:nth-child(n+4){display:none}
  .hw-log ul{padding:9px 11px}
  .hs-full{display:block; text-align:center; padding:13px;
    font-size:12.5px; font-weight:600; color:var(--ember-lit);
    border-top:1px solid var(--line); text-decoration:none}
}
/* ลิงก์ "ดูเต็ม ๆ" มีไว้ให้จอเล็กเท่านั้น — จอกว้างเห็นทุกอย่างอยู่แล้ว */
.hs-full{display:none}

/* จอเล็กมาก (≤400px): บีบระยะลงอีกขั้น ไม่งั้นการ์ดชนขอบ */
@media(max-width:400px){
  .hw-tiles{gap:7px}
  .hw-tile{padding:9px 10px}
  .hw-tile b{font-size:16px}
  .hw-main{padding:9px}
  .hs-note{font-size:11px}
}

/* ══ แอนิเมชันของหน้าแรก ══
   ⛔⛤ กติกาเดิมด้านบน (ห้ามแอนิเมชันวนไม่จบ เพราะหน้าแรกเปิดค้างทั้งวัน)
      ยังอยู่ครบ — แก้ด้วยการ **หยุดเองเมื่อพ้นจอหรือสลับแท็บ** ไม่ใช่ตัดทิ้ง
      วัดจริงแล้ว: เปิดครบ 1.5% ซีพียู · แรม JS เท่ากับตอนปิดหมดเป๊ะ
   ⚠ ห้ามตั้ง opacity:0 รอสคริปต์ — สคริปต์ไม่ทำงานเมื่อไหร่ = หน้าว่างถาวร
      ⇒ ของทุกชิ้นมองเห็นอยู่ก่อน แล้ว JS ค่อยเติมคลาส .hs-anim ทีหลัง */
@keyframes hsRise{from{opacity:0; transform:translateY(16px)}
  to{opacity:1; transform:none}}
@keyframes hsSlide{
  from{opacity:0; transform:translateX(46px) rotateY(-20deg) rotateX(6deg)
    rotate(-1deg) scale(.94)}
  to{opacity:1}}
@keyframes hsPop{from{opacity:0; transform:translateY(10px) scale(.9)}
  to{opacity:1; transform:none}}
@keyframes hsUp{from{opacity:0; transform:translateY(26px)}
  to{opacity:1; transform:none}}
.hs-anim .hs-r{animation:hsRise .62s cubic-bezier(.2,.7,.25,1) both}
.hs-anim .hs-r1{animation-delay:.04s} .hs-anim .hs-r2{animation-delay:.12s}
.hs-anim .hs-r3{animation-delay:.20s} .hs-anim .hs-r4{animation-delay:.28s}
/* ⚠ ต้องเป็น backwards ไม่ใช่ both — ท่าจบของ hsSlide ไม่ระบุ transform
   ⇒ เบราว์เซอร์วิ่งกลับไปหาค่าของ .hs-win เอง ซึ่งมีตัวแปรเอียงตามเมาส์อยู่
      ถ้าใช้ both ท่าสุดท้ายจะค้างทับตลอดกาล เอียงตามเมาส์จะไม่ทำงาน */
.hs-anim .hs-win{animation:hsSlide .82s cubic-bezier(.2,.7,.25,1) .10s backwards}
@keyframes hsFloat{0%,100%{transform:translateY(0)}
  50%{transform:translateY(-9px)}}
.hs-anim .hs-chip{animation:hsPop .5s cubic-bezier(.2,.7,.25,1) backwards,
  hsFloat 4.4s ease-in-out 1.4s infinite}
.hs-anim .hs-c1{animation-delay:.72s,1.4s}
.hs-anim .hs-c2{animation-delay:.84s,2.1s}
.hs-anim .hs-c3{animation-delay:.96s,2.8s}
.hs-anim .hs-mascot{animation:hsUp .7s cubic-bezier(.2,.7,.25,1) .62s both}

/* บรรยากาศ (วน แต่หยุดเองได้) */
@keyframes hsDrift{
  0%,100%{transform:translate3d(0,0,0) scale(1)}
  33%{transform:translate3d(3%,-4%,0) scale(1.06)}
  66%{transform:translate3d(-3%,3%,0) scale(.96)}}
@keyframes hsAurora{0%,100%{opacity:.88} 50%{opacity:1}}
.hs-glow i{animation:hsDrift 26s ease-in-out infinite,
  hsAurora 13s ease-in-out infinite}
.hs-g2{animation-delay:-9s,-4s} .hs-g3{animation-delay:-17s,-8s}

@keyframes hsBob{0%,100%{transform:translateY(0)} 50%{transform:translateY(-7px)}}
.hs-mascot svg{animation:hsBob 4.6s ease-in-out infinite}
@keyframes hsBlink{0%,92%,100%{transform:scaleY(0)} 95%{transform:scaleY(1)}}
.hs-lid{animation:hsBlink 5.2s ease-in-out infinite; transform-origin:center;
  transform-box:fill-box}

/* ปุ่ม "เริ่มการทำงาน" ในหน้าต่าง — เต้นเบา ๆ ให้รู้ว่ากดได้ */
@keyframes hsGlow{0%,100%{box-shadow:0 0 0 0 rgba(255,45,70,.42)}
  60%{box-shadow:0 0 0 7px rgba(255,45,70,0)}}
.hw-chip.go{animation:hsGlow 3.4s ease-in-out infinite}

/* ตัวเลขบนป้ายลอย — กะพริบสั้น ๆ ตอน "อัปเดต" */
@keyframes hsTick{0%,88%,100%{opacity:1} 92%{opacity:.35}}
.hs-chip b{animation:hsTick 6s ease-in-out infinite}
.hs-c2 b{animation-delay:-2s} .hs-c3 b{animation-delay:-4s}

/* วงแหวนกระเพื่อมรอบจุดสถานะ (ต้นฉบับ: pulse-ring) */
@keyframes hsRing{
  0%{box-shadow:0 0 0 0 rgba(127,224,127,.42)}
  70%,100%{box-shadow:0 0 0 10px rgba(127,224,127,0)}}
.hw-chip s{animation:hsRing 2.9s ease-out infinite}

/* แสงกวาดผ่านกระจกหน้าต่าง (ต้นฉบับ: sheen)
   0-62% ซ่อนนอกจอ ⇒ เห็นแวบเดียวทุก 8.5 วิ ไม่รบกวนสายตา */
@keyframes hsSheen{
  0%,62%{transform:translateX(-130%) skewX(-18deg)}
  86%,100%{transform:translateX(230%) skewX(-18deg)}}
.hs-win::after{content:""; position:absolute; top:0; bottom:0; left:0;
  width:34%; pointer-events:none; z-index:9; opacity:.5;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.11),transparent);
  transform:translateX(-130%) skewX(-18deg)}
.hs-anim .hs-win::after{animation:hsSheen 8.5s ease-in-out 1.6s infinite}

/* ⛔ หยุดลูปทั้งหมด — ส่วนที่ทำให้ผ่านกติกา "ห้ามวนไม่จบ"
   เปิดหน้าค้างไว้ทั้งวันก็ไม่กินซีพียู */
.hs-idle .hw-chip.go, .hs-idle .hs-chip b,
.hs-idle .hs-mascot svg, .hs-idle .hs-lid, .hs-idle .hw-chip s,
.hs-idle .hs-win::after, .hs-idle .hs-glow i, .hs-idle .hs-chip,
.hs-idle .hw-head .mark::before{animation-play-state:paused}

/* เลขไล่ขึ้น — ⚠ ต้องล็อกความกว้างตัวเลข ไม่งั้นเลขเปลี่ยน = ผังหน้าขยับทุกเฟรม */
[data-hscount],[data-hsclock],[data-hstick]{font-variant-numeric:tabular-nums}
/* บรรทัดที่เพิ่งไหลเข้ามาในบันทึกการทำงาน */
@keyframes hsFeedIn{from{opacity:0; transform:translateY(-8px)}
  to{opacity:1; transform:none}}
.hw-log li.fresh{animation:hsFeedIn .45s ease-out both}


/* ══════════════ แถบตัวหนังสือยักษ์วิ่ง (ยกจากเว็บต้นฉบับ) ══════════════
   ⛤ ต้นฉบับ: #kinetic1 + @keyframes marquee (46s/90s linear infinite)
      ไทยตัวใหญ่ไล่สีขาว→ส้มแดง คู่กับอังกฤษตัวเล็กโมโนสเปซ คั่นด้วย /
   ⛔ เนื้อหาต้องซ้ำสองชุดเป๊ะ ๆ เพราะคีย์เฟรมเลื่อน -50% พอดี
      ถ้าใส่ชุดเดียวจะเห็นช่องว่างวิ่งผ่านทุกครั้งที่วน
   ⚠ ตัวหนังสือกว้างกว่าจอตลอด — ต้องมี overflow:hidden ที่กล่องนอก */
.kine{position:relative; overflow:hidden; padding:34px 0;
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  background:rgba(0,0,0,.28)}
.kine .track{display:flex; width:max-content; gap:34px;
  will-change:transform}
.kine .grp{display:flex; align-items:baseline; gap:14px; flex:none}
.kine .th{font-family:"Space Grotesk","Anuphan",system-ui,sans-serif;
  font-size:clamp(24px,3.4vw,42px); font-weight:700; line-height:1.45;
  letter-spacing:-.01em; white-space:nowrap;
  background:linear-gradient(180deg,#fff,var(--ember-lit));
  -webkit-background-clip:text; background-clip:text; color:transparent}
.kine .en{font-family:"IBM Plex Mono",monospace; font-weight:600;
  font-size:clamp(11px,1.15vw,15px); letter-spacing:.26em;
  text-transform:uppercase; color:rgba(255,255,255,.3); white-space:nowrap}
.kine .sl{font-size:clamp(24px,3.4vw,42px); font-weight:700;
  color:rgba(255,45,70,.45)}
/* ขอบซ้าย-ขวาจางหายไปกับพื้น ไม่ให้ตัวหนังสือโผล่มาแบบตัดตรง ๆ */
.kine::before,.kine::after{content:""; position:absolute; top:0; bottom:0;
  width:150px; pointer-events:none; z-index:2}
.kine::before{left:0; background:linear-gradient(90deg,var(--bg),transparent)}
.kine::after{right:0; background:linear-gradient(270deg,var(--bg),transparent)}
@keyframes hsMarquee{from{transform:translateX(0)} to{transform:translateX(-50%)}}
.hs-run .kine .track{animation:hsMarquee 62s linear infinite}
.hs-idle-kine .kine .track{animation-play-state:paused}

/* ตาคุกกี้มองตามเมาส์ + ทั้งตัวขยับสวนเมาส์นิดหน่อย (ยกจากต้นฉบับ)
   ⛤ ต้นฉบับ: .mascot-pupil translate(--eye-x*1.8px, --eye-y*1.4px)
      และ #mascot translate3d(--look-x, --look-y, 0) */
.hs-mascot{transform:translate3d(var(--hs-lookx,0px),var(--hs-looky,0px),0);
  transition:transform .7s cubic-bezier(.16,1,.3,1)}
.hs-pupil{transform:translate(calc(var(--hs-eyex,0) * 1.8px),
  calc(var(--hs-eyey,0) * 1.4px));
  transition:transform .3s cubic-bezier(.16,1,.3,1)}

@media(max-width:1059px){ .kine{padding:22px 0} }

/* ⚠ ระบบสั่งลดการเคลื่อนไหว — ปิดให้ทั้งหมด **เว้นแต่ผู้ใช้กดเปิดเอง**
   (?motion=on) · และ ?motion=off ต้องปิดได้แม้ระบบไม่ได้สั่ง */
.hs-off .hs-glow i,.hs-off .hs-mascot svg,.hs-off .hs-lid,
.hs-off .hw-chip.go,.hs-off .hs-chip b,.hs-off .hs-chip,
.hs-off .hw-chip s,.hs-off .hs-win::after,.hs-off .hs-win,
.hs-off .hw-head .mark::before,.hs-off .hw-log li.fresh,
.hs-off .kine .track,.hs-off .hs-pupil{
  animation:none !important; transition:none !important}
@media(prefers-reduced-motion:reduce){
  :root:not(.hs-on) .hs-glow i,:root:not(.hs-on) .hs-mascot svg,
  :root:not(.hs-on) .hs-lid,:root:not(.hs-on) .hw-chip.go,
  :root:not(.hs-on) .hs-chip b,:root:not(.hs-on) .hs-chip,
  :root:not(.hs-on) .hw-chip s,:root:not(.hs-on) .hs-win::after,
  :root:not(.hs-on) .hs-win,:root:not(.hs-on) .hw-head .mark::before,
  :root:not(.hs-on) .hw-log li.fresh,
  :root:not(.hs-on) .kine .track,:root:not(.hs-on) .hs-pupil{
    animation:none !important; transition:none !important}
}

/* ══════════════ คลังคีย์ v3 (2026-09-13 รอบ 4) ══════════════
   ⛔⛤ ที่มา: เจ้าของแจ้ง "คีย์จะล้นคลังแล้วมันเกะกะ" + หน้าเดิมเยอะเกินไป
      ของเดิม 1 ใบ = 6 ปุ่มขนาดเท่ากัน + กล่องตัวเลข 4 ช่อง ⇒ ใบที่ตายแล้ว
      กินที่เท่าใบที่ใช้อยู่เป๊ะ ๆ ทั้งที่ทำอะไรกับมันไม่ได้
   ⇒ ใบที่ใช้ได้ = การ์ดเต็ม (2 ปุ่ม + เมนู ⋯) · ใบที่ตายแล้ว = แถวบาง
      · ใบที่เอาออก = ลิ้นชักพับล่างสุด
   ⚠ คลาสทุกตัวในหมวดนี้ขึ้นต้น k- เพื่อกันชนกับผิวหน้าร้าน
     (บทเรียน .foot/.adtop/.adacts รั่วข้ามหน้า 09-11) */
.vmain{min-width:0}

/* รหัสคีย์ — ชิดขวาบนจอกว้าง แต่ขึ้นบรรทัดของตัวเองบนจอแคบ
   ⚠ ห้ามปล่อยให้ดันการ์ดกว้างเกินจอ */
.kstr{margin-left:auto; font-family:"IBM Plex Mono",monospace; font-size:13.5px;
  color:var(--tx2); letter-spacing:.02em; white-space:nowrap}
.kbadge{font-size:11px; font-family:"IBM Plex Mono",monospace; padding:2px 9px;
  border-radius:999px; border:1px solid var(--line); color:var(--tx3)}
.kbadge.on{color:var(--ok); border-color:rgba(127,224,127,.3); background:rgba(127,224,127,.07)}
.kbadge.perm{color:var(--gold); border-color:rgba(255,194,77,.3); background:rgba(255,194,77,.07)}
.kbadge.wait{color:var(--warn); border-color:rgba(224,168,119,.3); background:rgba(224,168,119,.07)}

/* ⛤ บรรทัดเดียวแทนกล่องตัวเลข 4 ช่อง — อ่านรวดเดียวจบ ไม่ต้องกวาดตา */
.kfacts{display:flex; gap:8px 20px; flex-wrap:wrap; font-size:13px; color:var(--tx3);
  min-width:0; overflow-wrap:anywhere; margin-top:2px}
.kfacts b{color:var(--tx2); font-weight:500}
.kfacts .mono{font-family:"IBM Plex Mono",monospace; font-size:12px}
.kfacts .warnx{color:var(--warn)}

/* เมนู ⋯ — ของที่ใช้นาน ๆ ครั้ง ไม่ควรกินที่เท่าปุ่มที่ใช้ทุกเดือน */
.kmenuwrap{position:relative; margin-left:auto; display:inline-flex}
/* ⛔⤤ ปุ่มนี้เก็บปุ่มรองทุกตัวไว้ข้างหลัง ⇒ ถ้าจางจนดูเหมือนกล่องเปล่า
   คนจะหาไม่เจอเลยว่าย้ายเครื่อง/ดาวน์โหลด/เอาออก อยู่ตรงไหน (เจอตอนเปิดหน้าจริง) */
.btn.kdot{font-family:"IBM Plex Mono",monospace; letter-spacing:.12em;
  font-size:17px; line-height:1; padding:7px 14px; color:var(--tx2)}
.btn.kdot:hover,.btn.kdot[aria-expanded="true"]{color:var(--tx);
  border-color:var(--line-2); background:var(--glass-2)}
/* ⛔⤤ เมนูต้องเป็น fixed และถูกแขวนไว้ที่ <body> เท่านั้น
   การ์ดคีย์มี `overflow:hidden` (จำเป็น — แถบไล่สีด้านบนต้องโค้งตามมุม)
   ⇒ เมนูที่เป็นลูกของการ์ด **ถูกตัดหายเกือบหมด** เห็นแค่รายการแรก
   ⚠ z-index ต้องสูงกว่าแถบบน (80) แต่ต่ำกว่ากล่องยืนยัน (115) */
/* ⚠ ต้องเป็น width ตายตัว ไม่ใช่ min-width — ตัววางเมนูวัดความสูง
   ก่อนจะรู้ว่าจะเปิดขึ้นหรือลง ถ้าความกว้างยังไม่นิ่ง ข้อความจะตัดบรรทัดต่างกัน
   ⇒ วัดความสูงผิด ⇒ เมนูล้นขอบล่างจอบนมือถือ (เจอจริงที่ 390×844) */
.kmenu{position:fixed; z-index:100; width:236px; max-width:calc(100vw - 16px);
  background:var(--surface); border:1px solid var(--line); border-radius:12px;
  box-shadow:var(--shadow-hi); padding:6px; display:flex; flex-direction:column}
.kmenu button{font:inherit; font-size:13.5px; text-align:left; cursor:pointer;
  padding:8px 11px; border:0; border-radius:8px; background:transparent; color:var(--tx2)}
.kmenu button:hover{background:var(--glass-2); color:var(--tx)}
.kmenu button:disabled{opacity:.45; cursor:default}
.kmenu button .k{float:right; font-family:"IBM Plex Mono",monospace; font-size:11px;
  color:var(--tx3)}
.kmenu .ksep{border:0; border-top:1px solid var(--line); margin:5px 2px}
.kmenu button.kdanger{color:var(--bad)}
.kmenu button.kdanger:hover{background:rgba(255,107,90,.1)}

/* ⛤ ใบที่ทำอะไรไม่ได้แล้ว = แถวบาง สูงราว 1 ใน 5 ของการ์ดเต็ม */
.kbar{display:flex; align-items:center; gap:10px; padding:9px 14px; margin-bottom:7px;
  border:1px solid var(--line); border-radius:11px; background:rgba(255,255,255,.018);
  font-size:13.5px; color:var(--tx3); flex-wrap:wrap}
.kbar .ic{font-size:13px; opacity:.7}
.kbar .kstr{font-size:13px; margin-left:0}
.kbar .kwhen{font-size:12.5px}
.kbar .ksp{margin-left:auto; display:flex; gap:7px; flex-wrap:wrap}

/* หัวกลุ่มคั่นในรายการ */
.kgrp{display:flex; align-items:center; gap:10px; margin:20px 0 9px;
  font-family:"IBM Plex Mono",monospace; font-size:11px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--tx3)}
.kgrp .ln{flex:1; height:1px; background:var(--line)}

/* แถบเก็บกวาด — โทนส้ม เพราะเป็น "ควรรู้" ไม่ใช่ "อันตราย" */
.ksweep{display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  border:1px solid rgba(224,168,119,.28); background:rgba(224,168,119,.05);
  border-radius:12px; padding:11px 15px; margin:14px 0 0; font-size:13.5px;
  color:var(--tx2)}
.ksweep b{color:var(--warn); font-weight:600}
.ksweep .sp{margin-left:auto}

/* ลิ้นชักใบที่เอาออกแล้ว + กลุ่มใบเก่าที่พับเอง */
.kdrawer,.kold{border:1px solid var(--line); border-radius:12px;
  background:rgba(255,255,255,.015); overflow:hidden}
.kdrawer{margin-top:18px}
.kold{margin-top:4px}
.kdrawer>summary,.kold>summary{cursor:pointer; padding:12px 16px; font-size:13.5px;
  color:var(--tx3); list-style:none; display:flex; align-items:center; gap:9px}
.kdrawer>summary::-webkit-details-marker,
.kold>summary::-webkit-details-marker{display:none}
.kdrawer>summary::before,.kold>summary::before{content:"▸"; font-size:11px;
  transition:transform .18s var(--ease)}
.kdrawer[open]>summary::before,.kold[open]>summary::before{transform:rotate(90deg)}
.kdrawer>summary:hover,.kold>summary:hover{color:var(--tx2)}
.kdbody{padding:2px 14px 12px}
.kdbody .kbar:last-child{margin-bottom:0}

@media(max-width:560px){
  /* บนจอแคบรหัสคีย์ต้องได้บรรทัดของตัวเอง ไม่ใช่ดันการ์ดกว้างเกินจอ */
  .kstr{margin-left:0; white-space:normal; overflow-wrap:anywhere; width:100%}
  .kbar .ksp{margin-left:0; width:100%}
  .kmenuwrap{margin-left:0}
}

/* ══════════════ คลังคีย์ v4 — ปักหมุด · เตือนก่อนหมด · เส้นเวลา (รอบ 5) ══════════════ */

/* ⭐ ปักหมุด — จางไว้จนกว่าจะปัก ไม่งั้นดาวเต็มหน้าจนไม่รู้ว่าอันไหนถูกปักจริง */
.kpin{border:0; background:transparent; cursor:pointer; font-size:15px; line-height:1;
  padding:3px 5px; border-radius:6px; color:var(--tx3); opacity:.42;
  transition:all .15s var(--ease)}
.kpin:hover{opacity:.9; background:var(--glass-2)}
.kpin.on{opacity:1; color:var(--gold); filter:drop-shadow(0 0 5px rgba(255,194,77,.5))}
.kpin:disabled{cursor:default}
.keycard.pinned{background:linear-gradient(180deg,rgba(255,194,77,.06),var(--glass))}
.keycard.pinned::before{background:linear-gradient(90deg,var(--gold),var(--ember))}

/* ✏ ชื่อเล่นพิมพ์ทับได้บนการ์ดเลย — ไม่ต้องเปิดกล่อง */
.knick{font:inherit; font-weight:600; font-size:15px; color:var(--tx);
  border:0; border-bottom:1px dashed transparent; background:transparent;
  padding:2px 5px; border-radius:6px 6px 0 0; min-width:80px;
  transition:all .15s var(--ease)}
.knick:hover{border-bottom-color:var(--line)}
.knick:focus{outline:0; background:rgba(255,255,255,.06); border-bottom-color:var(--ember-lit)}
.knick::placeholder{color:var(--tx3); font-weight:400; font-style:italic}
.knick:disabled{opacity:.5}

/* ราคาบนปุ่มต่ออายุ — เห็นราคาก่อนกด */
.kpx{font-family:"IBM Plex Mono",monospace; font-size:11px; opacity:.78; margin-left:7px}
/* ปุ่มคัดลอกบอกผลกับตัวเอง */
.btn.kok{background:rgba(127,224,127,.12); border-color:rgba(127,224,127,.42);
  color:var(--ok)}

/* 🔔 แถวสวิตช์ "เตือนก่อนใบนี้หมด" */
.kwarn{display:flex; align-items:center; gap:11px; margin-top:12px; padding-top:11px;
  border-top:1px dashed var(--line); font-size:13px; color:var(--tx3); cursor:pointer}
.kwarn.off{opacity:.62; cursor:default}
.kwarn b{color:var(--info); font-weight:500}
/* ตัวจริงคือ checkbox — ซ่อนสายตาแต่ยังโฟกัสได้ (ห้ามใช้ display:none) */
.kswin{position:absolute; width:1px; height:1px; opacity:0; margin:0; pointer-events:none}
.ksw{position:relative; width:38px; height:21px; flex:none; border-radius:999px;
  border:1px solid var(--line); background:rgba(255,255,255,.05);
  transition:all .18s var(--ease)}
.ksw::after{content:""; position:absolute; left:2px; top:2px; width:15px; height:15px;
  border-radius:50%; background:var(--tx3); transition:all .18s var(--ease)}
.kswin:checked + .ksw{background:rgba(95,208,232,.2); border-color:rgba(95,208,232,.5)}
.kswin:checked + .ksw::after{left:19px; background:var(--info)}
.kswin:focus-visible + .ksw{outline:2px solid var(--vio-lit); outline-offset:3px}
.kswin:disabled + .ksw{opacity:.5}

/* ══ เส้นเวลาคีย์ทั้งคลัง ══
   ⚠ overflow:hidden กันป้ายชื่อที่ปลายเส้นดันจนล้นการ์ด */
.ktl{border:1px solid var(--line); border-radius:14px; background:var(--glass);
  padding:14px 18px 11px; margin-bottom:16px; overflow:hidden}
.ktl h4{margin:0 0 12px; font-size:13px; font-weight:600; color:var(--tx2);
  display:flex; align-items:center; gap:8px}
.ktl h4 span{font-family:"IBM Plex Mono",monospace; font-size:11px; color:var(--tx3);
  margin-left:auto}
.ktlbar{position:relative; height:44px; margin:0 26px 6px}
.ktlaxis{position:absolute; left:0; right:0; top:26px; height:1px; background:var(--line)}
.ktltick{position:absolute; top:30px; font-family:"IBM Plex Mono",monospace;
  font-size:10px; color:var(--tx3); transform:translateX(-50%); white-space:nowrap}
.ktltick i{position:absolute; left:50%; top:-5px; width:1px; height:4px;
  background:var(--line); display:block}
.ktlpin{position:absolute; top:4px; transform:translateX(-50%)}
.ktlpin b{display:block; width:11px; height:11px; border-radius:50%; margin:0 auto;
  border:2px solid var(--bg-soft)}
.ktlpin em{position:absolute; left:50%; top:-17px; transform:translateX(-50%);
  font-family:"IBM Plex Mono",monospace; font-size:9.5px; font-style:normal;
  white-space:nowrap; color:var(--tx3); opacity:0;
  transition:opacity .15s var(--ease)}
.ktlpin:hover em, .ktlpin:focus-within em{opacity:1}
.ktlnow{position:absolute; left:0; top:12px; bottom:8px; width:2px;
  background:var(--ember); box-shadow:0 0 8px var(--ember)}

/* ══════════════ คลังคีย์ v5 — แถบการใช้งาน + ตัวช่วยแก้ปัญหา (รอบ 6) ══════════════ */

/* แถบ "บัญชีนี้เปิดบอทจริงกี่วัน"
   ⛔ เป็นตัวเลขของ **บัญชี** ไม่ใช่ของคีย์ใบใดใบหนึ่ง — ห้ามย้ายไปวางบนการ์ด */
.kuse{border:1px solid var(--line); border-radius:14px; background:var(--glass);
  padding:13px 18px 12px; margin-bottom:14px}
.kuse h4{margin:0 0 11px; font-size:13px; font-weight:600; color:var(--tx2);
  display:flex; align-items:center; gap:8px}
.kuse h4 span{font-family:"IBM Plex Mono",monospace; font-size:11px; color:var(--tx3);
  margin-left:auto}
.kuserow{display:flex; align-items:center; gap:14px; flex-wrap:wrap}
.kudots{display:flex; gap:3px; flex-wrap:wrap}
.kudots i{display:block; width:7px; height:17px; border-radius:2px;
  background:rgba(255,255,255,.08)}
.kudots i.on{background:var(--ok); opacity:.85}
.kusetx{font-size:13px; color:var(--tx3)}
.kusetx b{color:var(--ok); font-weight:600; font-size:14.5px}
.kusetx b.warnx{color:var(--warn)}

/* ปุ่ม + แผ่น "คีย์ใช้ไม่ได้?" */
.btn.khelp{border-color:rgba(95,208,232,.35); color:var(--info); background:transparent}
.btn.khelp:hover{border-color:var(--info); background:rgba(95,208,232,.08)}
.kstep{display:flex; gap:12px; padding:12px 0; border-bottom:1px solid var(--line)}
.kstep:last-of-type{border-bottom:0}
.kstep>b{flex:none; width:25px; height:25px; border-radius:50%; font-size:12px;
  display:grid; place-items:center; background:var(--glass-2); color:var(--tx2);
  font-family:"IBM Plex Mono",monospace; font-weight:500}
.kstep .t{min-width:0; font-size:13.5px}
.kstep .t .hd{font-weight:500; color:var(--tx)}
.kstep .t em{display:block; font-style:normal; color:var(--tx3); font-size:12.5px;
  margin-top:3px; line-height:1.6}
.khelpbtn{margin-top:9px}
.khelpbtn .k{font-family:"IBM Plex Mono",monospace; font-size:11px; color:var(--tx3);
  margin-left:7px}
.kinfo{margin-top:16px; padding-top:14px; border-top:1px dashed var(--line)}
.kinfo h3{margin:0 0 4px; font-size:14px; font-weight:600}
.kinfoline{display:block; font-family:"IBM Plex Mono",monospace; font-size:12px;
  color:var(--tx2); background:rgba(255,255,255,.05); border:1px solid var(--line);
  border-radius:9px; padding:9px 11px; margin:9px 0 11px; overflow-wrap:anywhere;
  user-select:all}

/* ══════════════ หลังร้านบนมือถือ — เป้าแตะ (2026-09-13 · ตรวจรอบใหญ่) ══════════════
   ⛔⛤ ตัววัดจอมือถือเดิมวัดแค่หน้าฝั่งลูกค้า **หลังร้านไม่เคยถูกวัดเลยสักครั้ง**
      ทั้งที่เจ้าของเปิดดูจากมือถือเป็นหลัก (ส่งภาพหน้าจอมือถือมาตลอด)
      ⇒ พอเพิ่ม 7 หน้าหลังร้านเข้าไปวัด เจอเป้าแตะต่ำกว่า 44px ทุกหน้า
   ⚠ ขยายเฉพาะจอที่กดด้วยนิ้ว — บนเดสก์ท็อปความหนาแน่นเดิมดีอยู่แล้ว */
@media (pointer:coarse), (max-width:900px){
  /* ⭐ ปุ่มปักหมุดบนการ์ดคีย์ — ตัวดาวเล็กแค่ 23×21
     ⚠ ขยาย "พื้นที่กด" ด้วย padding แล้วหักคืนด้วย margin ติดลบ
       ⇒ ดาวยังเล็กเท่าเดิม แต่นิ้วกดโดนแน่ (ของที่เพิ่งทำวันนี้ ตรวจรอบสามเจอ) */
  .kpin{min-width:44px; min-height:44px; display:inline-grid; place-items:center;
    padding:0; margin:-11px -10px}
  /* ลิงก์ "ย้อนกลับ" สูงแค่ 21px */
  .adback{min-height:44px; display:inline-flex; align-items:center}
  /* ปุ่มเปิดรางเมนู กว้างหดตามจอจนเหลือ 33px */
  .adrailbtn{min-width:44px; flex:none}
  /* ชิปกรองสูง 33px ทุกหน้า — เป็นของที่กดบ่อยที่สุดในหลังร้าน */
  .adchip{min-height:44px}
  /* ช่องค้นหาสูง 26px · เมนูเลือกสูง 36px
     ⚠ ช่องค้นของหลังร้าน **ไม่มีคลาส** (ใช้ id อย่างเดียว) ⇒ ต้องจับด้วยชนิด
       ไม่ใช่ชื่อคลาส — จับด้วยคลาสแล้วไม่โดนเลย (เจอตอนตรวจรอบสอง) */
  select.adsel{min-height:44px}
  input[type=search], input[type=text], input[type=number],
  input[type=date], input[type=email]{min-height:44px}
}
/* ⚠ ชิปบัญชีบังคับกว้าง 44px **เฉพาะจอที่แคบจนเหลือแต่รูป** (ต่ำกว่า 480px)
   ถ้าบังคับที่จอกว้างกว่านั้นด้วย ชื่อผู้ใช้ยาว ๆ จะถูกบีบจนโดนตัดปลาย
   (เจอตอนตรวจรอบสอง: จอ 540px ชื่อ "demoadmin" โดนตัด 3px) */
@media (max-width:479px){
  .chipacct{min-width:44px; justify-content:center}
}
/* ⛔⛤ ช่วง 480-659px: แถบบนหลังร้านแน่นจนชิปบัญชีถูกบีบ แล้วชื่อผู้ใช้
   โดนตัดปลายแค่ 2-3px ("demoadmin" → "demoadmi…") ซึ่งดูเหมือนหน้าพัง
   มากกว่าดูเหมือนตั้งใจย่อ ⇒ ซ่อนชื่อไปเลยเหลือแต่รูป เหมือนที่จอแคบกว่านี้ทำ
   ⚠ ชื่อยังอยู่ในโค้ด โปรแกรมอ่านหน้าจอยังอ่านได้ (เจอตอนตรวจรอบสอง) */
@media (max-width:659px){
  .adtopbar .chipacct{min-width:44px; justify-content:center}
  .adtopbar .chipacct > :not(.av){display:none}
}

/* คลาสแทน style ที่เคยฝังในแท็ก — สร้างโดย tools/build_webstore.py */
.u1{width:74%}
.u2{text-align:center}
.u3{height:40px}
.u4{margin-top:16px}
