/* Hệ trạng thái sinhvu.com (anh duyệt 24/10/2026: giọng rê chuột A "Mực in" + bảng mã phản hồi).
   Một nguồn cho mọi chỗ người xem chạm vào; nạp mọi trang bằng MỘT dòng _worker.js khối head, sau mọi kiểu trang.
   Nhịp dùng biến --n-* của nhip.css (đường cong .16,1,.3,1 · 120/240/480/960 · so le 60); trang chưa có nhip.css
   vẫn chạy nhờ giá trị dự phòng. Sửa tệp này thì tăng TT_V ở _worker.js.

   Giọng A: chữ GIỮ màu. Phản hồi đến từ hình: gạch chân đậm lên, mũi tên đi xuyên khung, thẻ nhấc 2px.
   Màu chỉ đổi ở nút. Đỏ là dấu: chỉ cho nút việc chính, viền chọn bàn phím, mũi tên nhỏ.
   Luật gốc a:hover tô đỏ mọi liên kết đã gỡ ở tokens/base.css.

   Trạng thái việc gắn bằng THUỘC TÍNH, không bằng lớp riêng từng trang:
     [data-tt~="dang"]     đang xử lý: vòng quay trong nút, chặn bấm đôi
     [data-tt~="xong"]     vừa xong: chữ lắng xuống, dấu tích vẽ nét
     [data-tt~="loi"] / [aria-invalid="true"]   lỗi tại ô: viền đỏ, một vòng sóng, câu .tt-loi trượt xuống
     .tt-canh              dải cảnh báo hổ phách trượt vào
     [aria-disabled="true"] / :disabled   tắt: mờ 45%, vẫn bấm được để hiện lý do (.tt-vi-sao)
     [data-tt~="khoa"]     khoá: không mờ, nền sọc mảnh, ổ khoá lắc một lần khi bấm
     .tt-chon[aria-pressed="true"]   đang chọn: nền mực (lớp tự chọn vào: aria-pressed đã có kiểu riêng ở 30 tệp)
     .tt-luu[data-hien]    đã lưu tự động: xanh dương, tự tan
     .tt-tra               trả về: chỗ vừa rời sáng kem rồi tan
     .tt-xuong             khung xương chờ dữ liệu
   Tên thuộc tính gom vào MỘT data-tt (giá trị cách nhau bằng dấu cách) vì data-dang/data-xong đã có chủ ở
   công cụ Tự chấm (cong-cu.css .cc-tc-*): luật chung trùng tên sẽ chặn bấm ở đó. */

:root {
  --tt-cong: var(--n-cong, cubic-bezier(.16, 1, .3, 1));
  --tt-nhanh: var(--n-nhanh, 120ms);
  --tt-vua: var(--n-vua, 240ms);
  --tt-cham: var(--n-cham, 480ms);
  --tt-mo: var(--n-mo, 960ms);
  --tt-gach-nghi: color-mix(in srgb, currentColor 32%, transparent);
  --tt-xong: var(--color-success);
  --tt-loi: var(--color-danger);
  --tt-canh: var(--color-warning);
  --tt-luu: var(--color-info);
  --tt-khoa: var(--color-muted-text, var(--text-secondary));
  --tt-tra: var(--color-warm-cream);
}

/* ================= TẦNG 1: trạng thái cơ bản ================= */

/* Chữ trong câu: chữ theo màu câu, gạch chân mờ lúc nghỉ, đậm lên khi rê. Chỉ liên kết trần (không lớp) trong
   phần nội dung; liên kết có lớp là thành phần, tự lo giọng của nó. */
main :is(p, li, dd, figcaption, blockquote, td) > a:not([class]) {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: var(--tt-gach-nghi);
  transition: text-decoration-color var(--tt-nhanh) var(--tt-cong);
}
main :is(p, li, dd, figcaption, blockquote, td) > a:not([class]):hover { text-decoration-color: currentColor; }

/* Chọn bằng bàn phím: dùng vòng chọn sẵn có của tokens/base.css (:focus-visible + --ring), không khai lại. */

/* Thẻ dự án: nhấc 2px, viền đậm, bóng navy nhẹ; tiêu đề giữ màu, chỉ mũi tên đổi đỏ (không tô đặc vòng tròn).
   Khối .sv-case nội tuyến đúc sẵn trong khoảng 1.500 trang (bộ thành phần hệ thiết kế) còn nhấc 5px và tô đặc đỏ;
   "body" nâng độ ưu tiên một bậc để thắng mọi bản nội tuyến mà không sửa tay từng trang. Ảnh do nhip.css lo. */
@media (hover: hover) and (pointer: fine) {
  body .sv-case:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--border-strong); }
  body .sv-case:hover .sv-case__arrow { background: transparent; border-color: var(--text-primary); color: var(--color-signal-red); transform: translateX(3px); }
}

/* Nhấn: hai mức cho cả hệ. Phần tử nhỏ co 0,96; khối lớn co 0,985. Vào 120, nhả 240. */
body .sv-btn { transition: transform var(--tt-vua) var(--tt-cong), background-color var(--tt-nhanh) var(--tt-cong), border-color var(--tt-nhanh) var(--tt-cong), color var(--tt-nhanh) var(--tt-cong); }
body .sv-btn:active:not([aria-disabled="true"], :disabled, [data-tt~="khoa"]),
body :is(.chip, .sv-chip, .tag-chip):active { transform: scale(.96); transition-duration: var(--tt-nhanh); }
body .bd__o:active { transform: scale(.985); transition-duration: var(--tt-nhanh); }

/* Tắt: mờ 45%, con trỏ báo chưa bấm được, không đổi khi rê. Không chặn bấm: bấm vào thì trang hiện lý do (.tt-vi-sao). */
/* :where giữ độ ưu tiên 0: công cụ nào đã khai kiểu tắt riêng thì kiểu ấy thắng. */
:where(a, button, .sv-btn)[aria-disabled="true"], :where(button:disabled) {
  opacity: .45;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}
.tt-vi-sao {
  display: block; margin-top: 6px; font-size: var(--text-small, 14px); color: var(--text-secondary);
  opacity: 0; transform: translateY(-4px);
  transition: opacity var(--tt-vua) var(--tt-cong), transform var(--tt-vua) var(--tt-cong);
}
.tt-vi-sao[data-hien] { opacity: 1; transform: none; }
/* ô cần sửa nháy viền hổ phách một nhịp */
@keyframes tt-nhac { 0%, 100% { box-shadow: 0 0 0 0 transparent; } 30% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--tt-canh) 35%, transparent); } }
[data-tt~="nhac"] { animation: tt-nhac var(--tt-mo) var(--tt-cong); }

/* ================= TẦNG 2: trạng thái việc ================= */

/* Đang xử lý: nút giữ bề ngang, vòng quay nhỏ trước chữ, chặn bấm đôi. */
@keyframes tt-quay { to { transform: rotate(360deg); } }
[data-tt~="dang"] { pointer-events: none; cursor: progress; }
:is(button, a, .sv-btn)[data-tt~="dang"]::before {
  content: ""; display: inline-block; flex: none; width: 12px; height: 12px; margin-right: 8px; vertical-align: -1px;
  border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent;
  animation: tt-quay .7s linear infinite;
}

/* Xong: chữ lắng xuống, dấu tích vẽ nét (nét SVG mang lớp .tt-tich, hoặc chữ hình Phosphor). */
@keyframes tt-lang { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@keyframes tt-ve { from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } }
[data-tt~="xong"] { animation: tt-lang var(--tt-vua) var(--tt-cong); }
.tt-tich path { stroke-dasharray: 24; animation: tt-ve var(--tt-cham) var(--tt-cong) both; }
.tt-bao-xong {
  display: flex; gap: 8px; align-items: center; color: var(--text-status-success, var(--tt-xong));
  background: color-mix(in srgb, var(--tt-xong) 8%, transparent); border-radius: var(--radius-sm); padding: 10px 12px;
  animation: tt-lang var(--tt-cham) var(--tt-cong);
}

/* Lỗi tại ô: viền đỏ, một vòng sóng lan một lần, câu lỗi trượt xuống. Không rung lắc. */
@keyframes tt-song { from { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tt-loi) 35%, transparent); } to { box-shadow: 0 0 0 8px transparent; } }
:is(input, textarea, select)[aria-invalid="true"], [data-tt~="loi"] :is(input, textarea, select) {
  border-color: var(--tt-loi) !important;
  animation: tt-song var(--tt-cham) var(--tt-cong);
}
.tt-loi {
  display: flex; gap: 6px; align-items: baseline; margin-top: 6px;
  font-size: var(--text-small, 14px); color: var(--text-status-critical, var(--tt-loi));
  animation: tt-lang var(--tt-vua) var(--tt-cong);
}

/* Cảnh báo: dải trượt vào từ trên, viền trái hổ phách. */
@keyframes tt-truot { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
.tt-canh {
  display: flex; gap: 8px; align-items: baseline; padding: 10px 12px;
  border-left: 3px solid var(--tt-canh); border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--tt-canh) 8%, transparent);
  color: var(--text-status-warning, var(--tt-canh));
  animation: tt-truot var(--tt-vua) var(--tt-cong);
}

/* Khoá: quy trình đã chốt. Không mờ, nền sọc mảnh, ổ khoá (.tt-o-khoa) lắc nhẹ một lần khi bấm. */
[data-tt~="khoa"] {
  cursor: not-allowed; color: var(--tt-khoa);
  background-image: repeating-linear-gradient(135deg, transparent 0 6px, color-mix(in srgb, var(--tt-khoa) 10%, transparent) 6px 7px);
}
@keyframes tt-lac { 0%, 100% { transform: none; } 25% { transform: rotate(-10deg); } 60% { transform: rotate(6deg); } }
[data-tt~="khoa"][data-tt~="bam"] .tt-o-khoa { display: inline-block; animation: tt-lac 360ms var(--tt-cong); }

/* Đang chọn: nền mực, dấu tích vẽ ra từ trái. */
.tt-chon[aria-pressed="true"] {
  background-color: var(--text-primary); border-color: var(--text-primary); color: var(--color-white);
  transition: background-color var(--tt-vua) var(--tt-cong), border-color var(--tt-vua) var(--tt-cong), color var(--tt-vua) var(--tt-cong);
}

/* Đã lưu tự động: "Đang lưu" rồi "Đã lưu" hiện mờ, tự tan sau 2 giây (trang gỡ data-hien). */
.tt-luu {
  display: inline-flex; gap: 6px; align-items: center; font-size: var(--text-small, 14px);
  color: var(--text-status-info, var(--tt-luu)); opacity: 0;
  transition: opacity var(--tt-vua) var(--tt-cong);
}
.tt-luu[data-hien] { opacity: 1; }

/* Khung xương chờ dữ liệu: đúng hình nội dung sắp tới, không để vùng trắng. */
@keyframes tt-xuong { to { background-position: -200% 0; } }
.tt-xuong {
  display: block; border-radius: var(--radius-sm); min-height: 12px;
  background: linear-gradient(90deg, var(--surface-paper), var(--color-cream-50, var(--surface-page)), var(--surface-paper));
  background-size: 200% 100%; animation: tt-xuong 1.4s linear infinite;
}

/* ================= TẦNG 3: trả về ================= */
/* Đóng tấm hay quay lại: chỗ vừa rời sáng kem rồi tan trong 960. Trang gắn .tt-tra rồi gỡ khi animationend. */
@keyframes tt-tra { from { box-shadow: 0 0 0 4px var(--tt-tra); background-color: color-mix(in srgb, var(--tt-tra) 45%, transparent); } to { box-shadow: 0 0 0 4px transparent; background-color: transparent; } }
.tt-tra { animation: tt-tra var(--tt-mo) var(--tt-cong); }

/* ================= Người tắt hiệu ứng trong máy ================= */
@media (prefers-reduced-motion: reduce) {
  [data-tt~="xong"], .tt-bao-xong, .tt-loi, .tt-canh, .tt-tra, [data-tt~="nhac"],
  :is(input, textarea, select)[aria-invalid="true"], [data-tt~="loi"] :is(input, textarea, select),
  [data-tt~="khoa"][data-tt~="bam"] .tt-o-khoa, .tt-tich path { animation: none; }
  .tt-tich path { stroke-dashoffset: 0; }
  .tt-xuong { animation: none; }
  body .sv-btn:active, body .bd__o:active { transform: none; }
}
