Skip to content

Dọn màu admin.conan.school về token: 08.09.2026 ​

Site thứ hai về 0, sau www. 1.601 → 0.

Nhưng ở admin thì "dọn màu" không phải là việc chính. Việc chính là thứ tìm thấy khi đi tìm nguyên nhân vì sao một cụm ứng dụng lại tích được 1.601 chỗ: sáu cụm legacy mỗi cụm tự khai một bảng màu riêng, và không bảng nào là bảng của hệ thiết kế.

Nguyên nhân gốc: sáu khối @theme riêng, không cái nào đúng ​

CLAUDE.md → LUẬT UI viết: "token lấy từ packages/design-system/theme.css, không site nào tự khai @theme riêng." Cả sáu cụm đều khai:

theme.css (nguồn sự thật)Sáu cụm admin khai
--color-primary#d94f2b#f26625
--color-foreground#111111#111827
--color-muted#f2f2f2#f9fafb
--color-border#f2f2f2#e5e7eb
--color-accent#fff7ed#f3f4f6 ở ba cụm, #fff7ed ở ba cụm

Không giá trị nào khớp, và sáu cụm còn không thống nhất với nhau. Đây chính xác là hỏng mà LUẬT MÀU sinh ra để chặn, đổi --color-primary trong theme.css không lan tới đâu cả, nhưng ở quy mô cả một cụm ứng dụng, không phải vài chỗ lẻ.

Và không khối nào khai --color-emerald, --color-amber, --color-cyan. Người soạn trang admin mở index.css của cụm mình, thấy có primary và muted nhưng không có màu ngữ nghĩa nào cho "đúng / cảnh báo / thông tin", nên họ gõ text-emerald-600. 204 lần emerald, 222 lần amber. 1.601 chỗ vi phạm không phải do cẩu thả; nó là hệ quả trực tiếp của việc hệ thiết kế chưa bao giờ được nạp vào chỗ họ làm việc.

Đã thay cả sáu khối bằng @import "../../../../packages/design-system/theme.css".

Đính chính một điều tôi nói sai lúc hỏi ​

Khi hỏi nên chọn cách nào, tôi mô tả hệ quả là "màu nhấn admin đổi từ cam #f26625 sang đất nung #d94f2b". Điều đó không đúng với trang đang chạy.

Kiểm lại vite.config.ts và bản dựng: ứng dụng được deploy là vỏ SPA (admin.conan.school/src/), nó nạp legacy qua alias (@content, @learning…), và src/index.css của vỏ vốn đã @import theme.css. CSS trong dist/ chỉ có một giá trị:

--color-primary:#d94f2b

Sáu khối @theme kia chỉ có hiệu lực khi chạy một cụm riêng lẻ ở chế độ dev (mỗi cụm có index.html + main.tsx riêng). Nên thay đổi này không đổi diện mạo production, nó làm dev khớp với production.

Điều đó lại giải thích thêm một chuyện: người soạn trang admin ở máy nhìn thấy giao diện cam, rồi ship lên một cổng đất nung. Khi thứ mình nhìn không phải thứ người dùng nhìn, token mất hết ý nghĩa, và gõ thẳng slate-500 trở thành lựa chọn hợp lý hơn.

Ba lỗi khác tìm được ​

1. @source của cả sáu cụm trỏ vào thư mục không tồn tại ​

css
@source "../../packages/admin-shared/src";   /* từ legacy/<cụm>/src/ → legacy/packages/... */

Đúng phải là ../../../../. Nghĩa là khi chạy một cụm riêng lẻ, Tailwind không quét admin-shared, mọi lớp chỉ xuất hiện trong component dùng chung (Button, Badge, Input, LoginPage) đều không có CSS. Vỏ SPA khai đúng nên production không dính; lại thêm một chỗ dev và production lệch nhau. Đã sửa cả sáu.

2. 117 lớp dark: chết hoặc nửa vời ​

  • admin-course-content khai @custom-variant dark (&:where(.dark, .dark *)), dark mode gắn vào class .dark. Nhưng không nơi nào trong repo bật class đó. 93 lớp dark: là mã chết vĩnh viễn.
  • admin-learning có 11 lớp dark: mà không khai @custom-variant → chúng rơi về mặc định của Tailwind v4 là prefers-color-scheme, tức là vẫn áp dụng cho người dùng máy tối, đúng lỗi "nửa chế độ tối" đã gặp ở www.

Hai hành vi trái ngược nhau trong cùng một cổng, không cái nào là dark mode thật. Đã gỡ sạch.

3. Chín lớp border-slate-150: bậc số không tồn tại ​

Cùng loại với 55 lớp ở www: Tailwind chỉ có 50, 100, 200…, 150 không sinh CSS nên chín đường viền đó không tồn tại. Rải ở bốn cụm.

Cách quy đổi ​

Giống www (xem dọn màu www): slate/gray/zinc → foreground · muted-foreground · muted · border; emerald/green/teal → emerald; amber/yellow/orange → amber; red/rose → destructive; blue/sky/indigo/cyan → cyan; purple/violet → primary. Bậc nhạt thành độ mờ; 49 chỗ hover: quy về cùng token được đổi thành hover:opacity-90.

Kiểm chứng ​

Phép kiểm quan trọng nhất ở đây không phải là gác màu xanh, mà là: mọi lớp token có sinh ra CSS không? Quy đổi text-emerald-600 → text-emerald trong khi --color-emerald không tồn tại sẽ tạo ra đúng loại hỏng mà lượt rà soát này đang đi bắt.

lớp token dùng trong mã (kèm variant): 196
KHÔNG sinh CSS: 0

Phép kiểm phải giữ nguyên variant: bg-primary/90 chỉ xuất hiện dưới dạng hover:bg-primary/90, nên tìm .bg-primary\/90 sẽ báo thiếu sai. Lần chạy đầu tôi bỏ variant và nhận 29 báo động giả.

Ngoài ra: npm run build xanh; tsc --noEmit 0 lỗi; CSS đã dựng có đủ --color-primary:#d94f2b, --color-emerald, --color-amber, --color-cyan, --color-destructive; 0 lớp bậc số bảng màu, 0 lớp dark: bảng màu còn lại; gác màu: admin.conan.school: 0 (hạ từ 1601).

Không kiểm được bằng mắt sâu hơn màn hình đăng nhập: admin.conan.school nằm sau Cloudflare Access nên bản chạy ở máy dừng ở màn hình "Không có quyền truy cập" (màn hình đó render đúng token).

Còn lại ​

packages/admin-shared/.../DebugFooter.tsx (32 chỗ) vẫn ở mốc, lớp phủ gỡ lỗi với bảng màu tối riêng và màu theo HTTP method; chuyển nó là một lần viết lại thật với rủi ro hiển thị thật và giá trị cho người dùng bằng không.

Sau lượt này: 949 chỗ tồn đọng toàn repo (com 386, play 270, mam 175, mentors 53, packages 32, docs 12, video 11, api 10); www và admin đều khoá ở 0.

Tài liệu nội bộ nền tảng Conan School.