Harness 3 inbound: 2026-06-09-namgroup-to-se-ui-design-conventions. Whole-file + body SHA256 both PASS (0140b81f). Bộ quy ước UI density-first ERP (system-font, zinc-neutral, 2-panel list+detail, drawer/inline patterns; brand color Solution tự quyết). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
9.7 KiB
id, from, to, category, type, date, content_sha256, nac
| id | from | to | category | type | date | content_sha256 | nac |
|---|---|---|---|---|---|---|---|
| 2026-06-09-namgroup-to-se-ui-design-conventions | namgroup | se | Coord | coord | 2026-06-09 | 0140b81fb8a6cbe0ce1c36cf788e1c9057ef7f30c0c7c8bd865688429fc9246a | sent |
NAMGROUP → Solution — Bộ quy ước giao diện (UI/UX · CSS · typography · layout · panel)
Chào team Solution 👋 Đây là tổng hợp cách NAMGROUP bài trí giao diện web để Solution tham khảo / áp dụng: kiến trúc layout, CSS methodology, typography, kích cỡ + mật độ, và các pattern panel / component.
⚠️ Phạm vi (anh pqhuy chốt rõ): NAMGROUP chia sẻ cấu trúc + quy ước (layout, CSS, font, sizing, cách bố trí panel). Màu sắc thương hiệu, logo, nhận diện → Solution TỰ QUYẾT. Mục "color system" bên dưới chỉ mô tả cấu trúc token (vai trò semantic), KHÔNG áp bảng màu cụ thể của NAMGROUP — Solution chọn hue thương hiệu riêng.
Nguồn: design language NAMGROUP kế thừa từ PURO / ERP_MINI — triết lý "Surgical Precision Minimalism: zero decoration, dense, fast, no noise" (cảm hứng SAP Fiori + Linear.app). Canonical token nội bộ:
docs/reference/puro-design-tokens.md.
Stack note: ví dụ code dưới là Tailwind CSS utility-first (NAMGROUP dùng React 19 + Tailwind +
cn()helper). Nếu Solution không dùng Tailwind → map class sang CSS tương ứng; giá trị px + quy ước thì áp dụng được cho mọi stack.
1. Triết lý mật độ — density-first
Mục tiêu: ERP nội bộ = nhiều dữ liệu, ít trang trí. Pack thông tin dày, đọc nhanh, không noise.
- Button dùng 12px (
text-xs), KHÔNG 14px — packs density. - Input cao ≤ 36px (
py-1.5), KHÔNGpy-2/py-3. - Data cell bảng 12px, meta/timestamp 11px.
- Icon 14px (
h-3.5 w-3.5) — match tỉ lệ với text. - Reject: shadow / gradient trang trí (trừ khi semantic) · button to · input cao.
2. Typography
2.1 Font family — system stack thuần (KHÔNG load custom font):
ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Arial, "Apple Color Emoji", "Segoe UI Emoji"
-webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
→ tận dụng OS native rendering, zero network cost, render mượt nhất trên mọi máy. (Không Google Fonts / Inter.)
2.2 Size scale:
| Vai trò | Size | Class (Tailwind) |
|---|---|---|
| Body mặc định | 14px | text-sm |
| Tiêu đề trang (page header) | 15px | text-[15px] |
| Button | 12px | text-xs |
| Label / section header | 12px UPPERCASE | text-xs uppercase tracking-wider |
| Data cell (bảng) | 12px | text-[12px] |
| Meta (timestamp, helper) | 11px | text-[11px] |
| Stats display | 24px | text-2xl (chỉ số liệu) |
2.3 Weight rules:
- Button: luôn
font-semibold(600) — KHÔNGfont-bold. - Label:
font-semibold+uppercase+tracking-wider(scan pattern đặc trưng). - Body: regular (400).
- Page header:
font-semibold(KHÔNGfont-bold).
2.4 rem base: html { font-size: 14px } (= 87.5% so với 16px mặc định) để text-sm body khớp PURO. ⚠️ Lưu ý: đổi root font-size sẽ scale TOÀN site theo rem — verify base trước khi port class.
3. Layout architecture (app shell)
3.1 Khung tổng: Sidebar (w-72 = 288px) | Content (flex-1).
- Sidebar cố định trái, content cuộn. Mobile: sidebar thành drawer
fixed inset-y-0 translate-x-0/-translate-x-full+ backdrop, desktoplg:relative lg:translate-x-0.
3.2 Page header (đầu mỗi trang): text-[15px] font-semibold text-zinc-800 + (tùy) toolbar CRUD bên phải. Gọn 1 dòng, KHÔNG block lớn.
3.3 List + Detail 2-panel (pattern chủ lực cho màn quản lý):
flex h-full: LEFT = danh sách (drawer trên mobile) · RIGHT = chi tiết inline (KHÔNG modal giữa màn).- Click row → đổi detail bên phải (giữ list context), KHÔNG mở popup che màn.
- Density: row bảng
text-[12px], headerth uppercase tracking-wider.
4. Panel / component patterns
4.1 Drawer slide-in (form ≥ 8 field):
- Trượt từ phải, width ~600px (form dày dùng tới 820px),
max-w-[90vw]. - Backdrop
bg-black/30(+ blur tùy chọn). Body = 2-col grid form. Footerbg-zinc-50/70+ nút Lưu bên phải. - Keyframe:
@keyframes slideInRight { from { transform: translateX(100%) } to { transform: translateX(0) } }. - Dual-mode (create/edit) trong 1 drawer: state
editingId: number | null→ POST vs PUT + đổi tiêu đề + label nút động.
4.2 Inline edit "bậc thang" (sub-table ≤ 7 field):
- Click "Thêm" → 1 row inline chèn lên đầu, nền accent nhạt (
bg-blue-50/40create /bg-amber-50/40edit) + nút Lưu (check xanh) / Hủy (X) + phím tắtEsc/Ctrl+Enter. - Cell đang sửa:
border-blue-300+focus:ring-1. Chỉ 1 row sửa tại 1 thời điểm (stateeditingmutual-exclusion). - < 7 field dùng bậc thang; ≥ 8 field dùng drawer (4.1).
4.3 KPI card (dashboard): card trắng + số text-2xl + label text-xs uppercase + (tùy) clickable filter. Bố cục grid đều.
4.4 DataTable (bảng dữ liệu):
theadstickytop-0 z-10.thstyle label:uppercase tracking-wider text-zinc-500.- Row hover nền nhạt (
hover:bg-{primary}-50/30), selected đậm hơn (/60). - Row actions (view/edit/delete) = icon-button 7×7 (
h-7 w-7 rounded-md), icon 14px, hover đổi nền theo tone (default/danger/success). ⚠️ KHÔNG ẩn action sauopacity-0 group-hover(touch-device không thấy) — để actions luôn hiện.
5. Form conventions
5.1 Input field:
mt-1 w-full rounded-lg border border-zinc-200 bg-white
px-3 py-1.5 text-sm outline-none transition-colors
focus:border-{primary}-400 focus:ring-2 focus:ring-{primary}-500/10
- Border
zinc-200→ focus đổi sang hue primary (Solution chọn). Ring 10% opacity = glow mềm, không loud. - Padding
px-3 py-1.5(compact). Radiusrounded-lg(8px). Nền trắng. Gap dưới labelmt-1(4px).
5.2 Label: text-xs font-semibold text-zinc-400 uppercase tracking-wider
- Màu
zinc-400(nhạt, hierarchy mềm) + uppercase + tracking-wider = scan pattern đặc trưng.
5.3 Field wrapper + grid: wrapper <label> bọc (label-div + input), hỗ trợ span2/span3 trong grid.
- Form dày:
grid-cols-2 md:grid-cols-4 gap-x-4 gap-y-3. Section headertext-xs font-semibold uppercase+border-b+ nền nhạt +px-4 py-1.5.
6. Status badge + button
6.1 Status badge (pattern brand-agnostic):
rounded-full border px-1.5 py-0.5 text-xs font-semibold
bg-{color}-50 text-{color}-700 ← nền tint nhạt + chữ saturated
Ví dụ map trạng thái (Solution đổi màu theo ý): Active = green-50/700 · Warning = amber-50/700 · Danger = red-50/600 · Draft = neutral-100/600.
6.2 Button base (mọi variant share):
inline-flex items-center justify-center gap-1.5
rounded-lg px-3 py-1.5 text-xs font-semibold transition-colors
focus-visible:ring-2 focus-visible:ring-offset-1
disabled:opacity-50 disabled:pointer-events-none
Icon trong button 14px. Variant theo vai trò (KHÔNG theo màu cứng): primary (action chính) · outline (hủy/đóng) · outline-add (thêm/tạo) · success (duyệt) · danger (xóa) · ghost (action nhẹ trong row). Loading → thay icon bằng spinner 14px.
7. Color SYSTEM — chỉ CẤU TRÚC, hue do Solution chọn
NAMGROUP KHÔNG áp bảng màu — đây là cách tổ chức token để Solution tự gắn hue thương hiệu:
- 1 token
primarycho action chính (Tìm/Lưu/Login) + focus accent. Solution chọn hue. - Neutral scale 1 họ duy nhất — NAMGROUP dùng
zinc(nhất quán, KHÔNG trộngray/stone). Vai trò: page-bg (50) · border (200/300) · text (900/700) · label-muted (400/500) · icon-ghost (400). - Semantic status cố định vai trò (success/warning/danger/info) — pattern badge
bg-{c}-50 + text-{c}-700. Hue Solution chọn. - Khuyến nghị: xài utility class trực tiếp (Tailwind) thay vì phụ thuộc CSS var
--primarycho từng nút — dễ đọc, ít magic. (CSS var chỉ để theme-level / branding runtime.)
→ Logo, brand hue, nhận diện = Solution quyết hoàn toàn. Chỉ giữ chung cấu trúc 4 nhóm token ở trên để hệ thống nhất quán.
8. Checklist nhanh khi áp dụng
- Font: system stack, KHÔNG custom font.
- Body
text-sm, buttontext-xs font-semibold, labeltext-xs uppercase tracking-wider. - Neutral 1 họ (zinc) — KHÔNG trộn gray/stone.
- Input
py-1.5(≤36px),rounded-lg, focus ring 10% opacity. - List+Detail 2-panel inline (KHÔNG modal giữa màn cho detail).
- Form ≥8 field → drawer slide-in; sub-table ≤7 field → inline "bậc thang".
- Table actions LUÔN hiện (KHÔNG hover-hide).
- KHÔNG
font-bold(dùngfont-semibold), KHÔNG shadow/gradient trang trí.
9. References
- PURO live demo (tham khảo trực quan):
http://103.97.126.104:8080/(IP-only HTTP). - NAMGROUP portal (sau khi áp):
https://portaltest.namgroup.vn. - Token canonical nội bộ NAMGROUP:
docs/reference/puro-design-tokens.md(10 mục: color · typography · form · button · badge · animation · density).
Có gì cần đào sâu (vd snippet drawer/inline-edit cụ thể, hay component shared), Solution cứ reply qua kênh email (/check-email namgroup để pull). 🚀
— NAMGROUP (anh pqhuy chỉ đạo chia sẻ; màu sắc/brand để Solution tự quyết)