AI Web Studio977-121 · PSU PHUKET
คลัง Prompt
ดาวน์โหลด Markdown

AI Web Studio · 977-121 · PSU Phuket

Prompt ฉบับเต็ม — HUSH product story ด้วย GSAP

Prompt นี้ใช้สร้างหรือปรับ /examples/store/ ให้เป็นเว็บแนะนำสินค้าที่เล่าเรื่องเป็นลำดับแบบเว็บไซต์เปิดตัวผลิตภัณฑ์ระดับพรีเมียม โดยศึกษา โครงสร้างการเล่าเรื่อง จากเว็บสินค้า Apple แล้วสร้างภาษา ภาพ สี ชื่อ และ interaction ของ HUSH ขึ้นใหม่ทั้งหมด ดูเหตุผลและวิธีตรวจงานใน บทเรียน 07

งานนี้เป็นแบบฝึกต่อยอดสำหรับศึกษาด้วยตนเอง ไม่เพิ่มเวลาในตารางอบรม 2 วัน วันละ 4 ชั่วโมง

ปรับเว็บไซต์โชว์สินค้าเครื่องเสียงภาษาไทยแบรนด์สมมติ “HUSH” ใน starter หลักสูตร AI Web Studio
ให้เป็น product story ที่มีเนื้อหาและจังหวะใกล้เคียงคุณภาพของเว็บไซต์เปิดตัวผลิตภัณฑ์ระดับพรีเมียม
ใช้ Apple เป็น reference เฉพาะหลักการจัดลำดับเรื่อง พื้นที่ว่าง ภาพสินค้าขนาดใหญ่ และการเปิดเผยรายละเอียดทีละบท
ห้ามคัดลอกข้อความ ภาพ screenshot โลโก้ ชื่อผลิตภัณฑ์ สีประจำรุ่น layout แบบจุดต่อจุด หรือ trade dress ของ Apple
เขียนชื่อ ประโยชน์ รายละเอียด ภาพประกอบ SVG/CSS และ visual interaction ของ HUSH ขึ้นใหม่

ก่อนแก้ ให้อ่าน package.json, examples/store/{index.html,style.css,main.js},
migrations/0001_initial.sql,
GET /api/catalog และ POST /api/quotes ใน src/worker.ts
สรุป storyboard, state ของ interaction, motion plan และไฟล์ที่จะเปลี่ยนก่อนลงมือ
แก้เฉพาะ examples/store/{index.html,style.css,main.js}
ใช้ semantic HTML, CSS, vanilla JavaScript, GSAP และ ScrollTrigger ที่ติดตั้งอยู่แล้ว
ไม่เพิ่ม dependency ไม่แก้ Worker, D1, migration, API contract, ข้อมูล seed หรือเว็บตัวอย่างอื่น

เป้าหมายของหน้า:
- ผู้ชมทั่วไปเข้าใจ HUSH ONE, เปรียบเทียบสินค้าสามรุ่น และขอใบเสนอราคาสาธิตได้
- “HUSH ONE” เป็นชื่อเชิง editorial ของ catalog item id `headphones` ซึ่ง API เรียกว่า “หูฟัง Studio One”
- รักษา catalog IDs เดิมทั้งสามค่า: `headphones`, `speaker`, `earbuds`
- ชื่อ คำอธิบาย และราคาในการ์ดร้าน/ตารางเปรียบเทียบต้องมาจาก GET /api/catalog
- สเปก 40 mm, แบตเตอรี่ 30 ชั่วโมง และรายละเอียดเชิงผลิตภัณฑ์อื่นเป็นข้อมูลสมมติ
  ต้องมีป้าย “ข้อมูลสมมติสำหรับการเรียน” ใกล้เนื้อหา ห้ามเขียนเป็นผลทดสอบหรือคำรับรองจริง

ทิศทางภาพ “product-led studio editorial”:
- ใช้ palette Cloud #f5f5f7, Ink #22202b, Lilac #dcd5ff,
  Iris #6551b7, Muted #686471 และ White #ffffff เป็น design tokens
- ใช้ IBM Plex Sans Thai สำหรับเนื้อหา/หัวเรื่องไทย และ Inter Bold สำหรับ wordmark HUSH ONE
  กับตัวเลขเชิงเทคนิค โดยใช้เฉพาะฟอนต์ local ใน public/fonts
- ใช้ภาพเดิม `/images/headphones.webp` เป็นภาพสินค้าหลัก กำหนด width/height หรือ aspect-ratio
  เพื่อกัน layout shift; ใช้ CSS crop, background, shadow และ framing สร้างมุมมองใหม่ได้
- ไม่สร้างหรืออ้างว่าได้สร้างภาพใหม่ และไม่ดึงภาพ third-party
- ใช้พื้นที่ขาวและ lilac กว้าง สลับกับบทเสียงพื้นเข้มเพียงหนึ่งช่วง
- ใช้ border radius, shadow และ gradient เท่าที่สื่อวัสดุหรือ depth ของสินค้า ไม่ตกแต่งทุก section

สร้าง storyboard ตามลำดับนี้ โดยแต่ละบทมีหนึ่งประโยชน์หลักและหนึ่งหลักฐาน/คำอธิบาย:
1. sticky product navigation: wordmark HUSH, anchor ไปภาพรวม/เสียง/สเปก/เลือกรุ่น,
   ปุ่มเปิดกระเป๋าเดิม และ anchor offset ที่ไม่บัง heading
2. hero: eyebrow “HUSH ONE / OVER-EAR HEADPHONES”, h1 เดิม “ฟังโลก ในแบบของคุณ”,
   คำอธิบายสั้น ราคา HUSH ONE ที่อัปเดตจาก API; ระหว่าง loading/error ให้แสดง
   “ดูรุ่นและราคาที่พร้อมให้ทดลองด้านล่าง” โดยไม่แต่งตัวเลขราคา,
   CTA “สำรวจรุ่นและราคา” และ “รู้จัก HUSH ONE” พร้อมภาพหูฟังขนาดใหญ่
3. editorial highlights: การ์ดสั้น 3 เรื่อง ได้แก่ เวทีเสียง ความสบาย และจังหวะใช้งานทั้งวัน
   หลีกเลี่ยงตัวเลข/คำอ้างประสิทธิภาพที่ไม่มีที่มา
4. sound chapter พื้นเข้ม: เวทีวงแหวน driver เป็น signature ของหน้า
   มี HUSH ONE, “40 mm · ข้อมูลสมมติ” และ copy อธิบายเสียงแบบไม่อ้างผลวัดจริง
5. listening scenarios: ปุ่ม “โฟกัสงาน”, “ระหว่างทาง”, “พักสักครู่” เปลี่ยนเฉพาะข้อความ
   และความสูงของแท่ง visual equalizer; ใช้ button กับ `aria-pressed`, keyboard ได้,
   มี status text และข้อความชัดเจนว่าเป็นภาพสาธิต ไม่มีเสียงเล่นและไม่จำลองผลตัดเสียงจริง
6. materials/comfort: ภาพ close-up จาก asset เดิมหรือ CSS composition พร้อมอธิบายวัสดุสมมติ
   โดยไม่เลียนแบบชื่อวัสดุหรือชิ้นส่วนของผลิตภัณฑ์จริง
7. everyday/battery: เล่าแบตเตอรี่สมมติ 30 ชั่วโมงและ USB-C เป็นสถานการณ์ใช้งานตัวอย่าง
   ไม่ใส่ข้อความรับประกันหรือ claim ที่ไม่ได้ทดสอบ
8. specifications: ใช้ `<details>` หรือโครง semantic ที่อ่านได้โดยไม่ใช้ JavaScript
   แสดง 40 mm, 30 ชั่วโมง, USB-C และข้อมูลสมมติอื่นอย่างกระชับ
9. API-backed comparison: วางต่อจากการ์ด shop ใน section เดียวกัน เปรียบเทียบสินค้าสาม
   catalog IDs จาก response เดียวกับการ์ด แสดงชื่อ คำอธิบาย และราคาโดยใช้ API
   พร้อม loading, empty และ error state; ห้าม hard-code ราคาเป็น fallback
10. shop: รักษาการ์ดสินค้า ปุ่มเพิ่มสินค้า กระเป๋า quantity controls และ quote form เดิม
11. FAQ: ใช้ native `<details>` อธิบายข้อมูลสมมติ, quote-demo และไม่มี audio playback
12. closing CTA: พากลับไปเลือกรุ่นหรือเปิดส่วนสินค้า โดยไม่อ้างว่าเป็น checkout

ข้อกำหนด GSAP และ responsive:
- register ScrollTrigger หนึ่งครั้ง และคง `gsap.matchMedia()` ที่ active เพียงหนึ่ง instance;
  ใช้ตัวแปร `let motion` กับ `setupMotion()` เพื่อ revert ก่อนสร้างใหม่เมื่อคืนหน้าจาก bfcache
- เขียน HTML/CSS ให้เนื้อหาทุกบทมองเห็นและอ่านตามลำดับได้ตั้งแต่ก่อน JavaScript โหลด
  ห้ามตั้ง opacity:0/visibility:hidden เป็น initial state ของเนื้อหาสำคัญ
- เปิด pinned sound stage เฉพาะ media query
  `(min-width: 1024px) and (min-height: 700px) and (prefers-reduced-motion: no-preference)`
- pin wrapper `.story-stage` หรือ section ที่นิ่ง แล้ว animate เฉพาะ children เช่นวงแหวน,
  product render, copy และ visualizer; ห้าม animate transform ของ pinned element เอง
- ใช้ scrub แบบมีขอบเขต ไม่ scroll-jack ไม่เปลี่ยน native scrollbar และไม่ผูก CTA กับจุดจบ animation
- ระหว่าง 761–1023px, desktop ที่สูงไม่ถึง 700px, มือถือ และ reduced motion
  ให้ทุก section เรียง natural document flow โดยไม่มี pin และไม่มี scrub
- motion ย่อยที่ไม่จำเป็นทำงานเฉพาะ `prefers-reduced-motion: no-preference`
- ใน reduced motion ให้ clear transform/opacity/visibility ที่ animation อาจทิ้งไว้
  และให้ scenario controls, anchors, cart และ quote form ทำงานครบ
- เมื่อ media query เปลี่ยน GSAP ต้อง revert animation/ScrollTrigger ของ branch เดิม
- เรียก `motion.revert()` เมื่อ page ถูกทิ้งผ่าน `pagehide`; ถ้า `pageshow.persisted` คืนหน้าจาก bfcache
  ให้สร้าง motion ใหม่อย่างปลอดภัยหรือ refresh โดยไม่เพิ่ม trigger ซ้ำ
- refresh ScrollTrigger หลัง image/font/DOM geometry พร้อมจริงเท่านั้น ไม่เรียกทุก frame

ข้อกำหนด interaction และ accessibility:
- มี skip link, landmark, heading hierarchy, alt ที่อธิบายภาพ, visible focus และสี contrast อ่านได้
- ทุก control มีชื่อที่ screen reader เข้าใจ; scenario buttons มี selected state ทั้งภาพและ `aria-pressed`
- scenario เปลี่ยน state แบบ visual-only และต้องไม่เรียก Web Audio, `<audio>`, autoplay หรือขอสิทธิ์ microphone
- touch target ของ control หลักอย่างน้อย 44px; หน้า 320px และ 390px ต้องไม่ล้นแนวนอน
- sticky navigation ไม่บัง target หลังคลิกลิงก์ และไม่มี content ถูกภาพสินค้าทับ
- ใช้ status region สำหรับ catalog, scenario, cart และ quote โดยไม่ประกาศข้อความซ้ำเกินจำเป็น

รักษา cart และ quote contract เดิม:
- โหลดสินค้าและราคาจาก GET /api/catalog; cart เก็บเฉพาะ productId กับ quantity
- cart เพิ่ม/ลด/ลบสินค้า มี empty state ยอดรวม preview และ quantity 1–10
- เปิด dialog แล้ว focus อยู่ภายใน ปิดด้วย Escape ได้ พื้นหลังไม่รับ Tab
  และปิดแล้วคืน focus ไปปุ่มที่เปิดจริง; render ใหม่ต้องรักษา focus ของ quantity/remove control
- ส่ง JSON `{items:[{productId,quantity}],name,email,consent,website}` ไป POST /api/quotes
- ส่ง `Idempotency-Key`; ใช้ key เดิมเมื่อ retry payload เดิมหลัง network error
  และสร้าง key ใหม่เมื่อ cart หรือ form data เปลี่ยน
- ห้ามส่ง price, unitPrice, totalPrice, stock หรือ status ให้ server เชื่อ
- Worker อ่านราคาจาก D1 และคืน totalPrice เป็น integer satang
- HTTP 201 คือ `quote-demo`: แสดงเลขอ้างอิงและยอดที่ server คำนวณ
  ห้ามใช้คำว่า “ซื้อสำเร็จ”, “ชำระแล้ว” หรือสร้าง card/payment UI
- เมื่อ 400/403/5xx, response ไม่ใช่ JSON หรือ network error ให้แสดงข้อความที่ทำต่อได้
  และเก็บ cart/form ไว้แก้หรือ retry
- ใช้ชื่อ/อีเมลสมมติและแจ้งการปกปิดข้อมูลก่อนเขียน D1 ใน DEMO_MODE

ตรวจรับก่อนส่งงาน:
- ยืนยันว่ามีสาม catalog IDs เดิมและ HUSH ONE แสดงความสัมพันธ์กับ “หูฟัง Studio One” ชัดเจน
- ตรวจ no-JavaScript ว่า hero, chapters, specs, FAQ และทางไป shop ยังอ่านได้
- ตรวจ 1440×900 ว่า sound stage pin ทำงาน และ 1024×699 ว่าไม่ pin
- ตรวจ 390px และ 320px ว่าเป็น natural flow ไม่มี horizontal overflow และ CTA แตะได้
- ตรวจ live media-query change, reduced motion และ back-forward cache ว่า trigger ไม่ซ้ำ/เนื้อหาไม่หาย
- ใช้ keyboard เลือก listening scenarios, เปิด/ปิด cart, แก้ quantity และส่ง form
- ตรวจ catalog loading/success/empty/error, quote success/network error และ error response ที่ไม่ใช่ JSON
- แก้ราคาใน DevTools แล้วพิสูจน์ว่า response quote ยังมาจาก D1 ฝั่ง server
- รันชุด regression tests เดิมของ store, npm run typecheck, npm run test,
  npm run build และ npm run lint บนพอร์ตที่ shared-infra จองไว้

หลังแก้ ส่งสรุป storyboard, design tokens, motion branches, ไฟล์ที่เปลี่ยน,
ผลตรวจที่รันจริง และข้อจำกัดที่ยังเหลือ แยกสิ่งที่ตรวจแล้วออกจากสิ่งที่ยังไม่ได้ตรวจ

ที่มาของ pattern: Apple AirPods Max ใช้เป็น reference เฉพาะลำดับการเล่าเรื่อง, GSAP matchMedia() สำหรับแยก motion ตาม media preference และ ScrollTrigger สำหรับ pin/scrub lifecycle

ความคืบหน้าบันทึกเฉพาะเบราว์เซอร์นี้ ไม่มีบัญชีผู้เรียนหรือการส่งข้อมูลการเรียนขึ้นเซิร์ฟเวอร์