⌨️ Thế Giới Keycap Docs Design

DESIGN.md — thegioikeycap.vn

Hệ thống thiết kế. Nguồn thật là assets/css/main.css — file này mô tả và giải thích, không thay thế.

Toàn bộ CSS nằm trong một file duy nhất (2.014 dòng). Không tạo file CSS mới; thêm khối vào đúng mục trong main.css.

main.css load SAU CSS của WooCommerce, để đè style mặc định mà vẫn giữ layout form giỏ hàng/thanh toán.


Design token

Khai ở :root đầu main.css. Dùng token, đừng viết mã màu thẳng.

Brand

Token Giá trị Vai trò
--color-primary #ed5d47 Coral — màu chính
--color-primary-dark #b02318 Đỏ sậm — trạng thái hover
--color-accent #53211d Nâu maroon — chân trang, nhấn
--color-peach #ffbc7d Đào — điểm xuyết

Trạng thái

Token Giá trị Vai trò
--color-success #5ebb3e
--color-info #0a64f2
--color-out-of-stock #2a1a17 Nâu gần đen — badge "Hết hàng"

Trung tính

Token Giá trị Vai trò
--color-bg #ffffff Nền trang
--color-surface #f5f5f5 Nền khối
--color-surface-alt #fafafa Nền khối phụ
--color-border #ececec Viền
--color-heading #333333 Tiêu đề
--color-text #4a4a4a Chữ thường
--color-text-secondary #868686 Chữ phụ

Chữ

Token Giá trị
--font-heading 'Be Vietnam Pro', 'Helvetica', system-ui, sans-serif
--font-body 'Roboto', 'Helvetica', system-ui, sans-serif
--text-h1 clamp(1.9rem, 4.5vw, 2.5rem)
--text-h2 clamp(1.4rem, 3vw, 1.875rem)
--text-h2-panel clamp(1.2rem, 2.5vw, 1.375rem)
--text-h2-post 1.45rem
--text-h3-content 1.125rem
--text-btn 0.9rem

Layout

Token Giá trị Ghi chú
--container-max 1400px Bề rộng tối đa toàn site
--space-section-y clamp(2.25rem, 5vw, 4rem) Khoảng cách dọc giữa các khối
--radius-btn 6px
--radius-card 10px
--shadow-card-hover 0 10px 28px rgba(176, 35, 24, 0.16) Bóng đổ mang sắc brand
--transition-hover all 0.2s ease
--header-h 76px Dùng cho scroll-margin, sticky

⚠️ --container-max: 1400px áp cho cả trang sản phẩm và bài viết (quyết định 06/09/2026). Đổi giá trị này là đổi bề rộng toàn site.


Bố cục main.css

Dòng Mục
1–100 Token, reset, nền chung
102–167 Section heading, nút bấm
168–287 Header — 3 tầng
288–348 Trang chủ — hero, banner
349–453 Lưới sản phẩm — 5/hàng → 4 → 3 → 2
454–529 Breadcrumb / archive
530–549 Content box SEO dưới listing danh mục
550–626 PDP — trang chi tiết sản phẩm, gồm hàng mua .pdp-buy
627–1461 Giỏ hàng / Thanh toán / Tài khoản
1462–1623 Bài viết
1624–1664 Trang test bàn phím
1665–1691 Footer
1692–1724 Nút liên hệ nổi
1725–1743 Ô Cloudflare Turnstile
1744–1825 Panel mời đặt mật khẩu
1826–2014 Trang đặt hàng thành công + gợi ý mua thêm

Lưới sản phẩm

Đè trực tiếp ul.products của WooCommerce. WC dùng float, ta chuyển sang grid:

.woocommerce ul.products, ul.products { display: grid !important; }

Số cột: 5 (desktop) → 4 → 3 → 2.

Thẻ sản phẩm hiện gì

SKU | tên (2 dòng) | giá | nút icon tròn.

Số tồn kho cố ý không hiện (bỏ 06/09/2026) — khách cần biết còn bán hay không, không cần biết còn mấy cái. Tình trạng hết hàng báo bằng badge trên ảnh.

Hàng mua trên trang sản phẩm

.pdp-buy là một hàng flex: [ô số lượng] [Thêm vào giỏ] [Mua ngay].

Phân cấp cố ý — hai nút KHÔNG được đặc giống nhau:

Nút Kiểu Vì sao
Thêm vào giỏ viền rỗng coral hành động phụ, khách còn mua tiếp
Mua ngay đặc coral hành động mạnh, đi thẳng thanh toán

Cùng tông coral nên vẫn đọc ra là một cặp. Dưới 560px hai nút giãn full chiều ngang, ô số lượng đứng riêng.

Badge giỏ nảy một nhịp (.hdr__cart-badge.is-bump) khi thêm giỏ thành công — đây là tín hiệu duy nhất báo đã thêm, vì dải thông báo mặc định của WooCommerce không còn xuất hiện (thêm giỏ chạy AJAX, không tải lại trang). Có tôn trọng prefers-reduced-motion.

Hai badge trên ảnh

Badge Vị trí Nền
SALE trên-trái --color-primary (coral)
Hết hàng trên-phải --color-out-of-stock + viền trắng mảnh

⚠️ Badge "Hết hàng" cố ý KHÔNG dùng đỏ — đỏ đã là SALE, hai cái xuất hiện cùng lúc trên một thẻ sẽ lẫn nhau.

Trước 06/09/2026 badge này để --color-text-secondary (#868686) — xám giữa, chìm trên cả ảnh sáng lẫn ảnh tối. Nay dùng nền đậm + box-shadow hai lớp (bóng đổ để tách khỏi ảnh sáng, viền trắng 1px để tách khỏi ảnh tối).


Khối liên kết & CTA

Dùng toàn bộ token trong :root, không viết mã màu cứng.

Callout bài viết (.post-callout)

Dùng trong nội dung bài viết tin tức để điều hướng khách đang tìm hiểu sang danh mục sản phẩm có liên quan: * Nền: var(--color-surface-alt) * Viền: 1px var(--color-border), viền trái dày 4px var(--color-primary) * Bo góc: 0 var(--radius-card) var(--radius-card) 0 * Link: var(--color-primary-dark), hover: var(--color-primary)

Đặt ngay dưới khung bàn phím ảo của trang /test-ban-phim/ để gợi ý thay keycap sau khi test phím xong, không làm công cụ bị đẩy xuống: * Khung: flex container, nền var(--color-surface-alt), viền 1px var(--color-border), viền trái 4px var(--color-primary) * Badge: font 0.75rem, nền var(--color-surface), chữ var(--color-primary) * Tiêu đề: var(--color-heading), mô tả: var(--color-text-secondary) * Nút: .btn, dẫn sang /keycap/


⚠️ Nội dung dài phải style đủ BA container

Bảng, danh sách, tiêu đề trong nội dung dài xuất hiện ở ba chỗ khác nhau:

Selector Ở đâu
.post__content Bài viết
.cat-seo__body Mô tả danh mục (dưới lưới sản phẩm)
.woocommerce-tabs .panel Tab mô tả trong trang sản phẩm

Sót một cái là bảng mất viền hoặc heading lệch cỡ đúng ở chỗ đó. Đã vấp ba lần.

  • Bảng: dùng !important cho width/height để đè inline style do trình soạn thảo WordPress chèn vào.
  • Tiêu đề H2/H3: dùng chung một bộ quy tắc cho cả 3 container:
  • h2: font-size: var(--text-h2); color: var(--color-heading); margin-top: 2rem; margin-bottom: 0.75rem; line-height: 1.35;
  • h3: font-size: 1.15rem; color: var(--color-heading); margin-top: 1.5rem; margin-bottom: 0.5rem; line-height: 1.4;

Breakpoint

Không có thang breakpoint cứng — dùng theo nhu cầu từng khối. Các mốc dùng nhiều nhất: 560px (7 lần), 860px (4), 760px (4), 1024px (3), 480px (3).

Khi thêm khối mới, ưu tiên bám các mốc đã có thay vì đặt mốc mới.


Quy tắc CSS

  • Đặt tên theo khối, prefix ngắn: .ty* (thank-you), .tyup (upsell), .pwpanel (panel mật khẩu), .tgk-captcha, .kbtest, .hdr, .ftr.
  • Không dùng :has() để bắt phần tử của WordPress core — cấu trúc admin đổi là gãy im lặng. Thêm class riêng, hoặc dùng class core đã ổn định (vd term-description-wrap).
  • Dùng token, không viết mã màu thẳng.
  • !important chỉ dùng khi phải đè WooCommerce hoặc inline style của editor — và ghi chú lý do ngay tại chỗ.

Markup của giỏ hàng / thanh toán / tài khoản

Thiết kế port từ bản Astro cũ. Template WooCommerce đã được override trong theme/woocommerce/, nên markup ở các mục này là của mình, không phải shop_table mặc định. Sửa CSS ở đây phải xem template tương ứng — docs/WP_THEME.md §3b.