แผนปรับ UI/UX ทั้งเว็บ · UI/UX revamp plan
On this page
- 1. วิธีตรวจ (audit)
- 2. วินิจฉัย: ความแน่นมาจากไหน
- ทั้งเว็บ
- รายหน้า
- 3. หลักการออกแบบใหม่
- 4. การเปลี่ยน token
- ระยะห่าง
- ขนาดตัวอักษร (type scale)
- สี
- 5. Header และการนำทาง
- 6. ข้อเสนอรายหน้า
- หน้าแรก / (ลดจาก 4 section ที่แน่นเหลือ 5 section ที่โล่ง)
- /templates
- /builder
- /chat
- /docs
- /learn
- Studio /studio/
- 7. หน้าเข้าสู่ระบบ /login
- 8. ข้อความหน้าแรกฉบับใหม่ (ร่าง)
- 9. กฎสำหรับมือถือ
- 10. การเข้าถึง (accessibility)
- 11. แผนทยอยปล่อย (PR เล็ก)
- 12. สิ่งที่จะวัด
- 13. คอมโพเนนต์จาก 21st.dev (bookmark ของเจ้าของ)
- bookmark ทั้งหมด (13) และหน้าที่ใช้
- ต่อหน้า (สรุป)
- คอมโพเนนต์สาธารณะที่พิจารณาสำหรับ sign-in (ไม่อยู่ใน bookmark)
- 14. Phase 2: หน้าแรก (สถานะ)
- ช่องวิดีโอ
- 15. แหล่งอ้างอิงดีไซน์จากเจ้าของ (inspiration only)
- 16. Chat streaming และ thought chain (2026-10-15)
- 17. Customer connections, projects and deploys (PR-A to PR-E)
- DST vector mascot (src/components/brand/dst-mascot.tsx, 2026-10-15)
- nvx21st CLI (packages/nvx21st, 2026-10-15)
สถานะ: แผนเท่านั้น ยังไม่มีการแก้โค้ด ทุกเฟสที่เปลี่ยน layout หรือ section ต้องได้รับอนุญาตจากเจ้าของก่อน (AGENTS.md ข้อ 4) ระบบ token, คอมโพเนนต์ และหลักการ v0.5 อ่านได้ที่ concepts/design-system.md และ UI-FRAMEWORK.md
ที่มา: ผู้ประเมินบอกว่าเว็บ "แน่นและรก" เจ้าของต้องการให้ยึด nextjs.org เป็นต้นแบบ คือมีที่ว่างเยอะ ลำดับตัวอักษรชัด ใช้ของน้อยอย่างตั้งใจ และแบ่ง section ชัด พร้อมเขียนข้อความหน้าแรกใหม่ให้สั้นและเข้าใจง่ายขึ้น
1. วิธีตรวจ (audit)#
- ภาพหน้าจอแบบเต็มหน้า (Playwright,
npm run dev) ที่ 1440px และ 390px เก็บที่/workspace/shots/audit/บนเครื่องทำงาน (ไม่ commit เพราะเป็นภาพก่อนปรับ):/,/templates,/builder,/chat,/login,/docs,/learn,/studio/และเมนูมือถือ /studio/ตอบ 404 บนnext devเพราะ Studio ถูก build ลงpublic/studio/ตอนprebuildเท่านั้น ต้องตรวจซ้ำบนnpm run preview- ตัวเลขที่วัดได้ (ความสูงหน้า / จำนวนคำ / จำนวนลิงก์และปุ่ม):
| หน้า | 1440px สูง | 390px สูง | คำ | ลิงก์+ปุ่ม |
|---|---|---|---|---|
/ |
2,925 | 5,451 | ~480 | 43 |
/templates |
2,058 | 4,400 | ~446 | 62 |
/builder |
1,640 | 2,052 | ~241 | 40 |
/chat |
900 (เต็มจอ) | 844 | ~214 | 41 |
/login |
1,181 | 1,197 | ~100 | 27 |
/docs |
4,482 | 7,350 | ~774 | 195 |
/learn |
3,968 | 6,220 | ~535 | 42 |
header มีลิงก์และปุ่ม 20 ชิ้นบนทุกหน้า (/docs มี 34)
2. วินิจฉัย: ความแน่นมาจากไหน#
ทั้งเว็บ#
- header แน่นเกิน มีลิงก์หลัก 6 อัน + ปุ่ม Setup Cursor + Sign in + ค้นหา + ภาษา + ธีม + เมนู ทั้งที่จอกว้างพอแล้ว nextjs.org มีลิงก์หลักราว 4–5 อันและปุ่มด้านขวา 2 ชิ้น
- ตัวอักษรเล็กและจางเกินไปหลายระดับ ใช้ 11–13px ปนกันมาก (
text-[11px],text-[12.5px],text-[13px]) พร้อมtext-muted/text-subtleทำให้ทุกอย่างดูเท่ากันและอ่านยาก - ป้าย (badge/chip) เยอะเกิน การ์ดเทมเพลตแต่ละใบมีป้ายหมวด + runtime + ป้ายเครื่องมือ 3–5 อัน + ปุ่มสองปุ่ม ตาต้องสแกนจุดเล็ก ๆ ราว 10 จุดต่อใบ
- ไม่มีลำดับความสำคัญของ section ทุก section ใช้การ์ดขอบเทาบนพื้นดำแบบเดียวกัน ระยะห่าง
py-20เท่ากันหมด ไม่มี section ไหนเด่น - ซิกเนเจอร์เทอร์มินัลใน footer ทุกหน้า เป็นภาพใหญ่ที่ไม่เกี่ยวกับงานของหน้านั้น
- ข้อความยาวและเป็นศัพท์เทคนิค เช่น hero subtitle มีชื่อเครื่องมือ 8 ตัวและไฟล์ 2 ชนิดในประโยคเดียว
รายหน้า#
- หน้าแรก
/: hero มี badge + หัวข้อ 3 บรรทัด + คำอธิบายยาว 2 ประโยค + 2 ปุ่ม + หน้าต่างโค้ด + มาสคอตซ้อนทับโค้ด "How it works" เป็นการ์ด 3 ใบที่ข้อความยาวเท่า ๆ กัน ตามด้วยการ์ดเทมเพลต 6 ใบเต็มรายละเอียด (ซ้ำกับ/templates) แล้วต่อด้วย "Beyond a landing page" อีก 4 คอลัมน์ บนมือถือหน้ายาว 5,451px /templates: การ์ด 10 ใบแสดงข้อมูลทั้งหมดตั้งแต่แรก แถบตัวกรองมี 10 ชิป ปุ่ม "View steps" กับ "Open in builder" ซ้ำทุกใบ/builder: แถบ stepper 4 ขั้น + แถบ "Current stack" ที่มีชิปอีกหลายอัน + แท็บ + การ์ด AI + ตัวอย่างคำสั่ง 6 ชิป + checkbox + 2 ปุ่ม + กล่องว่าง ทั้งหมดอยู่ใน viewport แรก ลำดับขั้น "1/4 · Start" ซ้ำกับ stepper/chat: (ปรับใน commit8c0f0ebแล้ว ให้เต็มจอและ composer อยู่ล่างสุด) ยังเหลือตัวเลือกโมเดล 12 ปุ่มที่เป็นชิปเล็ก ควรเป็น dropdown เดียว/login: โครงดี แต่ปุ่มผู้ให้บริการใช้ตัวอักษรย่อ (C/G/GH) แทนโลโก้ ปุ่ม "Sign in" กับ "Create account" อยู่ในฟอร์มเดียวกันทำให้ไม่รู้ว่ากำลังทำอะไร/docs: 195 ลิงก์ในหน้าเดียว sidebar + เนื้อหา + สารบัญยาว/learn: การ์ด 13 ใบในสามกลุ่ม ตามด้วย "Three ways to start" อีก 3 การ์ด และ Setup Cursor ซ้ำกับปุ่มใน header
3. หลักการออกแบบใหม่#
- หนึ่ง section หนึ่งเรื่อง หนึ่งการกระทำหลัก ทุก section มีหัวข้อ 1 บรรทัด คำอธิบายไม่เกิน 2 บรรทัด และปุ่มหลักไม่เกิน 1 ปุ่ม
- ที่ว่างคือโครงสร้าง ใช้ระยะห่างแบ่ง section แทนเส้นขอบและการ์ด การ์ดใช้เฉพาะสิ่งที่คลิกได้
- ลำดับตัวอักษรชัด 3 ระดับต่อหน้า: display, หัวข้อ section, เนื้อความ ป้ายเล็กใช้น้อยที่สุด
- เปิดเผยทีละชั้น (progressive disclosure) รายละเอียด (ป้ายเครื่องมือ, OS notes, ตัวเลือกขั้นสูง) ซ่อนไว้จนผู้ใช้ขอดู
- ใช้ของเดิม ใช้ token และคอมโพเนนต์ใน
src/components/uiไม่สร้างระบบใหม่ คงพื้นดำ, Inter/IBM Plex Sans Thai, สีฟ้าสองบทบาท และมาสคอตชมพู - สองภาษาเท่ากัน ข้อความไทยต้องสั้นพอ ๆ กับภาษาอังกฤษ ไม่แปลตรงตัว
4. การเปลี่ยน token#
แก้ที่ src/app/tokens.css, src/app/globals.css (@theme) และ src/lib/design-tokens.ts แล้วเพิ่มคู่สีใน tests/tokens.test.ts
ระยะห่าง#
| token ใหม่ | ค่า | ใช้กับ |
|---|---|---|
--space-section |
128px (เดสก์ท็อป) / 80px (มือถือ) | ระยะระหว่าง section แทน py-20 sm:py-24 |
--space-block |
48px / 32px | หัวข้อ section ถึงเนื้อหา แทน mt-10 |
--container |
1120px | แทน max-w-7xl (1280px) บนหน้าการตลาด เนื้อหาไม่กว้างเกินไป |
--measure |
60ch | ความกว้างสูงสุดของย่อหน้า |
ขนาดตัวอักษร (type scale)#
| ระดับ | เดสก์ท็อป | มือถือ | น้ำหนัก |
|---|---|---|---|
| display | 64px / 1.05 (เดิม) | 40px | 700 |
| h2 section | 40px / 1.1 | 28px | 600 |
| h3 | 20px / 1.3 | 18px | 600 |
| lead | 20px / 1.5 | 17px | 400, text-muted |
| body | 16px / 1.6 | 16px | 400 |
| small | 14px | 14px | 400 |
| caption | 13px (mono) | 13px | เฉพาะป้ายและโค้ด |
ยกเลิกขนาดเฉพาะกิจ text-[10.5px], text-[11px], text-[12.5px] ใน UI ที่ผู้ใช้อ่าน (เก็บไว้ได้เฉพาะ metadata เช่น ตัวนับตัวอักษร) ภาษาไทยใช้ line-height อย่างน้อย 1.6
สี#
- คงพื้น
bgดำและprimary/linkฟ้าตามเดิม - ใช้
text-subtleเฉพาะ caption ห้ามใช้กับเนื้อความ (ตรวจ AA อีกครั้ง) - ลดเส้นขอบ: section ใช้พื้นต่างระดับ (
bg/surface) แทนborder-t - การ์ดใช้
border-borderขอบเดียว ไม่มีเงา และขอบสว่างขึ้นเมื่อ hover
5. Header และการนำทาง#
- ลิงก์หลักเหลือ 4 อัน: Templates, Builder, Chat, Docs ส่วน Functions, Dev Chat, Factory, Agents, Studio, Design ย้ายไปเมนู "More" (เดสก์ท็อป) และเมนูมือถือ
- ด้านขวาเหลือ 3 ชิ้น: ค้นหา (
⌘Kแบบช่องค้นหาสั้นเหมือน nextjs.org), Sign in (ข้อความ ไม่มีกรอบ) และปุ่มหลัก "Start building" (ไป/builder) - ปุ่มภาษาและธีมย้ายไป footer และเมนูมือถือ ข้อนี้ต้องให้เจ้าของตัดสินใจ เพราะผู้ใช้ไทยอาจหาปุ่มภาษาไม่เจอ ทางเลือกคือเก็บปุ่มภาษาไว้ใน header แต่ย้ายแค่ปุ่มธีม
- Setup Cursor ย้ายไปอยู่ในเมนู "More" และหน้า
/learn - header สูง 64px พื้นโปร่ง blur เส้นล่างแสดงเฉพาะเมื่อเลื่อนหน้าลงแล้ว
- Footer: เป็นลิงก์ 4 คอลัมน์ (Product, Resources, Developers, About) และย้ายซิกเนเจอร์เทอร์มินัลไปอยู่ที่
/learnกับ/design#signature(ต้องได้อนุญาต เพราะ design-system.md ระบุว่าอยู่ทุกหน้า)
6. ข้อเสนอรายหน้า#
หน้าแรก / (ลดจาก 4 section ที่แน่นเหลือ 5 section ที่โล่ง)#
- Hero อยู่กึ่งกลางแบบ nextjs.org มีหัวข้อ, subhead 1 ประโยค, 2 ปุ่ม และบรรทัดคำสั่งที่คัดลอกได้ (
npx create-next-app@latest) หน้าต่างโค้ดย้ายไปอยู่ใต้ hero และกว้างเต็ม container ส่วนมาสคอตอยู่ข้างหัวข้อ ไม่ทับโค้ด - สามขั้นตอน เป็นตัวเลขใหญ่กับข้อความ 1 บรรทัด ไม่มีการ์ด
- เทมเพลตยอดนิยม แสดง 3 ใบ เป็นการ์ดแบบย่อ (ชื่อ, คำอธิบาย 1 บรรทัด, runtime) และลิงก์ "ดูทั้งหมด"
- สิ่งที่ทำได้ 3 ข้อ (Templates, AI planner, Safe) เป็นหัวข้อสั้นกับประโยคเดียว
- CTA ปิดท้าย หัวข้อเดียวกับปุ่มเดียว
/templates#
- การ์ดแบบย่อ: ไอคอน, ชื่อ, คำอธิบาย 1 บรรทัด, runtime ทั้งการ์ดคลิกได้ (ไปหน้า detail) ป้ายเครื่องมือย้ายไปหน้า detail
- ตัวกรองเหลือ "ทั้งหมด / Node.js / Python" + ช่องค้นหา หมวดอื่นย้ายไปเป็น dropdown
- ใช้ 3 คอลัมน์และ gap 24px
/builder#
- stepper เป็นแถบบางด้านบน ลบหัวข้อ "1/4 · Start" ที่ซ้ำ
- แถบ "Current stack" ยุบเป็นปุ่ม "Current stack (7 steps)" ที่เปิด drawer ได้
- ตัวอย่างคำขอเหลือ 3 อัน ส่วนตัวเลือก "Use my own OpenAI key" ย้ายไปอยู่ใน "Advanced"
- ไม่แสดงกล่องว่าง "Your plan will appear here" จนกว่าจะส่งคำขอ
/chat#
- ตัวเลือกโมเดลเป็น dropdown เดียวในแถบบนของแชต (Select ของ Radix ที่มีอยู่) แทนชิป 12 อัน
- คำแนะนำเริ่มต้นเหลือ 3 อัน
/docs#
- sidebar ยุบหมวดเป็นค่าเริ่มต้น แสดงเฉพาะหมวดที่เปิดอยู่ และหน้าแรกของ docs เป็นการ์ด 4 ใบ (Get started, Guides, Reference, Operations)
- ความกว้างเนื้อหาไม่เกิน
--measure
/learn#
- รวมการ์ด 13 ใบเป็นรายการ 3 กลุ่ม (ชื่อกับประโยคเดียว ไม่ใช้การ์ด) และลบ "Three ways to start" ที่ซ้ำกับหน้าแรก
Studio /studio/#
- เป็นแอปแยก (
studio/) เฟสนี้แค่ปรับ header ให้ใช้ลิงก์ชุดเดียวกัน ไม่แตะ layout ภายใน
7. หน้าเข้าสู่ระบบ /login#
แหล่งอ้างอิง: ตรวจผ่าน connector 21st.dev ของเจ้าของ (list_bookmarks ทุกชนิด, list_bookmark_lists, get_bookmark_list) เมื่อ 15 ต.ค. 2026 พบ bookmark คอมโพเนนต์ 13 ชิ้น ใน list เดียวชื่อ "List" (13 ชิ้นเดียวกัน) ไม่มี theme หรือ template ที่บันทึกไว้ และ ไม่มีคอมโพเนนต์ sign-in ใน bookmark เลย การออกแบบหน้านี้จึงอิงคอมโพเนนต์ sign-in สาธารณะ ที่ใกล้เคียงที่สุด (ระบุไว้ชัดว่าไม่ได้มาจาก bookmark) ร่วมกับคอมโพเนนต์ใน bookmark ที่ใช้ประกอบได้ ดูตารางในหัวข้อ 13
| ใช้เป็น | คอมโพเนนต์ (id) | ที่มา | เหตุผล |
|---|---|---|---|
| โครงหลัก | Identifier First Login (37470) | สาธารณะ | ช่องอีเมลช่องเดียวก่อน แล้วค่อยเสนอวิธีที่เหมาะ (รหัสผ่าน หรือ GitHub/Google/Cursor) ตรงกับที่ DevStack มีทั้งบัญชีรหัสผ่านและ OAuth ลดปุ่มที่เห็นพร้อมกัน |
| ความเรียบ | Login (2426) | สาธารณะ | การ์ดเรียบกึ่งกลาง ใกล้สไตล์ nextjs.org ใช้เป็นแนวระยะห่างและขนาดตัวอักษร |
| ไม่เลือก | Split Login (28369) | สาธารณะ | split screen หนักเกินไปบนมือถือ และออกแบบมาสำหรับ GitHub อย่างเดียว |
| แจ้งผล | Dismissible Alert Stack (26527) | bookmark | รูปแบบ alert ตามระดับ (error/warning/info) สำหรับ `auth=invalid |
| ปุ่ม | Button (3507) | bookmark | สถานะ loading/disabled ในปุ่มระหว่างส่งฟอร์ม |
| หลังล็อกอิน | Avatar (34164) | bookmark | รูปโปรไฟล์และ fallback ตัวย่อใน AccountButton แทนตัวอักษรย่อของผู้ให้บริการ |
ข้อเสนอ (การ์ดกึ่งกลาง แบบ "Clean & Minimal" / "Centered Social Login"):
- ขั้นแรกแบบ identifier-first (จาก 37470): แสดงช่องอีเมลกับปุ่ม "ดำเนินการต่อ" และปุ่มโลโก้ผู้ให้บริการ 3 ปุ่มด้านล่าง เมื่อกดต่อจึงแสดงช่องรหัสผ่าน (เข้าสู่ระบบ) หรือช่องรหัสผ่านพร้อมยืนยัน (สร้างบัญชี) ฝั่งเซิร์ฟเวอร์ไม่บอกว่าอีเมลนี้มีบัญชีหรือไม่ เพื่อกันการเดาอีเมล ผู้ใช้จึงเลือกแท็บเองตามข้อ 2
- การ์ดกว้าง 400px กึ่งกลางจอ มีมาสคอตขนาด 40px, หัวข้อ "Sign in to DevStack" และบรรทัดรอง 1 บรรทัด
- แท็บ Sign in / Create account แยกกัน (ตอนนี้เป็นสองปุ่มในฟอร์มเดียว) แท็บ Create account มีช่องยืนยันรหัสผ่านและข้อความเงื่อนไขรหัสผ่านใต้ช่อง ส่วนค่า
actionยังส่งไปPOST /api/auth/passwordตัวเดิม - ช่องอีเมลและรหัสผ่านอยู่บนสุด และมีปุ่มแสดงหรือซ่อนรหัสผ่าน
- เส้นคั่น "หรือ / or"
- ปุ่มผู้ให้บริการ 3 ปุ่ม ใช้โลโก้จริง (simple-icons มีอยู่แล้วใน
src/components/brand): GitHub, Google, Cursor บนจอกว้างเรียงแถวเดียว 3 ช่อง บนมือถือเรียงแนวตั้ง - ข้อความแจ้งผล (
auth=invalid|taken|weak|error|missing) แสดงในการ์ดด้านบนฟอร์ม และใช้role="alert"เหมือนเดิม - บรรทัดล่าง: ความเป็นส่วนตัวกับลิงก์ docs เป็นตัวเล็ก 1 บรรทัด
- ไม่ต้องใช้ split screen หรือภาพประกอบใหญ่ เพื่อให้หน้าเบาบนมือถือ
8. ข้อความหน้าแรกฉบับใหม่ (ร่าง)#
หลักการเขียน: บอกว่า ได้อะไร ก่อนบอกว่า ทำงานอย่างไร ใช้ชื่อเครื่องมือเท่าที่จำเป็น ไม่เกิน 20 คำต่อย่อหน้า
| คีย์ | English | ไทย |
|---|---|---|
hero.badge |
Open source · Free | โอเพนซอร์ส · ใช้ฟรี |
hero.title |
Start any project in minutes | เริ่มโปรเจกต์ใหม่ได้ในไม่กี่นาที |
hero.subtitle |
Pick a template or describe your app. Get every setup command, in the right order, ready to copy. | เลือกเทมเพลตหรือบอกว่าอยากทำแอปอะไร แล้วรับคำสั่งติดตั้งครบทุกขั้น เรียงถูกลำดับ พร้อมคัดลอก |
hero.ctaAgent |
Start building | เริ่มสร้างเลย |
hero.ctaTemplates |
Browse templates | ดูเทมเพลต |
Section 1: สามขั้นตอน · How it works
| English | ไทย | |
|---|---|---|
| หัวข้อ | Three steps to a running project | สามขั้นตอนถึงโปรเจกต์ที่รันได้ |
| 1 | Choose a template, or ask the AI. | เลือกเทมเพลต หรือถาม AI |
| 2 | Adjust versions and tools. | ปรับเวอร์ชันและเครื่องมือ |
| 3 | Copy the commands or download a script. | คัดลอกคำสั่ง หรือดาวน์โหลดสคริปต์ |
Section 2: เทมเพลตยอดนิยม · Popular templates
- EN: "Ready-made stacks for Node.js and Python." / ลิงก์ "See all templates"
- TH: "ชุดเริ่มต้นสำเร็จรูปสำหรับ Node.js และ Python" / ลิงก์ "ดูเทมเพลตทั้งหมด"
Section 3: ทำไมต้อง DevStack · Why DevStack
| หัวข้อ EN | เนื้อหา EN | หัวข้อ TH | เนื้อหา TH |
|---|---|---|---|
| Every step explained | Each command says what it does and how to check it worked. | อธิบายทุกขั้น | ทุกคำสั่งบอกว่าทำอะไร และตรวจอย่างไรว่าสำเร็จ |
| AI that plans, not guesses | Describe your app in Thai or English. Works even without an AI key. | AI ช่วยวางแผน | อธิบายแอปเป็นไทยหรืออังกฤษก็ได้ ใช้ได้แม้ไม่มีคีย์ AI |
| Safe by default | We never run your commands. You stay in control. | ปลอดภัยเป็นค่าเริ่มต้น | เราไม่รันคำสั่งของคุณ คุณควบคุมเองทั้งหมด |
Section 4: CTA ปิดท้าย
- EN: "Your next project starts here." ปุ่ม "Start building"
- TH: "โปรเจกต์ถัดไปของคุณเริ่มที่นี่" ปุ่ม "เริ่มสร้างเลย"
หมายเหตุ: "Works even without an AI key" หมายถึงตัววางแผนสำรองแบบกฎ (offline planner) เมื่อไม่มีคีย์ AI ฝั่งเซิร์ฟเวอร์ ต้องตรวจถ้อยคำไทยกับเจ้าของ
9. กฎสำหรับมือถือ#
- ทุกหน้าไม่มีการเลื่อนแนวนอนที่ 320–414px (มี guard
overflow-x-clipบน body แล้วใน commit8c0f0eb) - จุดแตะอย่างน้อย 44×44px ปุ่มหลักกว้างเต็มจอใน hero และฟอร์ม
- เนื้อความ 16px ขึ้นไป (กันเบราว์เซอร์ iOS ซูมเมื่อโฟกัสช่องกรอก)
- grid 1 คอลัมน์ต่ำกว่า 640px ระยะขอบข้าง 20px
- หน้าแบบแอป (
/chat,/builderขั้นรีวิว) ใช้100dvh+ safe-area และให้แป้นพิมพ์ย่อ layout (interactive-widget=resizes-content) - เป้าหมายความสูงหน้าแรกบน 390px: ไม่เกิน 3,500px (ตอนนี้ 5,451px)
10. การเข้าถึง (accessibility)#
- คงเงื่อนไขเดิม: contrast AA ทั้งสองธีม (
tests/tokens.test.ts), ไม่มีอีโมจิในsrc/และL10nมีครบen/th - ลำดับหัวข้อถูกต้อง:
h1หนึ่งอันต่อหน้า และ section ใช้aria-labelledby - แท็บใน
/loginใช้ Radix Tabs (คีย์บอร์ดลูกศรได้) และ error ผูกกับช่องด้วยaria-describedby - เมนู "More" ใช้ Radix DropdownMenu และ focus กลับไปที่ปุ่มเมื่อปิด
- เคารพ
prefers-reduced-motion(มาสคอตและซิกเนเจอร์อยู่นิ่ง) - เพิ่ม test ด้วย axe ใน Playwright ของ
studio/e2e/site.spec.tsสำหรับหน้าที่ปรับ
11. แผนทยอยปล่อย (PR เล็ก)#
แต่ละ PR ผ่าน lint, typecheck, test, docs:check และ cf:build มีภาพก่อนและหลังใน screenshots/v0.9/ และอัปเดต CHANGELOG
| เฟส | PR | ขอบเขต | ต้องขออนุญาต layout |
|---|---|---|---|
| 0 | Tokens | ระยะห่าง, type scale, container, ลด text-subtle ในเนื้อความ, หน้า /design แสดง scale ใหม่ |
ไม่ |
| 1 | Header + footer | ลิงก์หลัก 4 อัน, เมนู More, ปุ่ม Start building, footer แบบลิงก์ ย้ายซิกเนเจอร์ | ใช่ |
| 2 | หน้าแรก + ข้อความ | hero กึ่งกลาง, 5 section + FAQ, ข้อความใหม่ใน src/lib/i18n.ts, How It Works Steps (26891), Two-Column FAQ (26910) |
ใช่ |
| 3 | /login |
identifier-first (37470), แท็บ Sign in/Create, โลโก้ผู้ให้บริการ, ยืนยันรหัสผ่าน (API เดิม), Alert Stack (26527) | ใช่ |
| 4 | /templates + การ์ด |
การ์ดแบบย่อ, ตัวกรอง runtime | ใช่ |
| 5 | /builder + /chat |
Process Timeline (28381) / Progress (3422), drawer current stack, Combobox โมเดล (9020) | ใช่ |
| 6 | /docs + /learn |
sidebar ยุบได้, learn แบบรายการ | ใช่ |
12. สิ่งที่จะวัด#
- ความหนาแน่น: ความสูงหน้าที่ 390px, จำนวนคำใน viewport แรก และจำนวนลิงก์/ปุ่มต่อหน้า (header เป้าหมายไม่เกิน 9 ชิ้น จาก 20) วัดด้วยสคริปต์ Playwright ชุดเดียวกับ audit
- ความเข้าใจ: ทดสอบ 5 วินาทีกับผู้ใช้ไทย 5 คน ("เว็บนี้ทำอะไร") ก่อนและหลังเฟส 2
- การใช้งานจริง (ถ้าเปิด Cloudflare Web Analytics ได้โดยไม่มีค่าใช้จ่าย): สัดส่วนคนที่กด CTA หลักจากหน้าแรก, สัดส่วนคนที่เริ่ม
/builderแล้วไปถึงขั้น Export และอัตราสมัครหรือล็อกอินสำเร็จที่/login - คุณภาพ: Lighthouse (Performance, Accessibility ≥ 95) ทั้งมือถือและเดสก์ท็อป และ CLS < 0.05
13. คอมโพเนนต์จาก 21st.dev (bookmark ของเจ้าของ)#
ข้อมูลจาก connector 21st.dev (metadata เท่านั้น ยังไม่ได้ดึงโค้ด เพราะ get_component ใช้โควตาแบบเสียเงิน) ใช้เป็น แบบอ้างอิง แล้วสร้างใหม่ด้วย NVX UI (src/components/ui, Radix) และ semantic token ไม่ติดตั้ง shadcn registry ทั้งชุด ก่อนนำโค้ดมาใช้ต้องตรวจสัญญาอนุญาตให้ผ่าน AGENTS.md ข้อ 9 (permissive เท่านั้น) และห้ามใช้ API_KEY_21ST ใน build
bookmark ทั้งหมด (13) และหน้าที่ใช้#
| คอมโพเนนต์ (id) | ผู้สร้าง | ใช้ที่ | เหตุผล |
|---|---|---|---|
| How It Works Steps (26891) | ln-dev7 | หน้าแรก section "สามขั้นตอน" | วงกลมตัวเลข 3 ขั้น เส้นเชื่อม และปุ่ม CTA กลาง ไม่มีไอคอน ตรงหลัก "ตัวอักษรทำงานแทน" และแทนการ์ด 3 ใบเดิม |
| Two-Column FAQ (26910) | ln-dev7 | หน้าแรก (ก่อน CTA ปิดท้าย) และ /learn |
คำถามที่พบบ่อยแบบ accordion ฝั่งขวา คำอธิบายฝั่งซ้ายติดอยู่กับที่ ช่วยย้ายข้อความอธิบายยาว ๆ (ความปลอดภัย, โหมดออฟไลน์, ใช้ฟรีไหม) ออกจาก hero และการ์ด |
| Process Timeline (28381) | shadcnui-blocks | /builder stepper และหน้า template detail |
timeline แนวตั้งที่มีเครื่องหมายถูกสำหรับขั้นที่เสร็จ แทน stepper 4 ช่องแนวนอนที่แน่น และใช้แสดงขั้นตอนของเทมเพลต |
| Progress (3422) | sean0205 | /builder (มือถือ) และโควตาใน /chat |
แถบความคืบหน้าบางแทน stepper บนจอแคบ และแสดงข้อความหรือรูปที่เหลือต่อวันแทนข้อความตัวเล็ก |
| Combobox (9020) | clevision | /chat ตัวเลือกโมเดล, ตัวกรอง /templates |
dropdown ค้นหาได้หนึ่งอัน แทนชิปโมเดล 12 อันและชิปหมวด 10 อัน รองรับตัวเลือกที่ปิดใช้ (โมเดลที่ไม่พร้อม) |
| Combo Kbd (28308) | ai2 | header (ช่องค้นหา ⌘K), /chat hint, /docs |
ป้ายคีย์ลัดแบบเดียวกันทั้งเว็บ แทน Kbd ที่ใช้ปนกันอยู่ |
| Dismissible Alert Stack (26527) | olewandowski1 | /login, /chat (banner โควตาหรือปิดบริการ), /builder |
alert ตามระดับที่ปิดได้ แทนกล่องข้อความหลายแบบ |
| Changelog List (28443) | shadcnstore | หน้าใหม่ /changelog (ทางเลือก) หรือหัวข้อใน /learn |
รายการ release พร้อมป้าย Added/Improved/Fixed อ่านจาก CHANGELOG.md เพื่อลดข้อความ "อัปเดตล่าสุด" ที่กระจายอยู่ใน docs (ต้องได้อนุญาต เพราะเป็นหน้าใหม่) |
| Avatar (34164) | appica-dev | AccountButton ใน header และเมนูมือถือ |
รูปโปรไฟล์ GitHub/Google และ fallback ตัวย่อสำหรับบัญชีรหัสผ่าน |
| Button (3507) | sean0205 | ทุกหน้า (อ้างอิงสถานะ) | สถานะ loading/disabled ที่ชัดเจน เทียบกับ buttonClasses เดิม เพิ่มเฉพาะสถานะที่ยังขาด |
| Focus Frame Border (29885) | shadcnspace | hero หน้าแรก (หน้าต่างโค้ด) เท่านั้น | มุมเรืองแสง 4 มุมรอบหน้าต่างโค้ด เป็นจุดเด่นเดียวของหน้า ใช้ที่เดียวเพื่อไม่ให้รก และปิดเมื่อ prefers-reduced-motion |
| Experience Timeline (28334) | shadcnui-blocks | ไม่ใช้ตอนนี้ | ออกแบบสำหรับประวัติการทำงาน ไม่มีหน้าที่ตรง อาจใช้กับ /learn ส่วนประวัติแพลตฟอร์มภายหลัง |
| Regex Tester (36190) | astralyxdev | ไม่อยู่ในขอบเขต revamp | เป็นเครื่องมือ ไม่ใช่ส่วน UI อาจเป็นไอเดียสำหรับ Studio หรือ MCP tool ภายหลัง |
ต่อหน้า (สรุป)#
- หน้าแรก: How It Works Steps (26891), Two-Column FAQ (26910), Focus Frame Border (29885) และ Combo Kbd (28308) ในบรรทัดคำสั่งของ hero
- Header: Combo Kbd (28308) ในช่องค้นหา และ Avatar (34164) ในปุ่มบัญชี
/templates: Combobox (9020) เป็นตัวกรองหมวด และ Process Timeline (28381) ในหน้า detail/builder: Process Timeline (28381) บนเดสก์ท็อป, Progress (3422) บนมือถือ และ Dismissible Alert Stack (26527)/chat: Combobox (9020) ตัวเลือกโมเดล, Progress (3422) โควตา, Dismissible Alert Stack (26527) และ Combo Kbd (28308)/login: ดูหัวข้อ 7 (Identifier First Login 37470 และ Login 2426 จากคอมโพเนนต์สาธารณะ ส่วน Alert Stack 26527, Button 3507 และ Avatar 34164 จาก bookmark)/docs: Combo Kbd (28308)/learn: Two-Column FAQ (26910) และ Changelog List (28443)
คอมโพเนนต์สาธารณะที่พิจารณาสำหรับ sign-in (ไม่อยู่ใน bookmark)#
ค้นด้วยคำว่า "sign-in" เจอ Auth UI (2624), Identifier First Login (37470), Sign In (2133), Login (2426), Sign In Flo (2553), Split Login (28369), Sign-in (4727), Modern Animated Sign In (2034), Sign In (3197) และ Modern & Stunning sign in (2060) เลือก 37470 กับ 2426 ด้วยเหตุผลในหัวข้อ 7 ส่วนแบบที่มีแอนิเมชันหนัก (2034, 2060, 2553) ขัดกับหลักการเรื่องความเรียบ ถ้าเจ้าของชอบชิ้นอื่น ให้ bookmark ไว้แล้วจะปรับหัวข้อ 7 ตาม
14. Phase 2: หน้าแรก (สถานะ)#
ทำแล้วและ merge เข้า main (PR #13) แล้ว deploy เป็น Worker 56a64535 บน https://devstack.bid (2026-10-15):
- เอาคำสั่งและคำว่า nvm ออกจากหน้าแรกทั้งหมด (โค้ดตัวอย่างใน hero และ
hero.subtitle) ข้อมูลเทมเพลตที่ใช้ร่วมกัน (ขั้นnode-nvmใน composer) และหน้า builder ไม่ได้แก้ - Hero ใช้ข้อความใหม่จากหัวข้อ 8 กรอบมุม Focus Frame (bookmark 29885) ใช้กับหน้าต่างโค้ดใน hero เท่านั้น (
.focus-frameใน globals.css และหยุด animation เมื่อผู้ใช้ตั้ง reduced motion) - มีหัวข้อ "สามขั้นตอน" แบบ How It Works Steps (26891) FAQ สองคอลัมน์ (26910) ใช้
<details>แบบ native ตัวอย่างเทมเพลตเหลือ 3 อันพร้อมลิงก์ไป/templates - ตัวอย่างโค้ดสดแบบ react.dev ใช้ Sandpack (
@codesandbox/sandpack-react, Apache-2.0) อยู่ในsrc/components/home/live-example.tsx(โหลดแบบ lazy ด้วยnext/dynamicเมื่อเลื่อนเข้าใกล้หรือกดปุ่ม) และlive-editor.tsx- เนื้อหา: เหมือน sandbox อ้างอิงของเจ้าของ (codesandbox.io/p/sandbox/pvtdl8) คือไฟล์ src/App.tsx ที่เป็น TypeScript, App.js ที่ re-export, index.js และ styles.css (ไฟล์ใน sandbox ไม่ใช่ใน repo นี้ ดู
src/components/home/sandbox-files.ts) หน้าตัวอย่างแสดง "Welcome to my app" กับปุ่ม "I'm a button" (ตัวอย่าง MyButton จาก Quick Start ของ react.dev) แท็บที่แก้ได้มี App.tsx และ styles.css - ปุ่ม: มี Reset, Open in CodeSandbox และ refresh ที่หน้าตัวอย่าง
- ธีม: ธีมขาวดำใช้ตัวแปร
--nvx-*หน้าตัวอย่างตามโหมดสว่างหรือมืดผ่านไฟล์ซ่อนtheme.cssโดยไม่ล้างโค้ดที่ผู้ใช้แก้ - มือถือ: ตัวแก้โค้ดอยู่บน หน้าตัวอย่างอยู่ล่าง
- CSP:
frame-src https://*.codesandbox.ioและform-action 'self' https://codesandbox.io(ดู api-hardening) COEP ยังอยู่ที่/studio/*เท่านั้น - ไลเซนส์:
@codesandbox/nodeboxใช้ Sustainable Use License (ไม่ใช่ permissive) เจ้าของอนุมัติให้เป็นข้อยกเว้นของกฎข้อ 9 เมื่อ 2026-10-15 บันทึกไว้ในEXCEPTIONSของscripts/third-party-licenses.mjsและใน THIRD_PARTY_LICENSES.md
- เนื้อหา: เหมือน sandbox อ้างอิงของเจ้าของ (codesandbox.io/p/sandbox/pvtdl8) คือไฟล์ src/App.tsx ที่เป็น TypeScript, App.js ที่ re-export, index.js และ styles.css (ไฟล์ใน sandbox ไม่ใช่ใน repo นี้ ดู
ช่องวิดีโอ#
- หน้าแรก: ช่อง
data-slot="howto-video"ใต้หัวข้อสามขั้นตอน (สัดส่วน 16:9) สำหรับวิดีโอสั้นประมาณ 30 วินาที ตอนนี้ยังเป็นข้อความ "เร็ว ๆ นี้" - วิดีโอแบบละเอียด: จะไปอยู่ใน docs หน้า เริ่มต้นใช้งาน ไม่ใส่บนหน้าแรก
- ไฟล์วิดีโอควรอยู่ใน
public/ของเราเอง (CSPmedia-src 'self') ถ้าจะฝังจาก YouTube หรือที่อื่นต้องแก้frame-srcและอัปเดต docs นี้กับ api-hardening ก่อน
15. แหล่งอ้างอิงดีไซน์จากเจ้าของ (inspiration only)#
เจ้าของส่งลิงก์ 21st.dev ต่อไปนี้มาเป็น แรงบันดาลใจเท่านั้น เราออกแบบและเขียนโค้ดเองทั้งหมดด้วย NVX UI และ semantic token แบบขาวดำ (phase 0-2) ไม่ได้คัดลอกโค้ด ไม่ได้เรียก get_component และไม่ได้ติดตั้ง package ของ 21st.dev หรือ shadcn registry จึงไม่มีผลต่อ licence ตาม AGENTS.md ข้อ 9
The owner shared these 21st.dev links as inspiration only. We redesigned everything ourselves with NVX UI and monochrome tokens. No code was copied, get_component was not called and nothing was installed.
| Reference (owner link) | What we took as an idea | Our implementation | Used in |
|---|---|---|---|
| Floating Dock by @manuarora700 (21st.dev) | A pill-shaped dock of icons fixed at the bottom of the screen that lifts on hover | src/components/plugins/category-dock.tsx: monochrome dock with bg-bg/70 blur, border-border, the active item in bg-fg text-bg, a CSS-only lift that is off under reduced motion, real toggle buttons with aria-pressed and labels, and horizontal scroll on small screens |
/plugins category quick-switch (shares state with the filter chips) |
| @nextjsshop library (21st.dev) | A clean card and grid rhythm with simple outline badges | src/components/plugins/plugin-card.tsx (outline category badge, mono repo slug, divided action row) |
/plugins, /plugins/[name] |
| Spinners (21st.dev) | A choice between a ring and a dots variant | Spinner in src/components/ui/skeleton.tsx (extended, not duplicated): variant="ring" | "dots", size, currentColor, role=status when it has a label |
Sandpack loading (home/live-example.tsx), chat status (chat/chat-app.tsx, dots), login submit (login-form.tsx), plus the existing Button loading, Factory and the sandbox panel |
ก่อนจะนำโค้ดจากลิงก์เหล่านี้มาใช้จริงในอนาคต ต้องตรวจสัญญาอนุญาตและขออนุมัติตามข้อ 9 ก่อน
16. Chat streaming และ thought chain (2026-10-15)#
แหล่งอ้างอิง (inspiration only): AI chat · thought chain on 21st.dev — ใช้เป็นแนวทางเรื่องลำดับขั้นตอนแนวตั้งและการยุบหลังตอบเสร็จ ไม่ได้คัดลอกโค้ด ไม่ได้เรียก get_component
ที่เราทำเอง (monochrome / nextjs.org-like):
| ไอเดียจาก reference | การ implement ของเรา |
|---|---|
| แถบขั้นตอน / chain เหนือข้อความตอบ | src/components/chat/thought-chain.tsx — รายการแนวตั้งเหนือ reply, ไอคอนตาม ActivityKind, Spinner ตอน running, ✓/✗ ตอน done/failed, ไม่แสดง reasoning |
| ข้อความไหลทีละส่วน | src/components/chat/stream-text.tsx + src/lib/chat/stream-buffer.ts — buffer ด้วย Intl.Segmenter (grapheme), ปล่อยด้วย requestAnimationFrame, Markdown ผ่าน markdown-view ไม่เกิน ~30fps, ตัดที่ fence code ที่ยังไม่ปิด |
| Caret ระหว่างสตรีม | แถบ caret สี bg-fg กะพริบ (ปิดเมื่อ prefers-reduced-motion) |
| ยุบ chain หลังเสร็จ | ThoughtChain ยุบอัตโนมัติ ~600ms หลัง reply ไม่ pending และไม่มี step running |
| เลื่อนตามข้อความ | chat-app.tsx เลื่อนเฉพาะเมื่อผู้ใช้อยู่ใกล้ล่าง; ปุ่ม “Jump to latest” (chat.jumpToLatest) |
SSE / รูปแบบ UiEvent ฝั่งเซิร์ฟเวอร์ไม่เปลี่ยน
17. Customer connections, projects and deploys (PR-A to PR-E)#
Pages: /settings/connections, /projects, /projects/[id], plus the deploy card in chat. Every one uses NVX UI with monochrome tokens: border-border, text-fg, text-subtle, and bg-fg text-bg for the strongest state. No colour is used for status; the shape and fill of the pill carry it. No code was copied. These are bookmark references from section 13, used as ideas only:
| Reference | Idea taken | Our implementation |
|---|---|---|
| Process Timeline by shadcnui-blocks (21st.dev id 28381) | A vertical connector line with a dot per step | src/components/projects/direct-deploy-panel.tsx: a border-l rail with an outlined dot per deployment; StatusPill in src/components/deploy/deploy-status.tsx uses outline for live, solid fg for failed and a Spinner while running |
| Dismissible Alert Stack by olewandowski1 (id 26527) | Inline, low-noise alerts | Connections and project errors render as a role="alert" outline box (border-fg/40), not a red banner |
| nextjs.org settings tabs (visual reference) | An underline tab row | src/components/settings-nav.tsx: MCP, Connections and Projects tabs with aria-current |
Accessibility rules:
- Status regions use
aria-live="polite". - Secret inputs use
type="password"withautocomplete="off"and are cleared after submit. - Every control has a visible focus ring.
DST vector mascot (src/components/brand/dst-mascot.tsx, 2026-10-15)#
- Original SVG drawn on the NVX master-logo 1024px grid (eye capsules reuse the in-house logo layout). No third-party code or assets copied.
- Visual reference: the user's own DST mascot artwork (black tile). Reference only.
- Canvas modes:
black(dark UI) andbrand(--nvx-brand-pink#fb0fab, light UI). Pink and the letter gradients are decorative mascot art only; controls stay monochrome. - Animations (float, yaw, blink) run only under
prefers-reduced-motion: no-preference.labelgivesrole="img"+aria-label; without it the mascot isaria-hidden. - Demo:
/design/dst-mascot.
nvx21st CLI (packages/nvx21st, 2026-10-15)#
- A zero-dependency Node CLI (MIT) that wraps what already exists:
POST /api/cli/scaffold(the same starter zip as/setup.sh),npx shadcn@latest addfor 21st components, a secrets-safe zip, andnpx wrangler@4 deploywith the user's own login. The manual, with NAME, SYNOPSIS and the other sections, ispackages/nvx21st/nvx21st.1.md. - Reference only, no code copied: the public 21st CLI docs (https://help.21st.dev/cli, https://help.21st.dev/cli/reference), for the
add <user>/<slug>,--print,@registry,theme <id>andlogo <query>command shapes.theme <id>calls the official@21st-dev/cli(MIT) at run time, andlogouses the public svgl API (https://svgl.app, MIT), the same source the 21st CLI uses. The studio page https://21st.dev/studio/thanabartbb/docs/cli needs a login and could not be read.
Source: docs/design/ui-ux-revamp-plan.md · /docs/design/ui-ux-revamp-plan.md