Dọn màu mam.conan.school về token: 09.09.2026
Site thứ năm về 0. 175 → 0.
Đây là lượt sạch nhất trong năm lượt: mam đã @import theme.css từ trước, không có mã hex tuỳ ý, không có hex trong style, không có bậc số bịa. Chỉ 175 lớp bậc số và 5 lớp dark:.
Nhưng nó có thứ đã cắn ở play: bốn vùng nền tối nằm lẫn trong một ứng dụng nền sáng.
Phân loại TRƯỚC khi quy đổi
Bài học từ play là quy đổi xám máy móc làm hỏng nền tối mà không có gì đỏ. Nên lượt này bắt đầu bằng việc tìm và tách vùng nền tối ra xử lý tay, rồi mới cho bộ quy đổi chạy phần còn lại:
grep -rnoE "(bg|from|to)-(slate|zinc|gray|neutral|stone)-(800|900|950)" app --include=*.tsxBốn kết quả, và không cái nào giống cái nào:
| Chỗ | Là gì | Quy đổi |
|---|---|---|
DebugFooter.tsx | panel gỡ lỗi nền tối trọn vẹn | surface-inverse + surface-inverse-foreground với độ mờ cho bậc trung gian |
BulkActionBar.tsx | thanh công cụ nổi nền tối trên trang sáng | như trên |
AssetPicker.tsx, UploadModal.tsx (bg-slate-900/60) | màn che của hộp thoại | bg-surface-inverse/60 |
UploadModal.tsx:153 (bg-slate-900 text-white) | nút tối trên hộp thoại sáng | bg-foreground text-background hover:opacity-90 |
Chỗ thứ tư là chỗ dễ sai nhất: nó cũng là bg-slate-900, nhưng nó không phải một vùng nền tối
- nó là một nút tương phản trên nền sáng. Cùng một lớp CSS, hai vai trò khác nhau, hai token khác nhau. Không có cách nào tự động phân biệt; phải đọc.
Đổi màu thật, nói cho đúng
Quy đổi này không giữ nguyên pixel. Nói rõ ra:
| Trước | Sau | Ở đâu |
|---|---|---|
slate-900 #0f172a (xanh navy đậm) | surface-inverse #111111 (đen trung tính) | thanh công cụ, panel gỡ lỗi, màn che |
slate-950 #020617 | surface-inverse #111111 | vùng log của panel gỡ lỗi |
slate-50 #f8fafc | muted #f2f2f2 | nền trang |
white #ffffff | card #ffffff | thẻ, sidebar, header, giống hệt |
Thang slate của Tailwind ám xanh; token của hệ thiết kế trung tính. Nên các vùng tối mất chút sắc xanh. Đó là điểm của việc này, không phải tác dụng phụ: mam không có lý do gì để có một tông tối riêng khác phần còn lại của conan.school.
Dọn thêm: 36 lớp white
Gác màu không bắt bg-white / text-white (chúng không có bậc số, không phải hex). Nhưng skill design-system nói rõ text-white trên nền token phải là text-background / text-primary-foreground. mam đủ nhỏ để dọn nốt:
bg-white→bg-card(cùng#ffffff, không đổi hình thức)text-whitetrênbg-brand-primary→text-primary-foregroundbg-white/10bên trong panel tối →bg-surface-inverse-foreground/10
Chỗ cuối là ví dụ nữa của cùng một bài học: bg-white/10 trên trang sáng gần như vô hình; trên nền tối nó là một mảng nổi rõ. Cùng một lớp, hai ý nghĩa.
@apply không sinh utility rời: và phép kiểm phải biết điều đó
Phép kiểm "mọi lớp token có sinh CSS không" báo 3 lớp thiếu: bg-card/70, border-card/20, selection:bg-primary/20. Cả ba đều báo động giả, chúng nằm trong @apply của app.css, nên Tailwind gộp thẳng giá trị vào rule .glass và html,body chứ không sinh class rời:
html,body{background-color:var(--color-muted);color:var(--color-foreground)}
.glass{border-color:color-mix(in oklab, var(--color-card) 20%, transparent)}
::selection{background-color:color-mix(in oklab, var(--color-primary) 20%, transparent)}Khi phép kiểm báo thiếu, kiểm chính rule đã biên dịch trước khi kết luận token hỏng, cùng tinh thần với bài học "tin bản dựng" ở lượt play.
Kiểm chứng
npm run buildxanh. Xem bằng mắt trên dev server: nền trangrgb(242,242,242)=muted, chữrgb(17,17,17)=foreground, sidebarrgb(255,255,255)=card, panel gỡ lỗi nền tốirgb(17,17,17)chữ trắng, vùng nền tối render đúng.- 80 lớp token dùng trong mã, 0 lớp không sinh CSS (sau khi loại ba báo động giả của
@apply). - 0 lớp bậc số bảng màu, 0 lớp
dark:, 0 lớpwhitecòn lại. - Cả bảy gác ở gốc repo xanh.
Phát hiện ngoài lề: 7 lỗi type có sẵn, không gác nào bắt
npx tsc --noEmit ở mam cho 7 lỗi, và đúng 7 lỗi đó, cùng phân loại, cả trước lẫn sau thay đổi của lượt này (đã đo bằng git stash chỉ phần app/):
1 × TS1484 import type thiếu `type`
1 × TS2304 thiếu kiểu `PagesFunction`
2 × TS2307 thiếu `./+types/root`, `./+types/home` (typegen của React Router chưa chạy)
3 × TS7006 tham số `prev` ngầm kiểu anyKhông lỗi nào do dọn màu. Nhưng đáng ghi vì ci-checks.yml không có job nào cho mam, giống play. Bảy lỗi này sống được vì không ai đo. Sửa chúng nằm ngoài phạm vi PR màu.
Trạng thái
118 chỗ tồn đọng toàn repo, từ 3.445 hôm qua. Năm site khoá ở 0: www, admin, com, play, mam. Còn: mentors 53 · packages 32 (DebugFooter của admin-shared, cố ý) · docs 12 · video 11 · api 10.