/* ============================================================
   CLASSIC ADMIN — Design System
   ============================================================ */

/* ---------- Tokens ---------- */
:root {
  /* Surface */
  --bg:            #f6f7fb;
  --surface:       #ffffff;
  --surface-2:     #f9fafb;
  --surface-3:     #f3f4f6;
  --border:        #e8eaf0;
  --border-strong: #d6d9e3;

  /* Text */
  --text:       #14161f;
  --text-2:     #5b6070;
  --text-3:     #8e93a3;
  --text-invert:#ffffff;

  /* Brand */
  --primary:     #4f46e5;
  --primary-600: #4338ca;
  --primary-soft:#eef0ff;

  /* Semantic */
  --success: #10b981;  --success-soft: #ecfdf5;
  --warning: #f59e0b;  --warning-soft: #fffbeb;
  --danger:  #ef4444;  --danger-soft:  #fef2f2;
  --info:    #0ea5e9;  --info-soft:    #f0f9ff;
  --purple:  #a855f7;  --purple-soft:  #faf5ff;

  /* Elevation */
  --sh-sm: 0 1px 2px rgba(20,22,31,.05);
  --sh:    0 2px 8px rgba(20,22,31,.06), 0 1px 2px rgba(20,22,31,.04);
  --sh-lg: 0 12px 32px rgba(20,22,31,.10), 0 2px 8px rgba(20,22,31,.05);
  --sh-xl: 0 24px 64px rgba(20,22,31,.16);

  /* Geometry */
  --r-sm: 8px;  --r: 12px;  --r-lg: 16px;  --r-xl: 22px;
  --sidebar-w: 248px;
  --header-h: 60px;

  /* Motion */
  --ease: cubic-bezier(.4,0,.2,1);
}

[data-theme="dark"] {
  --bg:            #0c0d12;
  --surface:       #15171f;
  --surface-2:     #1b1e28;
  --surface-3:     #232733;
  --border:        #272b38;
  --border-strong: #363b4d;

  --text:       #e9eaf0;
  --text-2:     #9ba1b4;
  --text-3:     #6b7183;

  --primary-soft:#1e1f3d;
  --success-soft:#0b2620;
  --warning-soft:#2a2010;
  --danger-soft: #2b1418;
  --info-soft:   #0c1e2e;
  --purple-soft: #1f1430;

  --sh-sm: 0 1px 2px rgba(0,0,0,.4);
  --sh:    0 2px 8px rgba(0,0,0,.45);
  --sh-lg: 0 12px 32px rgba(0,0,0,.55);
  --sh-xl: 0 24px 64px rgba(0,0,0,.65);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  transition: background .2s var(--ease), color .2s var(--ease);
}
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; }
a { color: var(--primary); text-decoration: none; }
table { border-collapse: collapse; width: 100%; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 6px; border: 3px solid var(--bg); }

/* ---------- Layout ---------- */
.app { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--sidebar-w);
  flex: none;
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  position: fixed; inset: 0 auto 0 0;
  z-index: 40;
  transition: transform .25s var(--ease);
}
.sidebar__brand {
  height: var(--header-h);
  display: flex; align-items: center; gap: 10px;
  padding: 0 18px;
  border-bottom: 1px solid var(--border);
  flex: none;
}
.sidebar__logo {
  width: 32px; height: 32px; border-radius: 9px;
  background: linear-gradient(135deg, var(--primary), var(--purple));
  color: #fff; font-weight: 800; font-size: 15px;
  display: flex; align-items: center; justify-content: center;
  flex: none;
}
.sidebar__title { font-weight: 700; font-size: 15px; letter-spacing: -.01em; }

.sidebar__nav { flex: 1; overflow-y: auto; padding: 14px 10px; }
.nav__label {
  font-size: 10.5px; font-weight: 700; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .07em;
  padding: 0 10px; margin: 14px 0 6px;
}
.nav__label:first-child { margin-top: 0; }
.nav__item {
  width: 100%;
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px; border-radius: var(--r-sm);
  color: var(--text-2); font-size: 13.5px; font-weight: 500;
  transition: background .13s var(--ease), color .13s var(--ease);
  text-align: left;
}
.nav__item:hover { background: var(--surface-3); color: var(--text); }
.nav__item.is-active { background: var(--primary-soft); color: var(--primary); font-weight: 600; }
[data-theme="dark"] .nav__item.is-active { color: #a5b4fc; }
.nav__icon { width: 18px; text-align: center; font-size: 15px; flex: none; }
.nav__text { flex: 1; }
.nav__badge {
  font-size: 10px; font-weight: 700; padding: 2px 7px; border-radius: 20px;
  background: var(--danger); color: #fff;
}

.sidebar__foot { flex: none; padding: 10px; border-top: 1px solid var(--border); }
.user-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: var(--r-sm);
  transition: background .13s var(--ease);
}
.user-chip:hover { background: var(--surface-3); }
.user-chip__av {
  width: 32px; height: 32px; border-radius: 50%; flex: none;
  background: linear-gradient(135deg, var(--primary), var(--purple));
  color: #fff; font-weight: 700; font-size: 12px;
  display: flex; align-items: center; justify-content: center;
}
.user-chip__info { flex: 1; min-width: 0; }
.user-chip__name { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-chip__role { font-size: 11px; color: var(--text-3); }
.icon-btn {
  width: 30px; height: 30px; border-radius: 8px; flex: none;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-3); font-size: 15px;
  transition: background .13s var(--ease), color .13s var(--ease);
}
.icon-btn:hover { background: var(--surface-3); color: var(--text); }

.main { flex: 1; margin-left: var(--sidebar-w); min-width: 0; display: flex; flex-direction: column; }
.topbar {
  height: var(--header-h); flex: none;
  background: color-mix(in srgb, var(--surface) 85%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 14px;
  padding: 0 22px;
  position: sticky; top: 0; z-index: 30;
}
.topbar__burger { display: none; }
.topbar__title { font-size: 17px; font-weight: 700; letter-spacing: -.02em; }
.topbar__sub { font-size: 12px; color: var(--text-3); margin-top: 1px; }
.topbar__actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.view { padding: 22px; flex: 1; }

/* ---------- Components ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-sm);
}
.card__head {
  padding: 15px 18px; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.card__title { font-size: 14px; font-weight: 700; letter-spacing: -.01em; }
.card__sub { font-size: 12px; color: var(--text-3); margin-top: 1px; }
.card__actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }
/* Thẻ đang thu gọn: bỏ vạch dưới tiêu đề, không thì còn trơ một đường kẻ
   chẳng ngăn cách cái gì. */
.card--gon .card__head { border-bottom: 0; }
.card__body { padding: 18px; }
.card__body--flush { padding: 0; }

.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px; border-radius: var(--r-sm);
  background: var(--surface); border: 1px solid var(--border-strong);
  color: var(--text); font-size: 13px; font-weight: 600;
  transition: all .13s var(--ease); white-space: nowrap;
}
.btn:hover { background: var(--surface-3); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn--primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn--primary:hover { background: var(--primary-600); }
.btn--danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn--danger:hover { filter: brightness(.93); }
/* Dùng cho nút "Cần hỗ trợ": nổi hơn nút thường để nhân viên thấy ngay là có
   đường kêu cứu, nhưng không đỏ như nút huỷ — xin hỗ trợ không phải chuyện xấu. */
.btn--warning { background: var(--warning); border-color: var(--warning); color: #fff; }
.btn--warning:hover { filter: brightness(.93); }
.btn--ghost { background: transparent; border-color: transparent; color: var(--text-2); }
.btn--ghost:hover { background: var(--surface-3); color: var(--text); }
.btn--sm { padding: 5px 10px; font-size: 12px; }
.btn--block { width: 100%; justify-content: center; }

.seg { display: inline-flex; background: var(--surface-3); border-radius: 10px; padding: 3px; gap: 2px; }
.seg button {
  padding: 6px 13px; border-radius: 7px; font-size: 12.5px; font-weight: 600;
  color: var(--text-2); transition: all .13s var(--ease);
}
.seg button:hover { color: var(--text); }
.seg button.is-active { background: var(--surface); color: var(--text); box-shadow: var(--sh-sm); }

.field { margin-bottom: 14px; }
.field__label { display: block; font-size: 12px; font-weight: 600; color: var(--text-2); margin-bottom: 6px; }
.input, .select, .textarea {
  width: 100%; padding: 9px 12px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  font-size: 13.5px; outline: none;
  transition: border-color .13s var(--ease), box-shadow .13s var(--ease);
}
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 14%, transparent);
}
.textarea { resize: vertical; min-height: 76px; font-family: inherit; }
.input--sm { padding: 6px 10px; font-size: 12.5px; }

/* Stat tiles */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px,1fr)); gap: 13px; }
.stat {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: 15px 17px; box-shadow: var(--sh-sm);
  position: relative; overflow: hidden;
}
.stat::after {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--accent, var(--primary));
}
.stat--success { --accent: var(--success); }
.stat--warning { --accent: var(--warning); }
.stat--danger  { --accent: var(--danger); }
.stat--info    { --accent: var(--info); }
.stat--purple  { --accent: var(--purple); }
.stat__label { font-size: 11.5px; font-weight: 600; color: var(--text-3); text-transform: uppercase; letter-spacing: .04em; }
.stat__value { font-size: 25px; font-weight: 800; letter-spacing: -.03em; margin-top: 5px; line-height: 1.15; }
.stat__value small { font-size: 14px; font-weight: 600; color: var(--text-3); }
.stat__hint { font-size: 11.5px; color: var(--text-3); margin-top: 4px; }

/* Table */
.tbl-wrap { overflow-x: auto; }
.tbl th {
  background: var(--surface-2); color: var(--text-3);
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  padding: 10px 14px; text-align: left; white-space: nowrap;
  border-bottom: 1px solid var(--border);
}
.tbl td { padding: 11px 14px; border-bottom: 1px solid var(--border); font-size: 13px; }
.tbl tbody tr { transition: background .1s var(--ease); }
.tbl tbody tr:hover td { background: var(--surface-2); }
.tbl tbody tr:last-child td { border-bottom: 0; }
/* Cột TÊN SẢN PHẨM: hiện ĐẦY ĐỦ, cho xuống dòng.
   Trước đây tên bị cắt bằng `.slice(0, 56)` nên "Dầu gội … Olaplex No.4 Bond
   Maintenance Shampoo 250ml" hiện thành "Dầu gội giúp phục hồi tóc bị hư tổn
   và tăng cường chắc k" — cụt đúng ở chỗ phân biệt No.4 với No.4P, mà đây
   lại là màn hình để NGƯỜI ĐỌC chọn đúng sản phẩm.
   `break-word` phòng tên không có dấu cách; `min-width` để cột không bị bóp
   thành một chữ mỗi dòng khi bảng chật. */
.tbl .sp { white-space: normal; word-break: break-word; min-width: 220px; }
.tbl .num { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.tbl .center { text-align: center; }

/* Tag / badge */
.tag {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 9px; border-radius: 20px;
  font-size: 11px; font-weight: 700; white-space: nowrap;
  background: var(--surface-3); color: var(--text-2);
}
.tag--success { background: var(--success-soft); color: var(--success); }
.tag--warning { background: var(--warning-soft); color: var(--warning); }
.tag--danger  { background: var(--danger-soft);  color: var(--danger); }
.tag--info    { background: var(--info-soft);    color: var(--info); }
.tag--purple  { background: var(--purple-soft);  color: var(--purple); }
.tag--primary { background: var(--primary-soft); color: var(--primary); }

/* Chấm báo trạng thái đang trong ca */
.dot {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  display: inline-block; background: var(--border-strong);
}
.dot--on {
  background: var(--success);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--success) 55%, transparent);
  animation: dotPulse 2.2s infinite;
}
@keyframes dotPulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--success) 55%, transparent); }
  70%  { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
.avatar-wrap { position: relative; display: inline-flex; flex: none; }
.avatar-wrap .dot {
  position: absolute; right: -1px; bottom: -1px;
  width: 10px; height: 10px; border: 2px solid var(--surface);
}

/* Alert */
.alert {
  padding: 12px 15px; border-radius: var(--r);
  font-size: 13px; display: flex; gap: 10px; align-items: flex-start;
  border: 1px solid transparent;
}
.alert__icon { font-size: 16px; flex: none; line-height: 1.3; }
.alert--danger  { background: var(--danger-soft);  border-color: color-mix(in srgb, var(--danger) 25%, transparent);  color: var(--danger); }
.alert--warning { background: var(--warning-soft); border-color: color-mix(in srgb, var(--warning) 25%, transparent); color: #92400e; }
.alert--success { background: var(--success-soft); border-color: color-mix(in srgb, var(--success) 25%, transparent); color: #065f46; }
.alert--info    { background: var(--info-soft);    border-color: color-mix(in srgb, var(--info) 25%, transparent);    color: #075985; }
[data-theme="dark"] .alert--warning { color: #fcd34d; }
[data-theme="dark"] .alert--success { color: #6ee7b7; }
[data-theme="dark"] .alert--info    { color: #7dd3fc; }

/* Biểu đồ đua — xếp hạng tác giả */
.race-row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 12px; border-radius: var(--r);
  border: 1px solid var(--border); margin-bottom: 8px;
  background: var(--surface); cursor: pointer;
  transition: border-color .13s var(--ease), transform .13s var(--ease);
}
.race-row:hover { border-color: var(--primary); transform: translateX(2px); }
.race-rank { width: 26px; text-align: center; font-weight: 800; font-size: 14px; color: var(--text-3); flex: none; }
.race-info { flex: 1; min-width: 160px; }
.race-track { flex: 1.2; min-width: 90px; height: 9px; border-radius: 5px; background: var(--surface-3); overflow: hidden; }
.race-fill { height: 100%; width: 0; border-radius: 5px; animation: raceGrow .7s var(--ease) forwards; }
@keyframes raceGrow { to { width: var(--w); } }
.race-score { flex: none; text-align: right; font-weight: 800; font-size: 14px; min-width: 76px; }
.race-score small { display: block; font-size: 10.5px; font-weight: 500; color: var(--text-3); }
@media (max-width: 720px) {
  .race-row { flex-wrap: wrap; }
  .race-track { order: 9; flex-basis: 100%; }
}

/* Empty / loading */
.empty { padding: 44px 20px; text-align: center; color: var(--text-3); font-size: 13px; }
.empty__icon { font-size: 30px; margin-bottom: 10px; opacity: .55; }
.skeleton {
  background: linear-gradient(90deg, var(--surface-3) 25%, var(--surface-2) 50%, var(--surface-3) 75%);
  background-size: 200% 100%; animation: shimmer 1.3s infinite; border-radius: var(--r-sm);
}
@keyframes shimmer { to { background-position: -200% 0; } }
.spinner {
  width: 15px; height: 15px; border: 2px solid var(--border-strong);
  border-top-color: var(--primary); border-radius: 50%;
  animation: spin .65s linear infinite; display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Modal */
.modal-bg {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(10,11,16,.5); backdrop-filter: blur(3px);
  display: none; align-items: flex-start; justify-content: center;
  padding: 44px 16px; overflow-y: auto;
}
.modal-bg.is-open { display: flex; }
.modal {
  background: var(--surface); border-radius: var(--r-xl);
  width: 100%; max-width: 460px; box-shadow: var(--sh-xl);
  animation: modalIn .18s var(--ease);
}
@keyframes modalIn { from { opacity: 0; transform: translateY(-10px) scale(.98); } }
.modal__head {
  padding: 17px 20px; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 12px;
}
.modal__title { font-size: 15px; font-weight: 700; flex: 1; }
.modal__body { padding: 20px; }
.modal__foot {
  padding: 14px 20px; border-top: 1px solid var(--border);
  display: flex; gap: 9px; justify-content: flex-end;
  /* Dính đáy để nút hành động luôn thấy được, kể cả khi nội dung dài */
  position: sticky; bottom: 0; z-index: 2;
  background: var(--surface);
  border-radius: 0 0 var(--r-xl) var(--r-xl);
}
.modal__body { max-height: calc(100vh - 210px); overflow-y: auto; }

/* Toast */
.toast-host { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); z-index: 200; display: flex; flex-direction: column; gap: 8px; align-items: center; }
.toast {
  background: var(--text); color: var(--bg);
  padding: 11px 18px; border-radius: var(--r); font-size: 13px; font-weight: 500;
  box-shadow: var(--sh-lg); animation: toastIn .22s var(--ease);
  display: flex; align-items: center; gap: 9px; max-width: 90vw;
}
@keyframes toastIn { from { opacity: 0; transform: translateY(14px); } }
.toast.is-out { opacity: 0; transform: translateY(10px); transition: all .22s var(--ease); }

/* Thẻ báo đơn mới — góc phải dưới, tự ẩn. Khác toast giữa màn hình: thẻ này
   mang thông tin đơn và bấm được, dùng cho việc KHÔNG cần chặn màn hình. */
.dm-host {
  position: fixed; right: 18px; bottom: 18px; z-index: 190;
  display: flex; flex-direction: column; gap: 9px; align-items: flex-end;
  max-width: min(330px, calc(100vw - 32px)); pointer-events: none;
}
.dm {
  pointer-events: auto; cursor: pointer; width: 100%;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-left: 4px solid var(--primary);
  border-radius: var(--r); box-shadow: var(--sh-lg);
  padding: 11px 13px; font-size: 13px;
  animation: dmIn .24s var(--ease);
}
.dm:hover { border-left-color: var(--purple); }
.dm__top { display: flex; align-items: center; gap: 7px; font-weight: 800; margin-bottom: 3px; }
.dm__row { display: flex; justify-content: space-between; gap: 10px; padding: 2px 0; }
.dm.is-out { opacity: 0; transform: translateX(14px); transition: all .24s var(--ease); }
@keyframes dmIn { from { opacity: 0; transform: translateX(18px); } }
@media (max-width: 560px) { .dm-host { left: 16px; right: 16px; max-width: none; } }

/* Utils */
.row { display: flex; align-items: center; gap: 10px; }
.row--between { justify-content: space-between; }
.row--wrap { flex-wrap: wrap; }
.grid { display: grid; gap: 13px; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(260px,1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(210px,1fr)); }
.mt-1 { margin-top: 5px; }
.mt-3 { margin-top: 13px; } .mt-4 { margin-top: 18px; }
.mb-1 { margin-bottom: 5px; }
.mb-3 { margin-bottom: 13px; } .mb-4 { margin-bottom: 18px; }
.muted { color: var(--text-3); }
.small { font-size: 12px; }
.bold { font-weight: 700; }
.num { font-variant-numeric: tabular-nums; }
.text-purple { color: var(--purple); }
.text-success { color: var(--success); } .text-danger { color: var(--danger); }
.text-warning { color: var(--warning); } .text-primary { color: var(--primary); }
.hidden { display: none !important; }

/* Mobile */
.backdrop { display: none; position: fixed; inset: 0; background: rgba(10,11,16,.45); z-index: 35; }
.backdrop.is-open { display: block; }
@media (max-width: 560px) {
  .modal-bg { padding: 12px; }
  .modal { max-width: 100% !important; }
  .modal__foot .btn { flex: 1; justify-content: center; }
}
@media (max-width: 900px) {
  .sidebar { transform: translateX(-100%); box-shadow: var(--sh-xl); }
  .sidebar.is-open { transform: translateX(0); }
  .main { margin-left: 0; }
  .topbar__burger { display: flex; }
  .view { padding: 15px; }
  .topbar { padding: 0 15px; }
}

/* ============================================================
   GIAO VIỆC
   ============================================================ */

/* Một dòng việc trong danh sách */
.viec {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 18px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background .12s;
}
.viec:last-child { border-bottom: 0; }
.viec:hover { background: var(--surface-2); }
.viec__chinh { flex: 1; min-width: 0; }
.viec__ten { font-weight: 600; font-size: 13.5px; }
.viec__ten--xong { text-decoration: line-through; opacity: .6; }
/* Vạch màu bên trái — đọc được khi lướt nhanh, không phải đọc chữ.
   Thứ tự ưu tiên: trễ (đỏ) đè lên cần hỗ trợ (vàng). */
.viec--hotro { border-left: 3px solid var(--warning); padding-left: 15px; }
.viec--tre { border-left: 3px solid var(--danger); padding-left: 15px; }

/* Có phản hồi mà mình chưa đọc: nền vàng nhạt + chấm tròn nhấp nháy.
   Chỉ tô nền chưa đủ — người quen mắt sẽ lướt qua; chuyển động mới kéo được
   mắt về, mà một chấm nhỏ thì không chói như cả dòng nhấp nháy. */
.viec--moi { background: var(--warning-soft); }
.viec--moi:hover { background: var(--warning-soft); filter: brightness(.97); }
.viec--moi .viec__ten::after {
  content: '';
  display: inline-block; width: 7px; height: 7px;
  margin-left: 7px; border-radius: 50%;
  background: var(--warning);
  animation: nhapNhay 1.6s var(--ease) infinite;
}
@keyframes nhapNhay { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) {
  .viec--moi .viec__ten::after { animation: none; }
}

/* Huy hiệu NEW — việc mới giao, chưa bắt đầu làm. Nền đặc để khác hẳn
   các nhãn nền nhạt xung quanh ("Mới giao", "Phản hồi mới"); không động. */
.viec__new {
  display: inline-flex; align-items: center;
  padding: 2px 6px; border-radius: 4px;
  font-size: 10px; font-weight: 800; letter-spacing: .06em; line-height: 1.4;
  background: var(--danger); color: #fff;
  flex: none;
}

.viec--an { opacity: .5; }

/* ---------- Khối: việc chính + việc con lồng bên trong ----------
   Việc con mặc định mang đúng tiêu đề của việc chính, nên để hai dòng ngang
   hàng là nhìn thấy hai dòng trùng tên, phải đọc tới dòng chữ nhỏ mới phân
   biệt được. Lồng vào và thụt lề thì quan hệ "thuộc về" đọc được ngay.

   MỖI KHỐI LÀ MỘT THẺ RIÊNG, có viền và có khoảng cách với khối kế tiếp.
   Trước đây các khối chỉ cách nhau một vạch 1px nên mười đầu việc dính thành
   một mảng chữ: mắt không tìm ra ranh giới, và việc con của khối này trông
   như nằm cùng nhóm với việc chính của khối dưới. Khoảng trống làm việc đó
   tốt hơn mọi vạch kẻ — đây là thứ mắt đọc được mà không cần nghĩ. */
.khoi {
  border: 1px solid var(--border);
  border-radius: 10px;
  margin: 0 12px 10px;
  background: var(--surface);
}
.khoi:first-child { margin-top: 12px; }
.khoi:hover { border-color: var(--border-strong); }
.khoi > .viec { border-bottom: 0; }
.khoi__con { background: var(--surface-2); border-top: 1px solid var(--border); }

/* BO GÓC CHO TỪNG PHẦN BÊN TRONG, KHÔNG dùng `overflow: hidden` trên `.khoi`.
   overflow:hidden cắt mọi thứ tràn ra ngoài — kể cả nhãn chỉ dẫn hiện khi rê
   chuột lên nút (.co-nhan::after). Nhãn đó vẽ PHÍA TRÊN nút, mà nút nằm sát
   mép trên của thẻ, nên nó bị xén mất một nửa: người dùng rê chuột vào và đọc
   được đúng "Xoá hẳn việc…".
   `z-index` không cứu được — overflow cắt theo hình khối, không theo tầng.
   Nên phải bo góc từng phần: phần nào có NỀN RIÊNG thì phần đó tự bo. */
.khoi > .viec:first-child { border-radius: 9px 9px 0 0; }
.khoi > .viec:only-child { border-radius: 9px; }
.khoi__con:last-child,
.khoi__con:last-child > .viec--con:last-child { border-radius: 0 0 9px 9px; }
/* Vạch dọc chạy suốt bên trái cụm con — cho mắt biết chúng cùng một nhánh */
.khoi__con .viec--con {
  padding-left: 26px;
  border-bottom: 1px solid var(--border);
  box-shadow: inset 2px 0 0 var(--border-strong);
}
.khoi__con .viec--con:last-child { border-bottom: 0; }
.viec--con .viec__ten { font-weight: 600; font-size: 12.5px; }
.viec__nhanh-dau { color: var(--text-3); font-size: 13px; margin-right: 2px; }

/* ---------- Số thứ tự: huy hiệu tròn đứng ngay trước tiêu đề ----------
   Nằm trong cùng dòng với tên việc, không tách ra thành cột riêng: số và tên
   phải đọc ra MỘT CỤM. Số lơ lửng ở lề thì mắt còn phải tự nối nó vào dòng
   nào, mà lúc nhãn xuống dòng là nối nhầm.

   Hình tròn chứ không phải chữ số trần: chữ số trần lẫn ngay vào "×3",
   "18/09", "1 điểm" — cả dòng này vốn đã đầy số. Cái vòng tròn là thứ nói
   "đây là số thứ tự", không cần chú thích.

   Bề rộng TỐI THIỂU bằng chiều cao để số một chữ ra hình tròn, số hai chữ
   giãn thành viên thuốc chứ không bị bóp méo. */
.viec__stt {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 21px; height: 21px; padding: 0 6px;
  border-radius: 999px;
  background: var(--surface-3); color: var(--text-2);
  border: 1px solid var(--border);
  font-size: 11.5px; font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums;     /* số 1 hẹp hơn số 0 → "11" lệch */
  user-select: none;
}
/* Số việc con (1.1) phải NHẸ hơn hẳn: cùng độ đậm thì hai tầng trông ngang
   hàng, mất luôn quan hệ "thuộc về" mà thụt lề vừa dựng ra. Bỏ luôn viền và
   nền đặc để nó lùi hẳn về sau. */
.viec__stt--con {
  min-width: 26px; height: 19px;
  background: transparent; border-color: transparent;
  color: var(--text-3); font-size: 10.5px; font-weight: 600;
}

/* ---------- Đồng hồ đếm ngược tới hạn ----------
   Chỉ hiện khi CÒN DƯỚI 3 NGÀY (xem demNguoc() trong js/core/rules.js). Hiện
   suốt thì mắt quen, tới lúc còn hai tiếng cũng không ai nhìn nữa. */
.viec__dem {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 7px; border-radius: 999px;
  background: var(--surface-3); color: var(--text-2);
  font-size: 11.5px; font-weight: 600;
  font-variant-numeric: tabular-nums;     /* chữ số đổi mỗi phút, đừng để nhảy */
  white-space: nowrap;
}
/* Dưới 24 giờ: đỏ. Đây là ranh giới "để mai" hay "làm ngay", nên nó phải
   khác MÀU chứ không chỉ khác con số — khác con số thì phải đọc mới biết. */
.viec__dem--gap {
  background: var(--danger-soft); color: var(--danger);
}
/* Vạch trễ/cần hỗ trợ của dòng con vẫn phải thắng vạch xám của cụm */
.khoi__con .viec--con.viec--tre { box-shadow: inset 3px 0 0 var(--danger); }
.khoi__con .viec--con.viec--hotro { box-shadow: inset 3px 0 0 var(--warning); }
.viec__nut { flex-shrink: 0; }

.viec__mota, .viec__ketqua {
  font-size: 13px; line-height: 1.65;
  padding: 10px 12px; border-radius: 8px;
  background: var(--surface-2);
  margin-bottom: 12px;
}
/* CHỈ phần CHỮ mới giữ xuống dòng, không phải cả khung.
   Để pre-wrap trên khung thì thụt lề của chuỗi HTML sinh ra cũng thành khoảng
   trắng hiện lên — khung "Kết quả: Ok hoàn thành nhé" phình cao gấp bốn, toàn
   khoảng trống. Đúng lỗi đã mắc ở bong bóng chat (.tn__bong), lần này ở khung
   kết quả. Mô tả việc vẫn cần pre-wrap vì người ta gõ nhiều dòng thật. */
.viec__mota { white-space: pre-wrap; }
.viec__ketqua { background: var(--success-soft); }
.viec__ketqua .kq__chu { white-space: pre-wrap; }

/* ---------- Cây việc: việc gốc ↑ và việc con ↳ ----------
   Một tầng, hiện ngay trong hộp chi tiết. Người dựng video cần đọc yêu cầu ở
   việc gốc, người viết kịch bản cần biết phần dựng tới đâu — bắt họ quay ra
   danh sách rồi dò lại tên việc là mất mạch. */
.viec__cay { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.viec__nhanh {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 11px; border-radius: 8px;
  background: var(--surface-2); border: 1px solid var(--border);
  cursor: pointer; transition: background .12s var(--ease);
}
.viec__nhanh:hover { background: var(--surface-3); }

/* ---------- Ô nhập link đăng, mỗi kênh một dòng ----------
   Nhãn kênh cố định 96px bên trái để mắt dò theo cột, không phải đọc lại từng
   dòng xem ô nào của kênh nào. */
.viec__odang {
  padding: 9px 11px; border-radius: 8px;
  background: var(--surface-2); border: 1px solid var(--border);
}
.viec__odang-hang {
  display: flex; align-items: center; gap: 8px; margin-top: 6px;
}
.viec__odang-hang > span { flex: 0 0 96px; color: var(--text-2); }
.viec__odang-hang > input { flex: 1 1 auto; min-width: 0; }

/* ---------- File đính kèm (nằm trên Google Drive) ---------- */
.viec__file {
  padding: 10px 12px; border-radius: 8px; margin-bottom: 12px;
  background: var(--surface-2); border: 1px solid var(--border);
}
.viec__file-hang {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 6px; font-size: 13px;
}
.viec__file-hang > a { flex: 1 1 auto; min-width: 0; word-break: break-word; }

/* Thanh tiến độ tải lên. Không có nó thì người ta tưởng máy treo rồi bấm
   lại, và file 2GB được tải lên hai lần. */
.viec__tailen {
  padding: 10px 12px; border-radius: 8px; margin-bottom: 12px;
  background: var(--info-soft); border: 1px solid var(--border);
}
.tien {
  height: 8px; margin-top: 6px; border-radius: 999px;
  background: var(--surface-3); overflow: hidden;
}
.tien__thanh {
  height: 100%; width: 0;
  background: var(--primary);
  transition: width .2s var(--ease);
}

/* Dòng bảng bấm được — báo cáo tháng mở thẳng hộp chi tiết của đầu việc */
.tr--mo { cursor: pointer; }
.tr--mo:hover { background: var(--surface-2); }

/* Mã bài trên sàn — chữ đều nét để chép tay không sót số */
.ma-bai {
  display: inline-block;
  padding: 1px 6px; border-radius: 5px;
  background: var(--surface-3); border: 1px solid var(--border);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11.5px; color: var(--text-2);
  user-select: all;          /* bấm một cái là chọn trọn mã */
}

/* ---------- Người cùng tham gia ---------- */
.viec__khach { margin-bottom: 12px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px 3px 3px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
  font-size: 12px; line-height: 1.4;
}
.chip__av {
  width: 22px; height: 22px; flex-shrink: 0;
  border-radius: 50%; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  font-size: 9px; font-weight: 700;
  background: var(--primary); color: #fff;
}
.chip__av img { width: 100%; height: 100%; object-fit: cover; }
/* 24px mới bấm trúng trên máy bảng ở quầy — dấu × một mình thì bé quá */
.chip__bo {
  width: 20px; height: 20px; margin-left: 2px;
  border: 0; border-radius: 50%; cursor: pointer;
  background: transparent; color: var(--text-3);
  font-size: 15px; line-height: 1;
}
.chip__bo:hover { background: var(--danger-soft); color: var(--danger); }

/* Ô chọn người trong form mời: cả cái chip là nhãn bấm được */
.chip--chon { cursor: pointer; padding-right: 11px; user-select: none; }
.chip--chon:hover { border-color: var(--border-strong); }
.viec__chonnguoi { max-height: 190px; overflow-y: auto; padding: 2px; }
.viec__khoicon {
  padding: 12px; border-radius: 10px;
  background: var(--surface-2); border: 1px solid var(--border);
  margin-bottom: 4px;
}

/* ---------- Khung trao đổi ---------- */
.chat {
  max-height: 320px; overflow-y: auto;
  padding: 12px; border-radius: 10px;
  background: var(--surface-2);
  display: flex; flex-direction: column; gap: 10px;
}
.chat__trong, .chat__mocc {
  text-align: center; font-size: 11.5px;
  color: var(--text-3);
  padding: 4px 0;
}
.chat__nhap { margin-top: 12px; }

/* Ô nhập có nút gửi nằm bên trong, kiểu khung chat quen thuộc.
   padding-right chừa chỗ cho nút, nếu không chữ chui xuống dưới nút. */
.chat__o { position: relative; }
.chat__o .textarea { padding-right: 52px; }
.chat__gui {
  position: absolute; right: 8px; bottom: 8px;
  width: 36px; height: 36px;          /* 36px mới bấm trúng trên máy bảng ở quầy */
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%; cursor: pointer;
  background: var(--primary); color: #fff;
  font-size: 15px; line-height: 1;
  transition: background .12s var(--ease), transform .08s var(--ease);
}
.chat__gui:hover { background: var(--primary-600); }
.chat__gui:active { transform: scale(.94); }
.chat__gui:disabled { opacity: .5; cursor: default; }

/* Một tin: avatar bên trái, bong bóng bên phải. Tin của mình đảo chiều.
   align-self chứ không phải margin: trong flex cột, item mặc định giãn hết
   chiều ngang nên bong bóng một chữ vẫn trải dài cả dòng. */
.tn { display: flex; gap: 8px; align-items: flex-end; max-width: 78%; align-self: flex-start; }
.tn--toi { align-self: flex-end; flex-direction: row-reverse; }
.tn > div { min-width: 0; }
.tn__av {
  width: 28px; height: 28px; flex-shrink: 0;
  border-radius: 50%; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 700;
  background: var(--primary); color: #fff;
}
.tn__av img { width: 100%; height: 100%; object-fit: cover; }

/* ẢNH ĐẠI DIỆN + TÊN, gộp làm MỘT khối.

   `inline-flex` + `align-items: center` để trình duyệt TỰ căn giữa vòng tròn
   với chữ. Bản trước kéo vòng tròn xuống bằng `vertical-align: -4px` — con
   số đó đúng với đúng một cỡ chữ, dòng nào chữ to hơn hay nhỏ hơn là lệch
   ngay, mà không có cách nào biết trước dòng nào sẽ lệch.

   `vertical-align: middle` trên cả khối để nó thẳng hàng với phần chữ còn
   lại của dòng (dòng có dấu `·` phân cách, chữ 12–13px).

   `white-space: nowrap`: tên người KHÔNG được rớt dòng tách khỏi ảnh của
   chính nó — rớt là ảnh nằm cuối dòng trên, tên nằm đầu dòng dưới, và người
   đọc ghép nhầm ảnh với cái tên đứng cạnh. */
.nguoi {
  display: inline-flex; align-items: center; gap: 5px;
  vertical-align: middle; white-space: nowrap;
}

/* Vòng tròn ảnh. Dùng `background-image` chứ không phải thẻ <img>: ảnh 404
   thì nền không vẽ ra và còn lại một vòng tròn MÀU RIÊNG của người đó — vẫn
   phân biệt được ai. Thẻ <img> hỏng thì trình duyệt vẽ biểu tượng ảnh vỡ
   trong một vòng tròn 20px, nhìn như giao diện lỗi.

   KHÔNG có `margin` và KHÔNG có `vertical-align` ở đây: khoảng cách do `gap`
   của `.nguoi` lo, căn dọc do `align-items` lo. Để cả hai chỗ cùng chỉnh thì
   sửa một bên là lệch bên kia. */
.av-nho {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; flex: none;
  border-radius: 50%; overflow: hidden;
  background-color: var(--primary); background-size: cover; background-position: center;
  color: #fff; font-size: 9px; font-weight: 700; line-height: 1;
  /* Chữ viết tắt không được kéo giãn khoảng cách chữ của dòng chứa nó */
  letter-spacing: 0;
}
.tn__bong {
  display: inline-block;
  padding: 7px 12px; border-radius: 12px;
  /* var(--surface) chứ không phải #fff — giao diện tối cũng phải đọc được */
  background: var(--surface); border: 1px solid var(--border);
  font-size: 13px; line-height: 1.55;
  word-break: break-word;
}
/* CHỈ phần chữ mới giữ nguyên xuống dòng. Để pre-wrap trên cả bong bóng thì
   khoảng trắng và thụt lề trong chuỗi HTML cũng thành khoảng trắng hiện ra —
   bong bóng một chữ "Dạ" phình cao gấp bốn lần đúng vì lỗi này. */
.tn__chu { white-space: pre-wrap; }
.tn--toi .tn__bong { background: var(--primary); color: #fff; border-color: transparent; }
.tn__bong--hotro { background: var(--warning-soft); border-color: var(--warning); }
.tn--toi .tn__bong--hotro { color: inherit; }
.tn__nhan { font-size: 11px; font-weight: 700; color: var(--warning); margin-bottom: 3px; }
.tn__chan { font-size: 10.5px; color: var(--text-3); margin-top: 3px; padding: 0 4px; }
.chat__nhap .textarea { min-height: 62px; }
.tn--toi .tn__chan { text-align: right; }

/* Nút biểu tượng trong danh sách việc — to đủ để bấm trúng trên máy tính
   bảng ở quầy, và có nhãn khi rê chuột vì một mình biểu tượng thì đoán mò. */
.btn--icon {
  width: 34px; height: 34px; padding: 0;
  justify-content: center; font-size: 15px;
}

.co-nhan { position: relative; }
.co-nhan::after {
  content: attr(data-nhan);
  position: absolute; bottom: calc(100% + 7px); left: 50%;
  transform: translateX(-50%) translateY(3px);
  background: var(--text); color: var(--text-invert);
  font-size: 11.5px; font-weight: 500; line-height: 1.4;
  padding: 5px 9px; border-radius: 7px;
  white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity .13s var(--ease), transform .13s var(--ease);
  z-index: 20; box-shadow: var(--sh);
}
.co-nhan:hover::after, .co-nhan:focus-visible::after {
  opacity: 1; transform: translateX(-50%) translateY(0);
}

/* Ảnh đại diện dùng chung */
.avt {
  border-radius: 50%; overflow: hidden; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--primary), var(--purple));
  color: #fff; font-weight: 700;
}
.avt img { width: 100%; height: 100%; object-fit: cover; }
.user-chip__av { cursor: pointer; overflow: hidden; }
.user-chip__av img { width: 100%; height: 100%; object-fit: cover; }

/* Số phiên bản ở chân sidebar — nhỏ, mờ, không tranh chỗ với menu */
.sidebar__ver {
  margin-top: 6px;
  font-size: 10.5px;
  letter-spacing: .2px;
  text-align: center;
  opacity: .45;
  user-select: text;
}

/* ---------- Token đã che (trang Kết nối) ----------
   Chặn bôi đen chỉ để nhắc mắt rằng đây không phải thứ mang đi dùng — che
   thật nằm ở máy chủ: cái hiện ra đây ĐÃ là bản che, giá trị đầy đủ không
   gửi về trình duyệt nên có bôi được cũng không copy ra token thật. */
.ma-che {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  letter-spacing: .2px;
  padding: 3px 9px;
  border-radius: 6px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-2);
  user-select: none;
  -webkit-user-select: none;
}

/* ============================================================
   FONT CHO MÀN HÌNH THUMBNAIL BÀI VIẾT

   `font-display: block` chứ KHÔNG phải `swap`: canvas vẽ bằng font nào đang
   sẵn ở đúng thời điểm gọi `fillText`. Với `swap`, trình duyệt vẽ tạm bằng
   font thay thế rồi mới đổi — nhưng ảnh đã xuất ra thì không đổi theo được,
   nên thỉnh thoảng ra một tấm sai font mà không có dấu hiệu gì.

   File chưa có thì `document.fonts.check()` trả false và màn hình NÓI RA.
   Xem fonts/README.md.
   ============================================================ */
@font-face {
  font-family: 'ClassicBrand';
  src: url('../fonts/brand.woff2') format('woff2');
  font-weight: 400 900;
  font-display: block;
}
@font-face {
  font-family: 'ClassicHep';
  src: url('../fonts/hep.woff2') format('woff2');
  font-weight: 400 900;
  font-display: block;
}

/* Khung xem trước thumbnail — ảnh canvas co theo bề ngang, giữ tỷ lệ. */
.tb-khung { display: block; width: 100%; height: auto; border-radius: 10px; background: var(--surface-2); cursor: grab; }
.tb-khung:active { cursor: grabbing; }
.tb-o { display: flex; gap: 6px; flex-wrap: wrap; }
.tb-o .btn { flex: 1 1 0; min-width: 72px; }

/* ---------- Hộp cập nhật Công việc (giaoviec_hop.js) ---------- */
.hop--trong .card__head { border-bottom: 0; }
.hop__ngan { margin-top: 10px; }
.hop__dau { display: flex; gap: 8px; align-items: center; margin-bottom: 6px; flex-wrap: wrap; }
.hop__dong { display: flex; gap: 12px; align-items: flex-start; padding: 9px 10px; border-radius: 10px;
  cursor: pointer; border: 1px solid var(--border); margin-bottom: 6px; background: var(--surface); }
.hop__dong:hover { background: var(--surface-3); }
.hop__noi { flex: 1; min-width: 0; }
.hop__viec { font-weight: 600; }
.hop__tin { font-size: 13px; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hop__phai { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex-shrink: 0; }
@media (max-width: 640px) { .hop__tin { white-space: normal; } }

/* ---------- Màu theo nhóm việc (giaoviec.js · NHOM) ----------
   Nhẹ: viền trái + nền đầu thẻ nhạt; dòng việc bên trong vẫn nền trắng để
   nhãn "Phản hồi mới" (nền vàng) còn nổi. Dùng token *-soft nên chế độ tối
   tự đổi theo. */
.nhom { border-left: 4px solid var(--nhom-mau, var(--border)); }
.nhom > .card__head { background: var(--nhom-nen, transparent); border-radius: var(--r-lg) var(--r-lg) 0 0; }
.nhom > .card__head .card__title { color: var(--nhom-chu, inherit); }
.nhom--cho_duyet { --nhom-mau: var(--purple);  --nhom-nen: var(--purple-soft);  --nhom-chu: #7e22ce; }
.nhom--qua_han   { --nhom-mau: var(--danger);  --nhom-nen: var(--danger-soft);  --nhom-chu: #b91c1c; }
.nhom--hom_nay   { --nhom-mau: var(--warning); --nhom-nen: var(--warning-soft); --nhom-chu: #b45309; }
.nhom--sap_toi   { --nhom-mau: var(--info);    --nhom-nen: var(--info-soft);    --nhom-chu: #0369a1; }
.nhom--khong_han { --nhom-mau: #94a3b8;        --nhom-nen: var(--surface-2);    --nhom-chu: #475569; }
.nhom--duoc_moi  { --nhom-mau: var(--primary); --nhom-nen: var(--primary-soft); --nhom-chu: var(--primary); }
.nhom--da_xong   { --nhom-mau: var(--success); --nhom-nen: var(--success-soft); --nhom-chu: #047857; }
[data-theme="dark"] .nhom--cho_duyet { --nhom-chu: #d8b4fe; }
[data-theme="dark"] .nhom--qua_han   { --nhom-chu: #fca5a5; }
[data-theme="dark"] .nhom--hom_nay   { --nhom-chu: #fcd34d; }
[data-theme="dark"] .nhom--sap_toi   { --nhom-chu: #7dd3fc; }
[data-theme="dark"] .nhom--khong_han { --nhom-chu: #cbd5e1; }
[data-theme="dark"] .nhom--duoc_moi  { --nhom-chu: #a5b4fc; }
[data-theme="dark"] .nhom--da_xong   { --nhom-chu: #6ee7b7; }
