Mọi thứ trên trang này chỉ dùng class của kit.css và biến của tokens.base.css.
Mọi thứ trên trang này chỉ dùng class của kit.css và biến của tokens.base.css. Ba ô chọn ở thanh trên đổi bộ token: Dáng (bo góc, bóng), Màu (bảng màu) và Font ghép tự do với nhau, mỗi bảng màu đã qua check-palette.mjs. Mặc định (base) là dáng mềm, màu ink, font Inter Display. Desktop, Mobile và Tất cả ở thanh trên chọn màn hình: Desktop và Mobile mỗi bên chỉ hiện phần dùng được ở màn đó (phần dùng chung hiện ở cả hai). Bên trái xếp theo năm lớp: Nền tảng, Thành phần, Mẫu thiết kế, Bố cục trang, Hướng dẫn (xem phần Quy ước ở cuối trang). Giao diện: app không phải màn hình mà là kiểu vẽ khác cho cùng các class (nút viên thuốc, viền thay bóng, chữ 16px, điều khiển 52px khi chạm); bật nó thì thêm vài phần chỉ có ở kiểu app.
Tokens
Màu nền, chữ, trạng thái.
bgnền trang
surfacethẻ, ô nhập
surface-2đầu bảng
sunkvô hiệu, lõm
primarynút chính
notice-bgthông báo
okthành công
warncảnh báo
dangerlỗi
infothông tin
xs 12sm 13md 14base 15lg 17xl 202xl 24
Icon
Biểu tượng Phosphor (MIT) trong icons.svg, màu theo chữ xung quanh.
Phosphor (MIT) trong icons.svg: 168 icon nét thường và 14 icon đặc (hậu tố -fill, dùng cho mục đang chọn). .icon là 20 px, .icon-sm 16 px, .icon-lg 24 px; màu theo chữ xung quanh.
sm 1620lg 24
app-window
archive
arrow-clockwise
arrow-counter-clockwise
arrow-down
arrow-left
arrow-right
arrow-square-out
arrow-up
arrows-clockwise
arrows-down-up
at
bank
barcode
bell
bell-ringing
book-open
bookmark
buildings
calendar
calendar-blank
calendar-check
calendar-plus
camera
caret-double-left
caret-double-right
caret-down
caret-left
caret-right
caret-up
caret-up-down
chart-bar
chart-line
chart-pie
chat-circle
chat-circle-text
chats
check
check-circle
circle
circle-dashed
clipboard-text
clock
clock-countdown
clock-counter-clockwise
cloud-arrow-up
coins
columns
compass
copy
copy-simple
credit-card
crop
currency-dollar
database
diamond
dots-nine
dots-three
dots-three-vertical
download-simple
envelope
eye
eye-slash
file
file-csv
file-image
file-pdf
file-text
file-video
file-xls
film-strip
fingerprint
flag
floppy-disk
folder
folder-open
funnel
gauge
gear
gear-six
globe
grid-four
hand-coins
heart
hourglass
house
identification-card
image
images
info
invoice
kanban
key
layout
lifebuoy
lightbulb
link
list
list-bullets
lock
magnifying-glass
map-pin
map-trifold
megaphone
microphone
minus
money
music-note
note-pencil
package
paint-brush
palette
paper-plane-tilt
paperclip
password
pause
pencil-simple
percent
phone
play
play-circle
plus
presentation-chart
printer
prohibit
push-pin
qr-code
question
receipt
receipt-x
rows
seal-check
shield
shield-check
shopping-bag
shopping-cart
sidebar
sign-in
sign-out
sliders
sliders-horizontal
sort-ascending
sort-descending
speaker-high
spinner
squares-four
star
storefront
table
tag
target
timer
trash
trend-down
trend-up
truck
upload-simple
user
user-circle
user-minus
user-plus
users
video-camera
wallet
warehouse
warning
warning-circle
wifi-high
wifi-slash
wrench
x
x-circle
x-square
book-open-fill
buildings-fill
calendar-check-fill
chart-bar-fill
clipboard-text-fill
file-text-fill
gear-fill
house-fill
map-pin-fill
package-fill
receipt-fill
seal-check-fill
sliders-fill
squares-four-fill
storefront-fill
truck-fill
user-fill
users-fill
wallet-fill
warehouse-fill
wifi-high-fill
wrench-fill
arrows-left-right
Cỡ chạm: --tap và data-tap
Dưới ngón tay mọi điều khiển cao ít nhất 44px; dưới chuột kit giữ cỡ gọn, trừ khi trang bật data-tap.
Mặc định: @media (pointer: coarse) nâng nút nhỏ, chip, mục .seg, nút lịch, nút xóa của chip, nút liên kết trong banner nháp… lên --tap (44px, tenant đặt lại được) và chữ ô nhập lên 1rem. Chuột (pointer: fine) giữ cỡ gọn. Tenant nào muốn mục tiêu 44px cả khi dùng chuột (máy tính tiền cảm ứng, laptop cảm ứng, hoặc thiết kế muốn 44px khắp nơi) đặt <html data-tap="all">: cùng danh sách cỡ của khối chạm, trừ cỡ chữ ô nhập (cỡ đó chỉ để iOS không phóng to). Không đặt thì không có gì đổi. Trong kiểu app, look-app.css giữ nút nhỏ ở 44px thay vì 40px. Ô .daterange: ô ngày cao hết khung và bấm vào lề hoặc dấu gạch ngang của khung thì focus ô ngày gần nhất. Không dùng cho liên kết nằm trong đoạn chữ (.btn-link trần), cũng như khối chạm.
ChipD10
Có bản nháp chưa lưu từ 09:41
Button
Nút: sáu kiểu, ba cỡ, nút chỉ có biểu tượng và trạng thái đang tải.
Biểu tượng đứng trước hoặc sau chữ, khoảng cách do .btn giữ. Trong .btn-sm biểu tượng tự nhỏ còn 16 px. Nút chỉ có biểu tượng dùng .btn-icon và bắt buộc có aria-label. Khi aria-busy="true" vòng quay thay biểu tượng.
.form-cols là lưới 12 cột; mỗi .field lấy .c-3, .c-4, .c-6 hoặc .c-8 cột (không có lớp: cả hàng). Khi bản thân biểu mẫu hẹp dưới 36rem, trong hộp thoại hẹp cũng như trên điện thoại, mọi ô chiếm cả hàng. Dùng .form-grid khi các ô bằng nhau.
Trên: đủ rộng, các ô theo số cột. Dưới: cùng kiểu trong khung 28rem, mỗi ô một hàng.
Số trong khoảng ngắn
.number-stepper[data-stepper] do kit.js điều khiển, cho số nguyên trong khoảng ngắn (chọn thay cho một hàng chip khi chỉ có vài giá trị). data-min (mặc định 0), data-max (mặc định không giới hạn) và data-step-by (mặc định 1) đặt trên khung. Gõ số rồi rời ô thì số được kẹp vào khoảng; chữ không phải số thì giữ giá trị cũ. Nút ra ngoài khoảng có aria-disabled="true" nhưng vẫn giữ tiêu điểm. ↑ ↓ trong ô tăng giảm, Home và End về hai đầu. Giá trị ở data-value; ô bắn input và change.
Dropdown with search
Ô nhập lọc danh sách (không cần gõ dấu) để chọn một mục.
.combo bọc input.input[role="combobox"] và danh sách ul.combo-list[role="listbox"][popover="manual"] gồm các li.combo-option[role="option"] (.combo-sub cho mã phụ, aria-disabled="true" cho mục khóa, .combo-empty khi không khớp). Gõ để lọc, không cần gõ dấu ("phu thanh" khớp "Phú Thành"); mũi tên chọn, Enter lấy, Esc đóng; rời ô thì chữ trở về mục đã chọn. Danh sách là popover nên bảng hay hộp thoại không cắt nó: đặt nó trong cùng hộp thoại với ô nhập. Dùng khi danh sách dài hơn khoảng 10 mục; ngắn hơn thì dùng .select. Kit lo hình thức, tenant lo lọc, chọn và vị trí (mẫu ở cuối trang).
12 nhà cung cấp. Gõ tên không dấu (phu thanh) hoặc mã (NCC-0) để lọc.
Công ty Phú ThànhNCC-012
Cửa hàng Minh SơnNCC-007
Hợp tác xã Nga ThanhNCC-031
Nguyễn Văn AnNCC-044
Trần Thị BìnhNCC-052
Công ty Thanh NhànNCC-060
Đại lý Hòa AnNCC-018
Nhà phân phối Đông ÁNCC-025
Cơ khí Đại PhátNCC-071
Xưởng bao bì Thành CôngNCC-081
Cửa hàng Ánh DươngNCC-090
Công ty Việt HưngNCC-094
Không có kết quả
Mục đã chọn có dấu tích. Kho 3 đang kiểm kê nên bị khóa.
Kho 1
Kho 2
Kho 3 (đang kiểm kê)
Kho vật tư
Không có kết quả
Ô chọn hai dòng, nhóm và dòng thêm mới
Ba thêm cho ô chọn có tìm kiếm: giá trị đã chọn hiện hai dòng (tên, rồi mã · điện thoại · công nợ), danh sách có nhóm kèm mô tả, và dòng “+ Thêm khách mới” ở cuối.
data-combo-two-line trên .combo cùng div.combo-value[aria-hidden="true"] (có .combo-value-main và .combo-value-sub rỗng) đặt sau ô nhập: input[role="combobox"] vẫn là ô điều khiển (gõ, aria-*, giá trị là dòng chính; dòng phụ là aria-describedby của nó), còn kit.js chỉ phủ hai dòng lên ô khi danh sách đóng và đã chọn mục. Dòng phụ lấy từ .combo-sub của mục. Ô cao bằng hai dòng dù có chọn hay chưa (không nhảy khi chọn), mỗi dòng cắt bằng “…”. Trong danh sách, dòng phụ nằm dưới tên. li.combo-group[role="presentation"] (.combo-group-title, tùy chọn .combo-group-desc) đứng trước các mục của nhóm: không phải mục chọn, phím mũi tên bỏ qua, và bị ẩn khi bộ lọc không còn mục nào của nhóm; tiêu đề nhóm chỉ để nhìn, nên đặt tên mục sao cho đọc riêng vẫn rõ. li.combo-option.combo-add[role="option"] cuối danh sách (biểu tượng plus rồi chữ): mũi tên với tới được, không bao giờ là giá trị, luôn hiện, dính ở đáy khi danh sách cuộn; Enter hoặc bấm thì danh sách đóng và .combo phát sự kiện combo-add (nổi bọt, detail.query là chữ đã gõ) để tenant mở form thêm.
Hai dòng, đã chọn một khách
Nguyễn Văn HùngKH-0012 · 0905 111 222 · Công nợ 12.400.000 đ
Công ty TNHH Cơ khí Nam Việt Nha Trang chi nhánh Diên KhánhKH-0007 · 0258 3822 100 · Công nợ 0 đ
Trần Thị MaiKH-0031 · 0912 345 678 · Công nợ 3.050.000 đ
Lê Quốc BảoKH-0044 · 0977 654 321 · Công nợ 860.000 đ
Không có kết quả
Ô đóng hiện tên và dòng phụ. Bấm hoặc gõ thì ô trở về một dòng chữ để lọc (gõ “0905” hay “nam viet” đều khớp); dòng quá dài bị cắt bằng “…” (xem ô hẹp bên dưới).
Tên dài trong ô hẹp
Nguyễn Văn HùngKH-0012 · 0905 111 222 · Công nợ 12.400.000 đ
Công ty TNHH Cơ khí Nam Việt Nha Trang chi nhánh Diên KhánhKH-0007 · 0258 3822 100 · Công nợ 0 đ
Trần Thị MaiKH-0031 · 0912 345 678 · Công nợ 3.050.000 đ
Lê Quốc BảoKH-0044 · 0977 654 321 · Công nợ 860.000 đ
Không có kết quả
Khung 15 rem: cả hai dòng đều bị cắt bằng “…”, chiều cao ô không đổi. Đọc đủ ở danh sách (dòng phụ xuống dòng) và ở trình đọc màn hình (tên là giá trị của ô, dòng phụ là mô tả).
Hai dòng, chưa chọn
Nguyễn Văn HùngKH-0012 · 0905 111 222 · Công nợ 12.400.000 đ
Công ty TNHH Cơ khí Nam Việt Nha Trang chi nhánh Diên KhánhKH-0007 · 0258 3822 100 · Công nợ 0 đ
Trần Thị MaiKH-0031 · 0912 345 678 · Công nợ 3.050.000 đ
Lê Quốc BảoKH-0044 · 0977 654 321 · Công nợ 860.000 đ
Không có kết quả
Chưa chọn thì chỉ có gợi ý, nhưng ô vẫn cao bằng hai dòng nên biểu mẫu không nhảy khi chọn.
Nhóm có tiêu đề và mô tả
Tiền mặtQuỹ giữ tại cửa hàng, ai lập phiếu cũng chọn được
Quỹ tiền mặt cửa hàngTM-01
Két sắt văn phòngTM-02
Ngân hàngChỉ kế toán chọn được
Vietcombank Nha TrangVCB-0071
BIDV Khánh HòaBIDV-2210
Sacombank Diên KhánhSTB-0418
Quỹ khác
Quỹ dự phòngDP-01
Không có kết quả
Ba nhóm; mũi tên bỏ qua dòng tiêu đề. Gõ “bidv” thì chỉ còn nhóm Ngân hàng, hai nhóm kia ẩn theo.
Dòng thêm mới ở cuối
Nguyễn Văn HùngKH-0012
Trần Thị MaiKH-0031
Lê Quốc BảoKH-0044
Không có kết quả
Thêm khách mới
Chưa bấm “Thêm khách mới”. Gõ “Hoàng” (không khớp ai) rồi bấm dòng đó hoặc Enter sau khi tới nó bằng mũi tên: sự kiện combo-add mang chữ đã gõ.
Tìm không phân biệt dấu: TvKit.fold
Hàm bỏ dấu tiếng Việt của kit, dùng cho danh sách tự lọc mà không cần ô chọn có tìm kiếm.
TvKit.fold(chuỗi) trả về chuỗi viết thường, bỏ dấu thanh và dấu mũ, đ thành d ("Đặng Thị Hương" thành "dang thi huong"). Đây chính là hàm ô chọn có tìm kiếm (.combo) vẫn dùng, nay mở cho trang tự lọc danh sách: TvKit.fold(tên).indexOf(TvKit.fold(từ khóa)) >= 0. Kit không lọc hộ: trang tự ẩn và hiện dòng, tự báo số kết quả.
10 người
Nguyễn Văn Đạt
Đặng Thị Hương
Trần Minh Chiến
Lê Thị Thu Hà
Phạm Ngọc Vinh
Bùi Đức Thịnh
Hoàng Quốc Việt
Đỗ Thị Ánh Tuyết
Vũ Thành Long
Ngô Quang Hải
Một input thường lọc một ul bằng TvKit.fold: gõ "dang" ra Đặng, "thinh" ra Thịnh, "d" ra mọi tên có chữ Đ hoặc D.
Ô nhập số: tiền và số lượng
Gõ tới đâu hiện dấu chấm nghìn tới đó, số tiền bằng chữ ngay dưới ô, và nút nhanh 000, 00, Xóa cho ngón tay cái.
input.input[data-money] do kit.js điều khiển: chỉ giữ chữ số, thêm dấu chấm giữa các nghìn khi gõ (1250000 hiện 1.250.000), giữ con trỏ ở chỗ người dùng đang gõ hay xóa (Backspace và Delete nhảy qua dấu chấm sang chữ số bên cạnh), dán chữ thì chỉ lấy chữ số, ô trống vẫn trống. Số thô nằm ở data-value; ô bắn input mỗi lần đổi và change khi rời ô hoặc nhấn Enter, nên lắng nghe change. data-max là số chữ số tối đa (chữ số vượt quá bị từ chối). data-words="id" ghi số tiền bằng chữ tiếng Việt vào phần tử đó (.field-hint hoặc p, tự có aria-live="polite"); chỉ cần có data-words là giới hạn mặc định 12 chữ số (999 tỷ). Lỗi là aria-invalid của biểu mẫu kèm .field-error; required cũng của biểu mẫu. .input-lg là cỡ lớn (2,25rem, cao 3rem, căn phải) cho nhập trên điện thoại. .money-keys chứa button.btn với data-append="000", data-append="00" và data-clear, nối với ô bằng data-money-keys="id" hoặc đứng cùng .field; nút cao và rộng 48px, giữ tiêu điểm trong ô.
Ô thường
đ
Chỉ gõ chữ số; tối đa 12 chữ số.
Thử: gõ 1250000, đặt con trỏ giữa số rồi gõ hoặc xóa, dùng Backspace và Delete cạnh dấu chấm, dán "1.250.000 đ" hay chữ lẫn số.
Ô lớn có đơn vị, số bằng chữ và nút nhanh
đ
Số tiền bằng chữ hiện ở đây.
.input-lg trong .input-affix với data-words và .money-keys (cùng .field nên không cần data-money-keys). Bấm nút, tiêu điểm vẫn ở trong ô.
Ô báo lỗi
đ
Số tiền chi phải lớn hơn 0.
Ô bị khóa
đ
Ô số lượng thập phân
Số lượng kiểu Việt Nam (kg, mét, giờ): dấu phẩy, tối đa 3 số lẻ, và bước 0,5 cho nút tăng giảm.
input.input[data-number] do kit.js điều khiển (inputmode="decimal"): chỉ giữ chữ số và một dấu thập phân; gõ dấu phẩy hay dấu chấm đều được và luôn hiện dấu phẩy. Một dấu chấm hay dấu phẩy đơn lẻ luôn là dấu thập phân ở mọi nơi: "4.162" là 4,162, không phải bốn nghìn. data-decimals (mặc định 3) là số chữ số lẻ tối đa: chữ số thừa bị từ chối (không làm tròn), ô có aria-invalid="true" và phần tử nêu ở data-error hiện ra ("Tối đa 3 số lẻ") cho tới lần sửa hợp lệ tiếp theo hoặc khi rời ô. Khi rời ô hoặc nhấn Enter: bỏ số 0 đầu và dấu phẩy thừa ở cuối (007 thành 7, "12," thành 12, ",5" thành 0,5), còn các số lẻ đã gõ thì giữ ("12,50" vẫn là "12,50"). Số ở dạng dấu chấm nằm ở data-value ("12.50"); ô bắn input và change. Số âm bị cấm trừ khi có data-allow-negative. .input-lg làm ô lớn; đơn vị đặt trong nhãn hoặc .affix. .number-stepper[data-stepper] nhận data-decimals thì data-step-by, data-min, data-max viết được 0,5; ô hiện dấu phẩy, giá trị làm tròn tới data-decimals nên 0,1 + 0,2 vẫn hiện 0,3; không có data-decimals thì như cũ, chỉ số nguyên. Một .affix sau ô cho đơn vị.
Ô thường và ô lớn có đơn vị
Dấu phẩy hoặc dấu chấm đều là dấu thập phân.
kg
Thử: gõ 4.162 (hiện 4,162), 12,50 rồi rời ô (vẫn 12,50), 007 (thành 7), ",5" (thành 0,5), thêm số lẻ thứ tư (bị từ chối), dán "3,25 kg".
Báo vượt số chữ số lẻ
Tối đa 3 số lẻ
Trạng thái ngay sau khi chữ số thứ tư sau dấu phẩy bị từ chối: ô giữ "4,162", aria-invalid và lời báo hiện ra, mất đi khi sửa hợp lệ hoặc rời ô. Với data-allow-negative thì cho phép dấu trừ đứng đầu.
Nút tăng giảm số thập phân, 0 đến 12, bước 0,5
g
g là giờ.
.number-stepper[data-decimals="1" data-step-by="0,5"]: ↑ ↓ và hai nút bước 0,5; gõ "3.5" hay "3,5" đều được và hiện "3,5". Hai ô nguyên ở mục "Nhập liệu" (số ảnh tối thiểu, số người) không đổi.
Date picker, range và điều hướng kỳ
Ô gõ ngày/tháng/năm kèm lịch, không phụ thuộc ngôn ngữ của trình duyệt.
.datepicker[data-datepicker] chứa input.input (gõ dd/mm/yyyy, hoặc 8 chữ số liền như 05102026), button.datepicker-btn (aria-haspopup="dialog") và .calendar[popover="manual"][role="dialog"]: .calendar-head (tháng trước, chọn tháng, chọn năm, tháng sau), table.calendar-grid[role="grid"] với td[role="gridcell"] chứa .calendar-day, .calendar-foot (Hôm nay, Xóa). Ngày được giữ ở data-value dạng yyyy-mm-dd; data-min, data-max tắt các ngày ngoài khoảng, data-min-input và data-max-input lấy giới hạn từ ô ngày khác (khoảng từ – đến). Ô tự bắn input và change khi ngày đổi; nên nghe change. Trong lịch: ← → ↑ ↓ đổi ngày hoặc tuần, Home và End về đầu và cuối tuần, Page Up và Page Down đổi tháng (thêm Shift thì đổi năm), Enter chọn, Esc đóng. Gõ sai hoặc ngoài khoảng thì ô có aria-invalid="true"; thông báo lỗi là việc của tenant (data-error trỏ tới phần tử lỗi). Khoảng ngày bằng một lịch:.daterange[data-daterange] chứa hai input.daterange-input (từ, đến, mỗi ô giữ data-value), .range-sep, button.datepicker-btn và .calendar.calendar-range: .calendar-presets (các nút .calendar-preset[data-preset]: today, yesterday, 7d, 30d, month, lastmonth, quarter, year; tenant bỏ bớt tùy ý), .calendar-months với hai .calendar-month (dưới 48rem chỉ một tháng, nút chọn nhanh thành hàng), .calendar-foot (gợi ý, Xóa). Bấm ngày đầu rồi ngày cuối (đảo thứ tự cũng được), các ngày giữa được tô; rê chuột hoặc dùng phím mũi tên sẽ xem trước. Chỉ khi chọn xong ngày cuối thì hai ô mới đổi và mới bắn input, change (ô nào đổi thì bắn ô đó, sau khi cả hai đã có giá trị mới). Esc bỏ lần chọn dở. Nút chọn nhanh trùng khoảng đang có thì aria-pressed="true"; nằm ngoài data-min, data-max thì aria-disabled. Gõ vào từng ô cũng được: đầu đến trước đầu từ thì ô đó aria-invalid="true".
Tháng 1
Tháng 2
Tháng 3
Tháng 4
Tháng 5
Tháng 6
Tháng 7
Tháng 8
Tháng 9
Tháng 10
Tháng 11
Tháng 12
Không có kết quả
Không có kết quả
T2
T3
T4
T5
T6
T7
CN
Tháng 1
Tháng 2
Tháng 3
Tháng 4
Tháng 5
Tháng 6
Tháng 7
Tháng 8
Tháng 9
Tháng 10
Tháng 11
Tháng 12
Không có kết quả
Không có kết quả
T2
T3
T4
T5
T6
T7
CN
Nhập ngày từ 01/10/2026 đến 31/12/2026, dạng ngày/tháng/năm.
Tháng 1
Tháng 2
Tháng 3
Tháng 4
Tháng 5
Tháng 6
Tháng 7
Tháng 8
Tháng 9
Tháng 10
Tháng 11
Tháng 12
Không có kết quả
Không có kết quả
T2
T3
T4
T5
T6
T7
CN
Khoảng ngày
Tháng 1
Tháng 2
Tháng 3
Tháng 4
Tháng 5
Tháng 6
Tháng 7
Tháng 8
Tháng 9
Tháng 10
Tháng 11
Tháng 12
Không có kết quả
Không có kết quả
T2
T3
T4
T5
T6
T7
CN
–
Tháng 1
Tháng 2
Tháng 3
Tháng 4
Tháng 5
Tháng 6
Tháng 7
Tháng 8
Tháng 9
Tháng 10
Tháng 11
Tháng 12
Không có kết quả
Không có kết quả
T2
T3
T4
T5
T6
T7
CN
Khoảng ngày, một lịch
–
T2
T3
T4
T5
T6
T7
CN
T2
T3
T4
T5
T6
T7
CN
Bấm ngày bắt đầu, rồi ngày kết thúc.
Nhập ngày dạng ngày/tháng/năm; ngày kết thúc không trước ngày bắt đầu.
Một ô, một lịch: bấm ngày bắt đầu rồi ngày kết thúc, hoặc chọn nhanh ở bên trái. Ô giới hạn đến 31/12/2026 (data-max). Trên: hai ô ngày ghép nhau, hợp khi mỗi đầu có nhãn và việc riêng.
Giờ trong ngày
Giờ 24, dạng 14:00
Giờ hạn viết dạng 14:00, phút từ 00 tới 59
input.input-time[data-time] do kit.js điều khiển: gõ 14:00, 1400, 930, 9h30 hoặc 14 đều thành HH:MM khi rời ô hoặc bấm Enter. Giờ chuẩn nằm ở data-value; giờ quá 23 hoặc phút quá 59 thì ô có aria-invalid="true" và hiện phần tử data-error. Ô tự bắn input và change.
Tháng
Nhập tháng trong năm 2026, dạng tháng/năm.
.datepicker[data-monthpicker] do kit.js điều khiển: gõ 11/2026, 11-2026 hoặc 112026, hoặc bấm nút để chọn trong 12 tháng. Tháng được giữ ở data-value dạng yyyy-mm; data-min, data-max cùng dạng, tắt các tháng ngoài khoảng (ô thứ hai chỉ nhận năm 2026). Ô bắn input và change. Trong bảng chọn: ← → đổi tháng, ↑ ↓ đổi ba tháng, Page Up và Page Down đổi năm, Home và End về đầu và cuối năm, Enter chọn, Esc đóng.
Điều hướng kỳ: ngày, tháng, quý, năm
Hai nút và nhãn để lùi hoặc tiến từng ngày, tháng, quý hoặc năm, có chặn ở hai đầu; kèm bộ chọn quý, chọn nhanh “Tuần này”, “Từ đầu” và bộ chuyển ngày dính trên đầu.
.period-nav[data-period-nav] (role="group" kèm aria-label) gồm button.btn.btn-icon[data-period="-1"] (mũi tên trái, aria-label “Tháng trước”), span.period-nav-label[aria-live="polite"][aria-atomic="true"] và button.btn.btn-icon[data-period="1"]. Trong nhãn có span.period-nav-text (kit.js viết “Tháng 09/2026”, “Quý 3/2026”, “Năm 2026”, “Thứ Tư, 30/09/2026”) và span.tag.tag-info.period-nav-now[hidden] (“Hôm nay”, hiện khi kỳ chứa ngày hôm nay). Thuộc tính: data-unit (day, month, quarter, year), data-value (yyyy-mm-dd, yyyy-mm, yyyy-Qn, yyyy; để trống thì lấy kỳ chứa hôm nay), data-min và data-max (kỳ đầu và kỳ cuối được phép, cùng các dạng đó; today là hôm nay, hợp với “không mở ngày tương lai”). Ở đầu hoặc cuối nút không đi tiếp được có aria-disabled="true", không phải disabled, nên bàn phím vẫn dừng ở nút và đọc được “không khả dụng”; nút mờ theo luật chung của .btn. Nhãn là chữ thường trong vùng thông báo lịch sự, không có role: role="status" là sai cho một nhãn, và nếu trang biến nhãn thành nút chọn thì chuyển aria-live sang một .visually-hidden bên cạnh. Mỗi lần đổi kỳ, phần tử bắn change (nổi bọt) với detail.value, detail.start, detail.end (ngày đầu và ngày cuối của kỳ, yyyy-mm-dd). Chỉ dùng nút và phím Tab, Enter hoặc Space; không có phím mũi tên. Nút button.btn.btn-link.btn-sm.period-nav-today[data-period-today] (“Hôm nay”) về kỳ chứa hôm nay và tự ẩn khi đang ở đó hoặc khi hôm nay ngoài khoảng cho phép; .period-nav-sticky làm thanh dính đầu khung cuộn (top: var(--sticky-top, 0), nền --surface, đường kẻ dưới). Bộ chọn quý:.datepicker[data-quarterpicker] dùng đúng khung của bộ chọn tháng (đầu bảng là năm với hai mũi tên), .month-grid.month-grid-q có bốn nút .month-btn xếp hai hàng hai cột; gõ Q3/2026, 3/2026, Q3-2026 hoặc Quý 3/2026; giá trị ở data-value="2026-Q3", data-min và data-max cùng dạng. Chọn nhanh của khoảng ngày:data-preset="week" (thứ Hai đến Chủ nhật của tuần này) và data-preset="all" (từ data-all-from, hoặc data-min, đến hôm nay) chạy sẵn; trang đăng ký thêm bằng TvKit.presets.register('fy', 'Năm tài chính', function (today, box) { return { from: '2026-04-01', to: today }; }) rồi viết nút data-preset="fy" trống (nhãn lấy từ đăng ký) hoặc có chữ riêng.
Tháng, chặn hai đầu
Tháng 04/2026Hôm nay
Tháng 07/2026Hôm nay
Tháng 09/2026Hôm nay
Sổ bắt đầu từ 04/2026 và có số liệu đến 09/2026 (data-min="2026-04", data-max="2026-09"): ở tháng đầu nút lùi mờ, ở tháng cuối nút tiến mờ, cả hai vẫn nhận phím Tab. Bấm thử để đổi kỳ.
Quý
Quý 2/2026Hôm nay
Quý 3/2026Hôm nay
Quý 4/2026Hôm nay
Năm
Năm 2024Hôm nay
Năm 2025Hôm nay
Năm 2026Hôm nay
Ngày, không mở ngày tương lai
Thứ Tư, 01/04/2026Hôm nay
Thứ Hai, 21/09/2026Hôm nay
Thứ Hai, 02/11/2026Hôm nay
Sổ công việc bắt đầu từ 01/04/2026 và không mở ngày chưa tới (data-max="today"). Ví dụ thứ ba để trống data-value, nên mở ở hôm nay: nhãn có thẻ “Hôm nay”, nút tiến mờ. Nhãn dài nhất (“Chủ Nhật, 30/08/2026”) vẫn nằm trong một dòng ở khổ 390 px.
Đặt từ script và ngày giả cho mockup
Hôm nay
TvKit.periodNav.set(el, value, { unit }) đặt kỳ từ script: value là yyyy-mm-dd, yyyy-mm, yyyy-Qn, yyyy hoặc "today" (làm tròn về kỳ, bị chặn bởi min/max); bỏ trống thì giữ kỳ đang xem. { unit } đổi đơn vị (nhãn nút trước/sau do kit viết đổi theo). Hàm không bắn change: người gọi đã biết; đọc data-value khi cần. data-today="2026-09-30" trên khung cố định hôm nay cho mockup: data-max="today", thẻ “Hôm nay” và nút “Hôm nay” đều theo ngày đó thay vì đồng hồ máy (data-max cũng nhận ngày yyyy-mm-dd trực tiếp). Ngày giả chỉ áp cho khung có thuộc tính, không áp cho lịch hay ô ngày.
Thanh chuyển ngày dính trên đầu
Thứ Hai, 21/09/2026Hôm nay
Cắt tôn tấm lớn
Tổ cắt · 8 giờ
Hàn khung cửa sổ
Tổ hàn 1 · 8 giờ
Sơn lót lô 14
Tổ sơn · 4 giờ
Lắp đặt công trình Hải Châu
Tổ lắp đặt · 8 giờ
Vệ sinh xưởng cuối ca
Tổ cắt · 8 giờ
Kiểm vật tư tồn
Tổ hàn 1 · 8 giờ
Chấm công tổ hàn
Tổ sơn · 4 giờ
Giao hàng đơn 0231
Tổ lắp đặt · 8 giờ
.period-nav.period-nav-sticky trong khung cuộn 15 rem (khung có tabindex="0"): thanh nằm ở đầu khung, các dòng trượt dưới nền --surface, có nút “Hôm nay” (.period-nav-today) vì ngày đang xem không phải hôm nay. Bấm “Hôm nay” thì nút ẩn đi, thẻ “Hôm nay” hiện ra và tiêu điểm chuyển sang nút lùi.
Thứ Hai, 02/11/2026Hôm nay
Cắt tôn tấm lớn
Tổ cắt · 8 giờ
Hàn khung cửa sổ
Tổ hàn 1 · 8 giờ
Sơn lót lô 14
Tổ sơn · 4 giờ
Lắp đặt công trình Hải Châu
Tổ lắp đặt · 8 giờ
Vệ sinh xưởng cuối ca
Tổ cắt · 8 giờ
Kiểm vật tư tồn
Tổ hàn 1 · 8 giờ
Chấm công tổ hàn
Tổ sơn · 4 giờ
Giao hàng đơn 0231
Tổ lắp đặt · 8 giờ
Cùng thanh ở ngày hôm nay: thẻ “Hôm nay” trong nhãn, không có nút “Hôm nay”, nút tiến mờ.
Bộ chọn quý
Nhập quý trong năm 2026, dạng Q3/2026.
.datepicker[data-quarterpicker] do kit.js điều khiển, theo mẫu bộ chọn tháng: gõ Q3/2026, 3/2026, q3-2026 hoặc Quý 3/2026, hoặc bấm nút để chọn trong bốn quý. Giá trị ở data-value dạng 2026-Q3; data-min, data-max cùng dạng (ô thứ hai chỉ nhận năm 2026). Ô bắn input và change. Trong bảng chọn: ← → đổi quý, ↑ ↓ đổi hai quý, Page Up và Page Down đổi năm, Home và End về đầu và cuối năm, Enter chọn, Esc đóng.
Khoảng ngày: chọn nhanh Tuần này, Từ đầu và một mục do trang đăng ký
Khoảng ngày với chọn nhanh Tuần này, Từ đầu và Năm tài chính
–
T2
T3
T4
T5
T6
T7
CN
T2
T3
T4
T5
T6
T7
CN
Bấm ngày bắt đầu, rồi ngày kết thúc.
Nhập ngày dạng ngày/tháng/năm; ngày kết thúc không trước ngày bắt đầu.
Ba mục chọn nhanh mới: “Tuần này” (thứ Hai đến Chủ nhật), “Từ đầu” (từ data-all-from="2026-04-01" đến hôm nay) và “Năm tài chính” (từ 01/04 đến hôm nay), do trang mẫu đăng ký bằng TvKit.presets.register('fy', 'Năm tài chính', fn); nút của nó trong mã nguồn để trống, chữ lấy từ lần đăng ký. Mục nằm ngoài data-max (31/12/2026) thì mờ và gạch ngang.
Tệp và ảnh
Vùng thả tệp có ô chọn tệp thật bên trong, kèm danh sách tệp đã chọn.
label.dropzone là cả vùng thả: ô input type="file" nằm trong nó và ẩn bằng .visually-hidden nên bàn phím và hộp chọn tệp của trình duyệt vẫn chạy, nhãn của ô là tiêu đề cộng dòng gợi ý. Tenant đặt data-over lúc đang kéo tệp qua, aria-invalid="true" trên ô khi từ chối tệp và lý do trong .field-error. Tệp đã chọn nằm dưới trong ul.file-list: mỗi tệp một li.file-item với data-state="done|uploading|error"; trạng thái luôn có chữ ở dòng phụ (không chỉ màu), và đang tải thì thêm .bar.
don-hang-thang-10.xlsx1,2 MB · Đã tải lên
khach-hang.csv340 KB · Đang tải lên 60%
ton-kho-cu.xlsx18,5 MB · Quá 10 MB, không tải lên được
Thử kéo một tệp .xlsx vào vùng trên, hoặc một tệp khác loại (.pdf) để xem lỗi: tệp đạt vào danh sách là đã chọn, tệp bị từ chối có lý do bằng chữ và ô báo lỗi. Ở đây không có gì rời khỏi trang; tenant tự tải lên và tự đổi data-state theo tiến độ.
Chọn một tệp Excel để nhập.
Hai trạng thái còn lại: báo lỗi (viền đỏ, lý do ở dưới) và không dùng được.
Ô thêm ảnh và lưới tệp
Ô gạch đứt ở cuối hàng ảnh để chụp hoặc chọn ảnh từ thư viện, và lưới tệp đính kèm có huy hiệu loại tệp bằng chữ.
li.thumb-add là mục cuối của .thumb-list: một label bọc input[type="file"][accept="image/*"][multiple] ẩn (.visually-hidden), biểu tượng và chữ. Có capture="environment" thì điện thoại mở camera sau (biểu tượng camera, chữ “Chụp ảnh”); không có thì mở thư viện ảnh, thêm .thumb-add-pick (biểu tượng image, chữ “Thêm ảnh”): hình dạng giống nhau. Cả ô là nhãn nên cả ô là vùng chạm (rộng bằng một ảnh, cao ít nhất --tap); vòng lấy nét hiện quanh ô khi dùng bàn phím. Không có script: muốn xem trước ảnh vừa chọn thì trang tự nghe change của ô nhập và chèn một li.thumb trước ô này. ul.file-grid > li > a.file-tile (hoặc div.file-tile): svg.file-tile-icon, .file-tile-type (PDF, XLS, DOC, JPG: chữ, không chỉ màu), .file-tile-name (tối đa hai dòng rồi “…”), .file-tile-foot với .file-tile-size và nút xóa tùy chọn. Nút không nằm được trong a, nên ô có nút xóa là div.file-tile và đường dẫn đặt trên tên (a.file-tile-name, trải kín ô). Cột tối thiểu 8 rem: hai cột ở điện thoại, nhiều hơn khi khung rộng.
Hai ảnh, ô chụp và ô chọn từ thư viện
Sàn khu khách
Ảnh 1 · nhận 14:32
Quầy pha chế
Ảnh 2 · nhận 14:35
Ô chụp (capture="environment") và ô thư viện (.thumb-add-pick) nằm cuối hàng, cùng dáng khung ảnh và thẳng hàng với ảnh. Bấm hoặc Tab tới rồi Enter/Space để mở; thử phím Tab để thấy vòng lấy nét.
Chưa có ảnh nào
Danh sách trống chỉ có ô thêm; cùng cỡ một ảnh nên chỗ của nó không đổi khi ảnh đầu tiên đến.
Cỡ nhỏ, bốn ô một hàng
Với .thumb-list-sm (5 rem) ô thêm vẫn cao hơn 44 px.
Khung 15 rem chỉ đủ một cột; tên vẫn hai dòng, không tràn ra ngoài.
Chọn nhanh: nút chọn một và thẻ quỹ
Nút chọn một trong vài mục cho ngón tay cái: các ô chia đều bề rộng, mục đang chọn mang màu riêng (Thu, Chi, Chuyển; Đi làm, Nghỉ phép; Xong, Có vấn đề).
.seg.seg-block là .seg kéo dài hết bề rộng của khung chứa: các .seg-item chia đều, cao ít nhất --tap (kiểu app: cao hơn 4 px), nhãn một dòng và bị cắt bằng “…” nếu không vừa, nên giữ mỗi nhãn khoảng mười ký tự (bốn mục vừa một thẻ 358 px ở 390 px). Biểu tượng đứng trước nhãn là svg.icon trong mục. data-tone="ok|warn|bad|info" trên một mục cho trạng thái đang chọn màu riêng: nền nhạt của tông (-bg), chữ màu tông và viền 2 px quanh mục, không phải nền đặc. Màu không đứng một mình: mục chọn khác mục còn lại bởi viền, nền và chữ đậm hơn, và chính chữ của mục nói nó là gì. Không có data-tone thì giữ dáng cũ. Vai trò như .seg: role="radiogroup" có tên, role="radio" và aria-checked trên từng mục, một điểm dừng Tab (tabindex="0" ở mục đang chọn), phím mũi tên đổi mục (gallery có script, bỏ qua mục bị khóa). Mục bị khóa dùng disabled; nói lý do ở dòng cạnh nhóm.
Loại phiếu: Chi, Thu, Chuyển
Loại phiếu
Ba mục, ba tông: data-tone="warn", "ok", "info". Mỗi mục có biểu tượng riêng; bấm hoặc dùng phím mũi tên để đổi.
Điểm danh: bốn mục trong thẻ 358 px
Nguyễn Văn An, thứ Hai 2/11
Bốn nhãn, dài nhất “Không phép”, nằm một dòng trong thẻ rộng 358 px đệm 12 px (điện thoại 390 px), cả ở chữ 14 px của kiểu app. Thẻ đệm 20 px chỉ còn 316 px cho nhóm: nhãn dài nhất sẽ bị cắt bằng “…”, nên giữ đệm hẹp hoặc rút nhãn. Không biểu tượng, vì nhãn đã đủ rõ.
Kết quả công việc: có biểu tượng
Kết quả
Biểu tượng đứng trước nhãn; mục “Đang làm” đang chọn với tông info.
Hai mục, không màu
Nhập hay xuất
Không có data-tone: mục chọn nổi trên nền chìm như .seg, chỉ rộng hết dòng.
Một mục bị khóa
Chuyển quỹ
Quỹ dự phòng chỉ kế toán chọn được.
Mục bị khóa mờ đi và phím mũi tên bỏ qua nó; lý do nằm ở dòng chữ bên dưới.
Chọn quỹ: dải cuộn, thẻ gọn, cặp Từ / Đến
Ba cách chọn quỹ khi có nhiều quỹ: dải thẻ cuộn ngang (quỹ âm tô đỏ), thẻ chọn gọn có biểu tượng và báo lỗi khi rút quá số dư, và cặp “Từ” / “Đến” có nút đổi chiều.
.kpi-tabs.kpi-tabs-scroll là .kpi-tabs cuộn ngang (mỗi thẻ rộng theo nội dung, tối thiểu --tab-w 9rem) và cho phép data-tone="ok|warn|bad": thẻ nhuộm màu, con số theo màu của tone. Màu không đứng một mình: số có dấu trừ (.num-neg) và dòng chân có chữ “Âm” (.tag.tag-bad). kit.js cuộn thẻ đang chọn vào khung khi thẻ đổi. .choice-cards.choice-cards-compact: thẻ từ 7,5rem, svg.icon + .choice-title + .choice-sub (số dư); aria-invalid="true" trên input của thẻ cho viền và nền đỏ, lời nhắn ở p.field-error dưới nhóm (nối bằng aria-describedby); nhóm vẫn là role="radiogroup", bàn phím là của ô radio. .pair-pick[data-pair-swap]: hai ô và button.btn.btn-icon.pair-swap[aria-label="Đổi chiều"] ở giữa; dưới 28rem hai ô xếp dọc và mũi tên xoay 90°. kit.js đổi giá trị của hai ô (select, .combo, thẻ chọn radio, ô chữ) và gọi input, change trên cả hai; hai ô phải có cùng danh sách lựa chọn.
Dải quỹ cuộn ngang, một quỹ âm
Sổ quỹ của Tiền mặt: danh sách phiếu thu, chi và chuyển của quỹ này.
Sổ quỹ của Vietcombank ·· 6789: danh sách phiếu thu, chi và chuyển của quỹ này.
Sổ quỹ của Techcombank ·· 1234: danh sách phiếu thu, chi và chuyển của quỹ này.
Sổ quỹ của BIDV ·· 4455: danh sách phiếu thu, chi và chuyển của quỹ này.
Sổ quỹ của Agribank ·· 0987: danh sách phiếu thu, chi và chuyển của quỹ này.
Sổ quỹ của Ví MoMo: danh sách phiếu thu, chi và chuyển của quỹ này.
Sổ quỹ của Quỹ dự phòng: danh sách phiếu thu, chi và chuyển của quỹ này.
Bảy quỹ không vừa khung nên dải cuộn ngang, thẻ bám mép đầu khi cuộn; Techcombank là quỹ âm: thẻ nhuộm đỏ, số có dấu trừ và có nhãn “Âm”. Chọn một thẻ ở xa (hoặc bấm mũi tên, End) thì dải tự cuộn thẻ đó vào khung.
Thẻ chọn quỹ gọn
Rút từ quỹ
Thẻ 7,5rem, biểu tượng, tên quỹ và một dòng số dư. Tab vào nhóm, mũi tên đổi quỹ.
Thẻ có một quỹ không hợp lệ
Rút từ quỹ
Rút quá số dư: còn 2.400.000 đ
Số tiền rút lớn hơn số dư của quỹ đã chọn: thẻ viền đỏ, biểu tượng đỏ và câu báo lỗi dưới nhóm nói rõ lý do. Bỏ aria-invalid khi người dùng đổi quỹ.
Cặp Từ / Đến có nút đổi chiều
Tiền mặt
Vietcombank ·· 6789
Techcombank ·· 1234
BIDV ·· 4455
Không có kết quả
Tiền mặt
Vietcombank ·· 6789
Techcombank ·· 1234
BIDV ·· 4455
Không có kết quả
Rộng: hai ô cạnh nhau, nút đổi chiều ngang hàng với ô. Bấm nút (hoặc Tab tới rồi Enter, Space) thì hai quỹ đổi chỗ; ở đây là hai ô chọn có tìm kiếm.
Cặp Từ / Đến trong khung hẹp
Khung dưới 28rem: hai ô xếp dọc, nút nằm giữa và mũi tên xoay thành lên xuống; đây là hai ô select thường.
Cặp thẻ chọn quỹ
Từ
Đến
Mỗi bên là một nhóm thẻ gọn (hai nhóm radio có tên khác nhau, cùng giá trị value); nút đổi chiều đổi quỹ đã chọn của hai bên.
Chip và tag
Chip là nút nhỏ bấm được (bộ lọc, chọn một, đường dẫn); tag là nhãn chỉ đọc nói trạng thái hoặc mức thay đổi.
.chip bấm được: bật tắt một bộ lọc (aria-pressed), chọn một trong nhóm (role="radio" trong .chip-group[role="radiogroup"]), hoặc dẫn đi (a.chip); thêm .chip-count, .chip-group-scroll, .chip-add, .chip-value + .chip-x cho giá trị đang lọc. .tag chỉ đọc, không bấm: -ok-warn-bad-info, -draft nét đứt, -solid nền đặc, -bare không nền, -lg cỡ lớn, .delta cho mức tăng giảm. Tag luôn có chữ (và thường biểu tượng) đi kèm, màu không đứng một mình. Dòng đầu bảng có chip mã (.code-chip) và bộ lọc .filter-active xem ở phần Panel, bảng và Filter bar. Hai kiểu khác của cùng tag: -solid (đặc) cho một trạng thái cần nặng hơn các trạng thái còn lại trong cột, ví dụ phiếu đã phát hành; -bare (không nền, không viền) cho cột mà dòng nào cũng có nhãn thì bảng rối, ví dụ kết luận đặt cạnh trạng thái; nó là cùng nhãn, cùng cỡ chữ. Nhãn kết quả khác nhau bằng hình chứ không chỉ bằng màu: tròn có dấu tích (đạt), vuông có dấu X (không đạt), tròn nét đứt (chưa đủ số liệu), thoi (không đánh giá), tròn gạch chéo (đã hủy). Màu của trạng thái chờ do tenant chọn: mặc định -warn và clock, nhưng tenant có hai trạng thái cần chú ý (chờ duyệt và bị trả lại) có thể cho chờ duyệt -info và bị trả lại -warn, rồi giữ nguyên ở mọi nơi.
Chip: chọn một và tag lớn
Tất cảChờ duyệtĐã duyệt
Tag lớn
Tag: nhãn trạng thái, nhãn đặc, huy hiệu tăng giảm
Đã duyệtChờ duyệtBị từ chốiThông tinBản nhápĐã hủyĐạtKhông đạtChưa đủ số liệuKhông đánh giáNhãn trạng thái: .tag + -ok -warn -bad -info, .tag-draft nét đứt, icon đứng trước chữ. Bốn nhãn cuối là .tag-bare: cùng nhãn, cùng cỡ chữ, bỏ nền và viền, mỗi kết quả một hình riêng
Đã phát hànhĐạtCần xem lạiKhông đạtChờ duyệtNhãn đặc: .tag-solid, một mình là màu mực
Tăng 24,6%Giảm 7,1%Không đổi 0,0%Huy hiệu tăng giảm: .tag.delta
Chip có số đếm, hàng cuộn, chip thêm và chip đường dẫn
Bốn thứ nhỏ cho bộ lọc trên điện thoại: số đếm trong chip, hàng chip cuộn ngang một dòng, chip “+ Thêm tổ” và chip dẫn đến danh sách đã lọc.
.chip-count đứng sau nhãn trong .chip: chữ số đều bề rộng, nét nhẹ hơn nhãn, cùng màu với chip nên đọc được cả trên chip đang chọn; khi số cần một từ cho trình đọc màn hình thì đặt .visually-hidden trong đó (“20 việc đang làm”). .chip-group.chip-group-scroll giữ cả nhóm trên một dòng và cuộn ngang (role="radiogroup" hoặc role="group" kèm aria-label); chip cuối trong tầm nhìn nên bị mép cắt để thấy hàng còn dài. Đệm quanh hàng giữ cho vòng focus của chip đầu và cuối không bị cắt, margin âm trả lại chỗ (hàng nhô ra 8 px mỗi bên, nên đặt trong lề trang hoặc đệm của thẻ). Hàng chip có thể focus (radio, nút, liên kết) đã vào được bằng bàn phím và tự cuộn theo chip đang focus; chỉ thêm tabindex="0" cho hàng khi không chip nào nhận được focus. Đưa chip đang chọn vào tầm nhìn khi lựa chọn đổi từ nơi khác (scrollIntoView({ block: "nearest", inline: "nearest" })) là việc của tenant. .chip.chip-add là chip làm một việc (“+ Thêm tổ”): nét đứt, icon dấu cộng, màu liên kết; là button type="button", không có aria-checked hay role="radio", nên khi đứng cuối hàng thì hàng là role="group" chứa .chip-group[role="radiogroup"] rồi đến nút. Khác .chip-dashed là chip giá trị. a.chip là chip dẫn đi đâu đó: cùng dáng, cùng chiều cao --tap khi chạm, không gạch chân. Mọi chip mới đều mang lớp .chip nên đã nằm trong quy tắc cao --tap của con trỏ thô.
Bộ lọc trạng thái có số đếm
Tất cả24 ngườiĐang làm20 ngườiĐã nghỉ4 người
.chip-count sau nhãn; chữ ẩn “người” cho trình đọc màn hình. Bấm hoặc dùng phím mũi tên để đổi.
Mười chip trên một dòng trong khung 32 rem (hẹp hơn nữa ở điện thoại): cuộn ngang, thanh cuộn mảnh. Chọn chip bằng phím mũi tên thì hàng tự cuộn tới chip đó.
.chip-add là nút (không phải radio) ở cuối hàng: nét đứt, dấu cộng, màu liên kết. Cuộn đến cuối hàng để thấy nó; các chip radio nằm trong .chip-group[role="radiogroup"] riêng.
a.chip với biểu tượng cảnh báo và số đếm: cùng dáng với chip thường, không gạch chân, cao --tap khi chạm. Biểu tượng và chữ nói đây là việc có vấn đề, màu không đứng một mình.
Checklist: dòng việc có nút, nút tick, ảnh
Danh sách việc để tích, nút tròn 56px cho tay ướt và ảnh minh chứng có trạng thái.
Dòng việc là li.work-row: phần chữ là liên kết mở dòng, nút tích nằm riêng ở mép phải ở mọi độ rộng. Việc cần ảnh hiện nút máy ảnh thay cho nút tích, để người làm không gặp nút bấm mà không có tác dụng. Mỗi ảnh nói trạng thái bằng chữ, không chỉ bằng màu viền.
Mép trái có vạch màu theo data-tone (Trễ, Chưa đạt); thẻ trạng thái luôn nói bằng chữ. Nút tích không co lại khi thẻ hẹp.
Nút tick
Chưa tích, đã tích (aria-pressed="true"), chụp ảnh (.tick-primary) và bị khóa (aria-disabled="true").
Ảnh thu nhỏ
Sàn khu khách
Ảnh 1 · nhận 14:32
Quầy pha chế
Ảnh 2 · đang gửi
Nhà vệ sinh
Chưa gửi được
Đã nhận, đang gửi (thanh tiến độ .bar) và lỗi (viền đỏ, chữ nói rõ và nút Thử lại). Ảnh thật là <img> trong .thumb-img.
.thumb-list-sm: bốn ảnh trên một hàng ở điện thoại.
Ảnh vuốt ngang
Sàn khu khách
Ảnh 1 trên 3 · nhận 14:32
Quầy pha chế
Ảnh 2 trên 3 · nhận 14:33
Nhà vệ sinh
Ảnh 3 trên 3 · nhận 14:35
.media-strip: mỗi ảnh rộng 86% hàng (tối đa 26rem) nên ảnh kế hiện ở mép; vuốt bằng tay, hoặc Tab vào hàng rồi dùng phím mũi tên. Chữ dưới ảnh nói đó là ảnh nào và nhận lúc nào.
Thẻ đóng mở
Khu vực tầng 1
4 việc, đã xong 3
Lau quầy, quét sàn, đổ rác, kiểm tra nhà vệ sinh.
Khu vực tầng 2
6 việc, chưa bắt đầu
Sắp xếp bàn ghế, lau cửa kính, hút bụi hành lang.
details.panel.panel-fold không cần script: summary.panel-head giữ tiêu đề, dòng phụ .panel-sub và biểu tượng .panel-caret ở cuối; .panel-body là phần mở ra. Thêm open để mở sẵn. Đóng thì đầu thẻ không có đường kẻ dưới; mở thì mũi tên quay lên.
KPI card và số liệu tổng quan
Một con số kèm tên, mức thay đổi so với kỳ trước và một dòng giải thích, cho đầu trang tổng quan.
.kpi-row xếp nhiều thẻ trên lưới (mỗi thẻ từ 13rem). Trong .kpi chỉ có ba phần: .kpi-head (.kpi-label và .kpi-icon nếu cần), .kpi-value (số lớn, .kpi-unit cho đơn vị) và .kpi-foot (huy hiệu .tag.delta, chữ ngữ cảnh, thanh .bar nếu có tiến độ). Ba phần này giúp các thẻ cùng hàng thẳng hàng với nhau. Thẻ là <a> khi bấm vào mở danh sách sau con số. data-tone="ok|warn|danger" thêm vạch ở mép trái, dày bằng vạch của notice; chữ ở .kpi-foot nói cùng điều đó nên màu không đứng một mình. Số luôn nằm trên một dòng: từ 100.000 trở lên viết gọn (k nghìn, M triệu, B tỷ, một số lẻ, dấu phẩy), số đầy đủ để trong .visually-hidden cho trình đọc màn hình và title cho chuột. Một hàng viết cùng một kiểu, nên cả hàng viết gọn khi có một thẻ cần. Nếu thẻ là cái chuyển nội dung bên dưới, dùng .kpi-tabs. .kpi-value đọc --font-figure (kiểu chữ riêng cho con số của tenant); không đặt thì dùng chữ của trang.
Thẻ thứ hai và thứ ba là liên kết (rê chuột đổi nền) và có vạch màu; thẻ đầu và thẻ cuối không phải liên kết. Số tiền từ 100.000 trở lên viết gọn nên không bị xuống dòng. Huy hiệu tăng giảm dùng .tag.delta của kit: ở thẻ công nợ, giảm là tốt nên huy hiệu để màu xanh.
Tiền mặt tại quỹ cửa hàng chính
845.200₫
Giảm 4,2% so với tháng 9, thấp nhất từ đầu năm
Mẫu đạt
94,2%
Đạt mục tiêu
Hai thẻ cùng hàng, tên thẻ đầu dài hai dòng và dòng chân dài hơn: thẻ cao bằng nhau, số và dòng chân của hai thẻ vẫn thẳng hàng. Số dưới 100.000 viết đủ.
Chỗ đặt biểu đồ hoặc bảng doanh thu theo ngày của tháng 10.
Chỗ đặt biểu đồ hoặc bảng số phiếu nhập kho theo ngày của tháng 10.
Chỗ đặt biểu đồ hoặc bảng công nợ phải thu theo khách hàng.
.kpi-tabs: các thẻ là bộ chuyển cho phần bên dưới. Thẻ đang chọn nổi lên trên nền chìm, như .seg; bấm hoặc dùng phím mũi tên, Home, End để đổi. Thẻ là <button role="tab"> nên ba phần bên trong viết bằng <span>, và không dùng data-tone ở đây.
Thẻ trạng thái có nút
Đã vào ca
7:18
Ca sáng 7:00 – 15:00, đã làm 3 giờ 12 phút
Giờ làm hôm nay
0giờ
Chưa vào ca
Mạng đang dùng
Wifi quán
Chưa khớp mạng cửa hàng đã lưu, nên chưa thể vào ca
.kpi-action đặt sau .kpi-foot, chứa một hoặc hai .btn. Thẻ có nút là div.kpi, không phải a.kpi. Trong một hàng, thẻ không có nút vẫn cao bằng thẻ có nút và số vẫn thẳng hàng, chỉ thừa chỗ dưới dòng chân.
Con số đủ đồng, vừa thẻ
Sổ tiền cần số đầy đủ ("549.500.000 đ"), nên con số thu nhỏ cho vừa thẻ thay vì viết gọn hoặc tràn.
.kpi-value.kpi-value-fit: con số vẫn một dòng, cỡ chữ tự co theo bề rộng của chính thẻ (container query, không script) từ --fs-3xl xuống tối thiểu --fs-md. Mặc định tính cho 14 ký tự (chữ số, dấu chấm và đơn vị); đặt --fit-chars trên .kpi-row (không đặt trên từng thẻ, để các thẻ cùng cỡ) khi số tiền ngắn hơn hoặc dài hơn: 12 cho "549.500.000 đ", 16 cho nghìn tỷ. Thẻ cần có bề rộng riêng (một ô của .kpi-row hoặc đặt width). .kpi-row-pair trên hàng đúng hai thẻ giữ hai thẻ cạnh nhau tới điện thoại hẹp nhất, nơi hàng thẻ bình thường xuống một thẻ một dòng. Số quá dài so với thẻ ở cỡ nhỏ nhất thì viết gọn: bộ k / tr / tỷ cho người dùng Việt (k nghìn, tr triệu, tỷ), xem COMPONENTS.md.
Hai thẻ cạnh nhau ở bề rộng điện thoại
Khách còn nợ mình
549.500.000đ
6 khách còn nợ
Mình còn nợ NCC
270.600.000đ
5 nhà cung cấp
Hàng 22rem (điện thoại) với .kpi-row-pair: hai thẻ vẫn ngang hàng, số vừa khít và không xuống dòng. Thiếu .kpi-row-pair thì dưới 27rem mỗi thẻ một dòng.
Hai thẻ ở bề rộng vừa và rộng
Quỹ tiền mặt
549.500.000đ
Sau phiếu hôm nay
Quỹ Vietcombank
1.270.600.000đ
Sau phiếu hôm nay
Quỹ tiền mặt
549.500.000đ
Sau phiếu hôm nay
Quỹ Vietcombank
1.270.600.000đ
Sau phiếu hôm nay
Cùng hai con số ở hàng 30rem và 44rem: càng rộng càng gần cỡ đầy đủ. Hai số dài ngắn khác nhau trong cùng hàng có cùng cỡ chữ, nên không lệch nhau.
Một thẻ lẻ, và số dài hơn mặc định
Tổng quỹ
1.549.500.000đ
Một thẻ lẻ rộng 22rem
Thẻ lẻ ở điện thoại còn chỗ rộng nên giữ cỡ đầy đủ. --fit-chars:16 báo trước số dài hơn mặc định để cỡ chữ không vượt thẻ; --fit-chars:12 trên hàng đầu tiên cho số 9 chữ số to hơn mức mặc định.
Bộ rút gọn tiếng Việt, khi chỉ cần liếc
Doanh thu quý 3
549,5tr549.500.000 đồng
tr = triệu
Doanh thu năm
2,34 tỷ2.340.000.000 đồng
tỷ = tỷ đồng
Bảng báo cáo, không phải sổ quỹ: số viết gọn bằng k (nghìn), tr (triệu), tỷ, kèm số đầy đủ cho trình đọc màn hình. Kit không tự định dạng số.
KPI: delta trung tính, thẻ nhấn mạnh, khối chờ tải
Ba bổ sung cho thẻ KPI: mũi tên delta không tốt không xấu (chi tăng 9,6%), thẻ cần nhấn mạnh hơn các thẻ khác, và khối chờ tải có chiều cao.
.tag.delta.delta-neutral: huy hiệu xu hướng chữ --muted trên nền --sunk, không sắc xanh hay đỏ, cho con số mà tăng hay giảm đều không tốt không xấu; mũi tên và chữ ẩn “Tăng ” / “Giảm ” vẫn có. .kpi[data-emphasis] (chỉ cần thuộc tính): thanh 4 px màu --primary ở đỉnh thẻ và con số lớn gấp 1,25 lần (cả giao diện app), nền vẫn --surface; là trọng lượng chứ không phải trạng thái nên không cần chữ đi kèm; chỉ nên một thẻ nhấn mạnh trong một hàng; có thể đi cùng data-tone. Màu được kiểm: chỉ --text và --primary trên --surface. span.skel-block là bản khối của .skel: --skel-w (mặc định 100%) và --skel-h (mặc định 3rem), nhịp nháy và màu của kit, tắt nhịp khi prefers-reduced-motion. Khối là trang trí: aria-hidden="true" trên từng khối, aria-busy="true" trên phần chứa chúng và một dòng .visually-hidden[role="status"] nói đang tải gì. Cách xếp khung chờ của một thẻ (ba phần của .kpi, các dòng của bảng) là việc của trang: đặt khối vào đúng thẻ hoặc bảng thật.
Delta tốt, xấu và trung tính
Doanh thu
128,5tr
Tăng 12,4%so với tháng 9
Nợ phải trả
86,0tr
Tăng 7,2%so với tháng 9
Tổng chi
66,1tr
Tăng 9,6%so với tháng 9
Doanh thu tăng là tốt (xanh), nợ phải trả tăng là xấu (đỏ), chi tăng thì chưa biết tốt hay xấu (xám: .delta-neutral). Mũi tên và chữ ẩn nói hướng ở cả ba.
Thẻ nhấn mạnh
Lãi gộp tạm tính
119,5tr
của 6 đơn giao, chưa gồm nhân công
Đơn nhận
9
trong quý 3
Quá hạn
2
Cần xemđơn chậm giao
Thẻ giữa là thẻ thường để so. Thẻ nhấn mạnh có thanh --primary ở đỉnh và số lớn hơn 1,25 lần; thẻ thứ ba có cả data-tone="danger" (thanh đỏ ở mép đầu, kèm chữ “Cần xem”).
Thẻ nhấn mạnh với số giữ nguyên cả số tiền (.kpi-value-fit)
Tiền mặt
549.500.000đ
cuối ngày 30/09
Ngân hàng
312.080.000đ
cuối ngày 30/09
Số vẫn vừa một dòng: kích thước tối đa của thẻ nhấn mạnh lớn hơn, nhưng không bao giờ rộng hơn thẻ.
Khối chờ tải: thẻ KPI và bảng
Đang tải số liệu
Đang tải danh sách phiếu
Khối trong khung thẻ KPI (ba khối cao 1, 2,25 và 1 rem) và ba khối cao 3 rem xếp như dòng bảng, khối cuối ngắn hơn (--skel-w: 70%). Nhịp nháy dừng khi người dùng chọn giảm chuyển động.
Dải tóm tắt
Dải phẳng hai đến bốn ô trong một panel: tên mờ phía trên, con số phía dưới, ngăn nhau bằng đường kẻ mảnh; không biểu tượng, không bóng đổ. Ba ô vẫn một hàng ở phone.
dl.stat-strip > div.stat-strip-item > dt (tên, mờ, được xuống dòng) + dd (con số: --font-figure, số cùng độ rộng, không bao giờ xuống dòng; đặt .num-in, .num-out, .num-neg trên span bên trong, dấu viết trong chữ với dấu trừ thật; một dd được chứa hai con số, chúng xuống dòng ở giữa). Hai hoặc ba ô luôn nằm một hàng: ô co lại, dt xuống hai dòng, cỡ chữ con số tự giảm theo bề rộng của dải (container query, không script) từ --fs-lg xuống --fs-sm, không nhỏ hơn; --fit-chars báo độ dài khác 14 ký tự. Bốn ô xếp hai nhân hai khi dải hẹp hơn 24rem. .stat-strip-item-total cho ô quan trọng nhất: con số đậm hơn, dt màu chữ chính. Dải là container nên cần bề rộng riêng: là khối trong panel, không phải phần tử flex co theo nội dung. Màu: chỉ --text, --muted, --ok, --danger trên --surface, đã được kiểm.
Thu, chi, chênh lệch (ô cuối đậm, màu theo dấu)
Quý 3 năm 2026
Thu
+ 108.600.000đ
Chi
− 66.072.000đ
Chênh lệch
+ 42.528.000đ
Ba ô một hàng ở mọi bề rộng. Chênh lệch dương dùng .num-in (xanh, có dấu “+”).
Chênh lệch âm, số dài nhất
Tháng 10 năm 2026
Thu
+ 24.800.000đ
Chi
− 37.200.000đ
Chênh lệch
− 12.400.000đ
“− 12.400.000 đ” còn nguyên một dòng trong ô khoảng 100 px ở phone nhờ cỡ chữ tự giảm. Số âm dùng .num-neg (đỏ); dấu trừ vẫn nằm trong chữ.
Đầu kỳ, vào / ra, cuối kỳ (số thường, một ô có hai số)
Tiền mặt ngày 30/09
Đầu 29/09
5.380.000đ
Vào / ra
+29,6tr−16,5tr
Cuối 30/09
18.450.000đ
Số không có dấu thì không cần lớp. Ô “Vào / ra” có hai số, mỗi số không xuống dòng, hai số có thể xuống dòng ở giữa khi ô hẹp.
Bốn ô (hai nhân hai khi hẹp hơn 24rem) và hai ô
Đơn hàng DH-2026-0031
Giá trị
225.000.000đ
Đã thu
+ 135.000.000đ
Còn phải thu
90.000.000đ
Lãi gộp tạm tính
+ 91.702.000đ
Bốn ô: một hàng khi dải rộng từ 24rem, hai nhân hai khi hẹp hơn (như ở phone).
Tổng chi Thuê ngoài gia công
− 62.400.000đ
Số phiếu
14phiếu
Hai ô, tên dài xuống hai dòng, con số vẫn nằm sát đáy ô nên các số thẳng hàng.
Trong khung hẹp: 21rem còn một hàng, 15rem thành từng dòng
Thu
+ 108.600.000đ
Chi
− 66.072.000đ
Chênh lệch
+ 42.528.000đ
Khung 21rem (dải khoảng 18rem): ba ô vẫn một hàng, con số giảm tới cỡ nhỏ nhất (--fs-xs).
Thu
+ 108.600.000đ
Chi
− 66.072.000đ
Chênh lệch
+ 42.528.000đ
Khung 15rem: dải hẹp hơn 17,5rem thì ba con số không còn đủ chỗ cạnh nhau, mỗi ô thành một dòng (tên ở đầu, số ở cuối) thay vì chồng lên nhau.
Ô có tone: số liệu có ngưỡng
Kiểm tra dữ liệu nhập
Đạt
284
Cảnh báo
12
Lỗi
3
data-tone="ok|warn|bad" trên .stat-strip-item tô màu con số (như tone của thẻ KPI); tên ô vẫn nói nghĩa bằng chữ (Đạt, Cảnh báo, Lỗi) nên màu không đứng một mình.
Số và mã chứng từ
Thu, chi, số dư âm và số của phiếu đã hủy, để mắt đọc nghĩa của con số ngay trong sổ.
.num-in (xanh: tiền hoặc hàng vào), .num-out (màu chữ: ra), .num-neg (đỏ: số dư dưới 0), .num-void (mờ, gạch ngang: phiếu đã hủy) đứng trên td.num, trên span trong dòng danh sách hoặc trên .kpi-value. Dấu viết trong chữ (+ 1.250.000, − 350.000 với dấu trừ thật U+2212 và dấu cách không ngắt sau dấu) và loại phiếu nằm ở tiêu đề cột hoặc trong một chữ .visually-hidden, nên màu không phải dấu hiệu duy nhất. .num-unit là đơn vị sau con số (đ, kg), nhỏ hơn một bậc. Gõ --font-figure trong tokens.json của tenant nếu con số dùng kiểu chữ hẹp hơn chữ thường. Font Barlow không có ký hiệu ₫: viết đ.
Sổ quỹ tiền mặt
Quý 3 · 2026
Diễn giải
Ngày
Thu
Chi
Số dư
Khách Tuấn Phát trả đợt 2
30/09/2026
+ 12.450.000đ
18.450.000đ
Mua que hàn, đá cắt
30/09/2026
− 350.000đ
6.000.000đ
Ứng lương tháng 9 (vượt số dư)
29/09/2026
− 7.200.000đ
− 1.200.000đ
Mua nhầm ống 40 Đã hủy
28/09/2026
− 90.000đ
Trong bảng dạng thẻ (.tbl-cards, đọc được trên điện thoại): tiêu đề cột Thu và Chi nói loại phiếu, dấu +/− nằm trong số. Dòng đã hủy dùng .num-void cho từng số khi dòng không phải tr.row-void.
Quỹ Vietcombank
− 1.200.000đ
Đã chi quá số dư 2 phiếu
Quỹ tiền mặt
+ 18.450.000đ
Còn sau phiếu hôm nay
Trên thẻ KPI: .num-neg đi với data-tone="danger" và câu chữ nói rõ, nên màu không đứng một mình.
Mã chứng từ
Số phiếu hoặc mã đơn viết bằng chữ đơn cách, không xuống dòng, có bản nền đậm cho số ở đầu phiếu.
.doc-code: chữ --font-mono, đậm, số cùng độ rộng, một dòng, không khung, để mã đọc ra là mã khi nằm trong tiêu đề, ô bảng hay dòng danh sách. .doc-code-solid: cùng mã đó trên tấm nền đậm (nền --heading, chữ --surface, cặp màu đã được check-palette.mjs kiểm đạt AA ở cả 7 bảng màu) cho số ở đầu phiếu. Không phải .code-chip (khung nhỏ cho mã 2–4 ký tự). Khi in, tấm nền thành khung viền cùng màu chữ vì trình duyệt thường không in nền.
Trong tiêu đề
Phiếu chi PC-2026-0412
Đơn hàng DH-2026-0087
Cỡ chữ theo tiêu đề quanh nó. .doc-code-solid cho số ở đầu phiếu, .doc-code khi mã chỉ là một phần của dòng.
Ở bảng thẻ (.tbl-cards) mã đứng ở ô đầu th[scope="row"]; trong dòng việc nó đứng trước tên, trên một dòng, không bị cắt.
Avatar
Avatar chữ cái đầu hoặc ảnh, chấm trạng thái, nhóm và ghép với tên.
.avatar (-xs -sm -lg -xl, -square, màu -primary -ok -warn -bad -info) chứa chữ cái đầu hoặc <img>; .avatar-dot báo trạng thái trực tuyến (ghi chữ trong .visually-hidden, vì màu một mình không nói gì); .avatar-group chồng nhiều người; .avatar-label ghép avatar với tên và một dòng phụ. Cạnh tên thì avatar chỉ để trang trí (aria-hidden="true", alt=""); đứng một mình cần role="img" và aria-label. Chữ cái đầu do tenant tính.
Cột nhóm Thu/Chi theo tháng vẽ bằng HTML và CSS (không SVG, chữ không co theo khung): chú giải, trục, vạch cùng kỳ năm trước; trên điện thoại biểu đồ cuộn ngang trong khung riêng, bảng số liệu đi kèm là nội dung thật.
figure.chart-cols (tên khác .chart của giao diện app, nên hai bên không đụng nhau) gồm figcaption.cc-title, ul.cc-legend (mỗi mục là span.cc-swatch[data-series="1"] cùng một chữ: Thu, Chi; mục cuối .cc-swatch-prev “Cùng kỳ năm trước”), rồi .cc-scroll > .cc-body > ol.cc-axis[aria-hidden] (mỗi li là một mốc, style="--t:.5" là vị trí từ 0 đến 1 của giá trị lớn nhất) và .cc-plot > .cc-group (một tháng) > .cc-cols > .cc-col[data-series][style="--v:.78"] (span, hoặc a khi cột là đường dẫn; bên trong có span.visually-hidden đọc giá trị và, nếu có, span.cc-mark[style="--v:.62"] là vạch cùng kỳ năm trước), kèm .cc-label (“T9”). --v là tỉ lệ so với giá trị lớn nhất của trục (0 đến 1); --cc-rows (mặc định 4) là số khoảng của đường kẻ ngang, phải khớp với các mốc của trục; --cc-h, --cc-group-w, --cc-col-max chỉnh chiều cao, bề rộng tối thiểu của nhóm và bề rộng tối đa của cột. Màu lấy từ --series-1 đến --series-4 và --series-prev của bảng màu (mọi bảng màu đặt đủ, qua cổng 3:1 trên --surface và --bg); màu không đứng một mình: chuỗi 1 đặc, chuỗi 2 sọc chéo, chuỗi 3 chấm, chuỗi 4 sọc dọc, chú giải lặp lại cả mẫu lẫn chữ. Hỗ trợ đọc: lời của biểu đồ nằm ở .cc-plot[role="img"][aria-label] (đọc cả chuỗi bằng chữ), không ở figure, vì khung cuộn phải focus được (tabindex="0", role="region", aria-label; thêm khi biểu đồ có thể cuộn, tức nhiều nhóm hơn mức vừa khổ hẹp nhất) mà bên trong role="img" không được có phần tử focus. Khi cột là đường dẫn thì .cc-plot là role="group" và mỗi liên kết có tên từ chữ .visually-hidden của nó. Nội dung thật là bảng số liệu: luôn đặt một table (hiện, hoặc .visually-hidden) ngay sau biểu đồ. Dưới ngón tay cột liên kết rộng ít nhất --tap; trục dính ở mép đầu khi cuộn, không bao giờ cuộn cả trang. Biểu đồ trống không có .cc-group, chỉ có p.cc-empty.
Thu và chi 12 tháng, kèm vạch cùng kỳ năm trước
Thu và chi theo tháng, năm 2026 (triệu đồng)
Thu
Chi
Cùng kỳ năm trước
0
100 tr
200 tr
300 tr
400 tr
500 tr
Thu tháng 1: 248 triệu, cùng kỳ năm trước 230 triệuChi tháng 1: 201 triệu, cùng kỳ năm trước 190 triệu
T1
Thu tháng 2: 262 triệu, cùng kỳ năm trước 251 triệuChi tháng 2: 219 triệu, cùng kỳ năm trước 205 triệu
T2
Thu tháng 3: 291 triệu, cùng kỳ năm trước 274 triệuChi tháng 3: 236 triệu, cùng kỳ năm trước 221 triệu
T3
Thu tháng 4: 305 triệu, cùng kỳ năm trước 288 triệuChi tháng 4: 262 triệu, cùng kỳ năm trước 240 triệu
T4
Thu tháng 5: 338 triệu, cùng kỳ năm trước 310 triệuChi tháng 5: 274 triệu, cùng kỳ năm trước 255 triệu
T5
Thu tháng 6: 347 triệu, cùng kỳ năm trước 320 triệuChi tháng 6: 290 triệu, cùng kỳ năm trước 270 triệu
T6
Thu tháng 7: 352,4 triệu, cùng kỳ năm trước 340 triệuChi tháng 7: 281,3 triệu, cùng kỳ năm trước 268 triệu
T7
Thu tháng 8: 421,5 triệu, cùng kỳ năm trước 380 triệuChi tháng 8: 322,5 triệu, cùng kỳ năm trước 300 triệu
T8
Thu tháng 9: 312,5 triệu, cùng kỳ năm trước 330 triệuChi tháng 9: 238,9 triệu, cùng kỳ năm trước 255 triệu
T9
Thu tháng 10: 396 triệu, cùng kỳ năm trước 370 triệuChi tháng 10: 301 triệu, cùng kỳ năm trước 285 triệu
T10
Thu tháng 11: 408 triệu, cùng kỳ năm trước 385 triệuChi tháng 11: 318 triệu, cùng kỳ năm trước 298 triệu
T11
Thu tháng 12: 452 triệu, cùng kỳ năm trước 420 triệuChi tháng 12: 361 triệu, cùng kỳ năm trước 330 triệu
T12
Thu và chi theo tháng năm 2026, triệu đồng
Tháng
Thu 2026
Thu 2025
Chi 2026
Chi 2025
T1
248
230
201
190
T2
262
251
219
205
T3
291
274
236
221
T4
305
288
262
240
T5
338
310
274
255
T6
347
320
290
270
T7
352,4
340
281,3
268
T8
421,5
380
322,5
300
T9
312,5
330
238,9
255
T10
396
370
301
285
T11
408
385
318
298
T12
452
420
361
330
Hai chuỗi, mười hai nhóm: ở khổ điện thoại biểu đồ cuộn ngang trong khung của nó (khung có tabindex="0" để cuộn bằng bàn phím), trục tung dính ở mép trái, chữ nhãn vẫn 12 px. Vạch đậm trên mỗi cột là cùng kỳ năm trước. Bảng bên dưới là nội dung thật.
Quý 3, ba nhóm: ở khổ rộng vừa khít, ở khổ điện thoại cuộn nhẹ trong khung (có tabindex), vì mỗi cột liên kết rộng ít nhất 44 px. Mỗi cột là a.cc-col (rê chuột thì nền cột đậm lên, Tab thì có khung focus; dưới ngón tay mỗi cột rộng ít nhất 44 px). .cc-plot là role="group", mỗi liên kết có tên “Thu tháng 7: 352,4 triệu, cùng kỳ năm trước 340 triệu”.
Chưa có số liệu
Thu và chi tháng 11 năm 2026 (triệu đồng)
Thu
Chi
0
Chưa có phiếu thu hay phiếu chi trong kỳ này.
Thu và chi tháng 11 năm 2026
Tháng
Thu
Chi
Chưa có số liệu trong kỳ.
Kỳ chưa có phiếu: giữ trục và chú giải, trong vùng vẽ có một câu p.cc-empty và aria-label nói rõ chưa có số liệu; bảng bên dưới cũng nói như vậy.
Một chuỗi
Chi vật tư theo tháng, quý 2 và quý 3 (triệu đồng)
Chi vật tư
Cùng kỳ năm trước
0
50 tr
100 tr
150 tr
200 tr
Chi vật tư tháng 4: 120 triệu, cùng kỳ năm trước 110 triệu
T4
Chi vật tư tháng 5: 140 triệu, cùng kỳ năm trước 150 triệu
T5
Chi vật tư tháng 6: 160 triệu, cùng kỳ năm trước 140 triệu
T6
Chi vật tư tháng 7: 155 triệu, cùng kỳ năm trước 160 triệu
T7
Chi vật tư tháng 8: 172 triệu, cùng kỳ năm trước 150 triệu
T8
Chi vật tư tháng 9: 138 triệu, cùng kỳ năm trước 145 triệu
T9
Chi vật tư theo tháng, triệu đồng
Tháng
Năm 2026
Năm 2025
T4
120
110
T5
140
150
T6
160
140
T7
155
160
T8
172
150
T9
138
145
Một chuỗi (chi vật tư) với vạch cùng kỳ năm trước; chú giải vẫn có chữ, trục tối đa 200 triệu. Sáu nhóm vẫn có khung cuộn có tên, vì ở khổ hẹp chúng không vừa.
Bốn chuỗi: bốn kiểu tô
Chi theo nhóm, quý 3 năm 2026 (triệu đồng)
Vật tư
Lương
Thuê ngoài
Khác
0
50 tr
100 tr
150 tr
200 tr
Vật tư tháng 7: 150 triệuLương tháng 7: 80 triệuThuê ngoài tháng 7: 20 triệuKhác tháng 7: 31 triệu
T7
Vật tư tháng 8: 180 triệuLương tháng 8: 90 triệuThuê ngoài tháng 8: 35 triệuKhác tháng 8: 17 triệu
T8
Vật tư tháng 9: 120 triệuLương tháng 9: 85 triệuThuê ngoài tháng 9: 18 triệuKhác tháng 9: 16 triệu
T9
Chi theo nhóm, quý 3 năm 2026, triệu đồng
Tháng
Vật tư
Lương
Thuê ngoài
Khác
T7
150
80
20
31
T8
180
90
35
17
T9
120
85
18
16
Cả bốn mẫu tô: đặc, sọc chéo, chấm, sọc dọc; kể cả khi in đen trắng hay với người khó phân biệt màu, chú giải và mẫu tô vẫn cho biết cột nào là chuỗi nào.
Danh sách xếp hạng có thanh
Các khoản lớn nhất xếp từ trên xuống: tên và dòng phụ, một thanh ngang, con số bên phải; trên điện thoại thanh nằm dưới tên. Cả dòng là một liên kết.
ul.rank-list (hoặc ol khi thứ tự quan trọng) > li > a.rank-row (div.rank-row khi dòng không dẫn đi đâu) gồm span.rank-no (tùy chọn: hạng, mờ, số căn đều; aria-hidden="true"), span.rank-name (đậm, được xuống dòng), span.rank-sub (tùy chọn, mờ: “Trả nhà cung cấp · 42 phiếu”), span.bar.rank-bar[aria-hidden="true"] (chính là .bar của bộ kit, bề rộng lấy từ --v: phần trăm so với dòng lớn nhất) và span.rank-val (con số kèm .num-unit, không xuống dòng, dùng --font-figure). Cả dòng là liên kết: cao ít nhất --tap, rê chuột thì nền --surface-hover, khung focus của bộ kit vẽ bên trong dòng; chữ vẫn là --text và --muted, hai màu đã qua cổng trên nền khi rê chuột. Màu thanh theo data-tone="ok|warn|bad" trên dòng, mặc định --primary; thanh chỉ là trang trí và lặp lại con số, nên trạng thái màu phải có chữ (trong .rank-sub hoặc một .visually-hidden trong tên). Khi danh sách rộng dưới 28 rem (@container của chính danh sách, không phải của cửa sổ) thanh xuống dưới tên và con số vẫn ở cuối dòng tên. Danh sách là container-type: inline-size, nên cần có bề rộng của cột chứa nó.
Mỗi dòng là liên kết tới các phiếu tạo ra con số (thanh là tỉ lệ so với khoản lớn nhất, 386,2 triệu). Hạng nằm trong .rank-no (aria-hidden, vì danh sách là ol).
Trái: a.rank-row, rê chuột hoặc Tab thì thấy nền và khung focus. Phải: div.rank-row, không có nền khi rê chuột, không có .rank-no và không có dòng phụ.
data-tone “ok”, “warn”, “bad” đổi màu thanh; trạng thái vẫn được nói bằng chữ trong dòng phụ (“Vượt định mức 12%”) và trong chữ ẩn của tên. Thanh “bad” đầy vì đã tới 100% bề rộng, con số ghi 112%.
Ngay trên máy tính, một cột rộng 20 rem (dưới 28 rem) đã dùng cách xếp của điện thoại: thanh nằm dưới tên, con số vẫn ở cuối dòng tên. Quy tắc theo bề rộng của danh sách, nên cột bên của một trang rộng cũng được.
Tên dài thì xuống dòng và không đẩy con số hay thanh ra ngoài; con số luôn trên một dòng.
Thanh tỉ lệ (100 %)
Các phần của một tổng nằm cạnh nhau trên một thanh: xếp loại của một đơn vị, trạng thái phiếu của một kỳ. Mỗi dòng bảng một thanh, các thanh tự thẳng hàng; có dòng tổng, đoạn là liên kết và trạng thái chưa có đánh giá.
div.share-bar (role="img" và một câu đủ số ở aria-label, hoặc role="group" khi đoạn là liên kết; data-tip-title là dòng đầu tooltip) > span.share-seg hoặc a.share-seg với style="--v:.034" (tỉ lệ thô, không phải số đã làm tròn), màu theo data-grade="1..5", data-tone hoặc data-series, data-tip là dòng của đoạn trong tooltip. .share-bar-lg cao 24px với span.share-lab trong đoạn; .share-bar-empty > span.share-empty khi mẫu số là 0. Thang xếp loại --grade-1 (A+, xanh đậm, chữ trắng) đến --grade-5 (D, đỏ đậm); --grade-2 và --grade-3 là màu nhạt, dưới 3:1 trên nền trắng: được phép vì đoạn có chữ cái hoặc bảng có số, khe 2px tách hai đoạn và chú giải gọi tên.
Một thanh có chữ trong đoạn
Trạm cấp cứu mỏ Hạ Long, Tháng 9/2026
A+ABC
A+
A
B
C
58 người được đánh giá: A+ 3, A 47, B 5, C 3. .share-bar-lg cao 24px, chữ cái nằm trong đoạn (màu chữ là cặp --on-grade-n); đoạn nào hẹp hơn chữ cộng 4px mỗi bên thì kit.js ẩn chữ (ở khổ điện thoại đoạn A+ và C chỉ còn màu), tooltip và chú giải vẫn nói. Rê chuột lên một đoạn: “Trạm cấp cứu mỏ Hạ Long · C · 3 người · 5,2 %”.
Mỗi đơn vị một dòng, có dòng tổng
Xếp loại Tháng 9/2026 theo đơn vị
Đơn vị
Được đánh giá
A+
A
B
C
Tỷ lệ
Ban Giám đốcBGĐ
3
00,0 %
3100,0 %
00,0 %
00,0 %
Phòng Tổ chức - Hành chínhP.TCHC
15
16,7 %
1386,7 %
16,7 %
00,0 %
Phòng Kế toán - Tài chínhP.KTTC
7
114,3 %
685,7 %
00,0 %
00,0 %
Phòng Kiểm định - Thử nghiệm và Bảo dưỡng thiết bị cứu hộ mỏP.KĐTN
8
00,0 %
675,0 %
225,0 %
00,0 %
Trạm cấp cứu mỏ Hạ LongTrạm HL
58
35,2 %
4781,0 %
58,6 %
35,2 %
Trạm cấp cứu mỏ Cẩm PhảTrạm CP
60
46,7 %
5083,3 %
58,3 %
11,7 %
Tổ xeTổ xe
14
17,1 %
1178,6 %
214,3 %
00,0 %
Đội cứu hộ Vàng Danh (mới thành lập)Đội VD
0
–
–
–
–
Chưa có đánh giá
Toàn trung tâm
165
106,1 %
13682,4 %
159,1 %
42,4 %
A+ABC
Thanh nằm trong td nên các thanh của một cột tự thẳng hàng; dòng tổng ở tfoot dùng .share-bar-lg. P.TCHC in ra 6,7 + 86,7 + 6,7 = 100,1 % nhưng độ rộng theo tỉ lệ thô (--v) nên vẫn đúng. Đội Vàng Danh chưa có đánh giá: .share-bar-empty với chữ, không NaN, không thanh rỗng. Trong bảng thanh mang aria-hidden="true" vì các ô đã đọc đủ số; thanh đứng riêng thì là role="img" với câu đầy đủ. Ở 390px bảng cuộn ngang trong khung của nó.
Mỗi đoạn là a.share-seg có aria-label riêng, nên thanh là role="group"; Tab đi qua từng đoạn và khung focus hiện cùng tooltip với khi rê chuột. Màu là tone của kit (data-tone: ok, warn, info, draft có gạch chéo, muted), chữ trong đoạn là --text. Dưới ngón tay thanh có liên kết cao ít nhất 24px.
Đoạn rất nhỏ và chưa có đánh giá
Chờ đánh giá 1 trên 196 phiếu (0,51 %)
Đã đánh giá 195Chờ đánh giá 1
Đơn vị chưa có phiếu nào được đánh giá
Chưa có đánh giá
Chưa có đánh giá
Một đoạn trên 0 luôn rộng ít nhất 3px, nên 0,51 % vẫn thấy (rộng hơn tỉ lệ thật một chút, tooltip và bảng ghi đúng số). Mẫu số bằng 0: đường viền đứt và một câu, ở cả hai cỡ.
Thanh trọng số so với mốc
Trọng số các tiêu chí trên một thang tuyệt đối, vạch mốc 100, phần vượt có gạch đỏ; sửa trọng số thì thanh cập nhật ngay.
.share-bar.share-bar-abs: rãnh --sunk là cả thang do tác giả chọn (tổng 105 thì thang 105); --v của đoạn là phần của thang. span.share-target[style="--at:.952"] > span.share-target-lab “100”: vạch 2px --text nhô 4px trên và dưới thanh, nhãn ở trên. .share-seg.share-over: phần vượt mốc, --danger gạch chéo --danger-line. Khe 2px giữa các đoạn là viền --share-gap (mặc định --surface; đặt bằng nền của dòng khi dòng có màu).
Trọng số 105 trên thang 105, mốc 100
Bản giao Tháng 10/2026: Đinh Thị Hằng
TC1 30TC2 20TC3 15TC4 15TC5 15TC6 10100
105 % · thừa 5
Trọng số từng tiêu chí
TT
Tiêu chí
Trọng số %
TC1
Tổ chức, cán bộ của phòng
30
TC2
Đào tạo, huấn luyện cán bộ
20
TC3
Bảo hiểm, chế độ chính sách
15
TC4
Tỷ lệ hoàn thành kế hoạch đào tạo
15
TC5
Đánh giá KPI cho nhân viên phụ trách
15
TC6
Tuân thủ nội quy lao động, giờ giấc làm việc; đăng ký, cập nhật, tự đánh giá KPI tuần, tháng
10
Tổng
105
Thang là 105 nên mốc 100 nằm ở --at:.952; mỗi đoạn là trọng số chia 105. TC6 có 10, nửa đầu vừa dưới mốc, nửa sau là .share-over (đỏ, gạch chéo) và không có chữ: mốc và dòng “105 % · thừa 5” bên cạnh đã nói. Chữ “TC6 10” không vừa đoạn của nó nên bị ẩn; tooltip vẫn có.
Sửa trọng số, thanh cập nhật ngay
TC1 30TC2 20TC3 20TC4 15TC5 15100
100 % · đủ 100
Gõ số vào một ô: --v của từng đoạn và --at của mốc đổi theo, bề rộng trượt trong --dur-2 (không trượt khi bật giảm chuyển động); tổng trên 100 thì thang giãn ra và phần vượt hiện gạch đỏ, dưới 100 thì phần còn lại của rãnh --sunk để trống.
Cột có tương tác và cột chồng
Biểu đồ cột nhóm có tooltip, dải nền khi rê, chọn một nhóm và vạch ngưỡng; cột chồng có tổng ở tooltip. Bật thêm, không đổi hình của biểu đồ cột hiện có.
Bật bằng data-chart (và data-select) trên figure.chart-cols; số của tooltip lấy từ data-value trên từng .cc-col (hoặc phần sau dấu hai chấm của chữ ẩn), data-value trên .cc-mark thêm dòng cùng kỳ. .chart-cols.cc-stacked: cột chồng. div.cc-ref[style="--t:.8"] > span.cc-ref-lab: vạch tham chiếu trong .cc-plot. Không có data-chart thì không gì thay đổi.
Tooltip, dải nền khi rê, chọn một tháng, vạch ngưỡng
Điểm trung bình tháng, P.TCHC (điểm)
Tự đánh giá
Cấp trên
0
25
50
75
100
125
Tự đánh giá tháng 1: 99,5 điểmCấp trên tháng 1: 98,3 điểm
T1
Tự đánh giá tháng 2: 97,8 điểmCấp trên tháng 2: 96,4 điểm
T2
Tự đánh giá tháng 3: 98,9 điểmCấp trên tháng 3: 97,6 điểm
T3
Tự đánh giá tháng 4: 99,2 điểmCấp trên tháng 4: 98,0 điểm
T4
Tự đánh giá tháng 5: 98,1 điểmCấp trên tháng 5: 97,3 điểm
T5
Tự đánh giá tháng 6: 97,6 điểmCấp trên tháng 6: 96,8 điểm
T6
Tự đánh giá tháng 7: 95,4 điểmCấp trên tháng 7: 94,2 điểm
T7
Tự đánh giá tháng 8: 100,6 điểmCấp trên tháng 8: 99,1 điểm
T8
Tự đánh giá tháng 9: 98,7 điểmCấp trên tháng 9: 97,8 điểm
T9
B
A+
Chưa chọn tháng nào. Bấm một nhóm cột, hoặc Tab tới vùng vẽ rồi ←/→ và Enter.
Điểm trung bình tháng, P.TCHC
Loại điểm
T1
T2
T3
T4
T5
T6
T7
T8
T9
Tự đánh giá
99,5
97,8
98,9
99,2
98,1
97,6
95,4
100,6
98,7
Cấp trên
98,3
96,4
97,6
98,0
97,3
96,8
94,2
99,1
97,8
data-chart trên figure.chart-cols bật tooltip từng nhóm (số đọc từ data-value của mỗi cột, định dạng theo data-decimals và data-unit), dải nền --surface-hover sau nhóm đang rê, chuyển động lúc vào và, với data-select, chọn một nhóm: cột đậm hơn, nhãn đậm, aria-pressed="true" và sự kiện tvkit:chart-select (dòng ngay dưới biểu đồ in lại nó). Vùng vẽ cột thường thành một điểm dừng Tab (←/→, Home, End, Enter, Esc). div.cc-ref là vạch ngưỡng có nhãn ở mép cuối, nét đứt, không nhầm với đường kẻ. Không có data-chart thì .chart-cols giữ nguyên như phần trên.
Cột chồng, có vạch ngân sách
Chi phí theo nhóm, quý 2 và quý 3 năm 2026 (triệu đồng)
Vật tư
Nhân công
Vận chuyển
Khác
0
100 tr
200 tr
300 tr
400 tr
Vật tư tháng 4: 120 triệuNhân công tháng 4: 85 triệuVận chuyển tháng 4: 40 triệuKhác tháng 4: 22 triệu
T4
Vật tư tháng 5: 132 triệuNhân công tháng 5: 88 triệuVận chuyển tháng 5: 46 triệuKhác tháng 5: 18 triệu
T5
Vật tư tháng 6: 110 triệuNhân công tháng 6: 90 triệuVận chuyển tháng 6: 38 triệuKhác tháng 6: 25 triệu
T6
Vật tư tháng 7: 145 triệuNhân công tháng 7: 92 triệuVận chuyển tháng 7: 52 triệuKhác tháng 7: 20 triệu
T7
Vật tư tháng 8: 138 triệuNhân công tháng 8: 95 triệuVận chuyển tháng 8: 49 triệuKhác tháng 8: 24 triệu
T8
Vật tư tháng 9: 150 triệuNhân công tháng 9: 97 triệuVận chuyển tháng 9: 55 triệuKhác tháng 9: 21 triệu
T9
Ngân sách 350 tr
Chi phí theo nhóm, triệu đồng
Nhóm
T4
T5
T6
T7
T8
T9
Vật tư
120
132
110
145
138
150
Nhân công
85
88
90
92
95
97
Vận chuyển
40
46
38
52
49
55
Khác
22
18
25
20
24
21
Tổng
267
284
263
309
306
323
.cc-stacked chồng các cột của một nhóm lên nhau (cột đầu ở dưới), mỗi --v là phần của giá trị lớn nhất của trục; khe 2px giữa các khúc, chỉ khúc trên cùng bo góc, mẫu tô từng chuỗi như cột nhóm. Tooltip ghi tổng ở dòng đầu (“Tháng 7 · Tổng 309 tr”).
Biểu đồ đường
Một đến bốn chuỗi theo kỳ cùng kỳ trước, vạch ngưỡng có nhãn, tháng thiếu thành khoảng trống, vùng nhạt cho một chuỗi; tooltip, vạch dọc, bàn phím, chạm, chú giải bật tắt và chọn kỳ.
figure.chart-line[data-chart-table="…"] > figcaption.chart-title, sau đó là bảng số (hiện, hoặc .visually-hidden): ô tiêu đề sau ô đầu là các kỳ, mỗi tbody tr một chuỗi có tên ở th, data-series="1..4|prev" chọn màu; data-value (dấu chấm thập phân, chưa làm tròn) thắng chữ trong ô; data-label trên ô tiêu đề là tên dài (“Tháng 7”). Trên figure: data-y-min, data-y-max, data-y-step, data-refs="80:B;90:A", data-unit, data-decimals, data-curve="linear", data-area, data-legend-toggle, data-select, data-series-in="cols", data-empty. kit.js dựng chú giải, vùng vẽ svg theo pixel thật (chữ không co theo khung) và vùng đọc; đường cong đơn điệu không vọt quá số thật.
Ba đường, vạch ngưỡng, tháng thiếu, chú giải bật tắt, chọn tháng
Điểm theo tháng, Lý Văn Quý (nhân viên P.TCHC), năm 2026
Chưa chọn tháng nào.
Điểm theo tháng, Lý Văn Quý, năm 2026
Chuỗi
T1
T2
T3
T4
T5
T6
T7
T8
T9
T10
T11
T12
Cấp trên
92,5
97,0
108,0
96,5
98,5
98,0
102,5
88,5
Tự đánh giá
94,0
98,0
108,5
97,0
99,0
99,5
103,0
90,0
96,5
Cùng kỳ năm 2025
95,0
93,5
97,0
99,0
96,5
101,0
94,0
92,5
98,0
97,5
99,5
103,5
Số lấy từ bảng ngay dưới (data-chart-table): ô trống là tháng thiếu, đường đứt ra chứ không về 0 (tháng 4 không đánh giá; tháng 10 cấp trên chưa chấm, tháng 11 và 12 chưa tới). Điểm trên 100 là bình thường, trục không cắt. Chuỗi 1 nét liền, chuỗi 2 nét gạch dài, cùng kỳ nét gạch ngắn màu --series-prev; chú giải vẽ đúng nét đó. Rê chuột: vạch dọc bám tháng gần nhất, chấm trên mọi đường, tooltip ghi số trước tên. Tab tới vùng vẽ: ←/→, Home, End, Enter chọn, Esc ẩn; vùng aria-live đọc “Tháng 7: Cấp trên 98,0 điểm; …”. Rê lên một mục chú giải thì các đường khác mờ còn 25 %, bấm thì ẩn hoặc hiện (luôn còn một đường, trục không đổi). Nút “Đổi số” sửa bảng rồi gọi TvKit.chart.render(figure): cùng tháng nên số trượt trong 350 ms. “Đang tải lại” đặt aria-busy="true": vùng vẽ mờ một nửa, khung giữ nguyên.
Một chuỗi có vùng nhạt
Điểm trung bình toàn trung tâm, năm 2026
Điểm trung bình toàn trung tâm, năm 2026
Chuỗi
T1
T2
T3
T4
T5
T6
T7
T8
T9
T10
T11
T12
Điểm trung bình
96,1
96,8
97,2
96,5
97,0
97,4
95,9
97,8
97,3
data-area: một lớp nhạt 10 % màu chuỗi dưới đường, chỉ khi biểu đồ có một chuỗi. Trục tự chọn bậc đẹp (1, 2, 2,5, 5 × 10ⁿ, bốn đến sáu đường) và không bắt đầu từ 0 khi số nằm sát nhau. Ở đây bảng nằm trong div.visually-hidden (đặt lớp lên chính table thì bảng không co về 1px và làm trang tràn ngang): trình đọc màn hình vẫn đọc được.
Bốn chuỗi và cùng kỳ, tên dài, một điểm đứng riêng
Điểm trung bình theo đơn vị, năm 2026
Điểm trung bình theo đơn vị, năm 2026
Chuỗi
T1
T2
T3
T4
T5
T6
T7
T8
T9
T10
T11
T12
Phòng Tổ chức - Hành chính
96,4
97,0
98,1
97,5
96,9
97,8
95,0
98,6
97,4
97,9
98,2
98,8
Phòng Kế toán - Tài chính
98,0
97,2
96,8
98,4
99,1
98,0
97,6
99,3
98,5
98,9
99,4
99,0
Trạm cấp cứu mỏ Hạ Long
93,5
94,2
95,0
94,4
95,8
96,1
92,7
95,5
94,9
95,6
96,0
96,4
Trạm cấp cứu mỏ Cẩm Phả
95,2
96,8
97,1
96,5
97,3
97,9
Toàn trung tâm năm 2025
95,1
95,6
95,9
96,2
96,0
96,6
95,2
96,4
96,1
96,8
97,0
97,5
Bốn chuỗi cùng năm, cùng thang điểm nên cùng là nét liền, phân biệt bằng màu, chú giải (rê chuột vào một mục làm mờ các đường khác), tooltip và điểm cuối; chỉ cùng kỳ năm trước là nét gạch ngắn vì là hệ quy chiếu khác. Trạm Cẩm Phả có số tháng 6 đứng riêng (tháng 5 và 7 trống): điểm không có hàng xóm luôn có chấm. Mười hai tháng ở 390px: nhãn tháng thưa ra (cách một, cách hai), tháng đầu và tháng cuối luôn hiện; cao 12,5rem khi biểu đồ hẹp hơn 40rem.
Chưa có số liệu
Điểm theo tháng, năm 2027
Điểm theo tháng, năm 2027
Chuỗi
T1
T2
T3
T4
T5
T6
T7
T8
T9
T10
T11
T12
Cấp trên
Không có số nào: một câu p.chart-empty trong vùng vẽ (chữ của data-empty), không vẽ trục.
Biểu đồ tròn rỗng (donut)
Phần của một tổng cho 2 đến 5 phần: số tổng ở giữa, chú giải có tỉ lệ, rê hoặc chọn thì phần đó nhô ra; quá năm phần thì gộp thành “Khác”.
figure.chart-donut[data-chart-table] (data-unit, data-decimals, data-total-label, data-select) > figcaption.chart-title, sau đó là bảng một chuỗi. kit.js vẽ div.cd-body (svg và số tổng ở giữa) và ul.cd-legend. Màu: --series-1..4 theo thứ tự, hoặc data-series, data-grade, data-tone trên ô tiêu đề (hay dòng) của phần đó; “Khác” là --series-prev. --donut-size đặt cỡ vòng (12rem).
Bốn phần, có tổng ở giữa, chọn một phần
Doanh thu quý 3 theo kênh
Chưa chọn phần nào.
Doanh thu quý 3 theo kênh, triệu đồng
Kênh
Cửa hàng
Đại lý
Bán online
Bán sỉ
Triệu đồng
412,5
268,0
154,3
96,2
Vòng dày 22 % bán kính, khe 2px giữa các phần, màu theo thứ tự chuỗi của bảng (không sắp lại theo độ lớn). Chú giải dưới vòng: mỗi phần một cột, ô màu, tên, tỉ lệ chữ lớn; bốn phần không đủ chỗ thì xếp 2 × 2, không bao giờ 3 + 1. Rê hoặc Tab tới vòng rồi ←/→: phần đó nhô ra 4px và tooltip ghi số trước, tỉ lệ sau; Enter (hoặc bấm) giữ nó nhô ra và gửi tvkit:chart-select.
Trạng thái phiếu, màu theo tone, bảng xếp dọc
Phiếu Tháng 10/2026 theo trạng thái
Phiếu Tháng 10/2026 theo trạng thái
Trạng thái
Số phiếu
Đã đánh giá
96
Chờ đánh giá
85
Đã giao, chưa gửi
13
Nháp
1
Không đánh giá
3
Bảng một cột số, mỗi dòng một phần (kit.js nhận ra cả hai chiều); data-tone trên ô đầu dòng (th) chọn màu tone thay cho màu chuỗi. Tone là màu nhạt: chữ, chú giải và bảng mang số, khe 2px tách các phần. Phần “Nháp” chỉ 0,5 % nên mỏng như một vạch, tooltip vẫn đọc được.
Tám khoản: danh sách bên cạnh vòng, “Khác” mở ra được
Chi phí tháng 9 theo khoản
Chi phí tháng 9 theo khoản, triệu đồng
Khoản
Triệu đồng
Vật tư
145
Nhân công
92
Vận chuyển
52
Điện nước
21
Sửa chữa
14
Văn phòng phẩm
9
Tiếp khách
6
Quảng cáo
4
Hơn năm phần thì bốn phần đầu giữ nguyên, phần còn lại gộp vào “Khác” (màu --series-prev). Từ năm phần chú giải là danh sách dọc (ô màu, tên, giá trị, tỉ lệ canh phải), nằm cạnh vòng khi hình rộng từ 34rem, dưới vòng trên điện thoại; bấm dòng “Khác” để xem từng khoản đã gộp với số của nó. Không dùng carousel: chú giải phải thấy hết một lần. Donut cho 2 đến 5 phần của một tổng; so các phần giữa nhiều dòng thì dùng thanh tỉ lệ.
Chưa có số liệu
Doanh thu quý 4 theo kênh
Kênh
Cửa hàng
Đại lý
Triệu đồng
0
0
Tổng bằng 0: vòng xám --sunk và một câu ở giữa, không có chú giải.
Sparkline
Đường xu hướng nhỏ không trục trong thẻ KPI hoặc ô bảng, điểm cuối nổi bật; nghĩa nằm ở chữ và một câu cho trình đọc màn hình.
span.spark[data-values="72,5 81 79 96,3"][aria-hidden="true"]: các số cách nhau bằng dấu cách, dấu phẩy thập phân, “-” cho tháng thiếu; đặt trong .kpi-foot, ngay sau .kpi-value, hoặc trong ô bảng. kit.js vẽ svg rộng 100 %, cao --spark-h; gọi TvKit.chart.render(span) sau khi đổi data-values.
Trong thẻ KPI
Điểm trung bình toàn trung tâm
97,3điểm
Tháng 9, giảm 0,5 so với tháng 8. Xu hướng 9 tháng: từ 96,1 lên 97,3, thấp nhất 95,9 ở tháng 7
Phiếu quá hạn
12
12 phiếu đã giao chưa gửi tự đánh giá. Xu hướng 9 tháng: từ 18 xuống 12, cao nhất 21 ở tháng 7
Tỷ lệ xếp loại A trở lên
89,2%
Tháng 9/2026. Xu hướng 9 tháng: từ 88,0 lên 89,2, tháng 3 không có số
Đường 2px theo tông của thẻ (--primary, hoặc màu data-tone của .kpi: thẻ giữa là warn); các tháng trước nhạt hơn, đoạn cuối và điểm cuối đậm. Rê chuột hoặc chạm: một chấm chạy theo tháng gần nhất và tooltip nói tháng (data-labels) và giá trị. Thẻ đầu đặt sparkline ngay sau con số, hai thẻ sau đặt trong .kpi-foot (sparkline lên trước chữ). Thẻ thứ ba thiếu tháng 3 (“-”): hai bên nối bằng nét chấm mờ. Nghĩa của hình nằm ở chữ trong thẻ và một câu .visually-hidden do tác giả viết.
Trong ô bảng
Điểm trung bình tháng 9 và xu hướng 9 tháng theo đơn vị
Đơn vị
Tháng 9
Xu hướng 9 tháng
Phòng Tổ chức - Hành chính
97,4
từ 96,4 lên 97,4
Phòng Kế toán - Tài chính
98,5
từ 98,0 lên 98,5
Trạm cấp cứu mỏ Hạ Long
94,9
từ 93,5 lên 94,9
Trong ô bảng sparkline rộng bằng ô (ít nhất 4rem), cao --spark-h (2rem); câu ẩn trong ô nói xu hướng.
Bảng tô màu theo giá trị
Ô số tô một tông, nhạt ở số nhỏ nhất, đậm dần đến số lớn nhất; số vẫn là thông tin chính, màu chỉ giúp.
table.tbl[data-heat]: mỗi cột so với chính nó, nên Thu và Chi cùng có tháng đậm nhất (T12) dù số khác nhau. Dòng tổng ở tfoot không tô. Ô đậm nhất vẫn đủ tương phản cho chữ (đã kiểm trên 7 bảng màu).
Một thang cho cả bảng
Thu và chi theo tháng, triệu đồng
Tháng
Thu 2026
Thu 2025
Chi 2026
Chi 2025
T1
248
230
201
190
T2
262
251
219
205
T3
291
274
236
221
T4
305
288
262
240
T5
338
310
274
255
T6
347
320
290
270
T7
352,4
340
281,3
268
T8
421,5
380
322,5
300
T9
312,5
330
238,9
255
T10
396
370
301
285
T11
408
385
318
298
T12
452
420
361
330
Cả năm
4.133,9
3.898
3.303,7
3.117
data-heat="table": mọi ô so với nhau, nên cột Thu đậm hơn hẳn cột Chi. data-heat="row" so trong từng dòng; th[data-heat="off"] bỏ một cột ra.
Có cả số âm và số dương
Lãi lỗ và chênh lệch so với cùng kỳ theo tháng, triệu đồng
Tháng
Lãi / lỗ
So với cùng kỳ
T1
12,5
−3,0
T2
8,0
1,2
T3
−4,5
−8,4
T4
15,2
6,0
T5
−12,8
−2,1
T6
3,1
9,5
T7
22,4
4,4
T8
−0,6
−15,0
T9
6,9
2,2
T10
18,0
11,3
T11
−7,2
0
T12
25,6
7,8
Âm nhiềuDương nhiều
Khi một thang có cả số âm và số dương, 0 là điểm giữa (nền trắng): số dương đậm dần màu xanh, số âm đậm dần màu đỏ, hai phía chung một độ dài nên −12,8 và 12,8 đậm như nhau. Dấu trừ vẫn nằm trong số. Tự bật, không cần thuộc tính; data-heat-mid="off" giữ thang nhạt đến đậm.
Tông khác
Thu và chi theo tháng, triệu đồng
Tháng
Thu 2026
Thu 2025
Chi 2026
Chi 2025
T1
248
230
201
190
T2
262
251
219
205
T3
291
274
236
221
T4
305
288
262
240
T5
338
310
274
255
T6
347
320
290
270
T7
352,4
340
281,3
268
T8
421,5
380
322,5
300
T9
312,5
330
238,9
255
T10
396
370
301
285
T11
408
385
318
298
T12
452
420
361
330
Cả năm
4.133,9
3.898
3.303,7
3.117
Đặt --heat-strong trên bảng để đổi tông (ở đây là ok); giữ mức pha để chữ vẫn đọc được.
Dải tóm tắt có liên kết và chênh lệch
Ô số liệu là liên kết tới danh sách, có dòng chênh lệch có dấu và màu theo chiều tốt; dải nhận đến sáu ô.
Ô liên kết: div.stat-strip-item > dt > a.stat-strip-link[href] (tên và svg.icon.icon-sm.stat-strip-caret “caret-right”) + dd. Chênh lệch: dd > span.stat-delta[data-dir="up|down|flat"][data-good="up|down"] > icon mũi tên + số có dấu + kỳ so sánh. Dải nhận 5 và 6 ô.
Cả ô là vùng bấm (liên kết nằm trong dt và phủ cả ô, vì dl chỉ chứa div > dt + dd): rê chuột thì nền --surface-hover, Tab thì khung focus nằm trong ô, mũi tên ở mép cuối màu --muted, chữ vẫn là màu chữ. Dòng chênh lệch có mũi tên, số có dấu và kỳ so sánh; xanh khi đi đúng chiều tốt (data-good), đỏ khi ngược, xám khi không đổi. “Chờ đánh giá −12” là tốt nên xanh; “Đã giao +1” là xấu nên đỏ.
Năm và sáu ô nằm một hàng khi đủ chỗ; dải hẹp hơn 40rem (điện thoại) thì xuống ba ô một hàng: sáu thành 3 + 3, năm thành 3 + 2.
Bảng cơ bản
Panel, bảng cơ bản, trạng thái dòng và dòng số dư đầu kỳ; nhãn và chip có phần riêng, bảng cuộn dính và bảng rộng ở Bảng nâng cao.
.panel (-head -body -foot -flush), .tbl-wrap > .tbl (-compact -dense, cột số dùng .num), .tag (-ok -warn -bad -info -draft). Nhãn .tag và chip xem ở phần Chip và tag; trong bảng mọi nhãn cao hơn một bước (--fs-sm) cho khớp chữ của bảng. Chip mã đứng trước tên là .code-chip trong .cell-lead.
Phiếu gần đây
5 phiếu gần nhất
Số phiếu
Khách hàng
Trạng thái
Kiểm hàng
Số lượng (kg)
Thành tiền (₫)
Thao tác
ỚTPN-0012Ớt bột
Công ty Phú Thành
Đã duyệt
Đạt
1.250,500
12.450.000
TXPN-0013Tiêu xay
Nguyễn Văn An
Chờ duyệt
Đạt
4,162
3.280.000
MTPN-0014Muối tinh
Cửa hàng Minh Sơn
Bị từ chối
Không đạt
0,350
890.000
BBPN-0015Bao bì 500 g
Trần Thị Bình
Bản nháp
Chưa đủ số liệu
12,000
1.020.000
ỚTPN-0016Ớt bột
Hợp tác xã Nga Thanh
Đã hủy
Không đánh giá
0,000
0
Cột đầu có chip mã (.code-chip trong .cell-lead): mã mặt hàng ngắn, hộp viền chữ đơn cách, để quét cột theo loại; tên mặt hàng vẫn nằm ở dòng phụ nên chip là aria-hidden. Trạng thái là nhãn có nền, kiểm hàng là nhãn không nền (.tag-bare): hai cột cạnh nhau vẫn đọc được, không thành hai hàng nhãn viên thuốc.
Tiêu đề cột dài
Cỡ
Sai số KL
Chảy nhỏ nhất (MPa)
Bền nhỏ nhất (MPa)
A5 nhỏ nhất (%)
D6CB240-T
−1,6 … −0,9 %± 8 %
311,0≥ 240
455,8≥ 380
25,3≥ 20
D10CB300-V
−1,1 … −0,4 %± 6 %
318,5≥ 300
459,9≥ 450
22,0≥ 19
.tbl-th-wrap: tiêu đề cột được xuống dòng, nên bảng có tiêu đề dài (kèm đơn vị) trên số ngắn vừa một cột hẹp mà không phải cuộn ngang. Ô số dạng khoảng giữ một dòng bằng .nowrap.
Trạng thái dòng: ngừng dùng, đã hủy, tô theo tone, vừa thêm
Một dòng bảng hoặc dòng danh sách có thể mờ, bị gạch, được tô màu hoặc đánh dấu là vừa thêm; chữ trong dòng luôn nói thêm điều đó.
tr.row-void (đã có): mờ và gạch ngang, nghĩa là đã hủy. .row-off trên tr, trên li hoặc .work-item của .work-list: chữ mờ, không gạch, cho thứ ngừng dùng, tài khoản bị khóa, người đã nghỉ việc; hãy thêm một .tag (“Ngừng dùng”) vì mờ một mình dễ bị đọc là dòng phụ. tr[data-tone="ok|warn|bad|info"] tô cả dòng bằng màu -bg của tone qua --row-bg (ô dính theo màu); hover và dòng đang chọn vẫn thắng màu tô, .cell-fill giữ màu riêng, và dòng vẫn phải có chữ nói trạng thái (tag, ô). .row-new: dòng vừa thêm, nền như dòng được chọn cộng một vạch ở đầu dòng và nên có chữ “Mới”; tenant gỡ lớp này sau ít giây, không có hiệu ứng. Dòng danh sách: .work-row[data-state="void"] hoặc .row-void làm dòng mờ, tên và mã bị gạch, con số như .num-void, tag “Đã hủy” vẫn rõ và vạch tone bị bỏ; .row-off và .row-new dùng như ở bảng. Trong bảng dạng thẻ (.tbl-cards) thẻ mang cùng màu và vạch.
Bảng: từng trạng thái
Vật tư và kho
Rê chuột vào một dòng để thấy hover (thắng màu tô)
Vật tư
Trạng thái
Số lượng (kg)
VT-0101Thép tấm 5 ly
Bình thường
1.250,500
VT-0102Que hàn 3.2 (phiếu đã hủy)
Đã hủy
− 90,000
VT-0103Sơn lót cũ (ngừng nhập)
Ngừng dùng
12,000
VT-0104Ống 40 (đã đồng bộ kho)
Đã đồng bộ
+ 40,000
VT-0105Đá cắt 100 (chưa đồng bộ)
Chưa đồng bộ
250,000
VT-0106Bulong M10 (lỗi đồng bộ)
Lỗi đồng bộ
− 1.200,000
VT-0107Tồn làm tròn của hệ thống
Hệ thống
0,350
VT-0108Tôn lạnh 0.4 (vừa thêm)
Mới
800,000
VT-0109Dây hàn lõi thuốc (đang chọn)
Đã chọn
35,000
Từ trên xuống: bình thường, row-void, row-off, bốn tone okwarnbadinfo, row-new, aria-selected. Dòng cuối đang chọn có cùng nền với dòng mới nhưng không có vạch.
Dòng đầu của sổ cái cho biết số còn lại trước khi các khoản phát sinh bắt đầu: nhạt hơn dòng thường, chỉ số dư là chữ đậm.
tr.row-open là dòng đầu tiên của tbody (“Số dư đầu kỳ 01/07”, “Tồn đầu kỳ”). Nền --surface-2, chữ mờ, đường kẻ dưới đậm hơn để tách khỏi các dòng phát sinh; không gạch, không nghiêng; chỉ ô số dư (td.num cuối dòng) là chữ đậm. Nhãn là ô tiêu đề dòng th scope="row": gộp cột (colspan) qua các cột trước số dư, hoặc giữ một ô và để trống các ô còn lại (nên làm vậy trong bảng .tbl-sticky-col, kẻo ô đầu rộng đè lên các ô đang cuộn). Con số nằm ở đúng cột của nó. Hover và dòng được chọn chạy như mọi dòng. Trong .tbl-sticky đầu bảng vẫn nằm trên dòng này khi cuộn. Trong .tbl-cards nó thành một thẻ cùng vẻ nhạt, nhãn là tiêu đề thẻ, các ô trống được bỏ. Số phát sinh dùng .num-in, .num-out, .num-neg.
Sổ quỹ có dòng đầu kỳ và dòng tổng
Sổ quỹ tiền mặt
Quý 3 · 2026
Diễn giải
Ngày
Thu
Chi
Số dư
Số dư đầu kỳ 01/07/2026
6.200.000đ
Khách Tuấn Phát trả đợt 1
03/07/2026
+ 12.450.000đ
18.650.000đ
Mua que hàn, đá cắt
05/07/2026
− 350.000đ
18.300.000đ
Ứng lương tháng 7
10/07/2026
− 7.200.000đ
11.100.000đ
Khách Hòa Bình trả tiền hàng
14/07/2026
+ 4.800.000đ
15.900.000đ
Tiền điện xưởng tháng 6
18/07/2026
− 3.150.000đ
12.750.000đ
Mua thép tấm 5 ly (vượt số dư)
22/07/2026
− 14.000.000đ
− 1.250.000đ
Khách Tuấn Phát trả đợt 2
28/07/2026
+ 12.450.000đ
11.200.000đ
Cộng phát sinh
+ 29.700.000đ
− 24.700.000đ
11.200.000đ
Dòng đầu kỳ: th[colspan="4"] cho nhãn, số dư ở cột cuối. Dòng cuối là tfoot (tổng phát sinh và số dư cuối kỳ).
Khung hẹp: thẻ
Sổ quỹ tiền mặt
Diễn giải
Ngày
Thu
Chi
Số dư
Số dư đầu kỳ 01/07/2026
6.200.000đ
Khách Tuấn Phát trả đợt 1
03/07/2026
+ 12.450.000đ
18.650.000đ
Mua que hàn, đá cắt
05/07/2026
− 350.000đ
18.300.000đ
Ứng lương tháng 7
10/07/2026
− 7.200.000đ
11.100.000đ
Cộng phát sinh
+ 29.700.000đ
− 24.700.000đ
11.200.000đ
Cùng bảng ở khung dưới 36rem: thẻ đầu kỳ nhạt, tiêu đề là nhãn, chỉ có ô số dư (ô trống được bỏ); tfoot thành thẻ cuối có viền đậm, các ô số của nó cần data-label như ô thường.
Bảng dính đầu, cuộn
Diễn giải
Ngày
Thu
Chi
Số dư
Số dư đầu kỳ 01/07/2026
6.200.000đ
Khách Tuấn Phát trả đợt 1
03/07/2026
+ 12.450.000đ
18.650.000đ
Mua que hàn, đá cắt
05/07/2026
− 350.000đ
18.300.000đ
Ứng lương tháng 7
10/07/2026
− 7.200.000đ
11.100.000đ
Khách Hòa Bình trả tiền hàng
14/07/2026
+ 4.800.000đ
15.900.000đ
Tiền điện xưởng tháng 6
18/07/2026
− 3.150.000đ
12.750.000đ
Mua thép tấm 5 ly (vượt số dư)
22/07/2026
− 14.000.000đ
− 1.250.000đ
Khách Tuấn Phát trả đợt 2
28/07/2026
+ 12.450.000đ
11.200.000đ
Cộng phát sinh
+ 29.700.000đ
− 24.700.000đ
11.200.000đ
.tbl-sticky trong .tbl-scroll: đầu bảng và dòng tổng dính, dòng đầu kỳ cuộn dưới đầu bảng như mọi dòng. Cuộn bảng để thấy đầu bảng ở trên dòng đầu kỳ.
Cột đầu dính, các ô trống giữ nguyên
Diễn giải
Ngày
Thu
Chi
Số dư
Số dư đầu kỳ
01/07/2026
6.200.000đ
Khách Tuấn Phát trả đợt 1
03/07/2026
+ 12.450.000đ
18.650.000đ
Mua que hàn, đá cắt
05/07/2026
− 350.000đ
18.300.000đ
Ứng lương tháng 7
10/07/2026
− 7.200.000đ
11.100.000đ
Khách Hòa Bình trả tiền hàng
14/07/2026
+ 4.800.000đ
15.900.000đ
Tiền điện xưởng tháng 6
18/07/2026
− 3.150.000đ
12.750.000đ
Mua thép tấm 5 ly (vượt số dư)
22/07/2026
− 14.000.000đ
− 1.250.000đ
Khách Tuấn Phát trả đợt 2
28/07/2026
+ 12.450.000đ
11.200.000đ
Trong bảng .tbl-sticky-col không dùng colspan: nhãn ở ô đầu, các ô khác của dòng đầu kỳ để trống.
Bảng nâng cao
Bảng cuộn: dính đầu và cột, chọn dòng, sắp xếp, tổng, phân trang.
Thêm vào .tbl: .tbl-sticky (đầu và dòng tổng dính, cần .tbl-scroll có chiều cao), .tbl-sticky-col (cột đầu dính; thêm .tbl-select thì cột chọn và cột sau nó cùng dính), .tbl-grid (kẻ ô), .tbl-zebra, tfoot (tổng), .th-sort + aria-sort, tr[aria-selected="true"] + .cell-check, .row-void, td.trunc; trong ô: .cell-sub (dòng phụ), .cell-metric với .bar (thanh tỷ lệ) hoặc .tag.delta (tăng giảm), td.nowrap.tnum (ngày giờ), td.cell-fill (ô tô màu); quanh bảng: .tbl-tools, .bulk-bar, .pager. Bảng dưới cuộn được cả hai chiều: thử chọn dòng, bấm tiêu đề cột để sắp xếp, bấm dấu ⋮ cuối dòng để mở menu thao tác, đổi kiểu bảng bằng các nút bên dưới. Cột Số lượng có thanh so với phiếu nhập nhiều nhất, cột Đơn giá có mức tăng giảm so với lần nhập trước (màu theo ý nghĩa, mũi tên theo chiều: giá nhập tăng là xấu nên đỏ, giảm là tốt nên xanh), cột Nhà cung cấp có mã ở dòng phụ.
GọnChữ nhỏKẻ ôSọc
Tất cảChờ duyệtĐã duyệt
Đã chọn 0 phiếu
Email
Kho
Trạng thái
Kiểm hàng
Đơn giá (₫)so với lần nhập trước
Ghi chú
Thao tác
PN-0101
01/10/2026 08:30
Công ty Phú ThànhNCC-012
lienhe@phuthanh.vn
Kho 1
Đã duyệt
Đạt
1.250,500
18.500Tăng 3,4%
23.134.250
Hàng đợt 1, đã kiểm đủ số lượng theo hợp đồng số 24/HĐ-2026
PN-0102
02/10/2026 09:15
Cửa hàng Minh SơnNCC-007
info@minhson.vn
Kho 2
Đã duyệt
Đạt
4,162
95.000Giảm 3,1%
395.390
Giao tại kho
PN-0103
03/10/2026 14:00
Hợp tác xã Nga ThanhNCC-031
ketoan@ngathanh.vn
Kho 1
Chờ duyệt
Chờ kết quả
320,000
42.000Giảm 4,5%
13.440.000
Chờ phiếu kiểm nghiệm
PN-0104
04/10/2026 10:45
Nguyễn Văn AnNCC-044
an.nguyen@email.vn
Kho 1
Đã duyệt
Đạt
0,350
1.200.000Tăng 4,3%
420.000
PN-0105
05/10/2026 16:20
Trần Thị BìnhNCC-052
binh.tran@email.vn
Kho 2
Bản nháp
Chưa đủ số liệu
75,250
31.000Giảm 6,1%
2.332.750
Chưa chốt giá
PN-0106
06/10/2026 08:05
Công ty Phú ThànhNCC-012
lienhe@phuthanh.vn
Kho 1
Đã duyệt
Đạt
980,000
18.500Không đổi 0,0%
18.130.000
Hàng đợt 2
PN-0107
07/10/2026 11:30
Cửa hàng Minh SơnNCC-007
info@minhson.vn
Kho 2
Đã hủy
Không đạt
12,000
95.000Không đổi 0,0%
1.140.000
Nhập nhầm kho, đã lập lại phiếu PN-0108
PN-0108
07/10/2026 13:10
Cửa hàng Minh SơnNCC-007
info@minhson.vn
Kho 1
Đã duyệt
Đạt
12,000
95.000Tăng 3,3%
1.140.000
PN-0109
08/10/2026 09:40
Công ty Thanh NhànNCC-060
kinhdoanh@thanhnhan.vn
Kho 2
Chờ duyệt
Cần xem lại
2.100,750
15.200Giảm 5,6%
31.931.400
Giá theo bảng giá tháng 10
PN-0110
09/10/2026 15:25
Hợp tác xã Nga ThanhNCC-031
ketoan@ngathanh.vn
Kho 1
Đã duyệt
Đạt
640,500
42.000Tăng 3,7%
26.901.000
PN-0111
10/10/2026 10:10
Nguyễn Văn AnNCC-044
an.nguyen@email.vn
Kho 2
Đã duyệt
Không đạt
1,000
2.500.000Giảm 5,7%
2.500.000
Thiết bị đo
PN-0112
12/10/2026 17:05
Trần Thị BìnhNCC-052
binh.tran@email.vn
Kho 1
Bản nháp
Chưa đủ số liệu
18,125
31.000Tăng 5,1%
561.875
Tổng
11 phiếu, không tính phiếu hủy
5.402,637
120.886.665
Cột Kiểm hàng là ô tô màu như cột Status của một bảng việc: td.cell-fill + -ok-warn-bad-info (không thêm màu là xám), bên trong .cell-fill-label chứa icon và chữ. Cả ô lấy màu, chữ ở giữa, một viền màu nền của dòng giữ các ô cách nhau; ô vẫn giữ màu khi dòng sọc, được rê chuột hoặc được chọn, còn dòng đã hủy bỏ màu để chữ gạch ngang đọc được.
Sheet cells
Bảng nhập liệu kiểu Excel: ô đang chọn, đã sửa, lỗi, chỉ đọc.
.tbl-grid + td.cell-edit chứa .cell-input. Trạng thái: ô đang chọn td[aria-selected="true"], ô đã sửa .cell-dirty, ô lỗi td[aria-invalid="true"], ô chỉ đọc (công thức) .cell-ro. Kit chỉ lo hình thức; phím mũi tên, dán nhiều dòng và lưu do tenant xử lý. Bấm vào một ô để thấy ô đang chọn.
STT
Mã hàng
Tên hàng
ĐV
Số lượng
Đơn giá (₫)
Thành tiền (₫)
1
6.266.000
2
7.350.000
3
—
4
2.760.000
5
—
Skeleton and empty table
Bảng đang tải và bảng trống.
.skel thay chữ trong lúc tải (đặt aria-busy="true" lên bảng); bảng trống là một dòng .tbl-empty chứa .empty.
Số phiếu
Nhà cung cấp
Trạng thái
Thành tiền (₫)
Số phiếu
Nhà cung cấp
Trạng thái
Thành tiền (₫)
Không có phiếu nào khớp
Bỏ bớt bộ lọc hoặc tạo phiếu mới.
Bảng cây đơn vị, đổi thứ tự
Danh sách đơn vị nhiều cấp trong bảng: thụt theo cấp, đường nối từ đơn vị cha, gập được, nút lên/xuống đổi thứ tự trong cùng cấp.
table.tbl.tbl-tree[data-row-sort], mỗi dòng tr[data-level="0".."3"] theo thứ tự cây, ô đầu th.tree-cell > (button.tree-toggle[aria-expanded]) + svg.icon (loại đơn vị: buildings, tree-structure, users) + tên. Cột cuối td.row-moves > button[data-row-up], button[data-row-down] (và nút sửa). Cột viết tắt dùng span.doc-code. kit.js vẽ đường nối, gập các dòng con, chuyển một dòng cùng toàn bộ dòng con của nó trong cùng cấp, làm mờ nút ở đầu và cuối, đọc vị trí mới và gửi change với detail { row, from, to } để tenant lưu.
Đơn vị
Thứ tự ở đây là thứ tự dòng trên các bảng tổng hợp
Đơn vị theo cây, đổi được thứ tự
Tên đơn vị
Viết tắt
Nhân viên
Trạng thái
Thứ tự
Trung tâm Kỹ thuật Nam Việt
TT
112
Đang dùng
Ban Giám đốc
BGĐ
3
Đang dùng
Phòng Tổ chức - Hành chính
P.TCHC
12
Đang dùng
Phòng Kế toán - Tài chính
P.KTTC
7
Đang dùng
Trạm Bắc
Trạm B
46
Đang dùng
Ban chỉ huy trạm
BCH Trạm B
4
Đang dùng
Tổ 1
T1
14
Đang dùng
Tổ 2
T2
14
Đang dùng
Tổ 3
T3
14
Đang dùng
Trạm Nam
Trạm N
44
Đang dùng
Ban chỉ huy trạm
BCH Trạm N
4
Đang dùng
Tổ 1
T1
20
Đang dùng
Tổ 2
T2
20
Đang dùng
Mỗi cấp thụt vào 1,75rem (3rem khi bảng có nút gập, để nút nằm giữa đường nối và icon); tên không xuống dòng; đường kẻ mảnh đậm hơn đường kẻ dòng một bậc (để không lẫn với lưới) đi từ icon của đơn vị cha xuống rồi cong vào icon của dòng con (như đường cây ở sidebar), dừng ở con cuối. Trạm Bắc đang mở, Trạm Nam đang gập (mũi tên quay ngang, dòng con ẩn). Nút lên/xuống chỉ đổi chỗ trong cùng cấp và kéo theo dòng con: đưa Trạm Nam lên thì cả bốn dòng của nó đi cùng. Nút đầu (lên) của dòng đầu và nút cuối (xuống) của dòng cuối mờ đi. Đơn vị gốc không có nút. Khi in, nút gập và nút thứ tự ẩn.
Tiêu đề bảng hai tầng
Dòng nhóm trên dòng tiêu đề cho số liệu đi theo nhóm (Tồn đầu, Nhập, Xuất, Tồn cuối; mỗi nhóm hai cột SL và Giá trị); cả hai dòng đều dính khi cuộn.
.tbl-head-group đặt trên thead: dòng đầu là các th[scope="colgroup"][colspan] căn giữa, mỗi nhóm có đường kẻ ngắn dưới phần của mình; cột đầu là một th[rowspan="2"]. Dòng hai là các th[scope="col"] như thường. Trong .tbl-sticky hai dòng cùng dính, dòng hai ngay dưới dòng một: dòng nhóm cao --tbl-head-row1 (mặc định tính từ đệm ô của bộ kit) và dòng hai dính ở độ lệch đó; đặt lại --tbl-head-row1 khi tên nhóm xuống dòng. colspan ở thead dính không sao (chỉ dính phía trên); với .tbl-sticky-col, ô đầu của dòng nhóm không được có colspan. Với .tbl-cards cả đầu bảng ẩn, nên mỗi td mang data-label gồm tên nhóm (“Nhập · SL”); ô trống ở tfoot bị bỏ khỏi thẻ tổng.
Phiếu tồn kho: bốn nhóm
Nhập xuất tồn quý 3
01/07 – 30/09/2026
Vật tư
Tồn đầu
Nhập
Xuất
Tồn cuối
SL
Giá trị
SL
Giá trị
SL
Giá trị
SL
Giá trị
Thép phi 10kg
1.200
21.600.000đ
800
14.400.000đ
1.450
26.100.000đ
550
9.900.000đ
Xi măng PCB40bao
240
22.080.000đ
600
55.200.000đ
540
49.680.000đ
300
27.600.000đ
Cát vàngm³
18
5.580.000đ
40
12.400.000đ
46
14.260.000đ
12
3.720.000đ
Cộng giá trị
49.260.000đ
81.980.000đ
90.040.000đ
41.220.000đ
Bảng thường: nhóm ở dòng trên, mỗi nhóm có đường kẻ riêng; “Vật tư” là ô rowspan="2" chiếm cả hai dòng. Dòng cuối là tổng giá trị (cột SL để trống vì đơn vị khác nhau). Bảng này dùng .tbl-cards nên dưới 36rem nó thành thẻ (xem ví dụ cuối).
Hai dòng đầu cùng dính khi cuộn
Vật tư
Tồn đầu
Nhập
Xuất
Tồn cuối
SL
Giá trị
SL
Giá trị
SL
Giá trị
SL
Giá trị
Thép phi 10kg
1.200
21.600.000đ
800
14.400.000đ
1.450
26.100.000đ
550
9.900.000đ
Xi măng PCB40bao
240
22.080.000đ
600
55.200.000đ
540
49.680.000đ
300
27.600.000đ
Cát vàngm³
18
5.580.000đ
40
12.400.000đ
46
14.260.000đ
12
3.720.000đ
Cộng giá trị
49.260.000đ
81.980.000đ
90.040.000đ
41.220.000đ
Hộp cuộn thấp: kéo xuống thì hai dòng đầu nằm chồng khít (không hở, không đè nhau) và dòng tổng dính ở đáy. Cuộn ngang thì cả hai dòng cuộn cùng cột.
Có cột đầu dính
Vật tư
Tồn đầu
Nhập
Xuất
Tồn cuối
SL
Giá trị
SL
Giá trị
SL
Giá trị
SL
Giá trị
Thép phi 10kg
1.200
21.600.000đ
800
14.400.000đ
1.450
26.100.000đ
550
9.900.000đ
Xi măng PCB40bao
240
22.080.000đ
600
55.200.000đ
540
49.680.000đ
300
27.600.000đ
Cát vàngm³
18
5.580.000đ
40
12.400.000đ
46
14.260.000đ
12
3.720.000đ
Cộng giá trị
49.260.000đ
81.980.000đ
90.040.000đ
41.220.000đ
Cùng bảng với .tbl-sticky-col: cột “Vật tư” đứng yên khi cuộn ngang; ô “SL” đầu tiên của dòng hai không bị dính theo.
Khung hẹp: thẻ
Vật tư
Tồn đầu
Nhập
Xuất
Tồn cuối
SL
Giá trị
SL
Giá trị
SL
Giá trị
SL
Giá trị
Thép phi 10kg
1.200
21.600.000đ
800
14.400.000đ
1.450
26.100.000đ
550
9.900.000đ
Xi măng PCB40bao
240
22.080.000đ
600
55.200.000đ
540
49.680.000đ
300
27.600.000đ
Cát vàngm³
18
5.580.000đ
40
12.400.000đ
46
14.260.000đ
12
3.720.000đ
Cộng giá trị
49.260.000đ
81.980.000đ
90.040.000đ
41.220.000đ
Với .tbl-cards dòng nhóm ẩn cùng đầu bảng; mỗi ô nêu nhóm trong data-label (“Nhập · SL”, “Nhập · Giá trị”). Các ô SL trống của tfoot bị bỏ khỏi thẻ tổng.
Ma trận phân quyền
Bảng vai trò theo quyền: mỗi giao điểm là một ô tích; có hàng nhóm quyền, ô khóa của Quản trị và ô vừa đổi chưa lưu; đầu bảng và cột quyền cùng dính.
.tbl.tbl-matrix.tbl-sticky.tbl-sticky-col trong .tbl-scroll. Cột đầu là th[scope="row"] (tên quyền, rộng --matrix-name-w 10rem), đầu bảng là th[scope="col"] mỗi vai trò. Ô tích là td.cell-check > label > input[type="checkbox"] với aria-label nêu cả quyền lẫn vai trò; label phủ kín ô nên vùng bấm cả ô và không nhỏ hơn 44 px. Mỗi nhóm quyền là một tbody mở đầu bằng tr.grp > th[scope="rowgroup"] (chỉ ô đầu có chữ, không dùng colspan vì ô đầu dính) và các td trống: nền --surface-2, chữ đậm, không đổi màu khi rê chuột. Ô khóa: td.cell-check[data-locked][aria-disabled="true"] có title, input thật là disabled checked và biểu tượng khóa; câu “Quản trị luôn có quyền này” cho trình đọc màn hình qua aria-describedby. Ô vừa đổi chưa lưu: td.cell-dirty (nền và vạch trái của ô đã sửa) thêm một chấm ở góc, và “đã đổi, chưa lưu” trong aria-label. Đếm “3 thay đổi chưa lưu” và lưu là việc của trang.
Năm vai trò, ba nhóm quyền
Quản trị luôn có quyền này
Quyền
Quản trị
Kế toán
Thủ kho
Quản đốc
Công nhân
Quỹ
Xem sổ quỹ, số dư quỹ
Lập phiếu thu, chi, chuyển quỹ
Khóa sổ quỹ
Kho
Xem tồn kho, thẻ kho
Lập phiếu nhập, xuất kho
Kiểm kê kho
Công việc
Xem sổ công việc
Chấm công, nhập ngày làm
Duyệt bảng công
Cột Quản trị bị khóa (hộp tích mờ, có khóa; rê chuột để thấy “Quản trị luôn có quyền này”). Hai ô của Quản đốc vừa được bật nhưng chưa lưu: nền vàng nhạt, vạch trái và chấm ở góc. Cuộn xuống thì tên vai trò vẫn ở trên, cuộn ngang thì tên quyền vẫn ở bên trái.
Ô chấm công và chú giải
Bảng công theo tháng: mỗi ô tô nhạt theo trạng thái (đủ công, nửa công, phép, không phép), cột Chủ nhật nền xám, ô “chưa vào làm” gạch chéo, số tăng ca ở góc ô, kèm chú giải.
td.cell-mark với -ok, -info, -bad, -muted (tô nhạt cả ô từ --ok-bg, --info-bg, --danger-bg, --sunk), -na (gạch chéo, chưa vào làm). Ký hiệu (“Đ”, “½”, “P”, “KP”) ở giữa ô, màu --text, không dùng màu của tone nên chữ mới là dấu hiệu chính. Ô có thể là liên kết: td.cell-mark > a, cả ô là vùng bấm không nhỏ hơn 44 px, vòng lấy nét nằm trong ô; đặt aria-label nêu đủ nghĩa (“Ngày 5, Hùng: đủ công, tăng ca 2 giờ”). td[data-off] (và th[data-off]) tô nền ngày nghỉ; đầu cột vẫn ghi “CN”. .cell-corner là số nhỏ 0,75rem ở góc trên bên phải ô, aria-hidden vì aria-label của ô đã nói đủ. Chú giải: ul.legend > li.legend-item > span.legend-swatch + chữ; ô mẫu -ok -info -bad -muted -off -na trùng ô chấm công, -solid và -line cho biểu đồ (màu theo --legend-color). Chú giải tự xuống dòng và không phải là điều khiển; .cc-legend của biểu đồ cột giữ nguyên.
Ba mươi mốt cột ngày, cột tên dính khi cuộn ngang. Chủ nhật (4, 11, 18, 25) nền xám cả cột; Tài vào làm từ ngày 10 nên các ô trước đó gạch chéo; ba ô có số tăng ca ở góc (ngày 6 của Hùng 2 giờ, ngày 13 của Lan 1,5 giờ, ngày 20 của Minh 3 giờ). Mỗi ô là một liên kết, Tab tới thì vòng lấy nét nằm trong ô.
Ô giờ số: một dòng đủ mọi trạng thái ngày
Bảng giờ số dùng .tbl-marks: ô 2,25rem dưới chuột, chứa được “8,5”, “7,5P”, “5K”, “1.200”; thứ Bảy, Chủ nhật, hôm nay, ngày chưa tới, trước khi vào làm, sau khi nghỉ, chưa chấm, thiếu giờ và dấu góc trên cùng một dòng.
.tbl-marks trên bảng: ô td.cell-mark rộng --mark-w (2,25rem) cao --mark-h (1,875rem) khi dùng chuột, về lại --tap khi chạm hoặc data-tap="all"; số dài làm rộng cột chứ không tràn. Mới: .cell-mark-warn (thiếu giờ), .cell-mark-missing (chưa chấm: vòng đứt rỗng, chữ ẩn “Chưa chấm”), .cell-auto (tự tính, sửa được: chữ nghiêng và sao ở góc), .cell-corner-start, .cell-corner-bottom (góc trên-đầu, dưới-cuối, nhận svg.icon). Cột: data-off="half" (thứ Bảy), th[aria-current="date"] + td[data-today] (hôm nay, cả cột), data-future (chưa tới, mờ cả đầu cột). Trước ngày vào làm và sau ngày nghỉ đều là .cell-mark-na.
Công nhân
1T5
2T6
3T7
4CN
5T2
6T3
7T4
8T5
9T6
10T7
11CN
12T2
13T3
14T4
15T5
16T6
17T7
18CN
19T2
20T3
21T4
22T5
23T6
24T7
25CN
26T2
27T3
28T4
29T5
30T6
31T7
Trần Thị LanVào làm 03/10, nghỉ việc từ 28/10
4
8,5
82
6,5
8
7,5P
4
0,5
81
Chưa chấm
8
1.200
4
8
5K
8
8
8
Ngày 1–2 (chưa vào làm) và 28–31 (đã nghỉ việc) gạch chéo; thứ Bảy (3, 10, 17, 24, 31) nền nhạt hơn Chủ nhật; hôm nay (23) có vạch dưới đầu cột và hai đường dọc cả cột; từ 24 là ngày chưa tới, đầu cột mờ; ngày 14 chưa chấm (vòng đứt, trình đọc màn hình nghe “Chưa chấm”). Ngày 13 có ba dấu: sao (tự tính, góc trên-đầu), số tăng ca (góc trên-cuối), vân tay (góc dưới-cuối).
Lưu ô: đang lưu, lỗi lưu, xung đột, đang sửa
Ô giữ giá trị vừa gõ; thông báo nổi trong top layer, neo vào ô, không bị khung cuộn cắt.
td[data-save="saving"] (chấm nhấp nháy góc trên-đầu, thêm aria-busy), "error" (viền đỏ liền, “Chưa lưu · Thử lại”), "conflict" (viền vàng đứt, “vừa được sửa bởi …, Tải lại ô”). Thông báo là div.cell-pop[popover="manual"] nằm trong ô: kit.js mở nó khi trạng thái đổi sang lỗi hoặc xung đột, khi ô nhận focus hoặc được bấm; đặt dưới ô (hoặc trên nếu hết chỗ), đi theo ô khi cuộn, ẩn khi ô khuất; Esc hoặc nút Đóng đóng lại và trả focus về ô; nút trong thông báo đi ngay sau ô khi nhấn Tab. Ô đang sửa: td.cell-mark > input.cell-input phủ lên ô, rộng ít nhất 5rem.
Công nhân
1T5
2T6
3T7
4T2
5T3
6T4
Lê Quang Minh
8
8,5
Chưa lưu · Thử lại. Máy chủ không phản hồi.
Giá trị đã gõ: 8,5, vẫn giữ trên ô.
4
Ô này vừa được sửa bởi Kế toán Hoa (10:42). Giá trị trên máy chủ là 8.
Giá trị đã gõ: 4, vẫn giữ trên ô.
7,5
Chưa lưu · Thử lại. Mất kết nối khi lưu ô này.
Giá trị đã gõ: 7,5, vẫn giữ trên ô.
8
Phạm Văn Tài
8
8
4
8
8
8
Bấm vào ô ngày 2 hoặc 3 (hay Tab tới) để mở thông báo; cuộn khung hoặc trang thì thông báo đi theo ô, ô khuất thì nó ẩn. Ngày 5 đang sửa: ô gõ rộng 5rem phủ lên ô bên cạnh. Ngày 6 tự tính (chữ nghiêng, sao).
Ô hai dòng: xem trước vân tay
Giờ quẹt ở dòng trên, kết quả ở dòng dưới; giờ quẹt bị bỏ qua thì gạch ngang.
td.cell-mark.cell-mark-2l > .cell-mark-sub (giờ quẹt, chữ nhỏ) + .cell-mark-main (kết quả, ghi chú trong <small>). Giờ quẹt không dùng viết bằng s.cell-mark-sub: gạch ngang, lý do ở dòng dưới (“chấm tay · giữ”, “bỏ qua”).
Công nhân
05/10T2
06/10T3
07/10T4
08/10T5
Nguyễn Văn HùngMáy số 14
07:28–17:058 giờ
07:30–19:108 giờtăng ca 2
07:31–16:027,5 giờthiếu 0,5
07:29!1 lần quẹt
Trần Thị LanMáy số 22
07:40–17:008 giờchấm tay · giữ
07:12–07:14—bỏ qua
không quẹt
07:25–17:018 giờ
Ô vàng: thiếu giờ hoặc một lần quẹt (chữ nói rõ). Hàng của Lan: ngày 5 giữ giá trị chấm tay, giờ quẹt gạch ngang; ngày 6 bỏ qua hai lần quẹt sát nhau.
Ô xếp loại theo tháng
Bảng người × 12 tháng: ô tô theo hạng (A+ tốt nhất … D kém nhất), chữ cái là tín hiệu chính.
td.cell-mark[data-grade="1".."5"]: nền --grade-N, chữ --on-grade-N (chưa có token thì lùi về --ok, --ok-line, --warn-line, --danger, --danger-hover). Trạng thái tháng: nhập từ file (đầu cột ghi “Từ file”, không có liên kết vì không có phiếu), chưa chốt (data-state="open": chữ nghiêng trong khung đứt; đầu cột ghi “Chưa chốt”), chưa tới (data-future, trống), không đánh giá (.cell-mark-muted với chữ “Không ĐG”). Khác với ô “chưa chấm” của bảng công: chưa chấm là vòng đứt rỗng không có giá trị, chưa chốt là giá trị nằm trong khung đứt.
Tháng 1–8 nhập từ file năm (không bấm được); tháng 9 đã chốt (bấm mở phiếu); tháng 10 chưa chốt (khung đứt, chữ nghiêng); tháng 11–12 chưa tới. Hoàng Văn Nam không được đánh giá tháng 4.
Chú giải cho các trạng thái mới
8Số giờ làm
6,5Thiếu giờ
PNghỉ phép
KNghỉ không phép
Chưa chấm
Chưa vào làm, đã nghỉ việc
Chủ nhật (CN)
Thứ Bảy (T7)
Hôm nay
Chưa tới
Tự tính, sửa được
Từ máy vân tay
Mỗi ô mẫu vẽ đúng như ô thật: -warn, -missing (vòng đứt), -half, -future, -today, -open, [data-grade] và một svg.icon trong ô mẫu cho dấu ở góc.
Chú giải cho biểu đồ
Công thực tế
Công tăng ca
Kế hoạch
-solid là khối màu, -line là nét kẻ; màu lấy từ --legend-color (mặc định --series-1). Đường kẻ chấm không phải điều khiển; chữ luôn đi kèm.
Bảng công tháng: nhiều cột dính, khối theo người
Đầu bảng, bốn cột trái, cột Thực lĩnh bên phải và ba dòng tổng cùng đứng yên; mỗi người một khối nhiều dòng; dòng nhóm theo tổ; thanh công thức, vùng chọn và toàn màn hình.
.tbl-sticky-cols với data-sticky="1".."6" trên mọi ô của cột trái (số là vị trí cột, nên dòng 2..n của một khối vẫn dính đúng chỗ) và data-sticky="end" cho cột cuối; kit.js đo bề rộng (ResizeObserver) và ghi --sticky-x2..6, không có kit.js thì đặt --sticky-w1..6. Khung cuộn hẹp hơn 48rem thì cột phải thôi dính. tfoot.tbl-foot-rows: nhiều dòng tổng dính đáy, mỗi dòng cao --tbl-foot-row (chỉ CSS), ô rowspan phủ cả ba dòng. tbody.tbl-block: một khối mỗi người, kẻ đậm giữa các khối, rê chuột sáng cả khối. tr.grp: dòng nhóm dùng được ở mọi bảng. td[data-range="top start"]: vùng chọn khi dán hay điền. .tbl-formula: thanh công thức. button[data-fullscreen]: toàn màn hình, Esc để thoát.
8Số giờ làm
6,5Thiếu giờ
PNghỉ phép
KNghỉ không phép
Chưa chấm
Chưa vào làm, đã nghỉ việc
Chủ nhật (CN)
Thứ Bảy (T7)
Hôm nay
Chưa tới
Tự tính, sửa được
Từ máy vân tay
Bảng chấm công tháng 10/2026
5 người · hôm nay 23/10 · Tạm tính
Nguyễn Văn Hùng · Giờ làm · ngày 16
Đang sửa: 7,5 giờ làm, phần còn lại của ca là nghỉ phép (P). Enter để lưu, Esc để bỏ.
STT
Mã thẻ
Họ tên
Hạng mục
1T5
2T6
3T7
4CN
5T2
6T3
7T4
8T5
9T6
10T7
11CN
12T2
13T3
14T4
15T5
16T6
17T7
18CN
19T2
20T3
21T4
22T5
23T6
24T7
25CN
26T2
27T3
28T4
29T5
30T6
31T7
Tổng
Đơn giá
Thành tiền
Thực lĩnh
Tổ hàn 1 · 3 người
1
CN-014
Nguyễn Văn HùngChính thức
Giờ làm giờ
8
8,5
4
8
8
8
8
7,5P
4
8
8
Chưa chấm
8
4
8
8
8
8
8
204
45.000
9.180.000
9.640.000 đ
Tăng ca giờ
2
2
0,5
2
6,5
60.000
390.000
Suất ăn suất
1
1
1
3
25.000
75.000
2
CN-022
Trần Thị LanKhoán
Giờ làm giờ
4
8
8
6,5
8
8
4
8
8
8
Chưa chấm
8
4
8
5K
8
8
8
148,5
41.000
6.088.500
6.120.500 đ
Tăng ca giờ
0,5
0,5
1
60.000
60.000
Suất ăn suất
1
1
25.000
25.000
3
CN-031
Lê Quang MinhChính thức
Giờ làm giờ
8
8
4
8
8
8
8
8
4
8,5
Chưa lưu · Thử lại. Mất kết nối khi lưu ô này.
Giá trị đã gõ: 8,5, vẫn giữ trên ô.
7
Ô này vừa được sửa bởi Kế toán Hoa (10:42). Giá trị trên máy chủ là 8.
Giá trị đã gõ: 7, vẫn giữ trên ô.
8
8
8
4
8
8
8
8
8
196
45.000
8.820.000
8.915.000 đ
Tăng ca giờ
1
1
2
60.000
120.000
Suất ăn suất
0
25.000
0
Tổ lắp dựng · 2 người
4
CN-040
Phạm Văn TàiKhoán
Giờ làm giờ
8
P
4
8
8
8
8
8
4
8
8
8
8
8
4
8
8
8
8
8
200
36.000
7.200.000
7.402.000 đ
Tăng ca giờ
1,5
1,5
1,5
1,5
1
7
26.000
182.000
Suất ăn suất
2
2
10.000
20.000
5
CN-047
Đỗ Thị MaiKhoán
Giờ làm giờ
8
8
4
8
K
8
8
6,5
4
8
8
8
8
8
4
P
8
0,5
K
8
176,5
20.000
3.530.000
Âm 1.250.000 đ
Tăng ca giờ
0
26.000
0
Suất ăn suất
0
25.000
0
Sản lượng kg
850
850
850
1.200
850
850
850
850
1.200
850
850
850
1.200
850
850
850
1.200
850
850
850
16.950
—
—
Tổng giờ cả xưởng
340
334
172
340
334
344
338
338,5
172
338
340
342
344
338
172
344
338
340
342
344
8.214
553.814.491 đ
Tổng tăng ca
9
10
11
8
9
10
11
12
8
10
11
12
8
9
10
12
8
9
10
11
196,5
Tổng suất ăn
6
7
5
7
5
6
7
5
6
5
6
7
5
6
7
6
7
5
6
7
118
Cuộn khung theo cả hai chiều: đầu bảng, bốn cột (STT, Mã thẻ, Họ tên, Hạng mục), cột Thực lĩnh và ba dòng tổng đứng yên. Hùng ngày 16 đang sửa (ô gõ 5rem), ngày 23 đang lưu; Minh ngày 12 lỗi lưu và 13 xung đột (bấm vào ô để xem thông báo, cuộn để thấy nó đi theo ô); Tài ngày 5–8 là một vùng chọn 2 × 4. Mai có bốn dòng (thêm Sản lượng, “1.200” kg) và thực lĩnh âm (chữ “Âm”). Bấm “Toàn màn hình” để bảng phủ cả cửa sổ; Esc để thoát.
Danh sách dòng
Danh sách việc cần làm, mỗi việc một dòng thay cho một bảng.
ul.work-list > li > a.work-item (là div khi dòng không phải liên kết; cả dòng bấm được, rê chuột tô nền): một dấu đầu dòng (.code-chip, icon), .work-main và .work-end. .work-main có .work-title (.work-code đậm rồi .work-name), .work-sub (một dòng mờ, dài thì cắt bằng dấu ba chấm) và .work-reason (icon và một câu màu cảnh báo: vì sao dòng này cần xem). .work-end có trạng thái (.tag, một con số) và .work-meta (ngày, giờ). Đặt trong .panel-flush để các dòng chạy sát mép thẻ, ngăn nhau bằng một vạch. Dưới 26rem bề ngang của chính nó, phần cuối chuyển xuống dưới chữ. Dùng cho hàng đợi ở trang tổng quan: vài dòng, mỗi dòng một việc. Khi người xem cần so sánh các cột giữa nhiều dòng thì dùng bảng.
Dòng tiêu đề đứng trên một nhóm dòng: tên nhóm, số lượng và số liệu của nhóm (tổng ròng của ngày, “4/5 đã chấm”), có bản dính khi cuộn.
h3.group-head (hoặc h4) gồm .group-head-title (đậm, được xuống dòng), .group-head-count (mờ: “· 4” kèm đơn vị trong .visually-hidden, dấu chấm giữa để aria-hidden) và .group-head-sum ở cuối dòng, không bao giờ xuống dòng: số liệu có .num-in, .num-out, .num-neg bên trong, hoặc chữ như “4/5 đã chấm”. Nó là thẻ tiêu đề thật nên trình đọc màn hình nhảy được từ nhóm sang nhóm; đặt nó trên danh sách của nhóm (ul.work-list, ul, .menu, một div các dòng): mỗi nhóm là một tiêu đề và một danh sách. Nền --surface-2 giữa hai đường kẻ, đọc như dòng tổng của nhóm; lề hai bên lấy từ --group-head-px (mặc định --sp-4, bằng đệm của dòng bên dưới). .group-head-sticky dính ở đầu khung cuộn (--sticky-top là chiều cao thanh bên trên) trên nền --surface-2 có đường kẻ dưới để các dòng trượt qua phía dưới; bọc mỗi nhóm (tiêu đề và danh sách) trong một div thì tiêu đề sau đẩy tiêu đề trước ra thay vì đè lên. Không có nút gập nhóm.
Mỗi ngày là một nhóm: tên ngày, số phiếu và tổng ròng của ngày (+ 2.350.000 đ xanh, − 3.550.000 đ đỏ; dấu đi cùng số nên màu không đứng một mình). Dòng ngày nằm trên nền --surface-2 giữa hai đường kẻ, đọc như dòng tổng của các phiếu bên dưới. Icon nói nguồn tiền: money tiền mặt, bank ngân hàng.
Số liệu có thể là chữ: “4/5 đã chấm”. Cùng lớp, cùng chỗ; không có dấu hay màu nào của sổ quỹ.
Tên nhóm dài, danh sách là các div
Danh mục chi phí vận hành của cơ sở sản xuất và các khoản phải trả định kỳ theo tháng· 3 mục
Điện− 2.870.000đ
Nước− 310.000đ
Tên nhóm quá dài thì xuống dòng, số đếm vẫn nằm liền một khối. Nhóm không có .group-head-sum chỉ còn tên và số đếm; các dòng bên dưới có thể là bất cứ thứ gì (ở đây là div).
Khung cắt ngang giữa một dòng phiếu (không cắt ngang tiêu đề), nên nhìn là biết còn nữa; cuộn thì tiêu đề ngày dính ở đầu, dòng trượt dưới nền --surface-2, ngày sau đẩy ngày trước đi. Khung có tabindex="0" để dùng được bàn phím.
Sortable rows
Vệ sinh cửa hàng đầu caHằng ngày · cần 2 ảnh
Kiểm tra nhiệt độ tủ lạnhHằng ngày
Chụp ảnh quầy pha chếThứ hai, thứ năm · cần 1 ảnh
Đóng cửa và khóa kétCuối ca
ul.sort-list[data-sortable]: kéo tay cầm (chuột hoặc ngón tay), hoặc bấm nút mũi tên lên xuống, là cách không cần kéo (bàn phím, đọc màn hình). kit.js dời dòng, đọc vị trí mới (“Vệ sinh cửa hàng đầu ca: vị trí 2 trên 4”) và bắn change với detail là { item, from, to }. Dòng đầu mất nút lên, dòng cuối mất nút xuống (aria-disabled).
Pager
Phân trang đầy đủ, có số dòng, gọn và Trước/Sau; tự gọn trên điện thoại.
nav.pager với aria-label: nút trước và sau (.btn-icon.btn-sm, aria-label), .pager-pages chứa các nút số (trang hiện tại aria-current="page") và .pager-gap cho dấu "…", .pager-status ("Trang 3 / 12") thay các nút số khi màn dưới 40rem hoặc khi thêm .pager-compact. .pager-center canh giữa khi đứng riêng; trong bảng, .pager-size và .pager-range nằm bên trái. Dãy số luôn đủ 7 chỗ (1 … 4 5 6 … 12) nên thanh không nhảy khi đổi trang; tenant tính dãy này, hàm mẫu ở cuối trang. Thu nhỏ cửa sổ dưới 40rem để xem hai kiểu đầu thu về "Trang x / y".
Notice, toast, empty state
Thông báo trong trang (bốn mức, hai mật độ) và toast góc trên phải.
.notice (-ok -warn -danger -info, -compact một dòng) gồm svg.notice-icon, .notice-body (.notice-title, nội dung, .notice-actions) và nút .notice-close. Mỗi mức có icon riêng (thông tin, thành công, cảnh báo tam giác, lỗi) và vạch màu bên trái, nên không chỉ dựa vào màu. Lỗi nên có role="alert", thành công role="status". Toast: .toast-host > .toast (-ok -warn -bad, mặc định là thông tin) gồm .toast-icon, .toast-body (.toast-title, .toast-text), .toast-action ("Hoàn tác") và .toast-close; nằm góc trên bên phải dưới thanh trên (điện thoại: cả chiều ngang) để không che phân trang; .empty.
Thông báo chung
Kỳ báo cáo tháng này chưa khóa.
Đã lưu
Phiếu PN-0017 đã được lưu.
Sắp đến hạn
3 phiếu cần duyệt trước thứ Sáu.
Không kết nối được máy chủ
Vui lòng thử lại sau ít phút.
Mẹo
Dán nhiều dòng từ Excel vào bảng để nhập nhanh.
Kỳ báo cáo chưa khóa.Còn 2 phiếu chờ duyệt.
Không lưu được 3 dòng.Kiểm tra các ô báo lỗi.
Nút đóng chỉ ẩn thông báo trong trang mẫu này.
Toast
Đã lưu phiếu PN-0017
Kho và công nợ đã cập nhật.
Không lưu được phiếu
Máy chủ không phản hồi. Thử lại sau ít phút.
Phiếu sắp quá hạn duyệt
3 phiếu cần duyệt trước thứ Sáu.
Đã đồng bộ 12 phiếu mới
Toast thành công tự ẩn sau 5 giây; cảnh báo và lỗi ở lại đến khi đóng.
Toast thành công và thông tin tự biến mất sau 5 giây, cảnh báo và lỗi ở lại đến khi đóng; rê chuột hoặc focus vào thì giữ lại. Mới nhất ở trên, tối đa ba, không bỏ toast lỗi để nhường chỗ.
Chưa có phiếu nào
Tạo phiếu đầu tiên để bắt đầu theo dõi.
Icon lấy từ icons.svg: .empty-ic tự lấy màu chữ nhạt và cỡ 3rem, có hoặc không có .icon.
Chưa có việc nào hôm nay
Quản lý chưa giao việc cho ca này.
Neutral notice
Thông báo xám có biểu tượng khóa, cho trạng thái đã khóa, bị chặn, chỉ xem.
.notice.notice-neutral dùng đúng cấu trúc của các mức khác (svg.notice-icon với icons.svg#lock, .notice-body với .notice-title và .notice-actions, button.notice-close; -compact cũng dùng được). Nền --surface-2, viền --panel-border, biểu tượng và vạch --muted, tiêu đề --text: các cặp màu này đã nằm trong bộ kiểm tra palette. Đây là trạng thái của trang, không phải tin báo gấp: dùng role="status" hoặc không có role, không bao giờ role="alert". Màu xám không phải dấu hiệu: biểu tượng khóa và câu chữ mới nói điều đó. Biểu tượng là phần markup như các mức khác, bỏ svg.notice-icon thì hộp vẫn đúng.
Liên hệ quản lý kho để được cấp quyền sửa phiếu kho.
Có nút đóng (.notice-close); trang chủ ẩn hộp khi đóng.
Phiếu đã chốt
Phiếu này đã vào sổ và chỉ để xem.
Không có biểu tượng (bỏ svg.notice-icon khỏi markup): vẫn là một hộp đúng, chữ nói nghĩa.
Tiến độ
Một tập tiêu chí, mỗi dòng có kết quả riêng bằng nhãn trạng thái.
Đặt trong .panel sau .panel-head (tên bên trái, số lượng bên phải bằng .muted). ul.progress-list > li.progress-item > .progress-row (span, hoặc a / button khi bấm dòng để mở chỉ tiêu đó) > .progress-no (mã do tenant đặt: "1/.", "A.2") + .progress-label + một .tag kết quả, cùng nhãn trạng thái với bảng: tag-ok đạt, tag-warn cần xem lại, tag-bad không đạt, tag-draft chưa có. Kết quả là chữ trong nhãn nên không phụ thuộc màu. Dòng đang xem (aria-current="true") có nền tô và vạch bên trái như dòng được chọn của bảng, chữ in đậm. Khác thanh bước (.stepper): thanh bước là các bước làm lần lượt, còn đây là các mục độc lập, mỗi mục chỉ báo kết quả của nó.
Chỉ tiêu
8
Hồ sơ nghiệm thu
4
1/.Biên bản nghiệm thuĐạt
2/.Bản vẽ hoàn côngCần xem lại
3/.Chứng nhận xuất xưởngKhông đạt
4/.Hóa đơn đầu vàoChưa kiểm
Trái: bấm dòng để chuyển dòng đang xem. Phải: dòng không bấm được, đủ bốn kết quả.
Thanh tiến độ báo trạng thái
Thanh tiến độ là nguồn duy nhất của một trạng thái (đã ghi 120/300 dòng): có vai trò thanh tiến độ, giá trị và câu nói cho trình đọc màn hình, kèm dòng chữ số; có bản chưa biết độ dài.
.bar nhỏ sau một con số vẫn là trang trí (aria-hidden="true", con số đứng cạnh nói thay). Khi thanh là nguồn duy nhất thì nó là thanh tiến độ: div.bar[role="progressbar"] với aria-valuenow, aria-valuemin, aria-valuemax, aria-valuetext (“Ghi 120/300 dòng”: câu mà trình đọc nói thay cho “40%”) và tên bằng aria-label hoặc aria-labelledby (“Ghi sổ”). Độ đầy là --v (từ 0% đến 100%), trang giữ cho khớp với aria-valuenow. Thanh rộng hết khung (--bar-w: 100%; quy tắc nào đặt bề rộng riêng, như thanh trong ảnh thu nhỏ, thì thắng) và dày 0,5rem khi đứng ngay dưới .bar-label (--bar-h đổi độ dày). data-tone="ok|warn|bad" đổi màu phần đầy (cùng bộ màu với .bar-ok, .bar-warn, .bar-bad); màu không bao giờ đứng một mình nên tình trạng phải có trong chữ. .bar-label là dòng chữ số đi kèm, ở trên hoặc bên cạnh: mờ, --font-figure, chữ số thẳng hàng; hai span trong đó nằm ở hai đầu. Nhãn lặp lại aria-valuetext nên khi tĩnh thì đặt aria-hidden="true"; khi trang đổi nhãn theo tiến độ thì dùng role="status" (polite) và để nó đọc được, vì thanh tiến độ không tự được đọc lại khi giá trị đổi. .bar[data-indeterminate] cho việc chưa biết độ dài: không có aria-valuenow (giữ aria-valuetext, “Đang ghi…”), phần đầy là sọc chéo chạy khắp thanh; khi người dùng chọn giảm chuyển động thì sọc đứng yên. Phần demo cập nhật bên dưới (nút “Ghi 10 dòng”) chỉ là script của thư viện mẫu.
0%, 40% và 100% với tone
Ghi 0/300 dòng0%
Ghi 120/300 dòng40%
Đã ghi xong 300/300 dòng100%
Gần hết hạn mức: 270/300 dòng90%
Dừng vì lỗi ở dòng 82/30027%
Mỗi thanh có aria-label và aria-valuetext; dòng chữ số phía trên chỉ lặp lại nên có aria-hidden="true". Tone nằm cả trong chữ (“xong”, “Gần hết hạn mức”, “Dừng vì lỗi”).
Chưa biết độ dài (data-indeterminate)
Đang ghi…
Không có aria-valuenow. Sọc chéo chạy khắp thanh; dừng lại khi hệ điều hành bật “giảm chuyển động”.
Cập nhật trực tiếp (demo của thư viện mẫu)
Ghi 0/300 dòng0%
Mỗi lần bấm: aria-valuenow, aria-valuetext, --v và nhãn cùng đổi; nhãn là role="status" nên trình đọc màn hình nói câu mới. Đủ 300 dòng thì thanh sang tone ok và nút tắt.
Chú thích và tooltip
Giữ một dòng phụ đề; lời giải thích dài ẩn đến khi bấm hoặc rê chuột.
.subtext là <details>: summary chứa .subtext-line (một dòng, cắt bằng "…" khi dài) và svg.subtext-caret, nội dung ẩn nằm trong .subtext-more. .tip là bong bóng chữ của nút .tip-btn (aria-controls, aria-describedby, aria-expanded), đặt cạnh nhãn hoặc tiêu đề trong .tip-row; mở khi rê chuột hoặc focus, bấm để giữ mở (trên điện thoại là chạm), Esc hoặc bấm ra ngoài thì đóng. Điều người dùng phải đọc mới điền được (định dạng bắt buộc, lỗi) không phải chú thích: để hiện sẵn bằng .field-hint hoặc .field-error.
So sánh: nhiều chữ và gọn
Thêm khách hàng
Nhập thông tin khách hàng mới. Thông tin này được dùng để lập phiếu bán, theo dõi công nợ và in giấy báo. Các trường có dấu * là bắt buộc.
Nhập đúng tên như trên hợp đồng hoặc hóa đơn, không viết tắt.
Gồm 10 số, bắt đầu bằng 0.
Tổng tiền khách được nợ cùng lúc. Vượt hạn mức thì phiếu bán mới cần quản lý duyệt. Để 0 nếu khách trả ngay.
Thêm khách hàng
Dùng cho phiếu bán, công nợ và giấy báo.
Nhập thông tin khách hàng mới. Thông tin này được dùng để lập phiếu bán, theo dõi công nợ và in giấy báo. Các trường có dấu * là bắt buộc.
Nhập đúng tên như trên hợp đồng hoặc hóa đơn, không viết tắt.
Gồm 10 số, bắt đầu bằng 0.
Tổng tiền khách được nợ cùng lúc. Vượt hạn mức thì phiếu bán mới cần quản lý duyệt. Để 0 nếu khách trả ngay.
Trái: lời giải thích hiện sẵn dưới mọi ô, màn hình dài và rối. Phải: một dòng phụ đề, giải thích đặt sau nút ⓘ; riêng định dạng số điện thoại cần để điền đúng nên vẫn hiện sẵn.
Tiêu đề có nút giải thích
Công nợ phải thu
Tổng tiền khách còn nợ sau khi trừ phiếu thu, tính đến cuối ngày hôm qua. Chưa gồm phiếu nháp.
Tính đến hết ngày 29/10/2026, 6 khách quá hạn.
Số liệu cập nhật mỗi đêm lúc 00:30. Khách quá hạn là khách có phiếu bán chưa thu quá 30 ngày kể từ ngày giao. Phiếu nháp và phiếu đã hủy không được tính.
Tooltip
Tên của nút chỉ có biểu tượng, hiện khi rê chuột một lúc hoặc khi tới bằng bàn phím.
Nút vẫn có aria-label làm tên; thêm data-tooltip để hiện chính chữ đó (hoặc chữ trong data-tooltip="…", ví dụ kèm phím tắt). Tenant giữ một .tooltip[popover="manual"] có aria-hidden="true" (tên đã nằm ở nút, trình đọc màn hình không đọc hai lần), hiện nó phía trên nút hoặc phía dưới khi hết chỗ, đóng khi chuột rời, nút mất tiêu điểm, cuộn trang hoặc nhấn Esc; chuột được phép di sang chính nó. Vì là popover nên không bị khung cuộn của bảng hay hộp thoại cắt. Là gợi ý, không phải chỗ cho thứ người dùng bắt buộc phải đọc: màn hình cảm ứng không có, nên biểu tượng khó đoán thì cần nhãn chữ. Không dùng cho nút disabled. Khác với .tip (chữ giải thích đứng cạnh nhãn hoặc tiêu đề, bấm để giữ).
Số phiếu
Khách hàng
Thao tác
PN-0012
Công ty Phú Thành
PN-0013
Nguyễn Văn An
Hàng trên: bốn nút, nút cuối có chữ riêng kèm phím tắt. Bảng dưới: nút trong hàng của bảng mở tooltip mà khung cuộn của bảng không cắt được, vì nó nằm ở lớp trên cùng của trang.
Modal và drawer
Hộp thoại mở bằng showModal(), có sẵn lớp phủ, khóa focus và phím Esc.
<dialog class="modal"> (-sm -lg) với .modal-head, .modal-body, .modal-foot; mở bằng showModal(), trình duyệt lo lớp phủ, khóa focus và phím Esc. Trên điện thoại nó thành tấm trượt từ dưới lên.
Drawer
Ngăn trượt từ phải hoặc trái cho chi tiết bản ghi và bộ lọc.
<dialog class="drawer"> (-lg rộng 560 px, -left trượt từ trái) với .drawer-head, .drawer-body, .drawer-foot; mở bằng showModal() như hộp thoại, nên có lớp phủ, khóa focus và phím Esc, bấm nền thì đóng. Dùng cho chi tiết một bản ghi hoặc biểu mẫu lọc mà người dùng không muốn rời trang; việc cần quyết định (xác nhận hủy) vẫn là hộp thoại. Trên điện thoại nó chiếm gần hết chiều ngang và chừa một dải lớp phủ.
Tabs và menu
Thẻ chuyển (tabs) và nút chọn kiểu viên thuốc.
.tabs (role="tablist") > .tab (role="tab", aria-selected, .tab-count); nội dung là .tab-panel. Kiểu viên thuốc: .tabs-pill. Phím mũi tên, Home, End do tenant gắn (mẫu ở cuối trang).
24 phiếu trong tháng này.
5 phiếu đang chờ người duyệt.
17 phiếu đã duyệt.
Menu
Menu mở từ nút: thao tác, chọn một, bật tắt mục, tài khoản.
.menu là popover mở từ một nút aria-haspopup="menu" có aria-controls trỏ tới menu. Mục là .menu-item (role="menuitem"); chọn một trong nhiều là role="menuitemradio", bật tắt từng mục là role="menuitemcheckbox", cả hai dùng aria-checked và .menu-check để hiện dấu tích; nhóm có role="group" với .menu-label; đầu menu tài khoản là .menu-head chứa .avatar-label. Nút có chữ dùng data-menu-align="start" để canh mép trái. Bấm Esc hoặc ra ngoài thì đóng, mũi tên, Home, End di chuyển, focus về nút khi đóng. Danh sách chọn có tìm kiếm ở mục "Dropdown có tìm kiếm".
Thao tác, chọn một, bật tắt cột, tài khoản
Global search
Nút trông như ô nhập; bấm hoặc nhấn Ctrl K để mở hộp tìm trong mọi bản ghi.
.search-btn (có .search-btn-text và kbd.kbd gợi ý phím) mở dialog.modal.modal-search: .search-box chứa input.search-input[role="combobox"], .search-results[role="listbox"] gồm các .search-group và .search-item[role="option"] (.search-item-icon, -title, -sub, -meta), .search-empty và .search-foot. Dưới 40rem hoặc với .search-btn-compact nút chỉ còn icon, chữ vẫn nằm trong trang cho trình đọc màn hình. Trên .topbar nút tự đổi sang màu header. Tenant tự lấy kết quả (gọi API, nhóm theo loại), đặt data-active khi bấm ↑ ↓ và mở mục khi bấm Enter; gallery chỉ lọc vài mục mẫu, không cần gõ dấu.
Danh sách liên kết tới các phần của một trang dài, tô phần đang xem.
nav.toc[aria-label] > ul > li > a; phần đang xem có aria-current="location" (đậm, vạch bên trái đổi màu chính, không chỉ đổi màu). Một danh sách đặt sau liên kết là mục con. .toc-label là tiêu đề nhóm (chữ, không phải liên kết) và có danh sách riêng. Không thêm class thì mục lục giữ kiểu mặc định này (vạch trái); các ví dụ dưới đây dùng kiểu Vibe. Dùng cho trang dài có nhiều phần: cài đặt, hướng dẫn, biểu mẫu chia mục. Giữ nó trong tầm nhìn bằng position: sticky ở phần bọc, và chuyển dấu khi cuộn; cột bên phải của chính trang này là mục lục dựng từ component này (từ 90rem trở lên nó nằm bên phải; hẹp hơn nó gập thành "Trên trang này" ở đầu trang). Trang ngắn hoặc đã có thẻ chuyển (.tabs) thì không cần.
Kiểu Vibe: .toc-pill (bỏ vạch trái, mục đang xem là viên xám đậm chữ), .toc-card + .toc-title (thẻ có tiêu đề), details.toc-float (thu thành nút icon, mở ra bên dưới). Mục con là một danh sách đặt sau liên kết. Cột phải của gallery là chính thẻ này, kèm mục con. Cột trái là thanh bên của kit: mỗi nhóm một details.side-group, mỗi phần một mục con.
Dải đường dẫn và tiêu đề phần
Dải liên kết ngang tới các phần của một trang, cuộn ngang trong chính nó ở phone, ẩn bớt mục theo vai trò; và tiêu đề của một phần có đường kẻ dưới và chỗ cho nút ở cuối.
nav.toc.toc-strip[aria-label] > ul > li > a: một cấp, không có .toc-label. Ở mọi bề rộng các liên kết nằm một hàng và cuộn ngang bên trong dải (không bao giờ cuộn cả trang), bám vào mép đầu; mỗi liên kết cao ít nhất --tap, chữ không xuống dòng. Phần đang xem đánh dấu aria-current="true" (aria-current="location" cũng được): chữ đậm, màu --text và thanh 2 px --primary ở dưới, nên dấu hiệu không chỉ là màu. Trang tự chuyển dấu khi cuộn. Muốn ẩn một mục theo vai trò thì đặt thuộc tính hidden trên li (hoặc a): CSS không phải làm gì, các mục còn lại khép lại. Mọi liên kết đều focus được nên người dùng bàn phím tới được mục ngoài màn hình (trình duyệt tự cuộn). .section-head (div hoặc header) > h2 (hoặc h3) + .section-head-actions (tùy chọn: nút “Excel”, một liên kết) có đường kẻ 1 px dưới --panel-border; không cần panel. Tiêu đề lấy chỗ còn lại, các nút nằm ở cuối; khi tiêu đề hẹp hơn khoảng 28rem thì các nút xuống dưới tiêu đề. Màu: --text, --muted và --primary (thanh, không phải chữ) trên --bg và --surface, đã được kiểm.
Dải sáu liên kết, một mục ẩn theo vai trò
Mục “Thu chi” đang xem (aria-current="true", thanh dưới). “Lãi gộp” có hidden (chỉ Quản trị thấy) nên không chiếm chỗ. Ở phone dải cuộn ngang trong chính nó; trang không cuộn ngang. Bấm một liên kết để thấy dấu nhảy về đúng phần dưới.
Tiêu đề phần: có nút Excel và không có nút
Thu chi trong quý 3
Phần nội dung của “Thu chi”.
Công nợ
Phần nội dung của “Công nợ”: tiêu đề không có nút.
Tiêu đề thứ nhất có .section-head-actions; khi chỗ hẹp hơn khoảng 28rem (như ở phone) nút xuống dưới tiêu đề. Tiêu đề thứ hai chỉ có đường kẻ.
Khung hẹp 18rem: nút xuống dưới tiêu đề
Nhân công và chấm công tháng mười
Tiêu đề dài xuống dòng, nút ở dòng dưới; đường kẻ nằm dưới cả hai.
Page head and columns
Đường dẫn, đầu trang với tiêu đề, nhãn và nút, rồi hai cột có cột phụ dính.
Khung của một trang trong .container: .stack (các khối xếp dọc, --stack-gap) > nav.crumbs[aria-label] > ol > li (trang hiện tại aria-current="page"), rồi header.page-head gồm khối tiêu đề (h1, .page-lead mô tả, .page-meta một dòng nhãn và dữ kiện) và .page-actions ở bên phải (rơi xuống dưới tiêu đề khi hẹp), rồi .page-cols > .page-main + .page-side (thêm .stack khi có nhiều thẻ). Hai cột nằm cạnh nhau khi cột chính còn ít nhất --main-min (36rem) và cột phụ rộng --side-w (20rem), tính theo chỗ trang có nên chạy được cả khi có thanh bên; không đủ chỗ thì cột phụ xuống dưới cột chính, rộng hết hàng. Cột phụ giữ trong tầm nhìn khi cuộn (cửa sổ cao từ 40rem), bên dưới --sticky-top (chiều cao thanh trên và một khoảng); nên để cột phụ ngắn hơn cột chính, và đặt nút chính của trang ở đó. --container-w đổi bề rộng tối đa của .container (72rem). Đổi cửa sổ hẹp dưới khoảng 60rem để xem cột phụ xuống dưới. Hàng đợi hai cột đều nhau dùng .page-cols.page-cols-even (xem ví dụ thứ hai). Cột phụ dính dưới thanh trên cùng ở --topbar-real-h (chiều cao thật của thanh: nút + đệm + viền, 61px ở kiểu chuẩn, 65px ở kiểu app); --topbar-h chỉ là chiều cao tối thiểu.
Chờ duyệtĐạt · 10 cỡLấy mẫu 24/10/2026Bùi Đức Thịnh
Thông tin trên phiếu
Đơn vị yêu cầu
Công ty CP Xây dựng Cầu đường Thành Đạt
Công trình
Đường D3 nối dài – gói thầu XL-02
Hạng mục
Cống hộp K0+350
Tư vấn giám sát
Công ty TNHH Tư vấn Giám sát Sao Việt
Lịch sử sửa từ đầu
3
Gửi duyệt lại
Bùi Đức Thịnh
v8
Sai số KL D22: Không đạt → Đạt
Đổi kết luậnBùi Đức Thịnh
Lý do: thử lại theo TCVN 1651: mẫu 2, 3 rớt thật
Gửi duyệt lần 1
Kết luận lúc đó: Không đạt
Ghi chú
Cột bên phải giữ nút phát hành trong tầm nhìn khi cuộn qua các thẻ dài như thế này.
Khung này lấy chỗ của riêng nó: cửa sổ rộng thì hai cột, hẹp thì cột phải xuống dưới. Cuộn trang để thấy cột phải đi theo.
Hai cột đều nhau
Nháp của tôi 2
TH-D3-14 · Cát vàng
TH-D3-16 · Đá 1×2
Sắp có kết quả 1
XM-D3-02 · Xi măng, đủ 28 ngày vào mai
Chờ duyệt 3
TH-D3-15 · Thép tròn trơn
TH-D3-12 · Bê tông M300
TH-D3-11 · Gạch
Không đạt trong 30 ngày 0
Không có kết quả không đạt.
.page-cols.page-cols-even > hai (hoặc ba) khối con, mỗi khối thường là .stack của vài thẻ: các cột rộng bằng nhau khi mỗi cột còn ít nhất --col-min (28rem), không đủ chỗ thì xếp dọc. Không có cột dính.
Thẻ dòng hàng, dòng kiểm kê và nút thêm gạch đứt
Dòng hàng của phiếu kho trên điện thoại là một thẻ (tên, mã · đơn vị, hai ô lớn số lượng và đơn giá, thành tiền, lỗi riêng), cuối danh sách có nút “+ Thêm vật tư”; dòng kiểm kê có ô nhập số ngay trong dòng.
li.line-card (trong ul.line-card-list, cách nhau --sp-3): .line-card-head (.line-card-name đậm, .line-card-sub mờ “VT-0101 · kg”, nút xóa .btn.btn-ghost.btn-icon ở cuối, có tên theo dòng), .line-card-body (hai .field cạnh nhau, nhãn trên ô: input[data-number] cho số lượng, input[data-money] cho đơn giá; chữ lớn hơn cỡ ô thường, số căn phải, inputmode thập phân; ghi đơn vị trong nhãn), .line-card-total (.line-card-total-label “Thành tiền” và output.line-card-total-figure, không xuống dòng, dùng --font-figure; output tự là vùng thông báo lịch sự) và p.field-error[aria-live="polite"] luôn có trong thẻ, trống cho đến khi dòng sai: có chữ thì thẻ viền đỏ, ô lỗi có aria-invalid="true" và aria-describedby trỏ vào lời lỗi. Tenant tự tính thành tiền (demo này có một đoạn script của riêng trang mẫu). button.btn.btn-dashed.btn-block ở cuối là nút thêm dòng: là .btn với viền đứt, đủ các trạng thái của .btn. li.count-row trong ul.count-list: .count-row-main (tên, mã · đơn vị), .count-row-book (“Sổ: 120,5”), .count-row-field với nhãn .visually-hidden và input[data-number] hẹp, và .count-row-diff bên dưới: .num-out/.num-in kèm chữ “Lệch” và dấu, hoặc chữ mờ “Khớp”; trống thì không chiếm chỗ. .work-act giờ cũng chứa được một .input (rộng 6 rem, số căn phải).
Hai thẻ dòng hàng, một thẻ có lỗi, và nút thêm
Thép hộp 40×40×1,4VT-0101 · kg
Thành tiền
Que hàn 3,2 mm (hộp 5 kg)VT-0214 · hộp
Thành tiền
Số lượng 9 hộp lớn hơn tồn kho 8 hộp. Giảm số lượng hoặc đổi sang kho khác.
Sửa số lượng hoặc đơn giá thì thành tiền đổi theo (script của trang mẫu). Thẻ thứ hai có lời lỗi: viền đỏ, lời lỗi nằm trong thẻ và trình đọc màn hình đọc nó khi nó xuất hiện. Cỡ 24 rem là điện thoại 390 px trừ lề.
Danh sách kiểm kê: lệch, khớp, chưa đếm
Thép hộp 40×40×1,4VT-0031 · cây
Sổ: 120,5Lệch − 2,5
Thép tấm 3 ly (cuộn)VT-0044 · kg
Sổ: 386,4Khớp
Ống kẽm Ø 27 dài 6 mVT-0052 · cây
Sổ: 45
Dòng 1 đếm ít hơn sổ (.num-out, chữ “Lệch” và dấu trừ), dòng 2 khớp (chữ mờ), dòng 3 chưa đếm: ô trống và không có dòng lệch.
.input trong .work-act: ô hẹp 6 rem, số căn phải, nhãn ẩn nêu tên dòng.
Offline draft
Biểu mẫu giữ bản nháp trên máy và hỏi có khôi phục không; báo khi mất mạng.
form[data-draft="khóa"] (khóa riêng cho từng biểu mẫu, ví dụ phieu-chi:new; data-draft-ttl là số giờ, mặc định 72). kit.js chỉ lưu vào localStorage (tvkit:draft:khóa) và không gửi gì qua mạng: lưu thật và gửi lại khi có mạng là việc của tenant. Sau 400 ms không gõ nữa, các ô có name được lưu: ô chữ, số, ngày, giờ, số tiền (như đang hiện, “1.250.000”), textarea, select, checkbox, radio, ô dropdown của kit (chữ của mục đang chọn) và [role="radiogroup"][data-name] như .seg (data-value của mục, hoặc chữ của mục). Không bao giờ lưu: mật khẩu, tệp, ô ẩn, nút, ô khóa hoặc chỉ đọc, và gì nằm trong [data-draft-skip]. Mở lại biểu mẫu mà có bản nháp còn hạn và khác giá trị ban đầu thì đầu biểu mẫu có .notice.notice-warn.draft-banner[role="status"] với “Khôi phục” (điền lại từng ô, bắn input và change nên ô số tiền, dropdown, lịch hiện đúng; focus về ô đầu tiên được điền; bỏ thanh) và “Bỏ nháp” (xóa nháp và thanh). Trong lúc thanh còn hiện, kit không lưu đè lên bản nháp đang chờ quyết định. TvKit.draft.clear(form hoặc khóa) gọi sau khi lưu thành công (biểu mẫu reset cũng xóa), TvKit.draft.save() lưu ngay, TvKit.draft.has(khóa) hỏi có nháp không. Khi trình duyệt mất mạng (offline), biểu mẫu thêm dòng .draft-offline[role="status"] (đầu .action-bar nếu có, không thì cuối biểu mẫu) và bắn draft-offline; khi có mạng lại bắn draft-online với detail.hasDraft, để tenant gửi lại. Câu chữ là tiếng Việt mặc định, đổi bằng data-draft-msg-found|restore|discard|offline|yesterday hoặc TvKit.draft.messages. Nếu bộ nhớ trình duyệt bị chặn hay đầy thì không có nháp và không có lỗi.
Gõ vài ô, đợi nửa giây rồi tải lại trang: đầu biểu mẫu có thanh “Có bản nháp chưa lưu từ …”. “Lưu phiếu” giả lập lưu thành công và gọi TvKit.draft.clear; “Nhập lại” (reset) cũng xóa nháp.
Thử nghiệm
Chưa có sự kiện nào.
“Giả lập mất mạng” bắn sự kiện offline rồi online lên window, không cắt mạng thật: biểu mẫu hiện dòng .draft-offline và bắn draft-offline, rồi draft-online kèm detail.hasDraft.
Chấm công theo ngày
Mỗi người một dòng: nút nhanh, ô giờ và tăng ca, suất ăn; chỉ ngày khác thường mới cần chạm.
ul.entry-list > li.entry-row: .entry-who (tên, mã, đơn giá, giờ quẹt), .entry-quick (một .seg với data-tone: Đủ giờ, Nửa ngày, P, K), .entry-field.entry-hours và .entry-ot (.input-affix có đơn vị), .entry-toggles (chip bật tắt, .mark-auto “tự” khi phần mềm tự bật), p.entry-note (.entry-note-warn cho cảnh báo). data-state="changed": nền vàng nhạt và vạch trái khi đã sửa chưa lưu. Danh sách là container: từ 72rem một dòng, 36–72rem hai dòng, dưới 36rem xếp dọc với nút nhanh chiếm cả chiều ngang.
Trần Thị Lan, đã sửa, chưa lưuCN-022 · Khoán · 8 giờ/ngày · 07:31
giờ
giờ TC
Máy vân tay chỉ có một lần quẹt (07:31). Cơm tăng ca tự bật vì tăng ca trên 1,5 giờ.
Lê Quang MinhCN-031 · 45.000 đ/giờ · 8 giờ/ngày
giờ
giờ TC
Nghỉ nên bữa trưa tự bỏ; bật lại được nếu vẫn ăn.
Phạm Văn TàiCN-040 · Khoán · 8 giờ/ngày · nghỉ việc từ 28/10
giờ
Số giờ làm không quá 24.
giờ TC
Hùng: ngày thường, không chạm gì. Lan: đã sửa chưa lưu (nền vàng, vạch trái), dòng cảnh báo và “Cơm TC tự”. Minh: nghỉ phép (P), ô tăng ca và Ca đêm khóa. Tài: số giờ sai, lỗi nằm ngay dưới ô. Thu hẹp cửa sổ để thấy dòng xuống hai dòng (tablet) rồi xếp dọc (điện thoại).
Filter bar
Bộ lọc nhiều ô trên một danh sách, kèm dòng "Đang lọc" và dòng kết quả.
.list-filters xếp ba phần cách nhau: .panel chứa .filter-bar, hàng .filter-active và .result-bar. Trong .filter-bar mỗi .field có bề rộng riêng (--field-w, mặc định 13rem), .filter-grow cho ô tìm lấy phần còn lại. Ô tìm có icon là .input-icon; khoảng ngày là .range (hai ô quanh .range-sep, nhóm có role="group" và aria-labelledby). Mỗi bộ lọc đang bật là một .chip.chip-value với nút .chip-x (aria-label nói rõ bỏ bộ lọc nào), cuối hàng là .btn.btn-link "Xóa lọc". .seg là nhóm radio dạng nút liền (role="radiogroup", .seg-item[role="radio"]) để đổi cách sắp xếp hay xem. Gallery nối sẵn các ô với chip; khi bỏ một chip, focus chuyển sang chip kế tiếp.
Tất cả vật liệu
Bê tông
Thép
Xi măng
Không có kết quả
Mọi trạng thái trừ Hủy
Bản nháp
Chờ duyệt
Đã phát hành
Đã hủy
Không có kết quả
Mọi kết luận
Đạt
Không đạt
Không có kết quả
Ngày lấy mẫu
–
T2
T3
T4
T5
T6
T7
CN
T2
T3
T4
T5
T6
T7
CN
Bấm ngày bắt đầu, rồi ngày kết thúc.
Đang lọc:
62 mẫu · 9 nháp · 6 chờ duyệt · 46 đã phát hành · 1 đã hủy
Table as cards
Bảng nhiều cột thành danh sách thẻ khi khung hẹp, để đọc từ trên xuống thay vì cuộn ngang.
Thêm .tbl-cards vào .tbl-wrap và data-label (tên cột) vào mỗi td. Khung rộng dưới 36rem thì mỗi hàng thành một thẻ: ô đầu (th scope="row") là tiêu đề, các ô còn lại xếp hai cột với nhãn trên giá trị, nút của hàng (td.actions) nằm dưới cùng, ô chọn lên góc. Rộng hơn thì vẫn là bảng. Khung bọc là container nên một bảng trong cột hẹp cũng đổi, không chỉ trên điện thoại. Dùng cho bảng thường: không kèm -sticky, -select hay .tbl-scroll. Hàng tiêu đề vẫn còn cho trình đọc màn hình.
Khung hẹp (điện thoại)
Phiếu gần đây
Số phiếu
Khách hàng
Trạng thái
Số lượng (kg)
Thành tiền (₫)
Thao tác
ỚTPN-0012Ớt bột
Công ty Phú Thành
Đã duyệt
1.250,500
12.450.000
TXPN-0013Tiêu xay
Nguyễn Văn An
Chờ duyệt
4,162
3.280.000
MTPN-0014Muối tinh
Cửa hàng Minh Sơn
Bị từ chối
0,350
890.000
Khung rộng
Phiếu gần đây
Số phiếu
Khách hàng
Trạng thái
Số lượng (kg)
Thành tiền (₫)
Thao tác
ỚTPN-0012Ớt bột
Công ty Phú Thành
Đã duyệt
1.250,500
12.450.000
TXPN-0013Tiêu xay
Nguyễn Văn An
Chờ duyệt
4,162
3.280.000
MTPN-0014Muối tinh
Cửa hàng Minh Sơn
Bị từ chối
0,350
890.000
Cùng một bảng, hai độ rộng khung: dưới 36rem là thẻ, trên đó là bảng. Ô td.actions không có data-label nên không có nhãn; ô th đầu là tiêu đề của thẻ.
Ít cột số: --cards-cols: 3
Sổ nhập kho
Phiếu
Số lượng
Đơn giá
Thành tiền
PN-0012 · Ớt bột
12,5
86k
1,08tr
PN-0013 · Tiêu xay
4,162
120k
499k
PN-0014 · Muối tinh
0,35
12k
4k
--cards-cols: 3 trên .tbl-cards (mặc định 2) xếp ba ô cạnh nhau dưới tiêu đề thẻ: bảng ít cột số ngắn thấp hơn gần một nửa. Mỗi con số tối đa chín ký tự (hoặc viết gọn k, tr).
Bảng công trên điện thoại
Mỗi người một thẻ; mở thẻ thì 31 ngày cuộn ngang trong thẻ, cột hạng mục đứng yên, trang không cuộn ngang.
Thẻ là details.row-fold; trong thân là .tbl-wrap.tbl-scroll > .tbl.tbl-sticky-cols.tbl-marks với một cột dính data-sticky="1" và --sticky-w1: 8.5rem (chỉ CSS, không cần kit.js). Khi chạm, ô ngày về --tap. Năm của một người (xếp loại 12 tháng) là ol.mark-strip: 12 ô nhỏ dưới tên, mỗi ô có tháng và hạng bằng chữ cho trình đọc màn hình.
Trần Thị Lan148,5 giờ · 1 giờ TC · 6.120.500 đ
Hạng mục
1T5
2T6
3T7
4CN
5T2
6T3
7T4
8T5
9T6
10T7
11CN
12T2
13T3
14T4
15T5
16T6
17T7
18CN
19T2
20T3
21T4
22T5
23T6
24T7
25CN
26T2
27T3
28T4
29T5
30T6
31T7
Giờ làm giờ
4
8
8
6,5
8
8
4
8
8
8
Chưa chấm
8
4
8
5K
8
8
8
Tăng ca giờ
0,5
0,5
Suất ăn suất
1
Nguyễn Văn Hùng204 giờ · 6,5 giờ TC · 9.640.000 đ
Mở để xem 31 ngày.
Kéo ngang bảng trong thẻ: cột “Hạng mục” rộng 8,5rem đứng yên, trang không cuộn ngang ở 390px.
Năm của một người
Vũ Thị Lan
Trưởng phòng
96,3
8/9 tháng ≥ A
T1A+Tháng 1: A+
T2ATháng 2: A
T3ATháng 3: A
T4ATháng 4: A
T5ATháng 5: A
T6ATháng 6: A
T7BTháng 7: B
T8ATháng 8: A
T9A+Tháng 9: A+
T10ATháng 10: A, chưa chốt
T11Tháng 11: chưa tới
T12Tháng 12: chưa tới
Tháng 10 chưa chốt (khung đứt, chữ nghiêng), tháng 11–12 chưa tới (ô trống).
Chi tiết bản ghi
Danh sách nhãn và giá trị của một bản ghi, và dòng lịch sử các lần sửa.
dl.dl > div > dt + dd. Mỗi hàng đặt nhãn và giá trị cạnh nhau khi đủ chỗ, và nhãn nằm trên giá trị khi hẹp (cột bên, điện thoại), nên không cần điểm ngắt riêng. -lines kẻ một vạch giữa các hàng, -tight là cỡ nhỏ cho cột bên; --dl-key đổi độ rộng nhãn, --dl-val độ rộng tối thiểu của giá trị. Dùng thay bảng hai cột cho thông tin của một bản ghi (phiếu, công trình, khách). Lịch sử: ol.timeline > li.timeline-item > .timeline-mark (phiên bản, ví dụ v9, trong một viên; dòng không có thì có một chấm) và .timeline-body > .timeline-title (điều đã đổi), .timeline-meta (ai và lúc nào, span và time cách nhau một dấu chấm giữa; nhãn .tag đứng đầu nếu có), .timeline-note (lý do, trong hộp nền nhạt). Dòng mới nhất là aria-current="true" (viên hoặc chấm tô màu chính). Dòng không được bỏ sót có data-tone="warn|danger|ok|info" (viên hoặc chấm và hộp lý do cùng sắc); sắc không phải dấu hiệu duy nhất, chính dòng phải nói điều gì đã đổi, và nên kèm một nhãn .tag. Khác thanh bước dọc (.stepper-vertical): thanh bước là tiến độ các bước làm lần lượt, còn đây là nhật ký các lần sửa, không có bước xong hay chưa. .timeline-feed là dạng dòng hoạt động quanh một bản ghi: mỗi dòng là ngày (time.timeline-date, chấm trên đường), hàng bo tròn .timeline-card (.timeline-ic + .timeline-text + nút mở ở cuối) và tùy chọn .timeline-detail (nhãn, giá trị, nút).
Thông tin trên phiếu
Đơn vị yêu cầu
Công ty CP Xây dựng Cầu đường Thành Đạt
Công trình
Đường D3 nối dài – gói thầu XL-02
Hạng mục
Cống hộp K0+350
Ngày ký
27/10/2026 (ngày thí nghiệm cuối)
Tư vấn giám sát
Công ty TNHH Tư vấn Giám sát Sao Việt
Ảnh chụp lúc phát hành
Phát hành
28/10/2026 10:06 · Lê Minh Tuấn
Phiên bản
v9 (xét v1–v9)
Bộ tính
Thép, phiên bản 1
Lần sửa
3
Lịch sử sửa từ đầu
5
Gửi duyệt lại
Bùi Đức Thịnh
v9
Uốn D25 mẫu 6: (trống) → Không nứt
Bùi Đức Thịnh
Lý do: bổ sung nhận xét theo số thí nghiệm
v8
Sai số KL D22: Không đạt → Đạt (thử lại 4 mẫu)
Đổi kết luậnBùi Đức Thịnh
Lý do: thử lại theo TCVN 1651: mẫu 2, 3 rớt thật
v7
D22 mẫu 1 khối lượng 1.685,0 → 1.785,0 g
Bùi Đức Thịnh
Lý do: gõ nhầm số cân, số cân ghi 1.785,0 g
Gửi duyệt lần 1
Kết luận lúc đó: Không đạt
Bốn sắc
v12
Đã phát hành phiếu 486
Lê Minh Tuấn
v11
Chuyển cho Trưởng phòng
Bùi Đức Thịnh
v10
Trả lại: thiếu ảnh chụp mẫu
Lê Minh Tuấn
Lý do: chưa có ảnh mẫu D22 sau khi thử lại
v9
Đổi kết luận D22
Bùi Đức Thịnh
Hoạt động gần đây
Phiếu TH-D3-15 đổi kết luận Đạt bởi Bùi Đức Thịnh
Phiếu 486 phát hành cho Công ty CP Xây dựng Cầu đường Thành Đạt
Số phiếu
486/LAS-XD 1222
Mẫu D22Không đạt sai số khối lượng, chờ thử lại
Phiếu TH-D3-07 được duyệt bởi Lê Minh Tuấn
Trái đến phải: .dl-lines ở cột chính, .dl-tight ở cột hẹp (nhãn trên giá trị khi không đủ chỗ), lịch sử kiểu nhật ký phiên bản (.timeline: viên số phiên bản .timeline-mark hoặc chấm, tiêu đề, dòng người và giờ, lý do trong hộp), bốn sắc của viên và hộp lý do, rồi dòng hoạt động (.timeline-feed: ngày, hàng bo tròn có icon và câu có nhãn, nút mở ở cuối, dòng chi tiết bên dưới).
Hiển thị đổi trước và sau
Một lần sửa, từng trường một: tên trường, giá trị cũ gạch ngang, mũi tên, giá trị mới đậm; nhiều trường xếp chồng, chữ vẫn đủ nghĩa khi không có màu.
dl.diff (hoặc div.diff) > .diff-row > dt.diff-field (tên trường, mờ) + dd.diff-values gồm del.diff-old (gạch ngang, --muted), svg.icon.diff-arrow[aria-hidden="true"] và ins.diff-new (không gạch chân, --text, đậm 600, nền --sunk). Trình duyệt và trình đọc màn hình đọc del và ins không đồng đều nên chữ phải tự đủ nghĩa: trong mỗi cái có span.visually-hidden “Trước: ” và “Sau: ”, người dùng trình đọc nghe “Trước: 350.000 đ, Sau: 380.000 đ”; nét gạch và mũi tên chỉ là dấu hiệu thứ hai. Giá trị cũ rỗng là del.diff-old.diff-empty viết “(trống)”, giá trị mới rỗng là ins.diff-new.diff-empty viết “(đã xóa)”: mờ, không gạch, không đậm (chữ viết trong markup, theo ngôn ngữ của khách). Số bọc trong span.num để chữ số thẳng hàng với --font-figure. Các trường cách nhau bằng đường kẻ mảnh. Giá trị dài xuống dòng, không bao giờ làm rộng khung. Khi danh sách hẹp hơn 28rem (container query, không script) tên trường lên trên giá trị, cũ trên mới và mũi tên quay xuống. Danh sách là container nên cần bề rộng riêng. Màu: --text và --muted trên --surface và --sunk, đã được kiểm.
Sửa phiếu chi bốn trường, khung rộng 36rem
Phiếu PC-2026-0412, sửa lúc 30/09 09:30
Người chi
Trước: Cây xăng PetrolimexSau: Cây xăng Phú Mỹ
Số tiền
Trước: 350.000 đSau: 380.000 đ
Ngày
Trước: 28/09/2026Sau: 29/09/2026
Ghi chú
Trước: Đổ xăng xe tải 51C-123.45Sau: Đổ xăng xe tải 51C-123.45 và xe cẩu 5 tấn đi lắp kèo thử tại công trình Bình Chánh, đã có hóa đơn đỏ kèm theo phiếu giấy
Chữ, số tiền (span.num), ngày và một ghi chú dài (xuống dòng ở cả cũ và mới). Mỗi trường là một hàng có đường kẻ mảnh.
Cùng bốn trường trong khung hẹp 20rem
Phiếu PC-2026-0412
Người chi
Trước: Cây xăng PetrolimexSau: Cây xăng Phú Mỹ
Số tiền
Trước: 350.000 đSau: 380.000 đ
Ngày
Trước: 28/09/2026Sau: 29/09/2026
Ghi chú
Trước: Đổ xăng xe tải 51C-123.45Sau: Đổ xăng xe tải 51C-123.45 và xe cẩu 5 tấn đi lắp kèo thử tại công trình Bình Chánh, đã có hóa đơn đỏ kèm theo phiếu giấy
Khung hẹp hơn 28rem: tên trường nằm trên giá trị, cũ ở trên mới, mũi tên quay xuống.
Giá trị cũ rỗng và giá trị mới rỗng
Phiếu PC-2026-0398, hủy
Lý do hủy
Trước: (trống)Sau: Ghi trùng với PC-2026-0397
Số hóa đơn
Trước: HĐ-0042Sau: (đã xóa)
“(trống)” và “(đã xóa)” mờ, không gạch và không đậm; người đọc màn hình vẫn nghe “Trước: (trống)” và “Sau: (đã xóa)”.
Cùng nội dung, khung hẹp
Lý do hủy
Trước: (trống)Sau: Ghi trùng với PC-2026-0397
Số hóa đơn
Trước: HĐ-0042Sau: (đã xóa)
Panel có tone, trạng thái và dòng gập
Panel nói được mình đang ở tình trạng nào: thanh 4 px ở mép đầu theo tone, viền nét đứt khi chưa lưu, nền xám khi chỉ đọc; và dòng danh sách gập thành nội dung, đủ nhẹ để dùng hai chục lần trong một danh sách.
.panel[data-tone="ok|warn|bad|info"]: thanh 4 px ở mép đầu (chính là viền của panel, không phần nào bên trong che được; cả ở giao diện app). Thanh không bao giờ đứng một mình: để chữ trong phần đầu, một .tag cùng tone trong .panel-state (“Có vấn đề”, “Đã duyệt”). .panel[data-state="unsaved"]: viền nét đứt --field-border, không bóng, kèm .tag.tag-warn “Chưa lưu” trong .panel-state. .panel[data-state="readonly"]: nền --surface-2, chữ mờ, kèm .tag “Chỉ đọc” có biểu tượng khóa. Cả hai trạng thái không vô hiệu hóa gì: ô nhập bên trong vẫn đọc được, vì thế markup vẫn đặt readonly hoặc disabled trên chúng. Tone và trạng thái đi cùng nhau được (thẻ chưa lưu có vấn đề giữ thanh trên viền đứt). .panel-state là chỗ của chữ đó trong .panel-head, đẩy về cuối, trước .panel-actions. details.row-fold > summary (dòng: tối thiểu --tap; bên trong dùng các phần của .work-row như .work-main, .work-reason, .work-end, .avatar, hoặc span.row-fold-main cho chữ thường; phần cuối là svg.icon.row-fold-caret[aria-hidden] quay khi mở) + .row-fold-body (thụt vào theo --row-fold-indent, mặc định 2,25rem; 2,75rem khi có .avatar-sm; có đường kẻ nhạt phía trên). Các dòng cách nhau bằng đường kẻ 1 px (anh em liền kề, hoặc li trong ul.row-fold-list). data-tone trên details vẽ thanh 4 px như .work-row, chữ nói tình trạng nằm trong summary. Bàn phím là của phần tử gốc (Enter, Space), không script; không có điểm đánh dấu mặc định, summary có vòng lấy nét của kit vẽ bên trong dòng. Màu: các cặp chữ trên --surface và --surface-2 mà kit đã kiểm.
Bốn tone, mỗi panel một chữ trong phần đầu
Phiếu PC-2026-0398
Đã duyệt
Quản trị đã xem và duyệt lúc 09:30.
Đơn DH-2026-0033
Cần xem
Còn thiếu một phiếu chi cho nhà thầu phụ.
Thẻ Trần Văn Bình
Có vấn đề
Một việc báo “Có vấn đề”: thiếu thép tấm.
Ghi chú của kế toán
Thông tin
Đối chiếu sổ phụ ngân hàng vào cuối tháng.
Thanh ở mép đầu là cue thứ hai; cue thứ nhất là chữ có biểu tượng trong .panel-state (tag cùng tone).
Chưa lưu và chỉ đọc
Lê Văn Cường
Chưa lưu
Giữ trên máy này, chưa gửi lên.
Phạm Thị Dung
Có vấn đềChưa lưu
Chưa lưu và có vấn đề: thanh đỏ nằm trên viền nét đứt.
Tháng 9 năm 2026
Chỉ đọc
Kỳ đã khóa từ 01/10, không sửa được.
Hai nhãn trong một phần đầu thì chỉ nhãn đầu có margin-inline-start: auto chia chỗ; ô nhập vẫn đọc được vì readonly nằm ngay trên ô, không do panel.
Dòng đầu có thanh đỏ và nói bằng chữ (“Có vấn đề”); dòng thứ ba mở sẵn (open), mũi tên quay lên, nội dung có đường kẻ nhạt phía trên và là một dl.diff (trước → sau). Tab tới dòng, Enter hoặc Space mở / đóng.
Dòng chữ thường, anh em liền kề (không ul)
Khi nào chốt sổ cuối tháng?
Ngày làm việc cuối cùng của tháng, sau khi kế toán đối chiếu sổ phụ.
Sửa phiếu đã chốt thế nào, và ai được sửa, và sửa đến khi nào thì phải xin quản trị mở lại kỳ?
Chỉ Quản trị mở lại kỳ; mọi thay đổi được ghi vào nhật ký.
Câu hỏi dài xuống dòng, mũi tên giữ nguyên ở cuối, dòng vẫn cao tối thiểu --tap.
Tiêu đề panel: h2, h3 hoặc h4
Tiêu đề h2
Tiêu đề h3
Tiêu đề h4
.panel-head cho cùng một cỡ chữ với h2, h3 và h4, để thứ bậc tiêu đề của trang đúng mà panel không đổi dáng.
App look: số liệu, biểu đồ, hình minh họa
Phần chỉ có ở kiểu "app": ô số liệu, vòng tiến độ, biểu đồ cột và bốn hình minh họa cho trạng thái trống.
Chọn "Kiểu: app" ở thanh trên thì phần này mới hiện. Màu lấy từ bảng màu đang chọn (teal hoặc chàm), nên đổi bảng màu thì cả hình lẫn biểu đồ đổi theo. .stat là ô số liệu nhỏ (.stat-head với .stat-ic và .stat-label, rồi .stat-value và .stat-unit); .stat-row xếp nhiều ô. .ring là vòng tiến độ vẽ bằng --p (phần trăm), chữ ở giữa là .ring-v, cỡ .ring-sm.ring-lg, màu .ring-ok.ring-warn.ring-bad; role="progressbar" kèm aria-valuenow. .chart là biểu đồ cột: số in ngay trên mỗi cột và aria-label của figure đọc lại cả dãy bằng một câu, nên chiều cao không phải nơi duy nhất mang số. Cột đang xét có aria-current="true". Hình minh họa: <svg class="empty-spot" aria-hidden="true"><use href="spots.svg#spot-empty"/></svg>, bốn hình là spot-empty, spot-search, spot-lock, spot-offline, vẽ riêng cho kit này.
Tổng quan trong ngày
Hôm nay của bạn
Thứ Sáu, 31 tháng 10
72%
Đã xong
18việc
Đang làm
5việc
Quá hạn
2việc
Số lớn và vòng nhỏ
Doanh thu tháng 10
128,5M128.450.000 đồng₫
Đạt 86% mục tiêu tháng
Chuyên cần
94%
Đi làm 22 trên 23 ngày
Biểu đồ cột
Việc xong trong tuần
Thứ Hai đến Chủ nhật
12
T2
18
T3
9
T4
15
T5
21
T6
6
T7
2
CN
Hình minh họa cho trạng thái trống
Chưa có việc nào hôm nay
Việc quản lý giao sẽ hiện ở đây.
Không tìm thấy kết quả
Thử từ khóa ngắn hơn hoặc bỏ bớt bộ lọc.
Bạn chưa có quyền xem trang này
Hỏi quản trị viên để được cấp quyền.
Mất kết nối mạng
Việc đã nhập vẫn được giữ trên máy và sẽ gửi khi có mạng.
Stepper, form nhiều bước và phần có số
Thanh bước ngang hoặc dọc, hiện bằng bước hoặc thanh tiến độ, và khung nhập liệu chia bước có kiểm tra từng bước.
ol.stepper > li.step[data-state="done|current|error|todo"] > .step-btn (là button khi người dùng được quay lại hoặc tới bước đó, là span khi chưa, bước hiện tại có aria-current="step") > .step-mark (số, dấu tích khi xong, "!" khi lỗi) + .step-label. Bốn kiểu bày cùng một danh sách: vòng tròn.stepper-circles (theo MultiStepIndicator của Vibe: vòng tròn nối nhau bằng vạch mảnh, chữ ở bên cạnh và có thể thêm .step-sub trong .step-text; bước hiện tại là vòng đặc có viền ngoài, bước xong là vòng đặc có dấu tích, bước chưa tới là vòng rỗng, bước lỗi giữ màu lỗi; .stepper-compact thu nhỏ vòng và chỉ giữ nhãn; dưới 40rem chỉ bước hiện tại còn chữ), ngang (kiểu mặc định, các ô trên nền xám như .tabs-pill, ô trắng là bước hiện tại; dưới 40rem chỉ bước hiện tại còn nhãn), dọc.stepper-vertical (cột nối bằng vạch, vạch tô màu thành công khi bước xong; mỗi bước có thể có .step-sub mô tả trong .step-text cùng nhãn và .step-meta bên phải cho ngày giờ), thanh tiến độ.stepper-bars (mỗi bước là một đoạn, nhãn nằm dưới, không có số). Bước xong màu thành công, bước lỗi màu lỗi, chữ cùng cỡ chữ thân trang; trạng thái luôn có chữ hoặc dấu hiệu ngoài màu (tích, "!", chữ ẩn "(đã xong)", "(có lỗi)"). Tiến độ chung: .wizard-progress gồm "Bước 2/4", một .bar (--v là phần đã đi) và phần trăm. Biểu mẫu chia bước: trong hộp thoại (.wizard-steps dưới phần đầu, chân có .modal-foot-start cho nút Hủy) hoặc trên trang (.wizard-page: thẻ bước dọc bên trái, thẻ biểu mẫu bên phải có tiến độ ở đầu, Quay lại và Tiếp tục ở chân; dưới 48rem các bước nằm ngang phía trên). Mỗi bước là một .wizard-panel (chỉ bước hiện tại hiện, có h3 để chuyển focus tới). Bấm Tiếp tục kiểm tra các ô required của bước đó: ô thiếu có aria-invalid và thông báo .field-error, bước chuyển sang lỗi và focus vào ô đầu tiên; Quay lại hoặc bấm bước đã qua thì không kiểm tra. Trang xác nhận ở bước cuối liệt kê các ô đánh dấu data-sum. Đóng hộp thoại là mất dữ liệu đã nhập; tenant nên hỏi xác nhận khi đã nhập dở.
Ngang, hiện bước
2Thời hạnNgày hiệu lực
4Xác nhậnXem lại và gửi
2Thời hạn
4Xác nhận
2Thời hạnNgày hiệu lực
4Xác nhậnXem lại và gửi
Kiểu Vibe, .stepper-circles. Trên: nhãn và mô tả. Giữa: gọn, .stepper-compact. Dưới: thanh hẹp, chỉ bước hiện tại giữ chữ. Bước đã xong và bước lỗi bấm được để quay lại.
Ngang, hiện thanh tiến độ
2Đang làm
3Đang duyệt
4Hoàn tất
Bước 2/450%
Dọc
Tiến trình giao hàng
3Đang vận chuyểnĐang ở trung tâm khu vực18/11 09:15
4Đã giaoHàng sẽ giao tận nơi
2Địa chỉ
4Xác nhận
Cùng dạng vòng tròn với bản ngang. Trái: có mô tả và ngày giờ. Phải: chỉ nhãn, để làm cột bước bên cạnh biểu mẫu.
Trong hộp thoại (ngang)
Hộp thoại bốn bước: thử bỏ trống ô có dấu *
Trên trang (dọc, có tiến độ)
Numbered parts, choice cards
Biểu mẫu dài chia thành các phần có số, chọn vật liệu bằng thẻ, chip nét đứt, ô có hậu tố cố định và hộp xác nhận.
Mỗi phần là một .panel có .panel-head.panel-head-part: .part-num (số trong vòng tròn; .part-num-ok với icon dấu tích khi phần đã đủ), tiêu đề, và .panel-meta ở cuối dòng (đã nhập bao nhiêu). Nhóm chọn dạng thẻ là .choice-cards > label.choice-card chứa input[type="radio"] thật, nên bàn phím và trình đọc màn hình dùng như nhóm radio thường. .chip-dashed đổi viền chip sang nét đứt cho giá trị khác loại. .input-affix > .input + .affix giữ chữ cố định trong khung ô. label.confirm là hộp tích xác nhận: màu hổ phách cho đến khi tích, rồi xanh lá.
1
Vật liệu
Chọn một
Đã đủ
Kích cỡ
3 cỡ
D10D12Ø16 tròn trơn
3
Phát hành
0/2
/LAS-XD 1222
Phần sau dấu gạch chéo tự thêm.
Phần 1 và 2: số trong vòng tròn, phần đã đủ đổi sang dấu tích xanh. Cỡ Ø16 tròn trơn có viền nét đứt vì khác loại với hai cỡ vằn. Hộp xác nhận ở phần 3 tích được: thử bấm.
Khung điện thoại
Thanh tab dưới, đầu trang con có nút quay lại, thanh nút ở đáy và toast ở đáy cho ứng dụng chạy trên điện thoại.
Thanh tab dành cho các trang chính và thanh nút cho trang con, nên hai thanh không chung một màn hình. Chỉ hiện thanh tab ở bố cục điện thoại; ở màn hình rộng các liên kết đó nằm trong sidebar hoặc thanh trên. Thêm .has-tabbar hoặc .has-action-bar vào trang để dòng cuối không bị thanh che. Toast ở đáy (.toast-host-bottom) tự nâng lên trên thanh.
Trang chính: .tabbar với mục hiện tại aria-current="page", icon -fill và số đếm .side-badge; toast hiện ngay trên thanh.
Pha trà nền buổi chiều
Thứ Bảy 31/10 · Ca chiều 14:00
Còn thiếu 1 ảnh.Chụp thêm ảnh thùng trà đã đậy nắp.
Pha 12 lít trà nền, để nguội trong thùng có nắp. Ghi giờ pha lên nhãn.
Gửi đủ 2 ảnh để bấm Xong
Trang con: .topbar-back, .topbar-title (tên và dòng phụ cắt bằng “…”) và .action-bar với ghi chú vì sao nút đang khóa.
Số đếm đứng riêng
.side-badge nằm trong dòng chữ vẫn giữ dạng viên thuốc; thêm chữ ẩn để đọc được ý nghĩa của số.
Đánh giá 9 chưa duyệt · Chấm công 1 chờ duyệt
Đầu trang điện thoại cấp một
Đầu trang của màn chính (trang chủ, sổ quỹ, kho): dấu hiệu hoặc biểu tượng, tiêu đề kèm dòng ngày, một hai nút biểu tượng, không có nút quay lại.
.topbar có phần tử đầu là .brand-mark hoặc svg.icon[aria-hidden] được bố cục như đầu trang con: một dòng, cùng chiều cao, .topbar-title-text (là h1 của trang, để mọi trang điện thoại đều có tiêu đề) và .topbar-title-sub bị cắt bằng “…”, .topbar-actions ở cuối với một hai nút .btn.btn-ghost.btn-icon có aria-label (cao và rộng ít nhất --tap). Chỉ dấu hiệu hoặc biểu tượng là phần tử đầu tiên mới tính, nên thanh trên của màn hình rộng (.brand và .nav), thanh mỏng của sidebar và đầu trang con giữ nguyên.
Tiêu đề và dòng phụ dài bị cắt bằng “…”, hai nút ở cuối không bị đẩy ra ngoài.
Thanh nút đáy có ô tổng, bản dính trên máy tính
Thanh nút ở đáy điện thoại có chỗ cho con số tổng (“Chi từ Tiền mặt, − 350.000 đ”), và trên màn hình rộng cùng thanh đó thành thẻ dính ở cuối cột biểu mẫu.
.action-bar-sum là khối đứng trước các nút (sau ghi chú nếu có): .action-bar-sum-label một dòng (bị cắt bằng “…” khi không vừa) và .action-bar-sum-figure mang lớp .num-in, .num-out hoặc .num-neg với dấu trong chữ. Con số không bao giờ xuống dòng và ô tổng không hẹp hơn nó; nhãn nhường chỗ, các nút chia phần còn lại. Tổng + một nút: một dòng ở 390 px (số 12 chữ số vẫn đủ chỗ). Tổng + hai nút: hai dòng, ô tổng chiếm cả dòng trên, hai nút chia dòng dưới (--action-bar-extra giữ .has-action-bar và toast ở trên thanh). Nút ⋯ (.btn-icon) không tính là nút thứ hai. Màn có ba việc: nút chính cộng nút ⋯ mở .menu, không thêm nút thứ ba. .action-bar-sticky: từ 64rem, cùng markup nhưng không dính mép cửa sổ mà là thẻ dính (position: sticky; bottom: var(--sp-4)) ở cuối cột biểu mẫu; đặt nó cuối cột, cột là khối thường, không phải lưới. Dưới 64rem vẫn là thanh cố định. Khóa nút bằng aria-disabled, .action-bar-note và .has-action-bar giữ nguyên.
Phiếu chi mới
Mã phiếu được cấp khi lưu
Chi từ Tiền mặt
− 350.000đ
Tổng và một nút: một dòng, tổng bên trái, nút chính lấy phần còn lại.
Phiếu thu mới
Mã phiếu được cấp khi lưu
Phiếu giữ trên máy, gửi lại khi có sóng
Thu vào VCB ·· 6789
+ 45.000.000đ
Tổng và hai nút: hai dòng. Ô tổng chiếm dòng trên, hai nút chia dòng dưới; ghi chú nằm trên cùng.
Phiếu chi mới
Mã phiếu được cấp khi lưu
Nhập số tiền để bấm Lưu
Chi từ Tiền mặt
0đ
Nút chính khóa bằng aria-disabled="true", ghi chú nói vì sao; tổng vẫn hiện.
Phiếu chi mới
Mã phiếu được cấp khi lưu
Chi từ Vietcombank
− 123.456.789.012đ
Số 12 chữ số vẫn một dòng, nút chính còn đủ rộng.
Phiếu chi mới
Mã phiếu được cấp khi lưu
Chi từ Tiền mặt
− 350.000đ
Màn có ba việc: nút chính và nút ⋯ mở .menu, không thêm nút thứ ba, vì thanh sẽ xuống dòng.
Bản dính trên máy tính
Phiếu chi
Quỹ tiền mặt
Chi từ Tiền mặt
− 350.000đ
Sau phiếu này
Quỹ tiền mặt
18.450.000 đ
Còn lại
18.100.000 đ
Từ 64rem, .action-bar.action-bar-sticky là thẻ ở cuối cột biểu mẫu, dính cách đáy cửa sổ 16 px khi cột còn dài; cùng nội dung với bản điện thoại. Thẻ đủ rộng nên tổng và hai nút nằm cùng một dòng. Dưới 64rem khung này hiện thanh cố định ở đáy khung. Trong ảnh chụp cả mục, thẻ đang dính giữa cột; cuộn trang để thấy nó trượt xuống cuối cột.
Nút nổi, bottom sheet, danh sách trong sheet
Nút tròn cho việc chính của trang có thanh tab, và tấm trượt từ đáy để chọn một thao tác hoặc đi tới một mục.
.fab là nút tròn primary cao --tap + 12px, bóng --sh-3, cố định ở mép cuối phía trên thanh tab (--fab-bottom đổi chỗ khi không có thanh tab); chỉ có icon thì cần aria-label. .fab-ext thêm chữ cạnh icon, thành hình viên thuốc, chữ là tên nên không cần aria-label; a.fab cho nút chuyển trang. Trang thêm .has-fab cạnh .has-tabbar để dòng cuối không bị che; toast ở đáy (.toast-host-bottom) tự nâng lên trên nút. Không dùng cùng trang có .action-bar. <dialog class="modal modal-sheet"> mở bằng showModal(): trượt từ đáy ở mọi bề ngang, giữa màn hình và rộng tối đa 32rem, dưới 40rem thì rộng hết; vạch ở đầu chỉ là dấu hiệu, đóng bằng nút đóng, bấm nền hoặc Esc. Bên trong: .sheet-list > li > .sheet-item (button hoặc a, cao tối thiểu 48px) với .sheet-ic (đĩa icon) và nhãn; a.sheet-item có thêm svg.icon mũi tên làm con cuối, tự đẩy về cuối dòng; .sheet-item-danger cho thao tác xóa, nhãn đã nói rõ việc xóa nên màu đỏ chỉ là tín hiệu thứ hai. Kiểu app tinh chỉnh bóng, bo góc và cỡ đĩa icon.
button.sheet-item.sheet-item-danger: nhãn nói rõ việc xóa, màu đỏ chỉ là tín hiệu thứ hai.
Mở bản thật
Thu hẹp cửa sổ dưới 40rem để thấy sheet rộng hết bề ngang.
Ô thao tác lớn
Vài ô to chạm bằng ngón cái: icon trong đĩa tròn đặt trên một nhãn ngắn, dùng trong sheet “Lập mới” và ở hàng nút nhanh của trang chủ.
.action-tiles > a.action-tile hoặc button.action-tile > span.action-tile-ic[aria-hidden] (svg.icon) và nhãn là chữ nên không cần aria-label. .action-tile-primary tô màu chủ đạo cho một ô (việc thường làm nhất). Lưới tự đếm bề ngang của chính nó (container query) nên dùng được trong sheet lẫn trên trang: từ 18rem là 3 ô một hàng, dưới đó là 2; đúng 2 hoặc 4 ô thì chia đôi hàng, một ô lẻ thì chiếm cả hàng. Ô cao tối thiểu 5.5rem, nhãn xuống dòng và không bao giờ làm ô rộng ra. Nên dừng ở sáu ô.
Khung rộng 16rem: lưới đếm bề ngang của nó chứ không đếm cửa sổ.
Bản button
button.action-tile trông giống hệt bản liên kết; dùng khi ô làm một việc tại chỗ thay vì đi tới trang khác.
App look: nút nổi, bottom sheet (bản kiểu app)
Nút nổi, tấm trượt từ đáy và danh sách trong sheet có ở cả hai kiểu (bản chuẩn ở phần "Khung điện thoại"); đây là bản kiểu app: bo tròn hơn, bóng thương hiệu, mục cao 52px.
Thanh tab, thanh trên của trang con, thanh nút ở đáy và toast ở phần "Khung điện thoại" bên trên đã tự đổi theo kiểu app (đầu thanh bo tròn, tab hiện tại là icon trên nền nhạt, toast viền theo mức). .fab là nút tròn 56px cho đúng một việc chính của trang có thanh tab, nằm trên thanh tab ở mép cuối; .fab-ext thêm chữ cạnh icon; không dùng cùng trang có .action-bar. <dialog class="modal modal-sheet"> mở bằng showModal() trượt từ đáy ở mọi bề ngang (giữa màn hình, rộng tối đa 32rem), có vạch ở đầu chỉ để báo đây là tấm trượt: đóng bằng nút đóng, bấm nền hoặc Esc, chưa có kéo xuống để đóng. Hộp thoại thường trên điện thoại cũng có đầu bo tròn và bóng hướng lên. Danh sách chọn trong tấm: .sheet-list > .sheet-item với .sheet-ic (đĩa icon), .sheet-item-danger cho thao tác xóa.
.modal.modal-sheet trong khung điện thoại (bản tĩnh để xem). Nút bên dưới mở bản thật.
App look: mẫu cho màn hình ứng dụng
Phần chỉ có ở kiểu "app": dải tuần, thẻ dự án, danh sách cài đặt với công tắc, thông báo, màn chào mừng và ô nhập mã.
.week là bảy nút chọn ngày (aria-pressed cho ngày đang chọn, aria-current="date" cho hôm nay, data-busy khi ngày có việc); tên đầy đủ, "hôm nay" và số việc nằm trong aria-label của từng nút. .project là thẻ dự án mang màu thương hiệu, hoa văn gợn sóng do chính thẻ vẽ; chữ và nhãn đảo màu đều dùng --on-primary, nên độ tương phản là cặp mà bộ kiểm màu đã chứng minh cho nút chính. Chồng avatar dùng .avatar-group của kit, đặt --avatar-ring bằng màu nền sau nó. .switch to hơn, kèm .switch-ui cho nơi giữ trạng thái bằng ARIA (mục menu menuitemcheckbox). .setting-list gồm các hàng .setting: liên kết, nhãn bọc công tắc, hoặc nút nguy hiểm. .notif là một thông báo; chưa đọc có data-unread, chấm và chữ ẩn "Chưa đọc". .onboard và .dots cho màn chào mừng; .otp cho mã dùng một lần (tenant lo việc nhảy ô, Backspace và dán).
.notif: hàng chưa đọc có nền nhạt, chấm và chữ đậm.
Mọi việc trong ngày, một chỗ
Xem ca của bạn, chụp ảnh minh chứng và báo xong ngay trên điện thoại.
.onboard, .dots và nút chính cỡ lớn.
Xác minh số điện thoại
Nhập mã 6 số
Mã đã gửi tới số 09•• ••• 412.
Gửi lại mã sau 0:42
.otp với .input.otp-cell: gõ thì nhảy sang ô sau, Backspace lùi, dán tự chia ô.
Hình cho màn chào mừng
spot-planspot-teamspot-bell
Sidebar
Thanh bên thu gọn về icon và trượt ra trên điện thoại.
.app-shell > .sidebar + .app-main. Mục là .side-item (aria-current="page", .side-label, .side-badge), nhóm có .side-heading, nhóm gập được (kiểu cây của Vibe) là details.side-group > summary.side-item (icon, .side-label, .side-group-caret) + .side-sub chứa các .side-item chỉ có chữ, chân thanh bên là .sidebar-foot. data-collapsed="true" thu về icon. Dưới 48rem thanh bên trượt ra trên trang (data-open="true" và .sidebar-scrim). Khung dưới đây thu nhỏ trình duyệt để xem cả hai.
Tổng quan
Thanh bên
Nút thứ hai thu gọn menu về icon; ở màn hẹp, nút đầu mở menu.
Số liệu có màu trên thanh bên
Màu theo trường hợp: xanh đã xong, vàng chờ xử lý, đỏ quá hạn, xanh dương mới.
.side-badge (xám) và -ok -warn -bad -info -primary, cùng cặp màu với .tag. Màu chỉ nói thêm mức độ; con số vẫn là nội dung chính, và khi màu có ý nghĩa thì ghi thêm chữ trong .visually-hidden (ví dụ " quá hạn"). Tenant giới hạn con số ("99+"). Khi thanh bên thu về icon, huy hiệu bị ẩn như trước.
Logo khách gửi qua đặt trong thanh trên cùng, thanh bên và trang đăng nhập.
Trong .brand, hoặc một img.brand-logo đứng một mình (file đã có tên khách trong đó, logo dài; alt là tên khách), hoặc một img[alt=""] trong .brand-mark (file vuông hoặc chỉ có biểu tượng) kèm tên bằng chữ bên cạnh. Chiều cao cố định (--logo-h, 2.25rem), chiều rộng theo file đến giới hạn --logo-w (11rem), không cắt và không kéo giãn. .brand-logo-lg cho trang đăng nhập. Logo vẽ cho nền sáng mà đặt trên thanh tối thì thêm .brand-logo-plate (nền đệm màu bề mặt). Thanh bên thu gọn: logo dài được nhìn qua khung vuông ở đầu trái, nơi thường có biểu tượng; file chỉ có chữ thì dùng kiểu logo vuông cạnh tên. Chưa có file hoặc file lỗi thì tenant hiện .brand-mark chữ viết tắt. Ảnh mẫu trong samples/ là thương hiệu giả "Nam Việt" của bộ kit.
Thương hiệu hai dòng (.brand-text > .brand-name + .brand-sub, dòng dưới cắt bằng dấu … khi dài), số đếm là .side-badge trong .nav-item, tài khoản là .btn chứa .avatar-label (mở một .menu). Nút chính .btn-primary giữ màu nền trên thanh trên.
Thêm .topbar-dense vào thanh trên khi vai có nhiều mục (từ sáu mục trở lên): dòng dưới của thương hiệu mất, tài khoản chỉ còn avatar (chữ vẫn cho trình đọc màn hình). Không cần thêm gì ở cửa sổ dưới 89rem (1424px): thanh tự thu gọn như vậy. Hẹp hơn nữa thì thanh xuống hai hàng.
Trên nền tối
Trái: logo chữ đen mất hút trên nền tối. Phải: thêm .brand-logo-plate.
Thanh bên
Mở rộng, thu gọn với logo dài (chỉ thấy đầu trái), thu gọn với logo vuông. Thu gọn chỉ thấy trên màn rộng; trên điện thoại thanh bên luôn mở đủ.
Trang đăng nhập
Đăng nhập để tiếp tục
Sign-in
Thẻ hẹp ở giữa trang với thương hiệu, tiêu đề, biểu mẫu và dòng trợ giúp.
main.login căn giữa cả hai chiều một .panel.login-card (rộng --login-w, mặc định 25rem) và một dòng .caption nhỏ bên dưới; --login-h là chiều cao trang (mặc định cả cửa sổ). Trong thẻ: .panel-body chứa .login-brand (một .brand, logo khách hoặc chữ), một div có h1 và .page-lead, rồi biểu mẫu .stack kết thúc bằng .btn.btn-primary.btn-lg.btn-block; .panel-foot chứa dòng trợ giúp. Màn chia đôi (một khung tối bên trái, biểu mẫu bên phải) là main.login-split > .login-aside + .login: khung trái chứa .brand, một div có h1 và p, hình vẽ svg.login-art (tô bằng màu của tenant, hoặc currentColor) và .login-facts (các cặp strong + chữ); thẻ bên phải phẳng, không viền. Ô mật khẩu có nút Hiện/Ẩn nằm trong ô là .input-action > .input + .btn.btn-ghost.btn-sm[data-reveal] (ô chừa --action-w, 5rem; tenant đổi type, chữ, aria-label và icon eye / eye-slash như script của trang này). Khung tối đổi bằng --aside-bg, --aside-fg, --aside-muted. Dưới 60rem khung trái thành dải phía trên biểu mẫu, bỏ hình vẽ và các cặp thông tin. Hình vẽ là của tenant: kit chỉ cho chỗ đặt.
Ghi mẫu nhận về, nhập số đo thô, xem kết quả tự tính và phát hành phiếu có số.
LAS-XD 1222Mã phòng thí nghiệm
ISO 9001:2015Hệ thống quản lý chất lượng
Đăng nhập
Dùng email và mật khẩu Quản trị đã cấp cho bạn.
Quên mật khẩu? Nhờ Quản trị đặt lại mật khẩu tạm.
.login-split làm cả trang (cao --login-h, ở đây 32rem); trên trang thật nó nằm trong main và cao cả cửa sổ. Thu hẹp cửa sổ dưới 60rem để xem khung trái thành dải trên.
svg.login-art là phần tử đầu của .panel-body, đứng trên .login-brand: nằm trong luồng, rộng --login-art-w (4rem), cùng mép với thương hiệu và mang màu chính (svg dùng currentColor). Hình chỉ để trang trí nên có aria-hidden="true".
Giấy in A4 và A5
Tờ A4 như khi in, cho phiếu khách cũng điền trên giấy.
.paper-stage (bàn xám đặt các tờ giấy, cuộn ngang khi màn hình hẹp) > .paper (.paper-landscape xoay ngang) > nội dung, cùng .paper-no là số trang ở chân tờ. Tờ luôn trắng chữ đen, không theo palette, vì bản in cũng vậy. Tenant đặt font tài liệu và lề cần dùng trên .paper. Khi in, bàn và bóng đổ bị bỏ, mỗi tờ ngắt trang. Tiêu đề giấy theo khách: header.paper-head > .paper-org (img.paper-logo + .paper-org-text có .paper-org-name và các dòng .paper-org-line: địa chỉ, MST, điện thoại) + p.paper-doc bên phải (mẫu số, số liên); logo cao cố định 14 mm (A5: 11 mm), rộng theo file tối đa 50 mm, không cắt không méo, in đúng màu của logo. Logo ngang có chữ hay logo vuông cạnh tên đều được; tên pháp lý luôn viết ra bằng chữ nên logo để alt="". Không có logo thì chỉ còn phần chữ. Ví dụ dưới cắt ngắn tờ (min-height: 0) cho vừa trang gallery.
Công trình: Đường D3 nối dài, hạng mục cống hộp K0+350. Mẫu: TH-D3-15, thép vằn D10–D16, lấy ngày 24/10/2026.
Chỉ tiêu
Yêu cầu
Kết quả
Kết luận
Giới hạn chảy (MPa)
≥ 400
452
Đạt
Giới hạn bền (MPa)
≥ 570
641
Đạt
Người thí nghiệmTrưởng phòng
1/1
A5 paper, signature row, no-print
Tờ A5 cho phiếu cửa hàng in và giữ lại, hàng chữ ký và lớp ẩn khi in.
.paper.paper-a5 (148×210 mm) và .paper.paper-a5-land (210×148 mm) đặt trong .paper-stage như tờ A4; lề bằng 0,7 lần lề A4, chữ 10pt. Kit chưa có @page cho A4, nên A5 tự mang trang riêng: @page a5 và @page a5-land (có tên, lề 0, lề thật là padding của tờ), chọn bằng thuộc tính page trên tờ. Trang có tên chỉ áp cho tờ gọi nó, nên tờ A4 trong cùng tài liệu vẫn theo trang mặc định của tài liệu (trang nên tự đặt @page { size: A4; margin: 0 } nếu máy in không mặc định A4). Hàng chữ ký: .paper-sign (ba cột đều; .paper-sign-2 cho hai cột) > .paper-sign-slot > .paper-sign-role (chức danh, đậm) + .paper-sign-hint (nghiêng, “(Ký, ghi rõ họ tên)”), chừa 18 mm để ký (--sign-space), cả hàng không bị cắt qua hai trang. Số tiền trên giấy dùng .num; .num-in, .num-out, .num-neg, .num-void trong tờ luôn đen (giấy in đơn sắc, dấu và chữ mang nghĩa; .num-void vẫn gạch ngang). .no-print ẩn phần tử khi in và chỉ khi in: dùng cho nút In, Quay lại quanh tờ. Các tờ dưới cắt ngắn (min-height: 0) cho vừa trang gallery.
Nút này mang .no-print: hiện trên màn hình, mất khi in.
Cửa hàng Vật liệu Minh Chiến
12 Nguyễn Trãi, Nha Trang · ĐT 0258 3 888 888
Mẫu số 02-TT Liên 1: lưu
PHIẾU CHI
Số PC-2026-0412 · Ngày 02/11/2026
Người nhận tiền: Nguyễn Văn An Lý do chi: Mua vật tư sửa kho 2
Nội dung
Số tiền (đ)
Xi măng PCB40, 20 bao
3.100.000
Phí vận chuyển
250.000
Cộng3.350.000đ
Bằng chữ: Ba triệu ba trăm năm mươi nghìn đồng.
Người lập phiếu(Ký, ghi rõ họ tên)
Thủ quỹ(Ký, ghi rõ họ tên)
Người nhận tiền(Ký, ghi rõ họ tên)
A5 đứng, ba chữ ký (mặc định). Số tiền in đen: “Cộng” dùng .num-out nhưng trong tờ không có màu.
Cửa hàng Vật liệu Minh Chiến
PHIẾU THU
Đã nhận của Công ty Thành Đạt: + 1.250.000đ (Một triệu hai trăm năm mươi nghìn đồng).
Người nộp tiền(Ký, ghi rõ họ tên)
Người thu tiền(Ký, ghi rõ họ tên)
.paper-a5-land với .paper-sign-2: hai chữ ký. .num-in trong tờ cũng đen; dấu “+” trong chữ nói nghĩa.
Bảng dài nhiều trang, khổ A3, in đen trắng
Bảng chảy qua nhiều trang: đầu bảng lặp lại mỗi trang, khối của một người không bị cắt, hàng chữ ký đi cùng phần cuối; ô chấm công in đen trắng.
.paper-flow thêm vào tờ (A4, A4 ngang, A3 .paper-a3, A3 ngang .paper-a3-land): trên màn hình là một tờ dài lề 10 mm; khi in, lề chuyển sang trang (trang tên a4-flow, a4-land-flow, a3-flow, a3-land-flow), thead lặp mỗi trang, mỗi tbody (một khối) và mỗi dòng không bị cắt, tfoot in một lần ở cuối, .paper-sign không đứng một mình đầu trang. Bảng .tbl-marks trong tờ: kẻ đen mảnh, không tô màu; P và K đậm, thiếu giờ gạch chân, chưa chấm gạch dày, chủ nhật cột xám có chữ “CN”, chưa vào làm gạch thưa, tự tính chữ nghiêng. Chữ 7pt trên A3, 5,6pt trên A4 ngang; cột ngày đặt bằng <col> (8,1 mm A3, 5,3 mm A4).
Khổ A4 ngang ở đây; tờ A3 ngang dùng .paper-a3-land.paper-flow.
Xưởng Minh Sơn Khu công nghiệp Nga Sơn
BẢNG CHẤM CÔNG THÁNG 10/2026
31 ngày, 4 chủ nhật · 5 người · in lúc 16:20 ngày 23/10/2026
Tạm tính
STT
Mã thẻ
Họ tên
Hạng mục
1T5
2T6
3T7
4CN
5T2
6T3
7T4
8T5
9T6
10T7
11CN
12T2
13T3
14T4
15T5
16T6
17T7
18CN
19T2
20T3
21T4
22T5
23T6
24T7
25CN
26T2
27T3
28T4
29T5
30T6
31T7
Tổng
Đơn giá
Thành tiền
Thực lĩnh
1
CN-014
Nguyễn Văn HùngChính thức
Giờ làm
8
8,5
4
8
8
8
8
7,5P
4
8
8
Chưa chấm
8
4
8
8
8
8
8
204
45.000
9.180.000
9.640.000 đ
Tăng ca
2
2
0,5
2
6,5
60.000
390.000
Suất ăn
1
1
1
3
25.000
75.000
2
CN-022
Trần Thị LanKhoán
Giờ làm
4
8
8
6,5
8
8
4
8
8
8
Chưa chấm
8
4
8
5K
8
8
8
148,5
41.000
6.088.500
6.120.500 đ
Tăng ca
0,5
0,5
1
60.000
60.000
Suất ăn
1
1
25.000
25.000
3
CN-031
Lê Quang MinhChính thức
Giờ làm
8
8
4
8
8
8
8
8
4
8,5
7
8
8
8
4
8
8
8
8
8
196
45.000
8.820.000
8.915.000 đ
Tăng ca
1
1
2
60.000
120.000
Suất ăn
0
25.000
0
4
CN-040
Phạm Văn TàiKhoán
Giờ làm
8
8
4
8
8
8
8
8
4
8
8
8
8
8
4
8
8
8
8
8
200
36.000
7.200.000
7.402.000 đ
Tăng ca
1,5
1,5
1,5
1,5
1
7
26.000
182.000
Suất ăn
2
2
10.000
20.000
5
CN-047
Đỗ Thị MaiKhoán
Giờ làm
8
8
4
8
8
8
8
8
4
8
8
8
8
8
4
P
8
0,5
K
8
176,5
20.000
3.530.000
Âm 1.250.000 đ
Tăng ca
0
26.000
0
Suất ăn
0
25.000
0
Sản lượng
850
850
850
1.200
850
850
850
850
1.200
850
850
850
1.200
850
850
850
1.200
850
850
850
16.950
—
—
Tổng giờ
925
30.827.500 đ
Tổng tăng ca
16,5
P nghỉ phép (đậm) · K nghỉ không phép (đậm) · số gạch chân: thiếu giờ · ô gạch dày: chưa chấm · ô gạch thưa: chưa vào làm hoặc đã nghỉ · cột xám: chủ nhật (CN) · chữ nghiêng: tự tính
Người lập bảng(Ký, ghi rõ họ tên)
Kế toán(Ký, ghi rõ họ tên)
Giám đốc(Ký, đóng dấu)
Trên màn hình: một tờ A4 ngang. Khi in với 40 người, bảng chảy qua nhiều trang, mỗi trang có đầu bảng, không khối nào bị cắt đôi, chữ ký ở cùng trang với các dòng cuối.
Dấu tạm tính, đã chốt
Con dấu nói trạng thái của cả một bảng hay một phiếu, trên màn hình và khi in.
span.stamp chữ hoa, viền đôi cùng màu chữ: -warn (tạm tính), -ok (đã chốt), -bad (đã hủy), không thêm gì là màu chữ thường; -lg to và nghiêng 2 độ cho đầu tờ. Trong .paper và khi in là đen trên trắng.
Tạm tínhĐã chốtĐã hủyBản nhápTạm tínhĐã chốt
Chữ trên dấu là trạng thái; màu chỉ giúp nhận ra nhanh. Bảng công tạm tính khi bảng lương tháng chưa chốt.
Quy ước sắp xếp và trạng thái
Năm lớp, bốn trạng thái, và chỗ đặt một thành phần mới để không phải sắp xếp lại lần nữa.
Mỗi phần của gallery là một <section class="g-section"> mang bốn thuộc tính: data-layer (lớp), data-group (nhóm trong lớp), data-area (both, desktop, mobile: màn hình dùng được) và, nếu không phải ổn định, data-status. Thanh bên và mục lục tự dựng từ các thuộc tính đó; node check-gallery.mjs kiểm tra.
Năm lớp
Nền tảng
Luật nhìn và cách chạm: token, biểu tượng, cỡ chạm. Không phải một thành phần.
Thành phần
Một phần tử dùng lại được, đứng một mình: nút, ô nhập, bảng, thông báo. Mọi biến thể (kiểu, cỡ, trạng thái) nằm trong thành phần đó, không thành mục riêng.
Mẫu thiết kế
Nhiều thành phần ghép lại để giải một bài toán: biểu mẫu nhiều bước, chi tiết bản ghi, bảng thành thẻ, màn hình điện thoại.
Bố cục trang
Cả một trang hoặc khung: khung ứng dụng, đăng nhập, giấy in.
Hướng dẫn
Quy ước, trạng thái, nhật ký thay đổi (phần này).
Đặt một thứ mới ở đâu
Là biến thể hoặc một phần của thứ đã có: thêm vào phần đó bằng <h3 class="g-sub g-sub-part" id="g-...">, thêm một dòng trong COMPONENTS.md.
Là một phần tử đứng một mình: phần mới trong lớp components, chọn một nhóm có sẵn (actions, inputs, selection, display, tables, feedback, overlays, navigation).
Là nhiều thành phần giải một việc: lớp patterns. Là cả trang: lớp templates. Là luật nhìn hoặc cách chạm: lớp foundations.
Đặt phần trong trang theo thứ tự lớp rồi nhóm (check-gallery.mjs báo nếu sai), phần cơ bản trước phần chuyên biệt.
Bốn trạng thái
Ổn địnhmặc định, không gắn nhãn: đã duyệt, dùng lại được.
Mớidata-status="new": vừa thêm, dùng được.
Thử nghiệmdata-status="experimental": đang thử, chưa chốt (kiểu app chưa chạy trên máy thật).
Không dùng nữadata-status="deprecated" kèm data-replaced-by: đừng dùng cho trang mới.
Nhật ký thay đổi
Những gì đổi trong kit từ bản v1.3 gốc, mới nhất ở trên; chi tiết nằm trong git.
Mỗi dòng nói thứ đã đổi và chỗ xem trong gallery. Thay đổi nào làm đổi cách vẽ của thứ đã có thì ghi rõ.
Chấm công (nhánh ui-kit-attendance)
Bảng: .tbl-sticky-cols (tới sáu cột trái và một cột phải dính, kit.js đo bề rộng), tfoot.tbl-foot-rows (nhiều dòng tổng dính), tbody.tbl-block (khối theo người), tr.grp ở mọi bảng, td[data-range], .tbl-formula, toàn màn hình ([data-fullscreen]).
Ô chấm công: .tbl-marks (ô giờ số 2,25rem), -warn, -missing, .cell-auto, góc -start và -bottom, data-save với .cell-pop, cột thứ Bảy, hôm nay, chưa tới, .cell-mark-2l, data-grade và .mark-strip; chú giải cho các trạng thái mới.
Mẫu: chấm công theo ngày (.entry-row), bảng công trên điện thoại. Giấy: .paper-flow, A3, ô chấm công in đen trắng, .stamp.
v1.3 (nhánh tranminhchien-kit-test)
Gallery: sắp theo năm lớp (Nền tảng, Thành phần, Mẫu thiết kế, Bố cục trang, Hướng dẫn); Desktop, Mobile và Tất cả ở thanh trên; chip và tag thành một phần riêng; trạng thái từng phần (data-status).
Cỡ chạm (g-tap): <html data-tap="all"> cho mục tiêu 44px dưới chuột; nút “Bỏ nháp” của banner nháp vào danh sách cỡ chạm; ô khoảng ngày là một mục tiêu cả khung.
Chiều cao thanh trên: --topbar-real-h (61, 65 hoặc 69px) cho thứ dính dưới thanh; .page-side dính thấp hơn 5px so với trước (thay đổi cách vẽ có chủ ý).
Kỳ: TvKit.periodNav.set(el, value, { unit }) và data-today trên .period-nav.
Nhỏ: .kpi-value đọc --font-figure; .panel-head cỡ h2, h3, h4; thẻ dòng không đổi viền vì lỗi ẩn; ô .stat-strip-item[data-tone]; thẻ chọn gọn rộng tối thiểu 6,5rem (ba cột ở 390px: thay đổi cách vẽ của phần chọn quỹ); --cards-cols cho bảng thành thẻ.