ACTUAL CODEX CLI RUN / STEP 07 Codex CLI 0.153.4 · captured 11 September 2026 This is a selected event transcript, not the Codex Desktop UI. Reasoning, environment diagnostics and supporting skill instructions are omitted. Paths are shortened. COMMAND codex exec -C --sandbox workspace-write --json --output-last-message 07-final.txt - < prompts/07-fix-controls.txt PROMPT SENT การตรวจ browser โดย parent/reviewer พบปัญหาที่ต้องแก้ตามหลักฐานนี้: - ขอบ input/button ที่ไม่ได้เลือกกลืนกับพื้น .lesson-controls: light #D0D0D0 บน #FFF =1.54:1; dark #555 บน #171717 =2.40:1 เพราะfillของcontrolเหมือนcontainer ขอบนี้จึงเป็น visual boundary ของcontrolและต้องมีcontrastอย่างน้อย3:1 - ลิงก์ walkthrough ใน footer ยังมีข้อความ กำลังสร้าง ซึ่งจะไม่ตรงกับฉบับเผยแพร่ แก้เฉพาะ index.html, style.css และบันทึก review-fix.md/อัปเดต handoff.md: เพิ่ม semantic token --control-line สำหรับขอบcontrol โดยใช้ light #767676 และ dark #858585 นำไปใช้กับ input, filter buttons และ clear/theme buttons ตามที่ต้องมีขอบ ไม่จำเป็นต้องเปลี่ยนdividerตกแต่งทั้งหมด รักษาfocus, layout, lightdefault/dark, storagefailure, search/filter/reset/noJS behaviorเดิม ไม่แก้main.js เปลี่ยนข้อความท้ายลิงก์walkthroughเป็นข้อความที่อ่านได้ตามปกติและยังชี้URLเดิม อย่าแก้historical snapshotsนอกรอบนี้ อย่ารันserverหรือdeploy บันทึกว่าbrowser/contrastrecheckรอparentrunner ไม่อ้างผ่านเองจากการอ่านโค้ด EXECUTED COMMAND /bin/bash -lc "pwd && rg -n --glob 'index.html' --glob 'style.css' --glob 'review-fix.md' --glob 'handoff.md' \"lesson-controls|walkthrough|input|filter|clear|theme|D0D0D0|#555|focus|handoff\" ." OUTPUT ./handoff.md:26:- Theme toggle: light เป็น default แม้ OS dark; หลังผู้ใช้เลือกจึงใช้/บันทึกค่าด้วย storage key `psu-course-website-theme-v1`; หาก storage ใช้ไม่ได้ toggle ยังทำงานใน session นั้น. ./handoff.md:31:`browser-verification.json` ระบุว่า **parent runner** เป็นผู้รัน Playwright (`npx playwright test tests/course-website.spec.mjs --reporter=json`) ที่ `http://127.0.0.1:3320` ไม่ใช่การรัน browser โดย Codex รอบนี้. ผล: 5 expected, 0 unexpected, 0 flaky; ครอบคลุม mapping 11 บท, search/filter/reset, default-light/storage fallback, no-JS, keyboard, viewport และ axe. ./style.css:43: --focus: #17653f; ./style.css:48:html[data-theme="dark"] { ./style.css:54: --line: #555555; ./style.css:58: --focus: #82efae; ./style.css:80:a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { ./style.css:81: outline: 3px solid var(--focus); ./style.css:86:.skip-link:focus { transform: translateY(0); } ./style.css:90: .skip-link:focus { clip-path: none; } ./style.css:136:button, input, select, textarea { min-height: 2.75rem; border: 1px solid var(--line); border-radius: 0.4rem; background: var(--surface-raised); color: var(--text); font: inherit; } ./style.css:138:input, textarea { width: 100%; padding: 0.6rem 0.8rem; } ./style.css:140:.theme-toggle { white-space: nowrap; } ./style.css:141:.lesson-controls { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1rem; align-items: end; margin-top: 1.5rem; padding: 1rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-raised); } ./style.css:143:.lesson-search-field label, .lesson-filter-field p { display: block; margin: 0 0 0.35rem; font-weight: 700; } ./style.css:144:.lesson-filter-buttons { display: flex; flex-wrap: wrap; gap: 0.5rem; } ./style.css:145:.lesson-filter-buttons button[aria-pressed="true"] { border-color: var(--action); background: var(--action); color: var(--action-text); font-weight: 700; } ./style.css:151: .lesson-controls { grid-template-columns: 1fr; align-items: stretch; } ./style.css:157: :root, html[data-theme="dark"] { color-scheme: light; --surface: #fff; --surface-raised: #fff; --text: #000; --muted: #333; --line: #888; --link: #000; } ./style.css:158: .skip-link, .site-nav, .theme-toggle, .lesson-controls, .lesson-empty { display: none !important; } ./index.html:2: ./index.html:27: ./index.html:96: ./index.html:97: ./index.html:100: ./index.html:167: อ่านบทเรียน 10 EXIT 0 EXECUTED COMMAND /bin/bash -lc "sed -n '1,180p' style.css && sed -n '145,190p' index.html && sed -n '1,180p' handoff.md && rg --files | rg '("'^|/)review-fix'"\\.md"'$'"'" OUTPUT @font-face { font-family: "Inter"; src: url("/fonts/Inter-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: "Inter"; src: url("/fonts/Inter-Bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; } @font-face { font-family: "Noto Sans Thai"; src: url("/fonts/NotoSansThai-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: "Noto Sans Thai"; src: url("/fonts/NotoSansThai-Bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; } :root { color-scheme: light; --surface: #f7f7f7; --surface-raised: #ffffff; --text: #0a0a0a; --muted: #505050; --line: #d0d0d0; --action: #3edc81; --action-text: #063119; --link: #17653f; --focus: #17653f; --radius: 0.75rem; --page-width: 72rem; } html[data-theme="dark"] { color-scheme: dark; --surface: #0a0a0a; --surface-raised: #171717; --text: #f7f7f7; --muted: #c8c8c8; --line: #555555; --action: #3edc81; --action-text: #062c16; --link: #82efae; --focus: #82efae; } * { box-sizing: border-box; } [hidden] { display: none !important; } html { background: var(--surface); } body { margin: 0; min-width: 0; background: var(--surface); color: var(--text); font-family: Inter, "Noto Sans Thai", sans-serif; font-size: 1rem; line-height: 1.7; overflow-wrap: anywhere; } a { color: var(--link); text-decoration-thickness: 0.12em; text-underline-offset: 0.18em; } a:hover { color: var(--text); } a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; } .skip-link { position: fixed; z-index: 5; top: 0.75rem; left: 0.75rem; padding: 0.6rem 0.85rem; background: var(--action); color: var(--action-text); transform: translateY(-150%); } .skip-link:focus { transform: translateY(0); } @media (prefers-reduced-motion: reduce) { .skip-link { transform: none; clip-path: inset(50%); } .skip-link:focus { clip-path: none; } } .site-header { border-bottom: 1px solid var(--line); } .header-inner, .page-shell, .site-footer { width: min(100% - 2rem, var(--page-width)); margin-inline: auto; } .header-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem 2rem; padding-block: 1.15rem; } .course-identity p { margin: 0; } .eyebrow, .preview-label { margin: 0; color: var(--muted); font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; } .course-code { font-weight: 700; } .institution { color: var(--muted); font-size: 0.9rem; } .site-nav { display: flex; flex: 1 1 26rem; flex-wrap: wrap; justify-content: flex-end; gap: 0.4rem 1rem; } .site-nav a { padding: 0.35rem 0; white-space: nowrap; } .page-shell { padding-block: clamp(2.5rem, 6vw, 5.5rem); } .course-hero { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(15rem, 0.65fr); gap: clamp(1.5rem, 5vw, 5rem); align-items: end; padding-bottom: clamp(2.5rem, 5vw, 4rem); border-bottom: 1px solid var(--line); } h1, h2, h3, h4 { margin: 0; color: var(--text); line-height: 1.22; text-wrap: balance; } h1 { max-width: 15ch; font-size: clamp(2.3rem, 7vw, 5.6rem); letter-spacing: -0.055em; } h2 { font-size: clamp(1.65rem, 4vw, 2.7rem); letter-spacing: -0.035em; } h3 { font-size: clamp(1.2rem, 2.2vw, 1.55rem); } h4 { font-size: 1.08rem; } .hero-subtitle { margin: 1.15rem 0 0; font-size: clamp(1.15rem, 2vw, 1.5rem); font-weight: 700; } .hero-summary { max-width: 58ch; margin: 0.85rem 0 0; color: var(--muted); font-size: 1.08rem; } .hero-actions { display: flex; flex-wrap: wrap; gap: 0.75rem 1.25rem; margin: 1.75rem 0 0; align-items: center; } .hero-actions a:first-child { display: inline-flex; min-height: 2.8rem; align-items: center; padding: 0.55rem 1rem; background: var(--action); border: 1px solid var(--action); border-radius: var(--radius); color: var(--action-text); font-weight: 700; text-decoration: none; } .learning-preview { padding: clamp(1.25rem, 3vw, 2rem); border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-raised); } .learning-preview ol { display: grid; gap: 0.75rem; margin: 1rem 0 0; padding: 0; list-style: none; counter-reset: route; } .learning-preview li { display: flex; align-items: center; gap: 0.7rem; font-weight: 700; } .learning-preview li::before { display: grid; width: 1.8rem; height: 1.8rem; place-items: center; border: 1px solid var(--line); border-radius: 50%; color: var(--muted); content: counter(route, decimal-leading-zero); counter-increment: route; font: 700 0.7rem/1 Inter, sans-serif; } .content-section { padding-top: clamp(3rem, 8vw, 7rem); } .content-section > p, .goals-section li { max-width: 72ch; } .content-section > p { color: var(--muted); } .goals-section ul { padding-left: 1.25rem; } .day-grid, .lesson-grid { display: grid; gap: 1rem; margin-top: 1.5rem; } .day-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .day-card, [data-lesson] { min-width: 0; padding: clamp(1.1rem, 3vw, 1.6rem); border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-raised); } .day-card p, [data-lesson] p { color: var(--muted); } .lesson-day + .lesson-day { margin-top: 2.5rem; } .lesson-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } [data-lesson] { display: flex; flex-direction: column; gap: 0.85rem; } [data-lesson] p { margin: 0; } [data-lesson] a { width: fit-content; margin-top: auto; font-weight: 700; } .resources-section ul { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem 2rem; padding: 0; list-style: none; } .resources-section a { display: inline-block; padding: 0.35rem 0; } .site-footer { margin-top: 2rem; padding-block: 2rem 3rem; border-top: 1px solid var(--line); color: var(--muted); font-size: 0.92rem; } .site-footer p { margin: 0.25rem 0; } button, input, select, textarea { min-height: 2.75rem; border: 1px solid var(--line); border-radius: 0.4rem; background: var(--surface-raised); color: var(--text); font: inherit; } button, select { padding-inline: 0.8rem; } input, textarea { width: 100%; padding: 0.6rem 0.8rem; } .theme-toggle { white-space: nowrap; } .lesson-controls { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1rem; align-items: end; margin-top: 1.5rem; padding: 1rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-raised); } .lesson-search-field { min-width: 0; } .lesson-search-field label, .lesson-filter-field p { display: block; margin: 0 0 0.35rem; font-weight: 700; } .lesson-filter-buttons { display: flex; flex-wrap: wrap; gap: 0.5rem; } .lesson-filter-buttons button[aria-pressed="true"] { border-color: var(--action); background: var(--action); color: var(--action-text); font-weight: 700; } .lesson-empty { margin-top: 1.5rem; padding: 1rem; border-left: 0.3rem solid var(--action); background: var(--surface-raised); font-weight: 700; } @media (max-width: 46rem) { .header-inner, .site-nav { align-items: flex-start; justify-content: flex-start; } .course-hero, .day-grid, .lesson-grid, .resources-section ul { grid-template-columns: 1fr; } .lesson-controls { grid-template-columns: 1fr; align-items: stretch; } h1 { max-width: none; } .site-nav { flex-basis: 100%; } } @media print { :root, html[data-theme="dark"] { color-scheme: light; --surface: #fff; --surface-raised: #fff; --text: #000; --muted: #333; --line: #888; --link: #000; } .skip-link, .site-nav, .theme-toggle, .lesson-controls, .lesson-empty { display: none !important; } .page-shell { padding-block: 1.5rem; } .course-hero, .day-grid, .lesson-grid, .resources-section ul { grid-template-columns: 1fr; } a { color: #000; } a[href]::after { content: " (" attr(href) ")"; font-size: 0.8em; } }

06 — เว็บเช่าอุปกรณ์: availability และ capacity ของ demo ที่รันได้จริง

พัฒนาเว็บเช่าอุปกรณ์ที่จัดการ availability และ capacity ของ demo ได้

อ่านบทเรียน 06

08 — รันและตรวจ deployment path ของโปรเจกต์ Cloudflare นี้

รันโปรเจกต์และตรวจเส้นทาง deployment ของ Cloudflare

อ่านบทเรียน 08

09 — Production Operations: security, observability, rollback และต้นทุน

ดูแล production ทั้งความปลอดภัย การสังเกตการณ์ การ rollback และต้นทุน

อ่านบทเรียน 09

10 — สร้างเว็บของตนเองและส่งมอบอย่างตรวจสอบได้

สร้างเว็บของตนเองและเตรียมการส่งมอบที่ตรวจสอบได้

อ่านบทเรียน 10

Labs และแหล่งเรียนต่อ

977-121 Module: Website Design and Development · มหาวิทยาลัยสงขลานครินทร์ วิทยาเขตภูเก็ต

สื่อออกแบบและจัดทำโดย Rawinnipa

# Handoff — เว็บไซต์ตัวอย่างรายวิชา 977-121 ## สถานะรอบนี้ อัปเดตเอกสารตามข้อกำหนดที่ได้รับเพิ่มแล้ว โดยไม่ได้แก้ `index.html`, `style.css` หรือ `main.js`; ไม่ได้รัน server, deploy หรือโมเดลอื่น. ยังไม่อ้างว่าเผยแพร่ public เพราะหลักฐาน browser ระบุว่าไม่ได้ทดสอบ public deployment. ## ไฟล์ | ไฟล์ | บทบาท/สถานะ | | --- | --- | | `brief.md` | บันทึก FACT, CTA, state ของ interaction, การปิด GAP และข้อจำกัดที่ยังไม่ยืนยัน | | `evidence.csv` | เก็บหลักฐานรอบแรกไว้ แล้วเพิ่ม FACT/VERIFIED/STATUS_CHANGE ของ D1–D3 และสถานะ public ที่ยังเป็น GAP | | `implementation-decisions.md` | ต้นทางคำสั่ง D1–D3 จาก parent; ไม่ได้แก้ | | `browser-verification.json` | ผลทดสอบที่ parent runner แนบมา; ไม่ได้รันซ้ำ | | `index.html`, `style.css`, `main.js` | อ่านเพื่อตรวจความสอดคล้องเท่านั้น; ไม่ได้แก้ | ## CTA ที่ยืนยัน - CTA หลัก `เริ่มจากบทเรียน 00` → `/learn/lessons/00-setup-and-web-basics/` - CTA รอง `ดูบทเรียนทั้งหมด` → `#lessons` (ไม่ใช่ `/`) - คู่มือ/ทรัพยากร → `/handbook/` และ `/resources/` ## Interaction และ token - Day 1 = บท 00–05; Day 2 = บท 06–10 จาก `dayData`. เป็นเส้นทางเลือกเนื้อหา ไม่ได้ทำให้ workshop 8 ชั่วโมงครอบคลุมทุกบทโดยอัตโนมัติ. - Theme toggle: light เป็น default แม้ OS dark; หลังผู้ใช้เลือกจึงใช้/บันทึกค่าด้วย storage key `psu-course-website-theme-v1`; หาก storage ใช้ไม่ได้ toggle ยังทำงานใน session นั้น. - Design tokens ที่อ้างอิง: light `#F7F7F7`/`#0A0A0A`/`#3EDC81`/`#17653F`; dark `#0A0A0A`/`#171717`/`#F7F7F7`; Inter และ Noto Sans Thai. ## หลักฐานตรวจ `browser-verification.json` ระบุว่า **parent runner** เป็นผู้รัน Playwright (`npx playwright test tests/course-website.spec.mjs --reporter=json`) ที่ `http://127.0.0.1:3320` ไม่ใช่การรัน browser โดย Codex รอบนี้. ผล: 5 expected, 0 unexpected, 0 flaky; ครอบคลุม mapping 11 บท, search/filter/reset, default-light/storage fallback, no-JS, keyboard, viewport และ axe. ## สิ่งที่ยังไม่ทำ / ยังไม่ยืนยัน - ไม่มีหลักฐาน deploy/public; JSON ระบุ `publication: not yet tested in public`. - ยังไม่ยืนยันข้อมูลผู้สอน, หน่วยกิต, ภาคเรียน, เกณฑ์คะแนน, ช่องทางสมัคร หรือ LMS — ต้องไม่อ้างว่าได้รับการยืนยันหรือแสดงข้อมูลเหล่านี้. - ยังรอยืนยันวันเผยแพร่ลิงก์บทความทีละขั้น, ข้อความ disclaimer ฉบับเจ้าของ, และการคงเครดิต Rawinnipa. เมื่อข้อกำหนดได้รับคำตอบแล้ว ต้องอัปเดตทั้ง `brief.md` และ `evidence.csv` ให้มีแหล่งยืนยัน/สถานะ GAP ที่ตรงกัน และทำให้ implementation สอดคล้องก่อนจึงจะถือว่าพร้อมตรวจรอบถัดไป. EXIT 1 FILE CHANGES [ { "path": "/handoff.md", "kind": "update" }, { "path": "/index.html", "kind": "update" }, { "path": "/review-fix.md", "kind": "add" }, { "path": "/style.css", "kind": "update" } ] CODEX MESSAGE แก้โค้ดและบันทึกการส่งต่องานแล้ว: token ใหม่ใช้เฉพาะ visual boundary ของคอนโทรลที่ระบุ, divider เดิมไม่เปลี่ยน, และ URL walkthrough คงเดิม. กำลังตรวจความสะอาดของ diff และยืนยันว่าไม่มีการแตะ `main.js` หรือ historical snapshots. EXECUTED COMMAND /bin/bash -lc "git diff --check && git status --short && git diff -- index.html style.css handoff.md review-fix.md && rg -n --glob 'style.css' --glob 'index.html' --glob 'handoff.md' --glob 'review-fix.md' -- \"control-line|build-course-website-step-by-step|กำลังสร้าง|main\\.js\"" OUTPUT ?? ../../../.diagram-design ?? ../../../.gitattributes ?? ../../../.gitignore ?? ../../../CLAUDE.md ?? ../../../DESIGN.md ?? ../../../INFRASTRUCTURE.md ?? ../../../PROJECT_PLAN.md ?? ../../../README.md ?? ../../ ?? ../../../design-system/ ?? ../../../diagrams/ ?? ../../../docs/ ?? ../../../examples/ ?? ../../../migrations/ ?? ../../../package-lock.json ?? ../../../package.json ?? ../../../playwright.config.mjs ?? ../../../public/ ?? ../../../scripts/ ?? ../../../src/ ?? ../../../tests/ ?? ../../../training-skills/ ?? ../../../tsconfig.json ?? ../../../worker-configuration.d.ts ?? ../../../wrangler.jsonc handoff.md:5:แก้ไขเฉพาะขอบคอนโทรลและข้อความลิงก์ walkthrough ตามข้อพบจาก parent/reviewer แล้ว: เพิ่ม `--control-line` (light `#767676`, dark `#858585`) ให้ input, ปุ่ม filter, ปุ่มล้าง และปุ่มเปลี่ยนธีม; เปลี่ยนข้อความลิงก์เป็น `อ่านการสร้างทีละขั้น` โดยคง URL เดิม. ไม่ได้แก้ `main.js`, historical snapshots, รัน server หรือ deploy. ยังไม่อ้างว่าเผยแพร่ public เพราะหลักฐาน browser ระบุว่าไม่ได้ทดสอบ public deployment. handoff.md:16:| `main.js` | ไม่ได้แก้ | handoff.md:30:- ขอบของ control ที่มี fill กลืนกับ `.lesson-controls` ใช้ `--control-line`: light `#767676`, dark `#858585`; divider ตกแต่งยังใช้ `--line` เดิม. style.css:40: --control-line: #767676; style.css:56: --control-line: #858585; style.css:141:input, .theme-toggle, .lesson-filter-buttons button, #clear-search { border-color: var(--control-line); } index.html:181:
  • อ่านการสร้างทีละขั้น
  • index.html:190: review-fix.md:5:- แก้เฉพาะ `index.html` และ `style.css`; ไม่แก้ `main.js` หรือ historical snapshots. review-fix.md:10:- เพิ่ม semantic token `--control-line`: light `#767676` และ dark `#858585`. review-fix.md:13:- ตัดข้อความ `(กำลังสร้าง)` จากลิงก์ walkthrough โดยคง URL `/learn/labs/build-course-website-step-by-step/`. EXIT 0 EXECUTED COMMAND /bin/bash -lc "git rev-parse --show-toplevel && sed -n '34,62p;132,149p' style.css && sed -n '176,184p' index.html && sed -n '1,80p' review-fix.md && sed -n '1,52p' handoff.md" OUTPUT color-scheme: light; --surface: #f7f7f7; --surface-raised: #ffffff; --text: #0a0a0a; --muted: #505050; --line: #d0d0d0; --control-line: #767676; --action: #3edc81; --action-text: #063119; --link: #17653f; --focus: #17653f; --radius: 0.75rem; --page-width: 72rem; } html[data-theme="dark"] { color-scheme: dark; --surface: #0a0a0a; --surface-raised: #171717; --text: #f7f7f7; --muted: #c8c8c8; --line: #555555; --control-line: #858585; --action: #3edc81; --action-text: #062c16; --link: #82efae; --focus: #82efae; } [data-lesson] a { width: fit-content; margin-top: auto; font-weight: 700; } .resources-section ul { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem 2rem; padding: 0; list-style: none; } .resources-section a { display: inline-block; padding: 0.35rem 0; } .site-footer { margin-top: 2rem; padding-block: 2rem 3rem; border-top: 1px solid var(--line); color: var(--muted); font-size: 0.92rem; } .site-footer p { margin: 0.25rem 0; } button, input, select, textarea { min-height: 2.75rem; border: 1px solid var(--line); border-radius: 0.4rem; background: var(--surface-raised); color: var(--text); font: inherit; } button, select { padding-inline: 0.8rem; } input, textarea { width: 100%; padding: 0.6rem 0.8rem; } input, .theme-toggle, .lesson-filter-buttons button, #clear-search { border-color: var(--control-line); } .theme-toggle { white-space: nowrap; } .lesson-controls { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1rem; align-items: end; margin-top: 1.5rem; padding: 1rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-raised); } .lesson-search-field { min-width: 0; } .lesson-search-field label, .lesson-filter-field p { display: block; margin: 0 0 0.35rem; font-weight: 700; } .lesson-filter-buttons { display: flex; flex-wrap: wrap; gap: 0.5rem; } .lesson-filter-buttons button[aria-pressed="true"] { border-color: var(--action); background: var(--action); color: var(--action-text); font-weight: 700; } .lesson-empty { margin-top: 1.5rem; padding: 1rem; border-left: 0.3rem solid var(--action); background: var(--surface-raised); font-weight: 700; }
  • Lab: ติดตั้งเครื่องมือ AI
  • Lab: จากการค้นคว้าสู่เว็บไซต์แบรนด์
  • Lab: เครื่องมือออกแบบและ MCP
  • เปิดคู่มือการเรียน
  • ดูทรัพยากร
  • อ่านการสร้างทีละขั้น
  • # Review fix — control boundaries and walkthrough label ## ขอบเขต - แก้เฉพาะ `index.html` และ `style.css`; ไม่แก้ `main.js` หรือ historical snapshots. - ไม่รัน server และไม่ deploy. ## การแก้ไข - เพิ่ม semantic token `--control-line`: light `#767676` และ dark `#858585`. - ใช้ token นี้กับ input, ปุ่ม filter, ปุ่มล้างการค้นหา/ตัวกรอง และปุ่มเปลี่ยนธีม ซึ่งเป็น control ที่มีขอบแยกจากพื้น `.lesson-controls`. - คง `--line` สำหรับ divider และขอบตกแต่งเดิม. - ตัดข้อความ `(กำลังสร้าง)` จากลิงก์ walkthrough โดยคง URL `/learn/labs/build-course-website-step-by-step/`. ## สถานะการตรวจ การตรวจ browser และ contrast หลังแก้ไขรอ **parent runner**. เอกสารนี้ไม่อ้างว่าผ่านจากการอ่านโค้ด; รอบนี้ยืนยันได้เพียง static diff และขอบเขตการเปลี่ยนแปลง. # Handoff — เว็บไซต์ตัวอย่างรายวิชา 977-121 ## สถานะรอบนี้ แก้ไขเฉพาะขอบคอนโทรลและข้อความลิงก์ walkthrough ตามข้อพบจาก parent/reviewer แล้ว: เพิ่ม `--control-line` (light `#767676`, dark `#858585`) ให้ input, ปุ่ม filter, ปุ่มล้าง และปุ่มเปลี่ยนธีม; เปลี่ยนข้อความลิงก์เป็น `อ่านการสร้างทีละขั้น` โดยคง URL เดิม. ไม่ได้แก้ `main.js`, historical snapshots, รัน server หรือ deploy. ยังไม่อ้างว่าเผยแพร่ public เพราะหลักฐาน browser ระบุว่าไม่ได้ทดสอบ public deployment. ## ไฟล์ | ไฟล์ | บทบาท/สถานะ | | --- | --- | | `brief.md` | บันทึก FACT, CTA, state ของ interaction, การปิด GAP และข้อจำกัดที่ยังไม่ยืนยัน | | `evidence.csv` | เก็บหลักฐานรอบแรกไว้ แล้วเพิ่ม FACT/VERIFIED/STATUS_CHANGE ของ D1–D3 และสถานะ public ที่ยังเป็น GAP | | `implementation-decisions.md` | ต้นทางคำสั่ง D1–D3 จาก parent; ไม่ได้แก้ | | `browser-verification.json` | ผลทดสอบที่ parent runner แนบมา; ไม่ได้รันซ้ำ | | `index.html`, `style.css` | แก้ขอบ control และข้อความลิงก์ walkthrough ตาม review-fix; ไม่เปลี่ยน behavior | | `main.js` | ไม่ได้แก้ | | `review-fix.md` | บันทึกขอบเขตและหลักฐานการแก้จาก parent/reviewer; browser/contrast recheck รอ parent runner | ## CTA ที่ยืนยัน - CTA หลัก `เริ่มจากบทเรียน 00` → `/learn/lessons/00-setup-and-web-basics/` - CTA รอง `ดูบทเรียนทั้งหมด` → `#lessons` (ไม่ใช่ `/`) - คู่มือ/ทรัพยากร → `/handbook/` และ `/resources/` ## Interaction และ token - Day 1 = บท 00–05; Day 2 = บท 06–10 จาก `dayData`. เป็นเส้นทางเลือกเนื้อหา ไม่ได้ทำให้ workshop 8 ชั่วโมงครอบคลุมทุกบทโดยอัตโนมัติ. - Theme toggle: light เป็น default แม้ OS dark; หลังผู้ใช้เลือกจึงใช้/บันทึกค่าด้วย storage key `psu-course-website-theme-v1`; หาก storage ใช้ไม่ได้ toggle ยังทำงานใน session นั้น. - Design tokens ที่อ้างอิง: light `#F7F7F7`/`#0A0A0A`/`#3EDC81`/`#17653F`; dark `#0A0A0A`/`#171717`/`#F7F7F7`; Inter และ Noto Sans Thai. - ขอบของ control ที่มี fill กลืนกับ `.lesson-controls` ใช้ `--control-line`: light `#767676`, dark `#858585`; divider ตกแต่งยังใช้ `--line` เดิม. ## หลักฐานตรวจ `browser-verification.json` ระบุว่า **parent runner** เป็นผู้รัน Playwright (`npx playwright test tests/course-website.spec.mjs --reporter=json`) ที่ `http://127.0.0.1:3320` ไม่ใช่การรัน browser โดย Codex รอบนี้. ผล: 5 expected, 0 unexpected, 0 flaky; ครอบคลุม mapping 11 บท, search/filter/reset, default-light/storage fallback, no-JS, keyboard, viewport และ axe. การตรวจ browser และ contrast หลังแก้ไข **รอ parent runner**; รอบนี้ตรวจเฉพาะ static diff และไม่อ้างว่าผ่านจากการอ่านโค้ด. ## สิ่งที่ยังไม่ทำ / ยังไม่ยืนยัน - ไม่มีหลักฐาน deploy/public; JSON ระบุ `publication: not yet tested in public`. - ยังไม่ยืนยันข้อมูลผู้สอน, หน่วยกิต, ภาคเรียน, เกณฑ์คะแนน, ช่องทางสมัคร หรือ LMS — ต้องไม่อ้างว่าได้รับการยืนยันหรือแสดงข้อมูลเหล่านี้. - ยังรอยืนยันวันเผยแพร่ลิงก์บทความทีละขั้น, ข้อความ disclaimer ฉบับเจ้าของ, และการคงเครดิต Rawinnipa. เมื่อข้อกำหนดได้รับคำตอบแล้ว ต้องอัปเดตทั้ง `brief.md` และ `evidence.csv` ให้มีแหล่งยืนยัน/สถานะ GAP ที่ตรงกัน และทำให้ implementation สอดคล้องก่อนจึงจะถือว่าพร้อมตรวจรอบถัดไป. EXIT 0 CODEX MESSAGE แก้ครบตามขอบเขตแล้ว - เพิ่ม `--control-line`: light `#767676`, dark `#858585` และใช้กับ input, filter, clear, theme controls ใน [style.css](/style.css:40) - ลบ `(กำลังสร้าง)` โดยคง URL walkthrough เดิมใน [index.html](/index.html:181) - บันทึกรายการแก้และสถานะรอ parent runner ใน [review-fix.md](/review-fix.md:1) และ [handoff.md](/handoff.md:3) ตรวจ `git diff --check` ผ่านแล้ว. ไม่ได้รัน server/deploy หรือแก้ `main.js`/historical snapshots. Browser และ contrast recheck หลังแก้ยังรอ parent runner; ไม่ได้อ้างว่าผ่านจาก static review. FINAL RESPONSE แก้ครบตามขอบเขตแล้ว - เพิ่ม `--control-line`: light `#767676`, dark `#858585` และใช้กับ input, filter, clear, theme controls ใน [style.css](/style.css:40) - ลบ `(กำลังสร้าง)` โดยคง URL walkthrough เดิมใน [index.html](/index.html:181) - บันทึกรายการแก้และสถานะรอ parent runner ใน [review-fix.md](/review-fix.md:1) และ [handoff.md](/handoff.md:3) ตรวจ `git diff --check` ผ่านแล้ว. ไม่ได้รัน server/deploy หรือแก้ `main.js`/historical snapshots. Browser และ contrast recheck หลังแก้ยังรอ parent runner; ไม่ได้อ้างว่าผ่านจาก static review.