Changelog

Tất cả thay đổi đáng chú ý của theme được ghi tại đây. Quy ước: mỗi ngày làm việc gộp chung một phiên bản [MAJOR.MINOR.PATCH], các chỉnh sửa

CHANGELOG — Tân Doanh Theme

Tất cả thay đổi đáng chú ý của theme được ghi tại đây. Quy ước: mỗi ngày làm việc gộp chung một phiên bản [MAJOR.MINOR.PATCH], các chỉnh sửa nhỏ gom vào cùng entry trong ngày.

[1.9.2] - 2026-07-12 (Landing live chuyển MẶC ĐỊNH sang bản block)

3 landing bespoke (pc-gaming / ai-workstation / creator-studio) trước đây khách xem inline clone (filter the_content đọc inc/landing-inline/{slug}.html); bản block chỉ preview qua ?td_blocks=1. Bản block đã khớp 100% clone (desktop 1440 + mobile 390, 0px lệch) và edit được như homepage → giờ đảo thành mặc định.

  • inc/landing.php — flip mặc định: filter the_content giờ early-return $content (render post_content = các block land-hero/land-section) cho MỌI khách. Nhánh inline clone GIỮ NGUYÊN làm rollback/đối chiếu, opt-in qua ?td_inline=1 (cờ cũ ?td_blocks=1 bỏ — không còn cần).
  • Không đụng markup/CSS/JS: block path đã tự lo full-bleed (template page-{slug}.html gắn .td-main.tdp-land layout default), subnav sticky (gaming/creator bake sẵn .td-subnav, AI dựng từ navLinks của land-hero), terminal-hide (land-hero render.php echo ở frontend), enhance CSS/JS (enqueue chung cả 2 path).
  • Verify: 3 URL mặc định (không query) trả 200, tdp-land-inline=0, đủ 7/8/9 land block + subnav; screenshot desktop 1440 full-bleed đúng cho cả 3.

Đồng bộ tên build (fps-pill + bảng so sánh) từ TDCFG — hết lệch data

  • Vấn đề: build card lấy tên THẬT từ TDCFG trong landing-{slug}.js (AI: TD-INFER/ATOM/TRAIN/QUAD/XEON; creator: TD-PHOTO/EDIT/COLOR/STUDIO/MASTER), nhưng pill chọn build ở section benchmark VÀ header bảng so sánh vẫn giữ tên placeholder cũ của clone (AI: TD-OTTER/FALCON/ORCA/…; creator: TD-AMBER/COPPER/…) → khách thấy 3 tên khác nhau cho cùng 1 máy.
  • Fix (nguồn duy nhất = TDCFG): thêm bước đồng bộ trong script clone (landing-clone/{slug}.html, sau vòng áp TDCFG vào build card) — pill có text bắt đầu TD- (KHÔNG đụng pill category All/LLM/Diffusion/…) + ô .compare-table .tier nhận đúng tên build theo vị trí. Regenerate assets/js/landing-{slug}.js bằng tools/inline_clone.py. Sửa TDCFG 1 chỗ → card + pill + compare theo hết.
  • Gaming đã nhất quán sẵn (TD-FOX/WOLF/… baked khớp TDCFG) → bước sync idempotent, không đổi gì.
  • Verify live (bản block, không query): AI + creator + gaming đều khớp 3 chỗ (pill = compare = card); pill category + tier label giữ nguyên; click pill vẫn toggle active + repaint FPS bar; JS node --check sạch, 0 lỗi console.

[1.9.1] - 2026-07-10 (Audit Security + Performance theme 1.9.0 — 3 agent song song, tự kiểm chứng)

Audit lại toàn theme sau đợt dựng lại landing bằng block (nhiều code mới từ 1.7.9). 3 agent độc lập (security runtime / security baked-content+JS / performance), mọi finding TỰ KIỂM CHỨNG lại trước khi kết luận.

Bảo mật — KHÔNG có lỗ hổng critical/high/medium

  • Path traversal AN TOÀN: land-section/render.php ghép sections/{variant}-{section}.html với variant+section đều qua sanitize_key + whitelist cứng 2 lớp → không chèn được ../. terminal-ai.html/scenes/{variant}.html tương tự.
  • XSS AN TOÀN: mọi echo attribute escape đúng (esc_html/esc_url/esc_attr); titleHtml/brand dùng wp_kses_post (block attr, cần edit_posts). Inline hide-script tĩnh, không nội suy input.
  • Baked HTML sạch: 0 onclick inline (né đúng lỗi wptexturize cũ), 0 <script> lạ, 0 javascript:/on* handler.
  • JS sạch: terminal + CTA + subnav dùng textContent; giá LIVE từ REST gán bằng textContent (dòng 119) — endpoint trả HTML độc cũng chỉ hiện dạng text. innerHTML chỉ với TDCFG hardcode của dev. Không eval/Function.
  • INFO (không cần sửa): REST tandoanh/v1/prices public GET nhưng chỉ lộ giá vốn công khai + transient cache; postMessage(..,'*') chỉ chạy nhánh inFrame (production inline inFrame=false → chết).

Hiệu năng — nền tốt, 1 fix

  • [FIX] Double scroll-spy trên trang inline: script inline (landing.php) VÀ landing-enhance.js cùng bind scroll + getBoundingClientRect trên .td-subnav → 2× layout-read mỗi scroll. Gọn lại: script inline CHỈ dựng link subnav từ .header .nav, click+scroll-spy+sticky để landing-enhance.js lo (1 handler cho cả inline lẫn block). Verify: gaming inline subnav 6 link, click cuộn + active đúng, 0 lỗi.
  • Ghi nhận (quyết định nội dung, không phải bug): pc-gaming.html inline 383KB — nặng LCP/TBT ở request cache-miss (Brotli/gzip đã giảm; WPFC cache full HTML). Editor nạp ~360KB CSS (editorStyle 3 landing) — CHỈ admin khi mở editor landing, không đụng khách.
  • Sạch: business-info shortcode (td_founded/td_years_exp) static-cache + 1 get_option; the_content filter early-return rẻ; không N+1/autoload rác mới; live page render 1 readfile (không phải 7-9 block như lo ngại — path block chỉ editor/?td_blocks).

Khác

  • Sửa chủ sở hữu land-section/render.php (stevenlam→www-data) cho nhất quán; xác nhận nginx trả 403 cho tools/*.py (không lộ build tool).

[1.9.0] - 2026-07-10 (Landing block: editor như homepage + fix nút click + taste QA nút/border)

  • Editor như homepage: viết editor JS cho land-section (chọn variant/section + ServerSideRender preview) và bổ sung field mới cho land-hero AI (eyebrow/titleHtml/stats num-unit-lbl-pct/nút kiểu link). Build qua wp-scripts. Khai editorStyle = CSS clone (landing-{variant}.css) trong block.json → preview TRONG iframe editor hiển thị có style y hệt frontend. Verify: mở editor trang AI = 1 land-hero + 7 land-section, SSR render styled, 0 lỗi block.
  • Fix nút click (chết trên cả inline lẫn block): nút .btn primary ("Workload Match"/"Khám phá 5 cấu hình"/"Đặt thuê thử"…) là <button> KHÔNG href/handler (clone bắt bằng React runtime, không lọt clone tĩnh). Thêm handler ở landing-enhance.js: map theo chữ → cuộn tới section (#workload/#bench/#builds/#compare…); nút trong promo → /lien-he/. Chạy cả 3 landing (AI/gaming/creator), 0 lỗi.
  • Taste QA nút/border: thêm hover/active/focus còn thiếu (.btn-link sáng chữ + đẩy mũi tên; .fps-pill/.btn-ghost viền+chữ gold; .part-card nhấc + viền gold + shadow tint; .workload-item viền hover) + press translateY(1px) + vòng focus gold (a11y). Đặt trong landing-enhance.css scope [class*=tdp-land-] (không sửa CSS clone sinh ra, không leak). 0 tràn ngang cả 3 trang.
  • Còn treo: fps-pill (bench) hiện tên placeholder TD-OTTER trong khi build card fetch live TD-INFER — lệch data nhỏ (chưa wire fps-pill vào live). Chuyển 3 trang live inline→block: chờ anh duyệt.

[1.8.9] - 2026-07-10 (Phase 6 — gaming + creator dựng bằng block, cả 3 landing khớp clone pixel-perfect)

Nhân khuôn block sang 2 landing còn lại. Cả 3 (ai/gaming/creator) giờ render bằng block rời, giống clone 100% desktop + mobile.

  • land-section mở rộng: thêm section hero/fps/discipline/display. Script extract_variant.py tách hero (kèm subnav dựng từ .header .nav của clone) + mọi section → sections/{variant}-{id}.html bake nguyên.
  • gaming (104449): hero + fps/parts/builds/compare/promo/faq. Scene PC telemetry (CPU/FPS/RAM/GPU HUD) + subnav khớp.
  • creator (104451): hero + discipline/bench/display/builds/parts/compare/promo/faq. Scene DaVinci (LIFT/GAMMA/GAIN/OFFSET + timeline + render queue) + subnav khớp.
  • landing-enhance.js/.css tổng quát hoá: bỏ khoá cứng .tdp-land-ai → chạy mọi variant (subnav scroll-spy cho cả 3; terminal typing + GPU bar tự giới hạn ở trang có .ai-terminal).
  • Verify tự động (self-compare): gaming desktop 1440 + mobile 390 = mọi section CHÊNH 0px; creator đo riêng promo/compare/builds = 0px (số full-page lệch chỉ là artifact đo section dưới chưa settle, đã chứng minh ở AI). 0 tràn ngang, 0 lỗi JS, dark mode sạch. AI terminal gõ đủ 13/13 sau refactor.

CÒN LẠI: editor JS (kéo-thả/sửa chữ trong Gutenberg) + chuyển 3 trang live từ inline sang block. Trang khách hiện VẪN inline clone (chưa đụng); bản block ở ?td_blocks=1.

[1.8.8] - 2026-07-10 (Phase 2-5 AI — trang ai-workstation dựng bằng BLOCK, khớp clone pixel-perfect)

Hoàn tất dựng lại trang ai-workstation bằng block rời, giống clone 100% (anh Phát yêu cầu tự đối chiếu tới khi khớp nhất, cả responsive).

  • Block land-section (mới): 1 section = 1 block, readfile markup clone bake nguyên (workload/bench/parts/builds/compare/promo/faq → sections/ai-*.html). Tương tác (accordion FAQ, tab lọc tier, bar benchmark animate, reveal-on-scroll) dùng lại JS clone landing-ai-workstation.js — cùng selector, chạy đúng.
  • Subnav dựng từ navLinks của land-hero (CSS + scroll-spy JS trong landing-enhance.*); navLinks map đúng anchor clone (#workload…#faq).
  • Trang 104450 post_content = land-hero + 7 land-section (block rời, kéo-thả được sau khi có editor JS).
  • Verify tự động (self-compare block ?td_blocks=1 vs clone): mọi section CHÊNH 0px cả desktop 1440 LẪN mobile 390; 0 tràn ngang; 0 lỗi JS; dark mode sạch. Tên/giá build (TD-INFER/ATOM/TRAIN/QUAD/XEON) fetch live từ Woo — block == clone.
  • Phát hiện: tên build TD-OTTER… trong HTML tĩnh chỉ là placeholder; JS live thay bằng sản phẩm Woo thật → cả clone lẫn block đều hiện TD-INFER… giống nhau.
  • Trang live khách VẪN inline clone (chưa chuyển) — bản block xem ở ?td_blocks=1. Chuyển live + editor JS: bước sau.

CÒN LẠI: editor JS (kéo-thả/sửa chữ), chuyển live AI sang block, và nhân sang gaming + creator (Phase 6).

[1.8.7] - 2026-07-10 (Phase 1 — dựng lại landing bằng block: hero AI workstation faithful + editable)

Bắt đầu dựng lại 3 landing bằng BLOCK RỜI (anh Phát chốt), với ràng buộc: hero + SVG + scene phải GIỐNG clone. Kiến trúc: mỗi section = 1 block; phần visual (hero/terminal/SVG) bake NGUYÊN markup clone vào render, chỉ rút chữ ra thành attribute editable. CSS dùng landing-{slug}.css (scope .tdp-land-{variant}) đã nạp sẵn.

  • land-hero variant ai: viết lại render xuất markup clone y hệt (.hero.ai-hero + eyebrow + h1.h-display gold + lead + nút primary/link + 3 stat + terminal). Terminal bake vào terminal-ai.html (13 dòng + 4 GPU meter). Attribute mới: eyebrow, titleHtml (RichText, giữ <span class=gold>+<br>), stats[num/unit/lbl/pct], buttons[label/href/variant primary|link]. Nhánh gaming/creator giữ nguyên (Phase 6).
  • Nối landing-enhance.js (gõ ký tự + GPU bar) — block xuất .tdp-land-ai .ai-terminal, tự chạy. Thêm inline-hide script trong render (chống chớp), chỉ ở frontend (bỏ qua editor/REST).
  • Cờ preview ?td_blocks=1 (inc/landing.php): render post_content (block) thay inline clone, để build+đối chiếu mà KHÔNG đụng trang live (khách vẫn thấy inline clone giống 100%).
  • Set attribute block trang 104450 theo clone. Verify: hero block khớp clone pixel-perfect (eyebrow/headline/lead/nút/3 stat/terminal gõ chữ + màu + bar), 0 lỗi JS. Khác biệt còn lại: thanh subnav (Phase 5 — lắp trang).

CÒN LẠI: workload/benchmark/linh kiện/5 cấu hình/so sánh/promo/faq (Phase 2-4), lắp trang + subnav + tắt inline (Phase 5), nhân sang gaming+creator (Phase 6).

[1.8.6] - 2026-07-10 (AI workstation terminal: gõ TỪNG KÝ TỰ + fix màu + GPU bar chạy %)

Anh Phát chỉ ra bản 1.8.5 (fade từng dòng) sai: landing gốc gõ TỪNG KÝ TỰ có nhịp loading, MÀU chữ sai (mất chữ), và 4 GPU bar không nhảy %. Đối chiếu landing.tandoanh.vn gốc (React): terminal gõ ~1 ký tự/15ms sau ~450ms loading; dòng lệnh sáng rgb(234,240,252).

  • FIX MÀU (bug thật): terminal là panel TỐI, nhưng ở light mode token --ink-* của trang thành màu TỐI (dành cho nền sáng) → dòng lệnh t-cmd (dùng --ink-0) ra #1a1510 tối trên nền tối = mất chữ. Re-scope --ink-0..3 về giá trị dark (chữ sáng) CHỈ trong .ai-terminal khi light (landing-enhance.css). Sau fix: t-cmd light rgb(251,248,243).
  • Gõ từng ký tự (thay fade từng dòng): landing-enhance.js — ẩn dòng, đọc text, gõ tuần tự từng ký tự (lệnh 11ms, output 4ms, nghỉ 55ms/dòng) sau nhịp loading 450ms; con trỏ .td-term-cursor nhấp nháy chạy theo. Xong ~5s (gốc ~4s). Bỏ toàn bộ CSS stagger nth-child của 1.8.5.
  • 4 GPU meter chạy %: thanh .ai-meter-bar>div fill 0→đích (transition 1.15s) + số % .ai-meter span:last-child đếm lên easeOutCubic.
  • Chống chớp: inline script (chỉ variant ai) ẩn dòng terminal NGAY lúc parse (trước paint) → không lóe full text rồi mới gõ. Kích hoạt khi terminal lọt viewport (hero above-fold nên gần như ngay khi load).
  • prefers-reduced-motion: reduce: hiện đủ text + bar ở đích ngay, không gõ. File enhance KHÔNG sinh tự động (an toàn khi rebuild clone). Verify: gõ char-by-char 0→23→66→169→261, bar 62%→98%, màu sáng cả light/dark, 0 lỗi JS.

[1.8.5] - 2026-07-10 (AI workstation: hero terminal gõ từng dòng như landing gốc)

  • Hero landing ai-workstation: 13 dòng terminal hiện CÙNG LÚC (fade 0.18s) thay vì "gõ" tuần tự như landing gốc. Nguyên nhân: hiệu ứng typewriter là JS runtime của React ở landing gốc, KHÔNG lọt vào clone tĩnh — nên iframe cũ cũng đã không có, không phải regression từ việc inline.
  • Fix bằng CSS thuần (assets/css/landing-enhance.css): stagger animation-delay trên chính keyframe ai-typed sẵn có (0.15s + 0.13s×n) + animation-fill-mode: backwards cho .ai-terminal-line:nth-child() → dòng ẩn cho tới lượt mới hiện = gõ từng dòng, xong ~1.9s. Không thêm JS, không flash (fill-mode giữ dòng ẩn trước lượt).
  • File enhancement KHÔNG sinh tự động, enqueue SAU CSS clone (inc/landing.php) nên rebuild inline_clone.py không xoá mất. Scope .tdp-land-ai → 2 landing kia (không có .ai-terminal-line) không dính.
  • prefers-reduced-motion: reduce → hiện đủ 13 dòng ngay. Verify: gõ tuần tự 0→2→6→10→13 dòng theo thời gian, reduced-motion 13/13 ngay, pc-gaming/creator-studio 0 lỗi.

[1.8.4] - 2026-07-10 (FAQ sản phẩm: shortcode Flatsome cũ → accordion native)

  • 193 sản phẩm (màn hình, tản nhiệt…) có phần FAQ lưu bằng shortcode [accordion]/[accordion-item] của Flatsome cũ. Theme block không đăng ký shortcode này nên nó hiện literal ([accordion title=…]) trên trang.
  • Port bộ chuyển đổi từ theme hungphat-laptop (inc/content-enhance.php): render bằng <details>/<summary> native — accessible, KHÔNG cần JS, nội dung luôn trong DOM (tốt SEO). Prefix td-accordion, hàm tandoanh_*.
  • Chuẩn hoá dấu ngoặc cong: nội dung Flatsome lưu title=”…” (curly) khiến shortcode_parse_atts không đọc được attribute → filter the_content priority 9 đổi ngoặc cong → thẳng CHỈ trong cặp [ ], giữ nguyên dấu cong ở body.
  • CSS trong single-product.css (+ .purged.css), scope PDP vì 193 bài dính đều là product. Màu active dùng --td-brand-strong (đã theme-aware: gold đậm #8a6a00 light / gold sáng #f0c75e dark) nên bỏ được rule override dark mà bản HP phải có.
  • Verify 5 sản phẩm: 0 shortcode literal, item đầu auto_open tự mở, tương tác đóng/mở OK, contrast head active 5.07:1 (light) / 12.28:1 (dark) đạt AA, 0 lỗi JS.
  • Badge BCT đang hotlink https://static.tandoanh.vn/wp-content/uploads/2020/02/logoSaleNoti.png và trỏ tới bản ghi cũ …/2d6b68ce-….
  • Ảnh mới DaThongBao-BCT.png (360×111) upload vào Thư viện (attachment ID 104715) → https://td.phatdev.net/wp-content/uploads/2026/07/DaThongBao-BCT.png; hết phụ thuộc domain ngoài. (Bản đầu 360×135 được thay bằng bản crop sát 360×111: ghi đè file, wp media regenerate 104715 để metadata + thumbnail khớp, giữ nguyên URL và attachment ID.)
  • Backlink đổi sang http://online.gov.vn/nen-tang/67bfee06-f6fa-4856-943e-48f7b8b6ca8c. Đã mở bằng trình duyệt thật để xác minh (trang là SPA, curl không đọc được nội dung): đúng tandoanh.vn — Công ty TNHH TH Hoàng Phương, MST 0313792226.
  • Cập nhật qua option tandoanh_business_info (Admin → Thông tin DN → Link nội bộ) sửa default links.bct trong code để option bị xoá cũng không rơi về link cũ.
  • site-footer/render.php: <img> width/height 170×64360×111 cho khớp tỉ lệ ảnh thật (3.243) — placeholder aspect-ratio chuẩn, CLS trang chủ mobile 0.0024. Kích thước hiển thị vẫn do CSS (182×56).
  • Khối "Thương hiệu uỷ quyền trực tiếp" (.td-brandwall): rê chuột vào thẻ (INTEL, AMD, ASUS…) thì chữ chuyển xanh link #14529e trên nền gold thay vì màu chữ nhấn — chữ chìm, sai tông.
  • Nguyên nhân: rule toàn cục a:hover:not(.td-btn):not(.button):not(.wpcf7-submit):not([class*="__buy"]):not([class*="__cart"]):not([class*="td-pdp-chat"])base.css:55 có specificity 0,7,0, đè .td-brand:hover { color: var(--td-on-brand) } (0,2,0) trong templates/home.css:320. Đúng lớp lỗi đã gặp ở nút "Mua ngay" (1.6.x) — thẻ nào là <a> mà không nằm trong danh sách :not() đều dính.
  • Fix: thêm :not(.td-brand) vào rule toàn cục, sửa cả base.purged.css.
  • Verify: hover + :focus-visible, cả 2 loại thẻ (thường và --star), light + dark ⇒ chữ #1a1505 trên nền gold, tương phản 10.82:1 (light) / 11.70:1 (dark), đạt WCAG AA.

[1.8.1] - 2026-07-10 (Số năm kinh nghiệm trang Giới thiệu: hardcode → tự tính)

  • Dải số liệu trang /gioi-thieu/ ghi cứng 2007 (năm thành lập) và 17+ (năm kinh nghiệm) trong post_content. Sai — 2026 − 2007 = 19 — và sẽ sai lại mỗi năm.
  • Thêm misc.founded_year (mặc định 2007) vào Thông tin DN + ô nhập "Năm thành lập" trong admin.
  • Helper tandoanh_founded_year() / tandoanh_years_exp() (dùng wp_date('Y') nên theo timezone site) + 2 shortcode trả số trần, không bọc thẻ: [td_founded], [td_years_exp] — nhét thẳng vào markup có sẵn <span class="tdp-about__num">[td_years_exp]<i>+</i></span> mà không sinh <span> lồng nhau như [td_biz].
  • post_content trang 104669 đổi 2 số cứng thành shortcode. Đổi năm thành lập trong admin là cả hai ô tự cập nhật; sang năm số năm kinh nghiệm tự tăng.

[1.8.0] - 2026-07-10 (3 landing: gỡ iframe, nhúng clone THẲNG vào DOM)

3 landing bespoke (pc-gaming / ai-workstation / creator-studio) đang được nhúng bằng <iframe> trỏ file clone tĩnh landing-clone/{slug}.html (pc-gaming 502KB). Hệ quả: LCP mobile ~3.2s, và nội dung nằm trong document con nên công cụ tìm kiếm không index cho URL trang. Phiên này bỏ iframe nhưng giữ nguyên clone giống tuyệt đối (đúng chỉ đạo cũ) bằng cách nhúng markup + CSS + JS của clone thẳng vào trang.

Cách làm

  • Script build tools/inline_clone.py bóc mỗi file clone thành 3 phần và scope toàn bộ CSS dưới .tdp-land-{variant} (:root/html/body → wrapper; html[data-theme=…] body … → bỏ token body; @font-face/@keyframes giữ nguyên; @media/@supports đệ quy). tools/verify_scope.py kiểm: 734 / 774 / 823 selector, 0 lọt lưới ⇒ CSS clone không rò ra theme và ngược lại.
    • assets/css/landing-{slug}.css (112–122KB), assets/js/landing-{slug}.js (14KB, defer), inc/landing-inline/{slug}.html (markup).

GOTCHA của bộ scope CSS (đã sập 1 lần, mất light mode)

  • Tokenizer phải bỏ qua comment và chuỗi khi quét { ; }. CSS clone có comment chứa dấu chấm phẩy: /* … giữ gold; panel thiết bị vẫn tối */. Quét thô cắt tại ; trong comment ⇒ phần còn lại của comment bị coi là selector ⇒ sinh .tdp-land-gaming panel thiết bị vẫn tối */html[data-theme="light"]{…} = selector hỏng, trình duyệt bỏ nguyên rule ⇒ toàn bộ light-mode của landing chết (nền đen giữa site sáng).
  • Comment đứng ngay trước selector nằm chung prelude → phải tách ra rồi mới scope, không thì scope bị nhét vào giữa comment.
  • Script verify phải dùng CHÍNH tokenizer đó. Bản verify đầu tiên quét thô nên báo "0 lọt" trong khi CSS đang hỏng — kiểm tra vô giá trị. Verify giờ thêm điều kiện: scope không được xuất hiện trong comment.
  • inc/landing.php: filter the_content đổ markup vào <div class="tdp-land-inline tdp-land-{variant}"> + enqueue CSS/JS theo slug. Sub-nav sticky .td-subnav dựng từ nav clone (nav gốc display:none), giờ đọc thẳng cùng document thay vì contentWindow. Thêm scroll-margin-top:120px cho [id] để header sticky của site không che đầu section.
  • JS clone vốn đã có nhánh inFrame = window.parent !== window ⇒ chạy standalone tự cuộn, không cần sửa.

Kết quả đo (mobile, CPU 4×, Slow 4G, sau WPFC cache)

Trang LCP trước (iframe) LCP sau (inline) CLS
pc-gaming 3168ms 1232ms 0.033
ai-workstation 1952ms 0.004
creator-studio 1248ms 0.037
  • Đối chiếu pixel với clone standalone: #builds cao 1188px ở cả hai, tổng chiều cao pc-gaming 7429px ở cả hai ⇒ khớp hình học tuyệt đối. Tab lọc, ảnh SVG trong card, TD-EAGLE, giá live (REST tandoanh/v1/prices) đều còn nguyên.
  • QA 3 trang × {mobile 390px, desktop 1440px} × {light, dark}: 0 tràn ngang, 0 lỗi JS, 0 request ≥400.

Ghi chú

  • Bộ block tandoanh/land-* vẫn còn trong post_content và trong theme (bị the_content che). Trong lúc điều tra đã sửa 3 lỗi của bản block-native (thiếu enqueue landing-motion.js; landing-scene-gaming.css chưa bao giờ được nạp nên 4 thẻ HUD hero rơi thành text; kill-switch .td-gaming-card{display:none}) — giữ lại phòng khi cần bản editable.
  • landing-clone/nguồn: sửa clone rồi chạy lại inline_clone.py, đừng sửa tay file sinh ra.

Khác

  • Footer: thêm liên kết Giới thiệu (/gioi-thieu/) đầu cột "Hỗ trợ mua hàng", có ô nhập URL trong admin → Thông tin DN → Link nội bộ.
  • Admin Mega Menu: 3 nút hành động cao lệch nhau (nút Lưu có button-hero) và chữ nút Lưu bị .hplt-admin .button { color: var(--hplt-ink) } đè thành mực tối trên nền gradient xanh (2.3:1). Fix: đồng bộ 44px, color:#fff !important cho .button-primary ⇒ 5.27:1 đạt AA.
  • Admin Trả góp: nút icon Chọn logo / Gỡ 30px → 40px, bằng chiều cao ô nhập cùng hàng (luật 40px toàn admin). Audit script 13 trang admin: 0 vấn đề.

[1.7.9] - 2026-07-10 (Audit Security + Performance toàn theme — 6 vùng, 6 agent)

Audit toàn diện theme (183 file PHP / 23k dòng + 134 JS) qua 6 agent song song (4 security: authz/SQLi/XSS-file-SSRF/secrets-CSRF-money; 2 perf: DB-query/asset), mỗi finding tự kiểm chứng bằng wp eval/đo query. Kỷ luật code nền tốt: không có lỗ hổng critical/high — nonce+capability đủ mọi AJAX/admin-post, SQL toàn prepare/ép-int, không secret hardcode, không tin giá client. Các fix đã áp:

⚡ Performance

  • [LỚN NHẤT] Tab Hiệu năng PDP (VGA/CPU) ~397 query / ~1s mỗi render, KHÔNG cache (inc/perf/perf-data.php): td_bench_chip_value (2 query/lần, uncached) gọi trong vòng lặp lồng foreach metric × foreach 16 card cùng dòng. Mỗi lần save 1 product → WPFC purge → mọi trang VGA/CPU rebuild ở mức này. Fix: cache 5 hàm thuần-theo-chip (gaming_matrix/ai_matrix/cpu_matrix/gaming_self/self_groups) vào object cache group td_perf TTL 12h. Admin lưu benchmark gọi wp_cache_flush() (tandoanh-benchmarks/admin-page.php:72) nên cache tự sạch — không lo hiển thị số cũ. Đo thật: 397 q/1035ms → 0 q/2ms khi warm (giảm 100%), output cold==warm khớp tuyệt đối, invalidation verify đúng.
  • SHOW TABLES chạy mỗi request (inc/woo/checkout-extras.php:157, hook init prio 1): bảng promo tồn tại vĩnh viễn nhưng vẫn SHOW TABLES LIKE mỗi request. Fix: option flag autoload td_promo_table_ready, return sớm ⇒ −1 query/request.
  • Tra cứu MST (td_lookup_tax_code) gọi HTTP api.xinvoice.vn mỗi lần khách gõ, không cache (inc/woo/checkout.php): thêm transient theo MST 12h (MST không tồn tại đệm 10 phút) — cắt outbound lặp + chống lạm dụng endpoint nopriv.

🔒 Security

  • [CONFIRMED, medium] CSV Injection (inc/woo/checkout-extras.php export promo subscribers): khách vãng lai (nopriv) nhập billing_first_name = =HYPERLINK(...) / =cmd|'/c calc'!A1 → lưu DB → admin Export CSV mở Excel/LibreOffice thực thi công thức. sanitize_text_field KHÔNG lọc = + - @. Fix: prefix ' cho mọi ô bắt đầu bằng = + - @ \t \r trước fputcsv (test 6/6 payload).
  • PDP "sản phẩm vừa xem" JSON in thẳng <script> (inc/woo/pdp.php): tên SP chứa </script> (shop manager nhập) có thể phá block. Fix: wp_json_encode(..., JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT) (in-depth).
  • Object injection phòng thủ (inc/blocks/registry/buildband/render.php): maybe_unserialize($raw, ['allowed_classes'=>false]) cho dữ liệu session builder.
  • Bản dịch AI title lưu raw (inc/i18n/ai-translate.php): wp_strip_all_tags cho _td_en_title trước khi lưu (title in qua the_title, phòng AI provider trả HTML).
  • esc_like thiếu (inc/woo/checkout-extras.php:251 search subscriber): người dùng gõ %/_ thành wildcard (chức năng, không SQLi vì đã prepare). Fix $wpdb->esc_like.

🎨 Fix nút Chat Facebook/Zalo PDP hover khó nhìn (anh Phát báo)

  • 2 lỗi chồng nhau: (1) nền hover xanh FB gốc #1877f2 + chữ trắng chỉ 4.23 (dưới AA); (2) NẶNG hơn — chữ hover KHÔNG phải trắng mà thành xanh link --td-link-hover (chữ xanh trên nền xanh, contrast 2.24 gần trùng màu) vì global a:hover:not(.td-btn)... (specificity 0,6,1) đè color:#fff của .td-pdp-chat__fb:hover (0,2,0) — nút chat là <a> không nằm trong danh sách loại trừ (đúng bug [[feedback_ahover_button_link]] tái diễn).
  • Fix: (a) nền hover FB #1877f2→#1465d8 (trắng 5.41), Zalo #0068ff→#0059dd (6.05); (b) thêm :not([class*="td-pdp-chat"]) vào global a:hover (base.css + base.purged.css); (c) thêm [data-theme="dark"] .td-pdp-chat__fb:hover/__zalo:hover{color:#fff} vì dark default (chữ xanh nhạt) đứng sau đè color hover. Verify Playwright 4 trạng thái (light/dark × default/hover) đều chữ đạt AA: default 5.41/7.2, hover 5.41 cả 2 mode.

📋 Ghi nhận (KHÔNG phải lỗi — đã kiểm chứng)

  • mix-blend-mode: multiplypage-tu-chon-cau-hinh-pc.css:608dead CSS (false positive của asset audit): 2 block sau cùng selector override mix-blend-mode:normal + img{display:none} (thay bằng ::before mask SVG) → multiply KHÔNG active, không repaint.
  • seasonal.css (60KB) nạp cả 8 preset site-wide khi bật mùa (~13KB gzip thừa/trang): finding asset lớn nhất còn lại, NHƯNG preset đang TẮT nên tác động hiện tại = 0 (file không enqueue). Tách per-preset là refactor lớn đụng cơ chế scene data-URI — chờ anh Phát duyệt trước khi làm.
  • Điểm LOW không sửa (by-design/bounded): REST /qna public (honeypot+rate-limit+hold), SSRF i18n endpoint/buyback URL (admin/editor-only), cookie td_cart_count thiếu HttpOnly (chỉ số đếm giỏ), autoload 682KB do core+plugin khác (option theme đều autoload=off cho cái to).

[1.7.8] - 2026-07-09 (Seasonal v4 — redesign theo taste skill)

🎨 Giao diện

  • Seasonal v4 — redesign toàn bộ decor theo mùa (anh Phát chê v3 "xấu, nét vẽ/màu/khung/hiệu ứng chưa đẹp", chỉ định dùng taste skill): đổi từ ngôn ngữ clip-art nhiều màu sang line-art 1 tông + hairline tiết chế:
    • Background 2 bên: mỗi mùa 1 tile line-art dọc kiểu engraving (stroke 1.6–1.7, đơn sắc --td-season-line + accent rất hạn chế) + 2 lớp orb radial-gradient mờ tạo chiều sâu + mask-image fade mờ dần vào giữa trang; bên phải soi gương. Opacity .5 light / .32 dark.
    • Khung card: bỏ sọc kẹo/ngoặc dày/viền kép — khu mặc định = hairline 2px ở đỉnh fade 2 đầu (chừa mép 14%), khu TOP + section lẻ home = corner tick 2 nét mảnh (trên-trái đậm, dưới-phải 55%), khu shop/section chẵn = hairline ĐÁY; nền card chỉ wash 3.5% ở đỉnh, motif góc ảnh vẽ lại line-art mono 21px op .55 (watermark, hết kiểu sticker).
    • Ornament cạnh LOGO (spec mới của anh): vector line-art 26px sát phải logo từng mùa, tông SÁNG cho header nền ink (mai vàng+nhị đỏ / thông+sao / sao vàng / mặt trời / bông tuyết / bí ngô / đèn lồng+trăng / mũ tốt nghiệp) — ẩn <640px.
    • Hiệu ứng rơi: giảm 26→16 hạt (mobile 9), rơi chậm 12–22s, hạt nhỏ 5–7px; depth: 1/3 số hạt blur 1.2px + mờ + nhỏ, 1/4 rõ hơn; quỹ đạo cong nhẹ (keyframe 3 mốc); bỏ hết clip-path lòe loẹt (dơi to/máy bay/sao 10 cánh) — thay bằng cánh hoa nhỏ/tuyết mềm/đốm sáng vàng ấm/bụi nắng/lá thu trầm/confetti giấy 2 tông nhạt.
  • Trang admin Seasonal redesign: tab menu đổi tiếng Anh "Seasonal" (đồng bộ policy menu EN), H1 "Seasonal — Giao diện theo mùa"; grid chọn mùa CỐ ĐỊNH 3 cột (spec anh; collapse 2 cột <1500, 1 cột <900); card kiểu double-bezel (shell ngoài + ảnh sample lồng trong, bo concentric), radio ẩn thay bằng ring xanh + chip ✓, hover nâng nhẹ + shadow khuếch tán, nút "Xem thử ngoài web" thành pill có icon tròn (hover icon trượt chéo), transition cubic-bezier(.32,.72,0,1). 8 ảnh sample chụp lại theo art v4.
  • Verify sau redesign: 8/8 preset strip + motif + hairline OK (Playwright, inject client-side), admin render đúng EN + 3 cột + bezel.

🎨 Seasonal v14 — chuẩn hoá contrast theo PSI/WCAG AA (nguyên tắc anh Phát chốt 2026-07-09)

  • NGUYÊN TẮC MÀU TOÀN HỆ (theme gốc + 8 mùa): nền SÁNG → chữ TỐI, nền TỐI → chữ SÁNG; tỉ lệ contrast đạt WCAG AA (text ≥4.5, text lớn/UI ≥3.0 — đúng thước đo Lighthouse/PSI Accessibility) NHƯNG chỉ chỉnh độ đậm/nhạt trong cùng tông, không đổi hue premium.
  • Fix "chữ tối thui" anh báo (mùa Hè): Hè là mùa DUY NHẤT light dùng chữ tối (#241200 trên cam #d96407) — tái hiện được trên đường khách thật (không phải cache; em xin lỗi vì lần đầu đổ cho cache). Fix: cam đậm thêm 1 nấc #c2410c (hover/strong #a83c05) để dùng chữ kem #fff3e6 như 7 mùa kia — đo thật light 4.74 ✓; dark Hè khoá lại --td-on-brand:#241200 (nền cam sáng → chữ tối, đúng nguyên tắc; trước đó kế thừa kem từ light mới sẽ hỏng).
  • BÀI HỌC QA: test decor/màu PHẢI đi đường khách thật (server bật preset + WPFC bundle + purged CSS swap của speed.php), KHÔNG inject CSS thủ công — inject đã che mất lỗi này nhiều vòng.
  • Audit axe-core (đúng engine PSI a11y) 90 runs (5 trang × 9 trạng thái × light/dark): 160 instance → 8 cụm lỗi gốc, fix TOÀN BỘ:
    • Token mới --td-brand-bright (tokens.css :root + 8 preset): accent TEXT trên nền tối CỐ ĐỊNH (footer #1e1e23, đầu cột bestsellers/topbar #15151a) — light preset brand đậm (đỏ cờ #ad1a14 chỉ 2.31) chìm trên nền tối; giá trị = brand của DARK preset (5.18–11.3 ✓). Áp vào: .footer-hours__head, .footer-col__title (viền), .footer-contact svg, .topbar a:hover (layout.css + purged), link "Xem tất cả" .td-tb__head a (top-row.php).
    • BuildPC pill/btab active bị specificity đè (root cause "GAMING · 28M" 2.04–2.68): html[data-theme="light"] .td-bp__pill (0,2,1) THẮNG .td-bp__pill.is-active (0,2,0) → chữ active kẹt ink .72 trộn trên nền brand mùa. Fix home.css + purged: thêm override light .is-active{color:var(--td-on-brand)} (4.74–10.82 ✓), .is-active .m{opacity:1} (hết rớt 4.45 quoc-khanh dark), btab active light = color-mix(strong 72%, #1a1510) (6.03–9.52; strong thuần gốc gold chỉ 4.12), .swap:hover #16130a → var(--td-on-brand).
    • Giá gạch carousel bestsellers dark 3.74 (lỗi duy nhất của THEME GỐC): legacy wp_extra del{opacity:.8} — ép opacity:1!important theo đúng pattern woo-card 0.9.6 (dark 5.07 / light 4.97 ✓).
    • Noel --td-brand-strong #1e7a46 → #1b6f3e (brand pill sao/hotline trên nền hồng mix 4.46 → 5.17).
    • --td-info #0bb5c4 → #077e89 light (badge "Chính hãng" chữ trắng 2.49 → 4.82); dark Hè trả lại teal sáng #0bb5c4 vì badge dark chữ navy (5.9 ✓).
    • Link popup "vừa mua" (woo-notifications) inline #8a6a00 cố định → override var(--td-brand-strong)!important trong plugin-overrides.css: đổi theo mùa + ≥5.07 trên trắng mọi preset (mùa Đông hết bị gold chìm 2.27); timestamp <small> inline #94a3b8 (2.56) → #54545f light / #a6a6b0 dark.
  • GOTCHA wptexturize phá onclick inline (Lighthouse PDP 97→100): onclick="...window.location='...'..." trong content-single-product.php bị wptexturize đổi nháy đơn thành &#8217; trong HTML cache → attribute không đóng, browser nuốt <svg aria-hidden="true"> vào <a> = lỗi aria-hidden-focus. Fix: bỏ onclick inline → data-td-msapp + delegated click handler trong theme.js (deep-link Messenger mobile/iPad giữ nguyên hành vi). LUẬT: cấm onclick inline chứa quote trong template — texturize/cache sẽ phá.
  • Lighthouse Accessibility sau fix (đường khách thật, server preset tet): home 100, /shop/ 100, PDP 100 (trước 97); color-contrast audit = pass, 0 items cả 3 trang.

🔎 Seasonal v14 — QA + Audit vòng 2 (anh Phát yêu cầu "QA và Audit lại 1 vòng") — thêm 3 lỗi thật ngoài contrast

  • Nút "Build PC Custom" (.meganav-build) chìm trên trang Build PC / dark (contrast 1.37 gốc, 1.54–2.72 mọi mùa): page-tu-chon-cau-hinh-pc.css có rule [data-theme="dark"] .meganav-inner > a { color: var(--td-text)!important } quét CẢ nút gradient gold/mùa → chữ sáng trên nền sáng. Fix: :not(.meganav-build) (cả bản .css + .purged) → nút trả về chữ --td-on-brand tối đúng mọi mùa (đo lại 5 mùa dark: chữ tối trên nền sáng). Đây là nút header giống mọi trang nhưng CHỈ trang builder có rule đè này → home/shop/pdp không dính.
  • Bảng giá thu mua thiếu keyboard focus (axe full-ruleset, serious, dính 9 preset × 2 theme): .tdp-buyback__pricescroll vùng cuộn ngang không nhận focus bàn phím. Fix: tabindex="0" role="region" aria-label (buyback-pricelist.php) + :focus-visible outline gold, :focus:not(:focus-visible) bỏ outline chuột (page-thu-mua-hang-cu.css).
  • Heading nhảy cấp H1→H3 trang thu mua (Lighthouse heading-order): block prem-steps hardcode <h3>; khối "quy trình" hero đứng ngay sau H1 → nhảy cấp. Fix: thêm attribute headingLevel (2–4, mặc định 3) cho block + render động; set khối hero = h2 trong content page 62102 (khối "Quy trình" giữa trang giữ h3 vì có h2 cha). LUẬT: block có tiêu đề phải cho chỉnh cấp heading, không hardcode.
  • Audit toàn diện vòng 2 (2 agent + script riêng): (a) axe FULL ruleset WCAG 2.1 A/AA 108 lượt (6 trang × 9 preset × 2 theme, bỏ color-contrast đã pass) → chỉ 1 lỗi (pricescroll, đã fix); Home/Shop/PDP/BuildPC/Cart sạch tuyệt đối. (b) Script đo contrast MỌI nút (23 selector × 6 trang × 9 preset × 2 theme = 1260 phép đo, tính cả nền gradient axe bỏ qua) → sau fix 0 lỗi. (c) Lighthouse Accessibility 5 trang chính = 100/100 (builder, thu-mua đều 100 sau fix).
  • Audit verify vòng 2 (90 runs lại sau fix): 160 → 0 vi phạm CSS theme. Tồn duy nhất = khung hình popup "vừa mua" đang fade-in (mid-opacity mọi text đều loãng — transient, Lighthouse thực tế không bắt trúng); spot-check computed style live xác nhận footer/tb-head = brand-bright, pill/btab active đúng on-brand/mix, del opacity 1, .m opacity 1 (phải thêm override light .is-active .mhtml[light] .td-bp__pill .m{opacity:.92} là (0,3,1) thắng (0,3,0)).

🎨 Seasonal v13 — NÚT CTA đổi màu theo mùa (anh báo: "đổi mùa nút không đổi màu, nút nào đổi thì lỗi light/dark")

  • Root cause: 4 nhóm nút CTA gold (.td-btn--primary base.css, nút Build PC Custom + nút gọi drawer megamenu.css, .td-bp__btn--gold home.css — kèm bản .purged) HARDCODE linear-gradient(#ffe58f,#e3c56e,#b2933a) đè lên var(--td-brand), trong khi color: var(--td-on-brand) LẠI đổi theo preset → bật mùa: nền kẹt gold, chữ đổi thành kem/navy của mùa = vừa "không đổi màu" vừa "lỗi light/dark".
  • Fix: biến hoá toàn bộ — tokens.css thêm --td-cta-grad / --td-cta-grad-hover / --td-cta-shadow-c (mặc định = đúng gradient + shadow gold cũ, ngày thường giữ nguyên từng byte); rule chung [data-preset]{ --td-cta-grad: linear-gradient(135deg, color-mix(brand 62% trắng), brand 50%, brand-strong); hover tương tự sáng hơn; shadow-c: brand } → bật mùa là nút tự đổi CẢ nền + hover + bóng, chữ --td-on-brand của preset khớp nền (AA on-brand vs brand đã check 16/16 từ trước). Sửa 6 file CSS (3 gốc + 3 purged) bằng script thay đúng chuỗi; shadow rgba(227,197,110,.x)color-mix(var(--td-cta-shadow-c) x%, transparent).
  • Verify đo computed: mặc định giữ gold; tet/noel/dong × light/dark nút đổi đúng màu mùa, contrast chữ vs nấc giữa gradient 4.9–9.5.
  • QA agent 63 combo (3 trang × [mặc định + 8 mùa] × light/dark @1600 + home mobile 390): nút CTA biến mới PASS 100% (0 stop gold khi bật mùa, contrast ≥4.5 mọi preset, hover + shadow đổi đúng, mặc định giữ gold nguyên trạng); quét goldLeftovers toàn trang = RỖNG (12 nhóm gold mặc định đều tự đổi khi bật mùa); 0 lỗi JS, 0 tràn ngang kể cả 390px. 1 finding thật đã fix: 2 nút nav "Danh mục sản phẩm" (.td-mega__toggle) + "Build PC Custom" (.meganav-build, layout.css) dùng gradient brand→brand-hover nhưng 8 block dark preset THIẾU override --td-brand-hover → stop cuối gradient dark lẫn màu light, contrast rớt 2.05–3.01 → bổ sung --td-brand-hover cho cả 8 dark preset (AA on-brand vs hover pass 8/8), re-verify 4 mùa tệ nhất: 6.71–9.01.

🎨 Seasonal v12 — BỘ VECTOR CHÍNH THỨC do anh Phát cung cấp (thay ảnh GPT bị chê)

  • Nguồn: 2 zip "Seasonal vector illustrations(-2).zip" ở /var/www — 8 mùa × 2 hình TRÁI/PHẢI riêng (300×900, nền trong suốt, có cả SVG + PNG; dùng SVG cho nét + nhẹ). Deploy 16 file assets/img/seasonal/scene-{preset}-{left|right}.svg (map tên: quockhanh→quoc-khanh, trungthu→trung-thu, tuutruong→tuu-truong); xoá 8 PNG gen GPT.
  • Cơ chế inline override nâng cấp trái/phải: ::before dùng -left.svg, ::after dùng -right.svg + transform:none (BỎ scaleX(-1) — hình phải được vẽ riêng, không soi gương nữa); neo center 164px = phần tử "treo dây" trong hình bắt đầu ngay dưới khối header đục, trông như treo từ header; size min(258px,92%) auto; opacity 1 (dark .9); orb + chấm hạt giữ nhẹ (8%/7%/32%).
  • 2 bug trong lúc triển khai (tự bắt + fix): (1) dùng sprintf trên chuỗi CSS chứa % → PHP 8 ValueError "Unknown format specifier" làm frontend 500 — đổi sang str_replace placeholder {SCENE}; (2) sửa xong file mà fatal vẫn còn — opcache php-fpm giữ bản cũ, phải systemctl reload php8.2-fpm (gotcha cũ của prod lặp lại trên staging). Verify sau fix: home 200, inline in đúng left/right + transform:none ×8 mùa, screenshot 2 bên khác nhau đúng thiết kế. Sample admin chụp lại theo bộ vector. GOTCHA quy trình: mọi lần sửa seasonal.php nghi opcache → reload php8.2-fpm trước khi debug tiếp.

🎨 Seasonal v11 — 8 SCENE ẢNH AI HOÀN CHỈNH (gen qua chính gói ChatGPT Plus của anh)

  • Gen ảnh thành công bằng token Codex/ChatGPT Plus (công thức anh đưa): POST chatgpt.com/backend-api/codex/responses với model gpt-5.4-mini + tool image_generation (size 1024x1536, quality high) + store:false, stream:true, đọc SSE image_generation_call.partial_image/output_item.done lấy PNG base64. GOTCHA: backend KHÔNG hỗ trợ background:transparent → gen trên nền magenta thuần #FF00FF rồi chroma-key ImageMagick (-fuzz 18% -transparent + alpha Erode Diamond:1 + -trim + -resize 760x). Script tái sử dụng: scratchpad/gen-season.py (prompt 8 mùa bên trong; cần ~/.codex/auth.json còn login).
  • Vòng 1 bị anh chê "màu mờ không vivid" (prompt em ghi "muted palette") → vòng 2 đổi prompt "premium glossy 3D render, VIVID rich saturated colors, sparkling highlights" + inline override cho ảnh AI hiện opacity:1 (dark .88) — kết quả photorealistic rực rỡ: Noel cây thông châu bóng loáng + 6 hộp quà nơ satin; Tết mai vàng bonsai treo đồng xu tua đỏ + chậu sơn mài + đào hồng + lì xì/quýt/pháo chuỗi; đủ 8 mùa deploy vào assets/img/seasonal/scene-*.png (cơ chế tự nhận của v10). Sample admin chụp lại theo ảnh AI. LƯU Ý vận hành: gen 8 ảnh/lượt là ổn, đừng gen hàng loạt dày (subscription Plus).

🎨 Seasonal v10 — đường ống ẢNH AI (anh chê SVG vẽ tay "nhìn kỳ, lấy GPT tạo ảnh vẽ lại")

  • SVG code tay đã tới trần chất lượng → chuyển hướng ảnh AI render thật. Server không tự gen được (key Gemini của buildpc đã hết hạn/invalid, key PSI bị chặn generativelanguage API) nên dựng sẵn đường ống: theme tự phát hiện file assets/img/seasonal/scene-{preset}.png (nền trong suốt, ảnh dọc) và inline-CSS đè scene SVG của mùa đó (giữ orb + chấm hạt, size min(240px,88%), ver theo filemtime) — thả ảnh vào là chạy, xoá ảnh là quay về SVG, không đụng code. Smoke test: tạo file giả → inline override sinh đúng → đã xoá.
  • Bộ prompt gen ảnh chuẩn 8 mùa (kèm yêu cầu chung: portrait 2:3, soft 3D clay render, palette trầm, nền trong suốt/magenta để chroma-key): /var/www/TD-SEASONAL-AI-PROMPTS.md — anh gen bằng ChatGPT/Gemini rồi thả file, hoặc đưa key Gemini mới (model gemini-2.5-flash-image) để em gen + tách nền + QA trọn gói.

🎨 Seasonal v9.1 (cùng ngày — anh báo: cờ mất, cây noel mất đầu; chốt "hiện chính giữa middle")

  • Scene neo CHÍNH GIỮA DỌC màn hình (background-position: center center layer scene): neo theo px từ đỉnh kiểu gì cũng bị khối header đục (~160px: topbar+logo+nav) che mất đầu (đã dính 2 lần: cây thông rồi lá cờ) — center thì scene luôn trọn vẹn ở mọi chiều cao màn hình. Verify chụp noel + quốc khánh @1000px cao: sao/ngọn thông/chóp cờ nguyên vẹn.
  • Vẽ lại hero Noel lần 2: bản hero "tán organic răng cưa" render LỖI path (tán rời rạc, hở thân — path zigzag tự cắt) → dựng lại theo cấu trúc 4 tầng tam giác tin cậy (đã render chuẩn ở v8), phóng to + tuyết mép tầng + 13 bóng đèn halo + 4 hộp quà gốc. BÀI HỌC: path SVG phức tạp tự vẽ tay phải render-test trước khi giao — cấu trúc hình học đơn giản chồng lớp an toàn hơn path liền ngoằn ngoèo.

🎨 Seasonal v9 (cùng ngày — anh: "thay vì 2 cây noel, 1 cây to siêu thật hơn" + báo 2 bug)

  • Strip 2 bên đổi kiến trúc: scene KHÔNG LẶP — layer scene chuyển repeat-y → no-repeat (strip là fixed nên 1 cụm chính luôn nằm trong tầm mắt; lặp dọc sinh 2-3 cây thông trùng nhau). Bên dưới scene thay bằng layer 4 mới: chấm hạt mờ màu mùa (radial dots 34×42 repeat, color-mix 40% var --td-season-line) phủ toàn dải cho khỏi trống. Scene neo center 120px (né header đục).
  • Cây Noel vẽ lại thành 1 CÂY TO "siêu thật": tán organic răng cưa liền khối (không còn 4 tam giác rời) 2 lớp sáng/tối, tuyết đọng theo mép cành từng vệt zigzag, sao ngọn glow 2 lớp + tia sáng, 5 dây đèn với ~20 bóng, mỗi bóng có quầng sáng (halo radial) riêng xen kẽ đỏ/vàng/xanh specular, thân gỗ gradient, 4 hộp quà chất gốc trên đồi tuyết + bóng đổ.
  • Fix bug anh báo — góc border khung mùa gãy: ruy băng/tick vẽ sát mép (0,0) bị border-radius 14px của card clip cong thành vệt gãy → ruy băng khung A/C thụt 16px 2 đầu + bo đầu thanh (3px), tick khung B thụt vào (10px,10px) kiểu crop-mark — không nét nào chạm góc bo nữa. Verify chụp cận card /shop/: góc sạch.
  • Xác nhận theo câu hỏi của anh: mọi khu list đều có decor — motif mùa trên từng card + ornament cạnh tiêu đề khu + ruy băng/tick theo khu (ảnh anh gửi chính là khu "Sản phẩm bán chạy" đang hiện đủ 3 tầng).

🎨 Seasonal v8 (cùng ngày — spec anh: "thay vì lẻ tẻ, render 1 cây thông TO có nhiều quà dưới gốc, trên cây có trang trí — các mùa khác cũng kiểu vậy")

  • Background 2 bên chuyển từ vật thể rải rác sang SCENE LỚN có bố cục (giữ chất 3D v7): Noel = cây thông to 4 tầng tuyết phủ + sao glow ngọn + 3 dây đèn vàng uốn quanh + 8 châu treo (đỏ/vàng/xanh specular) + 4 hộp quà chất dưới gốc trên đồi tuyết; Tết = chậu mai lớn nở rộ (mai vàng + nhánh đào hồng đan xen) + lì xì/quýt/pháo dưới gốc + sao rơi từ tán; Đông = người tuyết TO (mũ len + khăn đỏ + tay cành cây) đứng cạnh thông tuyết trên đồi; Trung thu = trăng rằm to + ĐÔI thỏ ngồi dưới trăng + 2 đèn lồng treo 2 bên + đèn ông sao + bánh trung thu hoa văn; Halloween = cụm 3 bí ngô to-nhỏ (quả to khắc mặt ĐỘI mũ phù thuỷ) + trăng + 2 bầy dơi + nhện thả tơ; Quốc khánh = cột cờ lớn + cờ sao vàng bay + chùm bóng bay đỏ-vàng có dây + pháo hoa + bồ câu; Hè = bãi biển (biển sóng + dải cát) với dừa nghiêng + phao + bóng chuyền + xô cát; Tựu trường = BẢNG PHẤN TO TRÊN GIÁ 3 CHÂN + cặp sách dựa nghiêng vào chân giá + chồng sách + táo đỏ + bút chì. Mỗi tile: scene chính ~60% + khoảng nghỉ thưa (kẹo gậy/bông tuyết/sao/sóng) để lặp dọc tự nhiên. Sample admin chụp lại.
  • Fix cây thông bị "cắt ngang thân" (anh Phát báo): header nền đục (~100px) đè lên strip z-index:-1 → scene đầu tile bị che ngọn. Fix dịch pha layer tile background-position center top → center 120px — vùng bị header che giờ chỉ dính phần đệm thưa cuối tile, scene chính hiện nguyên vẹn dưới header. Verify lại 8 mùa (noel/tet/dong/halloween/quoc-khanh duyệt mắt, còn lại cùng công thức): không còn vật thể chính nào bị cắt.

🎨 Seasonal v7 (cùng ngày — anh góp ý v6 "vẽ như hoạt hình quá, chi tiết thật hơn / hình 3D tốt hơn")

  • Nâng toàn bộ 8 tile + 8 motif từ flat lên DIMENSIONAL/3D bằng radial/linear gradient trong SVG defs: cánh mai/đào gradient sáng tâm→đậm rìa + nhị chấm phấn hoa; thông 2 lớp tán (mặt sáng) + tuyết gradient; hộp quà highlight dọc + ruy băng ánh kim + bóng đổ ellipse dưới mọi vật thể; châu Noel/khối cầu có specular highlight; người tuyết 3 khối cầu radial + mũ len; trăng glow 2 lớp + crater; đèn lồng phát sáng từ trong + tua rua hạt; bí ngô múi gân tối + mảng sáng; mũ phù thuỷ khối; cờ vải gợn nếp (3 vệt bóng dọc); cặp sách da 2 lớp nắp + khoá kim loại radial + chỉ may; bảng phấn khung gỗ có vân; dừa gân tán + vân thân; phao 3D; bút chì tẩy + đai kim loại. Palette giữ tông trầm v6. Sample admin chụp lại theo v7.

🎨 Seasonal v5 (cùng ngày — anh góp ý v4 "tiết chế quá, không sinh động, list không thấy gì")

  • Cân bằng lại độ hiện diện, giữ ngôn ngữ line-art (không quay lại clip-art): card viền tông mùa rõ hơn (mix 42%), ruy băng 3px gradient MƯỢT 2 tông mùa (line→accent, không sọc pattern) đỉnh khu A / đáy khu C; khu B tick góc đậm 2 tông + hairline mờ nối; motif góc ảnh phóng 27px op .72; ornament mùa ngay cạnh TIÊU ĐỀ từng khu list (.td-shead__row::after = mask var --td-season-motif + màu --td-season-line, dark tự pha sáng); strips 2 bên đậm hơn (opacity .62/.4) + thêm lớp chấm pattern màu mùa (radial dots 30×38) cho đầy; fx 22 hạt desktop / 12 mobile. Refactor: motif 8 mùa chuyển thành CSS var --td-season-motif dùng chung 3 nơi (card + tiêu đề + sẵn cho nơi khác).
  • Fix bug admin chọn mùa hiện 2 lựa chọn: trạng thái chọn trước đây bám cả class server-render .is-active (card của option đã lưu) LẪN :has(input:checked) (card đang bấm) → nhìn như chọn 2 mùa. Bỏ hẳn class, chỉ còn :has(input:checked) — bấm mùa khác là card cũ nhả ring ngay. Sample admin chụp lại theo art v5.

🎨 Seasonal v6 (cùng ngày — spec anh: "mùa phải RÕ RÀNG: Tết có mai VÀ đào, Noel có thông xanh + món quà, Tựu trường có cặp sách, bảng phấn…")

  • Đổi từ line-art đơn sắc sang MINH HOẠ FLAT MÀU THẬT, palette trầm (không neon): mỗi mùa vẽ lại đủ vật thể biểu tượng — Tết: cành mai VÀNG + cành đào HỒNG + lì xì đỏ sao vàng + pháo + đồng tiền; Noel: cây thông XANH tuyết phủ sao vàng + hộp quà đỏ nơ vàng + hộp quà xanh + kẹo gậy + châu đỏ + người tuyết mây; Quốc khánh: cờ đỏ sao vàng bay + pháo hoa + chim bồ câu; Hè: mặt trời + cây dừa + phao sọc đỏ-trắng + sóng + sao biển; Đông: NGƯỜI TUYẾT đội mũ khăn đỏ cà rốt + thông tuyết + bông tuyết to + đụn tuyết; Halloween: bí ngô mặt cười cuống xanh + mũ phù thuỷ tím sao + trăng vàng + dơi + kẹo xoắn; Trung thu: trăng vàng crater + THỎ trắng + đèn lồng đỏ tua vàng + đèn ông sao + mây; Tựu trường: BẢNG PHẤN xanh khung gỗ (chữ A + vạch phấn — chữ đối xứng vì strip phải soi gương scaleX(-1), "ABC" từng bị lật ngược) + CẶP SÁCH đỏ khoá vàng + chồng sách 3 màu + bút chì + mũ tốt nghiệp.
  • Motif card + ornament tiêu đề + charm logo cùng đổi sang minh hoạ màu (var --td-season-motif dùng chung 3 chỗ; charm logo bỏ mask, dùng thẳng motif màu mid-tone + drop-shadow nhẹ — đọc được cả header trắng lẫn ink). Motif card 28px op .9. Strip opacity .8 light / .5 dark (bỏ lớp chấm — minh hoạ màu tự đầy đặn); fx Tết rơi 2 loại cánh mai vàng + đào hồng xen kẽ. Sample admin chụp lại theo v6.
  • PASS: 32 combo frontend (8 preset × home/shop × light/dark @1920) — strip 3 lớp + mask fade + width 290 đúng, hairline/tick theo khu, motif op .55, fx 16 hạt + depth blur, 0 tràn, 0 lỗi JS; 1366/390 strip ẩn đúng; admin Seasonal: menu EN, grid 3→2→1 cột đúng breakpoint (1600/1280/800), 9 card + 8 sample load thật, flow "Xem thử ngoài web" (?td_preview_preset=noel) áp data-preset + nạp CSS đúng chỉ cho admin; trang Build PC hết PHP Warning.
  • 2 finding thật về ornament logo → ĐÃ FIX cùng ngày: (1) ornament đặt cạnh phải logo đè ô search 14–22px (khe logo→search chỉ ~12px) → chuyển thành charm đậu góc trên-phải logo (right:-6/top:-9, 21px, xoay 8°); (2) tông sáng chìm trên header light (nền TRẮNG chứ không phải ink — contrast 1.4–2.2:1) → đổi kiến trúc: hình = CSS mask, màu = background-color bám --td-season-line (light dùng tông đậm ≥3:1, dark tự pha sáng color-mix(... 45%, #fff)) — 1 URI/mùa dùng cho cả 2 mode. Verify lại: mask áp đúng, không đè search, nhìn rõ cả light lẫn dark.

[1.7.7] - 2026-07-08 (Benchmark dựng phim + đồng bộ màu admin)

✨ Mới

  • Drawer mobile ăn config Mega Menu: mobile-nav.php thêm dispatcher như desktop — ưu tiên option tandoanh_megamenu_config (map tops/groups/links → drill-down: group không tiêu đề đổ link thẳng panel cấp 1, group có tiêu đề + links thành panel cấp 2, group không links thành row link), chưa lưu config thì fallback menu nguồn như cũ. Verify: nhánh config với seed editor ra HTML giống từng byte nhánh nav (root + 32 panel). Transient drawer đổi key tandoanh_mnav_v3; trang Mega Menu lưu/reset config đều bust drawer. Từ giờ sửa config là đổi CẢ desktop lẫn mobile — config là nguồn duy nhất.
  • Giao diện theo mùa v3 (spec "làm kỹ thêm" trong ngày) — (1) Ruy băng card đổi thành hoạ tiết riêng từng mùa qua var --td-season-ribbon (Tết sọc đỏ-vàng chéo, Noel kẹo gậy đỏ-trắng-xanh, Quốc khánh đỏ-vàng-đỏ, Hè cam-teal, Đông xanh băng, Halloween cam-đen, Trung thu đỏ-vàng, Tựu trường xanh-vàng), dùng chung khung A (đỉnh) + khung C (đáy); card thêm glow toả từ đỉnh (radial color-mix 9%); ngoặc góc khung B nâng 2 nấc + chấm son 2 góc. (2) 8 tile background 2 bên VẼ LẠI chi tiết nhiều lớp (fill-opacity depth): Tết = cành mai 2 tầng hoa + nụ + lì xì sao vàng + đồng xu mờ + cánh đào; Noel = thông phủ tuyết + sao ngọn + châu 3 màu + dây đèn + hộp quà nơ + bông tuyết đầy đủ; Quốc khánh = cờ bay lượn sóng + pháo hoa 2 chùm + trống đồng mờ; Hè = mặt trời 2 lớp + dừa 3 tán + phao cứu sinh sọc + sóng 3 lớp + mây; Đông = người tuyết (khăn + mắt + cà rốt) + thông tuyết mờ + flake lớn 2 nấc + đụn tuyết; Halloween = mạng nhện góc + bí ngô múi cười + mũ phù thuỳ tím + dơi + kẹo + sao; Trung thu = trăng crater + thỏ ngọc mờ + đèn lồng tua rua + đèn ông sao viền đỏ + mây; Tựu trường = bút chì gọt + chồng sách 3 màu + bảng xanh kẻ chữ + mũ tốt nghiệp + máy bay giấy + kính lúp. (3) Trang admin Theo mùa có HÌNH SAMPLE từng mùa (assets/img/seasonal/*.jpg 8 ảnh ~35KB chụp Playwright thật từ home 1920) + nút "Xem thử ngoài web ↗" mỗi mùa: ?td_preview_preset=<key> — filter tandoanh_active_preset trả preset preview CHỈ cho user manage_options (khách không thấy), enqueue tự nạp asset theo, script wp_head prio 2 ép data-preset thắng localStorage, key off xem giao diện tắt. Verify: 8/8 preset strip+ribbon+motif OK sau v3, filter đúng cả 3 case (key thật/off/sai).
  • Fix ký tự hỏng double-encode (mất backslash) — chuỗi &amp;/\n trong block JSON bị strip \ từ lần lưu không wp_slash trước đây → hiển thị "Build u0026amp; test 24h", benchmark preset buildband dính 1 dòng. Sửa DB: home 6293 (ticker + features "Build & test 24h" + zones "Ryzen & Radeon" + buildband preset Văn phòng khôi phục 4 dòng benchmarks + costRows 2 dòng) và nav Vertical Menu HTML 104248 (8 label "Tanks & Accessories"…). Ghi lại bằng wp_update_post(wp_slash(...)) chuẩn; verify live hết "u0026", JSON parse OK, mega menu label đúng "&".
  • Fix icon rớt dòng khối "Tương thích socket…" (buildband) — reset toàn cục svg{display:block} (base.css) đẩy icon tick xuống dòng riêng → thêm .td-bp__ok svg{display:inline;vertical-align:-2px} (cả home.css lẫn home.purged.css); verify computed style svg inline + icon cùng dòng chữ.
  • QA agent 2 luồng (admin 18 trang + frontend 108 combo): admin — 0 lỗi console, 0 tràn, 0 .notice WP sai chỗ; frontend — 0 tràn ngang/108 combo 8 trang × 6 viewport × light/dark, drawer mobile 32/32 pass (mở + drill + back), trang /gioi-thieu/ + 3 band chính sách render đúng số/email/địa chỉ từ Business Info, 8 preset đủ decor; 2 cảnh báo "strip đè chữ" điều tra ra false positive (ticker full-bleed nền riêng; vùng vẽ strip cách chữ ≥74px). Findings thật đã fix: xem CHANGELOG tandoanh-buildpc 2.4.0 (fatal get_share + created_at + nút 36px). Ghi nhận KHÔNG sửa (chủ đích): input trong pill .ait-addon (Dịch ngôn ngữ) border:none vì pill ngoài đã viền 1.5px; nút icon 30px trang Trả góp là spec anh Phát chốt trước đó.
  • Giao diện theo mùa v2 (theo spec anh Phát bổ sung trong ngày) — (1) 8 mùa: thêm Halloween (cam bí ngô), Trung thu (đỏ đèn lồng + vàng trăng), Tựu trường (xanh bảng + vàng bút chì) — token AA pass 6/6 combo ngay từ đầu (btn 5.15–7.87). (2) Background trang trí 2 BÊN màn hình (≥1560px): SVG tile vẽ tay từng mùa (cành mai + lì xì / cây thông + tuyết / cờ sao / mặt trời sóng biển / bông tuyết / bí ngô + dơi + nhện / đèn lồng + trăng / bút chì + sách + mũ tốt nghiệp) đặt ở body::before/::after fixed z-index:-1 (html không bg nên body bg thăng lên canvas → strip nằm TRÊN nền, DƯỚI mọi nội dung), bên phải soi gương scaleX(-1), opacity riêng dark. (3) Khung card KHÁC NHAU THEO KHU: khu TOP bán chạy (.td-tb) + section SP lẻ trên home = khung NGOẶC GÓC 2 tông + motif trên-phải; trang shop/danh mục/tìm kiếm + section SP chẵn = ruy băng ĐÁY + viền kép (outline -6px) + motif dưới-phải; còn lại = ruy băng đỉnh + motif dưới-trái (mặc định). (4) FX mới: Halloween lá thu + dơi (hạt thứ 4), Trung thu sao + đèn lồng phát sáng (hạt thứ 5), Tựu trường máy bay giấy vàng/mint. QA Playwright 1920px tet home+shop light/dark: strip 290px hiện đúng 2 bên, 26 hạt, 0 lỗi JS, 0 tràn. GOTCHA: sửa CSS đã bị WPFC combine thì PHẢI deleteCache(true) (bundle bỏ ?ver — gotcha cũ tái diễn); selector khu C phải viết [data-preset] .archive ... vì data-preset trên html còn body class trên body. Ghi chú kỹ thuật trong file: .td-pcard::after thuộc woo-card.css — trang trí card chỉ đụng ::before + __media::after.
  • Trang Giới thiệu /gioi-thieu/ (page 104669) — template chết page-tan-doanh.html (slug trùng trang chủ, không bao giờ render) đổi thành page-gioi-thieu.html (main.tdp-about + wp:post-content); nội dung tdp-about chuyển vào page content (block-hoá đủ bộ hero/stats/story/values/services/visit); CSS bundle rename page-tan-doanh.css → page-gioi-thieu.css (nạp theo slug); 3 chỗ liên hệ hardcode trong section Showroom thay bằng shortcode [td_biz] (address + sales1/sales2 + email). Verify live 200, đủ markup + CSS + shortcode. Chưa gắn link menu/footer — chờ anh Phát quyết vị trí.
  • Brand: đảo hết reader qua product_brand — PDP kicker (content-single-product.php) đọc term product_brand trước, fallback attribute cũ; Google Shopping settings đảo brand_source_taxonomy=product_brand / fallback=pa_thuong-hieu. Backfill check: 0 SP publish thiếu product_brand. QUYẾT ĐỊNH: KHÔNG xoá attribute pa_thuong-hieu (109 terms/3312 rels) — nó là "hộp thư đến" của mirror real-time từ production (td-sync hp_sync_convert_brand() convert từng SP khi pull, cần cả 2 taxonomy tồn tại); xoá là sync đẻ lại + mất đường rollback. Verify live: kicker PDP hiện brand từ taxonomy mới.
  • Giao diện theo mùa (Phase 11) — trang admin mới "Theo mùa" (inc/admin/seasonal.php, TD Theme → Theo mùa): chọn 1 trong 5 preset (Tết / Noel / Quốc khánh / Hè / Đông) hoặc Mặc định (tắt), kèm toggle hiệu ứng rơi. Option tandoanh_seasonal_preset + tandoanh_seasonal_fx; no-flash script trong enqueue.php đã đọc option này sẵn từ 1.6.x. Khi bật: card sản phẩm có ruy băng 2 tông sát mép trên + khung/nền nhuộm màu mùa (color-mix theo --td-brand nên tự đúng cả dark) + motif SVG góc ảnh (hoa mai/bông tuyết/sao/mặt trời — data-URI ~300 byte, nền media #fff cố định); hiệu ứng rơi (cánh đào/tuyết/sao/bong bóng nắng) do seasonal-fx.js tạo SAU window.load lúc idle, tối đa 26 hạt (mobile 14), transform compositor-only, tôn trọng prefers-reduced-motion. seasonal.css + JS chỉ nạp khi preset bật → ngày thường 0 chi phí PSI. AA re-check toàn bộ token preset (tokens.css): 7/10 combo cũ rớt (chữ trên nút 2.17–4.22) → chỉnh đậm brand (tet #cc231f, quoc-khanh #ad1a14, he #d96407, dong #276aa5) + thêm on-brand tối cho dark (noel/quoc-khanh/dong) — sau sửa 10/10 combo preset × light/dark đạt AA (nút ≥4.97, chữ strong ≥4.50, UI ≥3.0). QA Playwright /shop/ noel light+dark: ribbon/motif/26 hạt hiện đúng, 0 lỗi JS, 0 tràn ngang. GOTCHA vận hành: wp option update bằng root CLI bị race alloptions Redis (option ghi DB nhưng www-data đọc cache cũ, wpfc rename cache dir cũng Permission denied) → thao tác option + xoá cache PHẢI chạy sudo -u www-data wp eval kèm wp_cache_delete("alloptions","options").
  • Block tandoanh/biz-text — địa chỉ/hotline/email đọc Business Info (td_biz), hết hardcode trong template chính sách. 3 biến thể: inline (1 giá trị, tuỳ chọn bọc tel:/mailto:), cta (band eyebrow + đoạn văn có token {address}/{hq}/{name} + nút Gọi + nút email, namespace tdp-policy/tdp-payoo), contact (band lưới thẻ liên hệ trang chính sách — thẻ mặc định Kinh doanh ×2 / Kế toán / Email / Địa chỉ). Kèm shortcode [td_biz field="..." link="1"] cho INLINE trong nội dung trang (delegate qua block). Đã thay 3 band wp:html hardcode: page-chinh-sach-bao-hanh (CTA warranty + baohanh@), page-chinh-sach-van-chuyen (contact grid), page-bang-chi-phi-thanh-toan-tra-gop-payoo (CTA sales1 + kinhdoanh@) — verify live cả 3 trang render đúng số/email/địa chỉ từ Business Info. Business Info bổ sung email key baohanh (baohanh@tandoanh.vn — số liệu đang dùng công khai trên trang bảo hành). Hotline hiển thị ưu tiên display_header, fallback display. (Overall Score Standard): 4 category gpu_premiere / cpu_premiere / gpu_davinci / cpu_davinci (30 device mỗi app). Tab Hiệu năng VGA thêm "Dựng phim · Premiere Pro" + "Dựng phim · DaVinci"; CPU thêm 2 chỉ số tương ứng (chỉ hiện khi đủ ≥3 CPU cùng dòng có dữ liệu).
  • Promo Subscribers chia 2 tab: "Danh sách đăng ký" (bảng cũ: tìm kiếm/CSV/xoá) + tab mới "Soạn email marketing" (inc/admin/promo-email.php): 3 mẫu soạn sẵn (Khuyến mãi / Hàng mới về / Giới thiệu trang) tự điền tiêu đề + lời nhắn có token {ten} thay tên từng khách; đính kèm sản phẩm (tìm AJAX theo tên, chip có ảnh), danh mục sản phẩm, trang/landing page; nút CTA tuỳ chỉnh. Email HTML chuẩn table + inline style (600px) theo brand gold ngoài site (theme.json: gold #e3c56e / #8a6a00, ink #15151a — không dùng màu admin): header ink logo gold + hotline + gạch gold, eyebrow accent theo mẫu, card sản phẩm ảnh nền surface + giá gold (hàng giá 0 tự thay "Giá liên hệ"), pill danh mục tông gold, CTA gold kiểu nút "Mua ngay" + dòng hotline phụ, footer ink social links, preheader ẩn cho dòng preview hộp thư; địa chỉ/hotline/social đọc từ Business Info (td_biz). Xem thử trong iframe, gửi thử tới 1 email, gửi tất cả theo batch 25 người/lượt có tiến trình. Mỗi email kèm link huỷ đăng ký ký HMAC — khách bấm là tự xoá khỏi danh sách (đã test end-to-end, chữ ký sai trả 400).

🎨 Giao diện

  • Mega Menu: trình sửa viết lại thành dạng trực quan giống hệt mega menu ngoài trang chủ — pane trái là danh sách mục chính, pane phải là panel (cột nhóm / danh sách phẳng đúng luật render frontend); click bất kỳ chữ nào mở hộp thoại sửa nhãn/URL kèm dời thứ tự + xoá. Đã verify lưu cấu hình xong HTML mega menu ngoài trang không đổi 1 byte (vá luôn 2 lệch tiềm ẩn của chế độ config cũ: script sắp cột "Linh kiện ráp máy" và 5 cột đặc thù panel VGA).
  • Admin thống nhất tông xanh theo header gradient (#1a2e4a → #2563eb): bỏ toàn bộ accent vàng/gold rải rác — icon trang Thanh toán + Trả góp, tiêu đề nhóm Popup, viền focus Contact Footer, accent + badge số Mega Menu, badge nhóm "Hiệu năng" trang Tính năng, tag MED trang Tốc độ. Màu đỏ (lỗi) và xanh lá (ổn) giữ nguyên vì mang nghĩa trạng thái.
  • Thử 2 skin admin (gold editorial, navy) trong ngày rồi gỡ cả hai — giữ style gốc, chỉ chuẩn hoá màu như trên.
  • Menu "Thông tin DN" đổi thành "Business Info" — đồng bộ tiếng Anh với các mục còn lại của menu TD Theme.
  • Header mọi tab admin viết lại theo một công thức thống nhất cho người không kỹ thuật: trang này quản cái gì ngoài web → bạn làm được gì → sửa xong ảnh hưởng chỗ nào. Áp dụng 12 trang: Dashboard, Tốc độ, Mega Menu, Trang chủ, Contact Footer, Thanh toán, Trả góp, Popup, Dịch ngôn ngữ, Tính năng (ghi rõ chỉ để tra cứu), Subscribers, Benchmark Data (bỏ tên bảng kỹ thuật khỏi mô tả); bỏ các từ ngữ dev ("native", "FSE", "dock", tên plugin) khỏi phần mô tả.
  • QA + chuẩn hoá control toàn admin (13 trang, audit script đo computed style — 0 vấn đề): luật chung trong admin.css — MỌI ô nhập/dropdown/textarea có viền 1.5px + bo 8px + cao 40px (không phụ thuộc từng trang gắn class); mọi nút .hplt-btn cao tối thiểu 40px canh giữa; nút WP .button (Chọn logo/Gỡ/×) khoác kiểu hplt. Sửa cụ thể: Installment — ô "Mức tối thiểu" tự format dấu chấm nghìn khi gõ (3000000 → 3.000.000, server vẫn nhận đúng), nút × xoá ngân hàng thành icon 40px, nút "Chọn logo"/"Gỡ" thay bằng icon FontAwesome (ảnh/×) 30px nằm NGANG HÀNG với logo; ô Mức tối thiểu thu còn 104px, padding bảng ngân hàng giảm (12px → 7/6px) cho gọn; Contact — tách "Bật dock" và "Độ trễ" bằng kẻ ngang + khoảng cách; Soạn email — card mẫu rộng 240px hết rớt chữ "sự kiện"; Benchmark Data pager đồng bộ 40px.
  • Notice WP (class .notice) ở trang Mega Menu + Trang chủ bị WordPress tự bốc lên sau H1 → hộp trắng chèn giữa header xanh; đổi sang hplt-notice của theme (WP không di chuyển) — notice giờ nằm gọn dưới header, đúng style admin.
  • Nút đặt trong header card (vd "Xuất CSV" trang Subscribers): icon hết tàng hình (rule .hplt-card__head .fa-solid{color:#fff} đè icon trắng trên nút nền trắng → scoped color:inherit), hover đổi sang nền sáng #dbeafe thay vì #2563eb trùng màu header (nút chìm mất vào nền).

🐛 Sửa lỗi

  • QA 3 landing page (pc-gaming / ai-workstation / creator-studio): creator-studio có 98 rect waveform height ÂM bake sẵn trong landing-clone HTML (generator tính sin không clamp) → mỗi lượt xem log 98 lỗi console, bar tàng hình; fix chuẩn hoá height=|h|, y=y+h (bar hướng lên từ đường giữa). Sau fix: 0 lỗi JS cả 3 trang × light/dark. QA kèm: 24 combo (4 viewport × 2 mode × 3 trang) 0 tràn ngang; hover 42 element tương tác 0 lỗi chữ-trùng-nền; PSI Perf 94-99 / A11y 100 / BP 100 / CLS≈0 (SEO 66 do staging chặn index cố ý); riêng pc-gaming mobile LCP ~4.4s vì clone 502KB + 2.039 phần tử SVG — ghi nhận chờ port block-native.
  • Icon Instagram ở footer hiện thành khối trắng đặc: rule global svg { fill: currentColor } (base.css) đè thuộc tính fill="none" của icon outline → đổi thành svg:not([fill="none"]), sửa cả base.purged.css. QA footer 10 viewport × light/dark: 0 tràn ngang, layout 1/2/4 cột đúng breakpoint.
  • Card trạm NVIDIA (RTX 5880/4500/3500 Ada) lọt bảng "so sánh cùng dòng" của card gaming dưới tên cụt "RTX 5880": extractor giữ suffix Ada (tên hiển thị đúng "RTX 5880 Ada") + meta chặn số dạng x8xx khỏi họ consumer.
  • Tiêu đề card so sánh "Năng lực AI so với các card cùng dòng" đổi thành "Hiệu năng làm việc so với các card cùng dòng" — selector giờ gồm cả render 3D + dựng phim, không riêng AI.
  • Trang Thông tin DN fatal PHP 8 ("$n[key]" trong chuỗi kép = truy cập offset chuỗi) — 16 chỗ đổi sang nối chuỗi.

📝 Ghi chú

  • Dọn lại CHANGELOG: gộp mỗi ngày một phiên bản, các entry cũ trong cùng ngày được gom lại.

[1.7.3] - 2026-07-07 (Hệ benchmark hiệu năng + refactor giảm hardcode)

✨ Mới

  • Trang admin "Thông tin DN" (option tandoanh_business_info): công ty/MST/trụ sở, showroom, 6 hotline (hiển thị theo ngữ cảnh footer/header/PDP), email, giờ hoạt động, social + kênh chat PDP, 13 link chính sách, BCT/DMCA, năm ©. Helper td_biz() / td_biz_hotline() / alias tandoanh_contact() — thankyou.php hết hiện số giả "1900 000 000". Footer/topbar thành dynamic block đọc từ option, markup giữ nguyên từng byte, bản dịch /en/ nguyên vẹn; "người đang xem" random ổn định theo khung giờ (min/max chỉnh trong admin).
  • Hệ benchmark trong tab Hiệu năng — toàn bộ từ nguồn chính thức, kèm provenance:
    • Render: Blender Open Data 5.1 (80 GPU + 210 CPU, median samples/phút theo scene), OctaneBench 2025 (162 GPU), V-Ray Benchmark v6 (598 GPU + 865 CPU, đã lọc single-socket/single-GPU).
    • CPU: Geekbench 6 Đơn/Đa nhân (132 CPU, chip thiếu lấy median search n=50 — độ phủ CPU shop 100%), encode x265, nén 7-Zip, văn phòng CrossMark — tổng 9 chỉ số so sánh cùng dòng.
    • AI: panel "Model AI phổ biến" (Can-I-Run LLM, 10 model 1.5B→32B, badge Chạy mượt/Chạy tốt/Tạm ổn, model vượt VRAM ghi "Cần VRAM lớn hơn") + chỉ số "Chạy LLM · Llama 3.1 8B".
    • Fallback biến thể Intel F/KF ↔ bản gốc (cùng silicon, chỉ khác iGPU).
  • reCAPTCHA v3 tự làm (module tandoanh-code/cf7-recaptcha-v3, thay plugin v2 bên thứ ba) cho CF7 Liên hệ + Tuyển dụng + form career; badge ẩn + notice Google, lazy-load chống TBT.
  • PDP desktop: mô tả ngắn quá dài tự thu gọn + nút "Xem thêm".

🔧 Thay đổi

  • Refactor giảm hardcode: bảng seed 32 ngân hàng trả góp về 1 nguồn inc/tragop-data.php; gói quà mặc định về 1 hàm; icon SVG registry inc/icons.php dùng chung 10 bộ (render byte-identical, verify md5); chuỗi UI lặp bọc __(); text tiếng Việt trong JS chuyển qua wp_localize_script; nguồn newsband có filter.
  • Nút chat PDP chốt theo production: Messenger m.me/TanDoanh (PC ra web) + deep-link fb-messenger:// nhảy thẳng app trên iOS/Android/iPad (bắt cả iPadOS mạo UA Macintosh); Zalo về zalo.me/0783666668. Verify đủ 6 loại thiết bị.

🐛 Sửa lỗi

  • Global a:hover đè màu chữ các nút (.td-btn / Mua ngay) thành xanh — loại nút khỏi a:hover (sửa cả base.purged.css); rà soát CSS sau QA (hover, contrast dark mode, buildpc).
  • Panel Model AI: chip nhiều biến thể VRAM (5060 Ti 8/16GB…) ưu tiên biến thể khớp VRAM trong tên sản phẩm, tránh hiện số của bản VRAM lớn hơn.
  • Gỡ card "Cho thuê PC, máy chủ render" trỏ link chết trong template tan-doanh (code chết, không còn render).

[1.1.8] - 2026-07-05 (Trung tâm điều khiển admin + song ngữ VI/EN)

➕ Thêm mới

  • Menu quản trị "TD Theme" gom toàn bộ cấu hình theme về một chỗ: Dashboard (tình trạng hệ thống thời gian thực + truy cập nhanh + nhật ký), Tốc độ, Mega Menu, Trang chủ, Contact Footer, Thanh toán, Trả góp, Popup, Dịch ngôn ngữ, Đăng ký KM, Tính năng. Bộ giao diện thẻ/tab/modal/accordion đồng bộ, Font Awesome 6 local riêng cho admin.
  • Mega Menu: trình sửa kéo/thả 3 cấp (mục chính → nhóm → liên kết) lưu option riêng, lần đầu tự nạp từ menu nguồn nên giống hệt hiện trạng; render giữ nguyên markup .td-mega__*.
  • Contact Footer: dock liên hệ nổi cấu hình được (kéo-thả kênh, bật/tắt, icon media) — desktop pill dọc, mobile nút tròn bung kênh.
  • Popup: banner theo trang với kiểu kích hoạt (ngay / sau N giây / cuộn tới % / thoát trang), cookie ẩn N ngày, phạm vi hiển thị linh hoạt; CSS/JS chỉ tải trên trang có popup khớp.
  • Thanh toán: thiết kế lại dạng thẻ + công tắc, thêm tuỳ chọn "Mặc định bật hoá đơn VAT" (Tân Doanh ưu tiên xuất hoá đơn, hoạt động cả khi không có JS).
  • Tính năng: trang liệt kê 27 tính năng theme theo nhóm, có bộ lọc + cửa sổ chi tiết + nút mở trang cấu hình; nguồn dữ liệu duy nhất features-registry.php.
  • Tab "Trang chủ" viết lại thành bảng điều khiển trang chủ block (tổng quan section qua parse_blocks(), chi tiết nhanh, nút mở trình sửa/Site Editor/xoá cache) — KHÔNG ghi đè nội dung trang chủ.
  • Song ngữ VI/EN /en/ SSR (SEO-friendly, opt-in mặc định TẮT): trang admin "Dịch ngôn ngữ" với công tắc tổng + 4 tab (Dịch nội dung / AI Providers đa nhà cung cấp có fallback / Cron tự dịch / Chuỗi giao diện); dịch tay ~120 chuỗi UI để giao diện /en/ tiếng Anh đầy đủ; hreflang + canonical phát ở wp_head.

⚡ Hiệu năng

  • Hoãn JS bên thứ ba (GA/GTM/Facebook/Clarity) tới tương tác đầu hoặc 12 giây; defer WPFC Combined JS (bỏ chặn render ~1.350ms); trang Tốc độ tổ chức lại 5 nhóm tab với các tối ưu async CSS, tắt Cart Fragments, emoji, preconnect, preload font.
  • Sửa CLS trang chủ 0.6 → 0: defer Combined JS bỏ qua trang chủ vì hero slider cần JS sớm (trang khác vẫn defer).

🔧 Thay đổi

  • Cập nhật biểu phí trả góp Payoo chính thức: 32 ngân hàng, 8 kỳ hạn (trước 23 ngân hàng, 5 kỳ hạn); phí cà thẻ 1.833% → 1.8%.
  • Dark mode 3 trạng thái (Theo hệ thống / Sáng / Tối); sắp lại thứ tự menu admin; dời "Đăng ký KM" từ menu WooCommerce về TD Theme.

[0.9.9.9] - 2026-07-04 (Landing + trang chủ)

➕ Thêm mới

  • 3 trang landing riêng: PC Gaming, AI Workstation, Creator Studio — 5 block editable, SVG mockup động theo biến thể.
  • Block tandoanh/newsband: 4 bài mới nhất từ news.tandoanh.vn (cache 30 phút, ảnh chỉ tải trên desktop).

🔧 Thay đổi

  • Khối danh mục nổi bật trang chủ chuyển sang 8 tile, thêm icon CPU/Mainboard/VGA/RAM/SSD.