/* ============================================================================
 * Giao diện V365-PM.
 *
 * Cấu trúc layout VÀ CHẤT CẢM kế thừa từ VBIM-PM (sidebar tối + panel trắng nổi
 * trên nền xám + bo góc mềm + transition ngắn). **Màu thì lấy từ token V365.**
 *
 * 🔴 CHỖ ĐI KHÁC spec/05 — có chủ ý, người dùng chốt 18/09/2026:
 *   spec/05 luật 2 nói "góc vuông là mặc định, radius-none cho bảng/khối".
 *   Người dùng muốn mềm và hiện đại như VBIM-PM, nên:
 *     · bảng, panel, thẻ  → radius-md / radius-lg (thay vì radius-none)
 *     · nút, ô nhập       → radius-md (thay vì radius-sm)
 *     · badge, chip       → radius-pill
 *   Mọi thứ khác của spec/05 giữ nguyên: token màu, thang khoảng cách, cỡ chữ,
 *   luật badge luôn có chữ, một điểm nhấn brand-red mỗi mặt.
 *
 * Màu: chỉ dùng var(--…) của tokens-v365.css, hoặc color-mix() suy từ chúng.
 * Không có giá trị màu viết tay, trừ lớp phủ modal rgba(0,0,0,.45) theo spec/05.
 * ========================================================================== */

:root {
  /* 🔴 FONT: dùng font hệ thống, giống VBIM-PM (người dùng chốt 20/09/2026).
   *
   * `tokens-v365.css` đặt --font-sans là "Be Vietnam Pro" nạp từ Google Fonts. Đè ở đây
   * chứ KHÔNG sửa file token — token là bản design system, giữ nguyên để còn đối chiếu.
   *
   * Đổi luôn được ba thứ:
   *   · bỏ phụ thuộc ngoài cuối cùng của app (mạng công ty chặn CDN là chữ vỡ font)
   *   · CSP bỏ được fonts.googleapis.com + fonts.gstatic.com
   *   · không còn một request chặn render lúc mở trang
   *
   * "Segoe UI" đứng trước system-ui cho khớp đúng VBIM-PM. Cỡ chữ GIỮ NGUYÊN theo
   * spec/05 (15px/24px), không hạ về 13px như VBIM — người dùng chỉ đổi font. */
  --font-sans: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;

  /* Biến suy từ token — gom một chỗ để đổi là đổi hết, không rải rác trong file. */
  --v-r-nho: var(--radius-sm);      /* 4px  — chi tiết nhỏ trong ô */
  --v-r: var(--radius-md);          /* 8px  — nút, ô nhập, hàng danh sách */
  --v-r-lon: var(--radius-lg);      /* 12px — panel, bảng, thẻ */
  --v-nhanh: 120ms;

  /* Quầng focus mềm thay cho viền cứng — vẫn 2 lớp như spec/05 luật 4 yêu cầu,
     chỉ đổi lớp ngoài thành quầng mờ cho đỡ gắt. */
  --v-quang: 0 0 0 3px color-mix(in srgb, var(--brand-red) 22%, transparent);

  /* Sidebar tối: brand-black và on-brand-red là hai token KHÔNG đổi theo theme
     (đã kiểm trong tokens-v365.css), nên sidebar giữ nguyên chất ở cả hai mặt. */
  --v-ben: var(--brand-black);
  --v-ben-chu: var(--on-brand-red);
  --v-ben-mo: color-mix(in srgb, var(--on-brand-red) 62%, transparent);
  --v-ben-noi: color-mix(in srgb, var(--on-brand-red) 10%, transparent);
  --v-ben-vien: color-mix(in srgb, var(--on-brand-red) 16%, transparent);
}

*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; margin: 0; }

body {
  /* Nền xám để panel trắng nổi lên — trắng trên trắng là cái làm bản trước bẹt. */
  background: var(--surface-sunken);
  color: var(--ink);
  font: 400 15px/24px var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

.hidden { display: none !important; }
.fill { flex: 1; }
.note { color: var(--ink-muted); font: 400 12px/18px var(--font-sans); }
.note.warn { color: var(--warning); }
.note.err { color: var(--danger); }
.dim { color: var(--ink-secondary); }
.num, .totals { font-variant-numeric: tabular-nums; }
.ok { color: var(--success); }
.bad { color: var(--danger); }
code {
  font: 400 12px/18px var(--font-mono);
  background: var(--surface-sunken);
  padding: 1px var(--space-2);
  border-radius: var(--v-r-nho);
}

/* ------------------------------------------------------------- màn gate -- */

.gate {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-6);
  /* Nền dịu, một vệt sáng phía trên — mềm hơn hẳn nền phẳng. */
  background:
    radial-gradient(900px 520px at 50% -12%,
      color-mix(in srgb, var(--brand-red) 9%, var(--surface)) 0%,
      var(--surface-sunken) 62%);
}
.gate-card {
  position: relative; overflow: hidden;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--v-r-lon);
  box-shadow: var(--shadow-lg);
  padding: var(--space-8);
  max-width: 470px; width: 100%;
  display: flex; flex-direction: column; gap: var(--space-4);
}
/* Dải nhấn thương hiệu chạy dọc mép trái — điểm nhấn brand-red duy nhất của mặt này. */
.gate-card::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--brand-red);
}
.gate-brand, .brand-name {
  font: 700 20px/28px var(--font-sans);
  border-left: 3px solid var(--brand-red);
  padding-left: var(--space-3);
}
.gate-card h1 { margin: 0; font: 700 24px/32px var(--font-sans); }
.gate-card p { margin: 0; color: var(--ink-secondary); max-width: 60ch; }
.gate-actions { display: flex; gap: var(--space-3); margin-top: var(--space-2); }
.gate-logo { margin-bottom: var(--space-1); }

/* --------------------------------------------------------------- khung -- */

.app { display: grid; grid-template-columns: 268px 1fr; height: 100vh; }

/* Sidebar tối — tương phản mạnh với vùng nội dung sáng, đúng chất VBIM-PM. */
.sidebar {
  background: var(--v-ben);
  color: var(--v-ben-chu);
  padding: var(--space-5) var(--space-4);
  display: flex; flex-direction: column; gap: var(--space-5);
  overflow: hidden;
}

.brand { display: flex; flex-direction: column; gap: var(--space-1); align-items: flex-start; }
.brand small { color: var(--v-ben-mo); font: 400 12px/18px var(--font-sans); }

/**
 * Logo là PNG trong suốt, chữ "365" màu ĐEN — trên sidebar đen nó biến mất.
 * Đặt lên tấm nền trắng, giữ nguyên màu thương hiệu thay vì bịa bản đảo màu
 * (đảo màu là đỏ V365 hỏng hẳn). spec/05 vốn đã ghi "chưa có logo vector".
 * ⇒ Nên xin bộ phận thương hiệu file .svg và một bản cho nền tối, rồi bỏ tấm nền này.
 */
.logo {
  display: block; height: auto; max-width: 100%;
  background: #fff;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--v-r);
}
/* Màn gate nền sáng thì logo không cần tấm nền. */
.gate .logo { background: none; padding: 0; }

.side-block { display: flex; flex-direction: column; gap: var(--space-2); min-height: 0; }
.side-block.fill { flex: 1; min-height: 0; }
.side-label {
  font: 700 11px/16px var(--font-sans); letter-spacing: .08em;
  text-transform: uppercase; color: var(--v-ben-mo);
}
.side-head { display: flex; align-items: center; justify-content: space-between; }
.side-empty { color: var(--v-ben-mo); font: 400 13px/20px var(--font-sans); padding: var(--space-3) var(--space-2); }

.sidebar input, .sidebar select {
  background: var(--v-ben-noi);
  border-color: var(--v-ben-vien);
  color: var(--v-ben-chu);
  font-size: 13px;
}
.sidebar input::placeholder { color: var(--v-ben-mo); }
.sidebar input:focus, .sidebar select:focus {
  border-color: var(--brand-red);
  box-shadow: var(--v-quang);
  outline: none;
}
.sidebar select option { background: var(--surface); color: var(--ink); }

.new-bucket { display: flex; gap: var(--space-2); }
.new-bucket input { flex: 1; min-width: 0; }

.bucket-list { overflow-y: auto; display: flex; flex-direction: column; gap: 2px; min-height: 0; }

.b-row {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--v-r);
  cursor: pointer;
  color: var(--v-ben-mo);
  font: 400 14px/22px var(--font-sans);
  transition: background var(--v-nhanh), color var(--v-nhanh);
}
.b-row:hover { background: var(--v-ben-noi); color: var(--v-ben-chu); }
/* Mục đang chọn: nền brand-red đặc — đọc rõ hơn hẳn dải trái mảnh trên nền tối. */
.b-row.on { background: var(--brand-red); color: var(--on-brand-red); font-weight: 600; }
.b-row.b-tat-ca { border-bottom: 1px solid var(--v-ben-vien); border-radius: var(--v-r) var(--v-r) 0 0; margin-bottom: var(--space-1); padding-bottom: var(--space-2); }
.b-row.gone { opacity: .45; text-decoration: line-through; }
.b-row .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.b-row input.nm { font: 400 14px/22px var(--font-sans); }
.b-row .cnt { font: 400 12px/18px var(--font-sans); opacity: .75; font-variant-numeric: tabular-nums; }
.b-row .acts { display: flex; gap: 2px; opacity: 0; transition: opacity var(--v-nhanh); }
.b-row:hover .acts, .b-row.on .acts { opacity: 1; }
.b-row .acts button {
  border: 0; background: none; cursor: pointer; padding: 0 var(--space-1);
  color: inherit; opacity: .7; font-size: 13px;
}
.b-row .acts button:hover { opacity: 1; background: none; }

.side-foot {
  border-top: 1px solid var(--v-ben-vien); padding-top: var(--space-3);
  display: flex; align-items: center; gap: var(--space-2);
}
.side-foot .who { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.side-foot .who b { font: 600 13px/20px var(--font-sans); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.side-foot button {
  background: transparent; color: var(--v-ben-mo);
  border-color: var(--v-ben-vien);
  font: 400 12px/18px var(--font-sans); padding: var(--space-1) var(--space-3);
}
.side-foot button:hover { background: var(--v-ben-noi); color: var(--v-ben-chu); }

/* --------------------------------------------------------------- main --- */

.main {
  display: flex; flex-direction: column; min-width: 0; overflow: hidden;
  background: var(--surface-sunken);
}

.tabs {
  display: flex; align-items: center; gap: 2px;
  padding: 0 var(--space-5);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex: none;
}
.tab {
  background: none; border: 0; border-bottom: 2px solid transparent; border-radius: 0;
  padding: var(--space-4) var(--space-3) calc(var(--space-4) - 2px);
  font: 400 15px/24px var(--font-sans);
  color: var(--ink-secondary); cursor: pointer;
  position: relative;
  transition: color var(--v-nhanh), border-color var(--v-nhanh);
}
.tab:hover { color: var(--ink); background: none; }
.tab.on { color: var(--ink-accent); border-bottom-color: var(--brand-red); font-weight: 600; }
.tab .dot {
  position: absolute; top: 12px; right: 2px;
  width: 6px; height: 6px; border-radius: var(--radius-pill);
  background: var(--warning);
}
.tabs-fill { flex: 1; }
.ctx { color: var(--ink-muted); font: 400 13px/20px var(--font-sans); padding-right: var(--space-2); }

.pane {
  flex: 1; display: flex; flex-direction: column; min-height: 0;
  padding: var(--space-4) var(--space-5) var(--space-5);
  gap: var(--space-3);
}

.toolbar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; flex: none; }
.toolbar .lbl { color: var(--ink-muted); font: 400 12px/18px var(--font-sans); }
.vr { width: 1px; height: 20px; background: var(--border); }

/* ----------------------------------------------------------------- nút -- */

button, .btn {
  font: 600 14px/22px var(--font-sans);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--v-r);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--v-nhanh), border-color var(--v-nhanh), color var(--v-nhanh);
}
button:hover:not(:disabled), .btn:hover { background: var(--surface-sunken); }
button:disabled { opacity: .5; cursor: not-allowed; }

/* Nút chính: nền brand-red. CHỈ `button.primary` và nút trong gate / khối trống —
 * spec/05 luật 1 cho đúng MỘT điểm nhấn brand-red mỗi mặt. */
button.primary,
.gate .btn,
.khoi-trong .btn {
  background: var(--brand-red); color: var(--on-brand-red); border-color: var(--brand-red);
  box-shadow: var(--shadow-sm);
}
button.primary:hover:not(:disabled),
.gate .btn:hover,
.khoi-trong .btn:hover {
  background: var(--brand-red-hover); border-color: var(--brand-red-hover);
}
button.primary { padding: var(--space-2) var(--space-5); }

button.ghost { background: var(--surface); color: var(--ink); border-color: var(--border); }
button.ghost:hover:not(:disabled) { background: var(--brand-surface); border-color: var(--border-strong); }

button.danger { background: var(--surface); color: var(--danger); border-color: var(--border); }
button.danger:hover:not(:disabled) { background: var(--danger-surface); border-color: var(--danger); }

button.icon {
  width: 24px; height: 24px; padding: 0; line-height: 1; font-size: 16px;
  border-radius: var(--v-r-nho); border: 0; background: none; color: inherit; opacity: .7;
}
button.icon:hover { opacity: 1; background: var(--v-ben-noi); }
button.mini {
  border: 0; background: none; color: var(--ink-muted);
  padding: 2px var(--space-2); font-size: 13px; border-radius: var(--v-r-nho);
}
button.mini:hover:not(:disabled) { background: var(--danger-surface); color: var(--danger); }
button.mini-btn { font: 600 12px/18px var(--font-sans); padding: var(--space-1) var(--space-3); }
label.btn { display: inline-flex; align-items: center; }

/* Chip lọc — viên thuốc. */
.chip {
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink-secondary);
  font: 400 13px/20px var(--font-sans);
  padding: var(--space-1) var(--space-4);
}
.chip:hover:not(.on) { background: var(--brand-surface); border-color: var(--border-strong); }
.chip.on { background: var(--brand-surface); color: var(--ink-accent); border-color: var(--ink-accent); font-weight: 600; }

/* -------------------------------------------------------------- ô nhập -- */

input, select, textarea {
  font: 400 14px/22px var(--font-sans);
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--v-r);
  background: var(--surface);
  color: var(--ink);
  min-width: 0;
  transition: border-color var(--v-nhanh), box-shadow var(--v-nhanh);
}
input::placeholder, textarea::placeholder { color: var(--ink-muted); }
textarea { resize: vertical; min-height: 80px; padding: var(--space-2); }
select { cursor: pointer; }
input:disabled, select:disabled, textarea:disabled { background: var(--surface-sunken); color: var(--ink-muted); }

/* Focus: quầng mềm thay cho viền cứng. Vẫn hai lớp (viền đổi màu + quầng) nên đủ
 * tương phản như spec/05 luật 4 đòi, chỉ dịu hơn. */
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--brand-red);
  box-shadow: var(--v-quang);
}
:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* --------------------------------------------------------------- bảng --- */

/* Panel trắng bo góc nổi trên nền xám. `border-collapse: separate` để bo góc ăn. */
.tbl-wrap {
  flex: 1; min-height: 0; overflow: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--v-r-lon);
  box-shadow: var(--shadow-sm);
}

.tbl { width: 100%; border-collapse: separate; border-spacing: 0; background: var(--surface); }
/* Header: chữ nhỏ in hoa giãn chữ trên nền xám nhạt — nhẹ hơn hẳn dải màu đặc. */
.tbl th {
  position: sticky; top: 0; z-index: 2;
  background: var(--surface-sunken);
  color: var(--ink-muted);
  font: 600 11px/16px var(--font-sans);
  letter-spacing: .05em; text-transform: uppercase;
  text-align: left;
  padding: var(--space-3) var(--space-3);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.tbl th.num, .tbl td.num { text-align: right; }
.tbl th.dim { opacity: .75; font-weight: 400; }
.tbl td {
  font: 400 14px/22px var(--font-sans);
  padding: 4px var(--space-2);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.tbl tbody tr:last-child td { border-bottom: 0; }
.tbl tbody tr { transition: background var(--v-nhanh); }
.tbl tbody tr:hover td { background: color-mix(in srgb, var(--brand-surface) 45%, var(--surface)); }
.tbl tbody tr.dirty td:first-child { box-shadow: inset 3px 0 0 var(--warning); }
.tbl tbody tr.gone td { opacity: .45; }
.tbl tbody tr.gone input { text-decoration: line-through; }
.tbl tbody tr.muted-row td { color: var(--ink-muted); }
.tbl tr.total-row td {
  font-weight: 600; background: var(--surface-sunken);
  border-top: 1px solid var(--border-strong); border-bottom: 0;
}
/* Ô nhập trong bảng: viền MỎNG luôn hiện, để nhìn ra ngay ô nào gõ được.
 * Bản trước để trong suốt tới khi hover — trông sạch nhưng phải rê chuột mới biết
 * chỗ nào nhập được. Người dùng chốt 18/09/2026: thêm viền mỏng. */
.tbl td input, .tbl td select {
  width: 100%;
  border-color: var(--border);
  background: var(--surface);
}
.tbl td input:hover:not(:disabled), .tbl td select:hover:not(:disabled) { border-color: var(--border-strong); }
.tbl td input:disabled, .tbl td select:disabled { border-color: var(--border); background: var(--surface-sunken); }
.tbl-empty { padding: var(--space-12) var(--space-4); text-align: center; color: var(--ink-muted); }
.cell-1d { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 380px; }

/* Độ rộng cột đọc từ biến để KÉO ĐƯỢC bằng tay nắm ở mép phải ô tiêu đề.
 * Giá trị dự phòng phải trùng COT_MAC_DINH trong app.js. */
.c-n { width: var(--w-n, 34px); min-width: var(--w-n, 34px); color: var(--ink-muted); text-align: right; font-variant-numeric: tabular-nums; font-size: 12px; }
.c-cap { width: var(--w-cap, 146px); min-width: var(--w-cap, 146px); }
.c-name { width: var(--w-name, 232px); min-width: var(--w-name, 232px); }
.c-who { width: var(--w-who, 186px); min-width: var(--w-who, 186px); }
.c-date { width: var(--w-date, 138px); min-width: var(--w-date, 138px); }
.c-hrs { width: var(--w-hrs, 84px); min-width: var(--w-hrs, 84px); }
.c-nhan { width: var(--w-nhan, 130px); min-width: var(--w-nhan, 130px); }
.c-hm { width: var(--w-hm, 160px); min-width: var(--w-hm, 160px); }
.c-uu { width: var(--w-uu, 128px); min-width: var(--w-uu, 128px); }
.c-note { width: var(--w-note, 180px); min-width: var(--w-note, 180px); }
.c-done { width: var(--w-done, 150px); min-width: var(--w-done, 150px); white-space: nowrap; }
.c-act { width: 34px; min-width: 34px; }

/* Ghim cột # và Tên khi cuộn ngang — 11 cột thì không ghim là lạc mất đang sửa việc nào.
 * `left` của cột Tên = độ rộng cột #, nên đọc chung biến: kéo cột # là cột Tên tự dịch
 * theo, không phải tính lại bằng JS. */
.tbl th.c-n, .tbl td.c-n { position: sticky; left: 0; z-index: 1; background: var(--surface); }
.tbl th.c-name, .tbl td.c-name {
  position: sticky; left: var(--w-n, 34px); z-index: 1; background: var(--surface);
  box-shadow: 1px 0 0 var(--border);
}

/* ---- tay kéo đổi độ rộng cột ---- */
.tbl th { position: relative; }
.keo {
  position: absolute; top: 0; right: -3px; bottom: 0; width: 7px;
  cursor: col-resize; z-index: 4;
  display: flex; align-items: center; justify-content: center;
}
.keo::after {
  content: ''; width: 2px; height: 60%;
  background: transparent; border-radius: var(--radius-pill);
  transition: background var(--v-nhanh);
}
.keo:hover::after { background: var(--brand-red); }
/* Trong lúc kéo: khoá con trỏ và chặn bôi đen chữ, nếu không kéo một cái là chọn cả bảng. */
body.dang-keo-cot { cursor: col-resize; user-select: none; }
body.dang-keo-cot .keo::after { background: var(--brand-red); }
.tbl thead th.c-n, .tbl thead th.c-name { z-index: 3; background: var(--surface-sunken); }
.tbl tbody tr:hover td.c-n, .tbl tbody tr:hover td.c-name {
  background: color-mix(in srgb, var(--brand-surface) 45%, var(--surface));
}
.tbl tbody tr.la-cha td.c-n, .tbl tbody tr.la-cha td.c-name { background: var(--surface-sunken); }

/* --- cây cha ↔ con, dựng giống Planner --- */
.cay { display: flex; align-items: center; gap: var(--space-1); min-width: 0; }
.cay > input { flex: 1; min-width: 0; }
.tbl td .cay .gap, .tbl td .cay .gap-cho {
  flex: none; width: 16px; height: 20px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.tbl td .cay .gap {
  border: 0; background: none; cursor: pointer;
  color: var(--ink-muted); font-size: 11px; line-height: 1;
}
.tbl td .cay .gap:hover { color: var(--ink-accent); background: none; }

.tbl tbody tr.la-cha > td { background: var(--surface-sunken); }
.tbl tbody tr.la-cha .cay > input { font-weight: 600; }
.tbl tbody tr.la-cha > td:first-child { box-shadow: inset 2px 0 0 var(--border-strong); }
.tbl tbody tr.mo-coi > td:first-child { box-shadow: inset 3px 0 0 var(--danger); }
.note.tinh { font-variant-numeric: tabular-nums; font-style: italic; }

/* Ô Cấp: hàng ← số → luôn một dòng; ô chọn việc cha xuống hàng dưới. */
.cap-o { display: flex; flex-direction: column; gap: 2px; align-items: stretch; }
.cap-hang { display: flex; align-items: center; gap: 2px; flex-wrap: nowrap; }
.cap-o .mini { font-size: 12px; padding: 0 3px; flex: none; }
.cap-o .mini:hover:not(:disabled) { color: var(--ink-accent); background: var(--brand-surface); }
.cap-o .cap-so {
  min-width: 15px; text-align: center;
  font: 600 12px/18px var(--font-sans); color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}
.cap-so.tu-cha { color: var(--ink-accent); }

.chon-cha {
  width: 100%;
  display: flex; align-items: center; gap: var(--space-1);
  padding: 1px var(--space-2);
  font: 400 12px/18px var(--font-sans);
  background: var(--surface); color: var(--ink-secondary);
  border: 1px solid var(--border); border-radius: var(--v-r-nho);
  text-align: left;
}
.chon-cha:hover { background: var(--brand-surface); border-color: var(--border-strong); }
.chon-cha-ten { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chon-cha-mui { flex: none; color: var(--ink-muted); font-size: 10px; }
.chon-cha.co-cha { border-color: var(--ink-accent); color: var(--ink-accent); font-weight: 600; }
.chon-cha.mat { border-color: var(--danger); color: var(--danger); }

/* ------------------------------------------------------- nhãn & badge --- */
/* Badge LUÔN có chữ — chấm màu trơn không đọc được khi in đen trắng (spec/05 luật 3). */

.hm-chip {
  display: inline-block; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: var(--surface-sunken); color: var(--ink-secondary);
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  font: 400 12px/18px var(--font-sans); padding: 0 var(--space-3);
}

.nhan-chip {
  display: inline-block;
  background: var(--brand-surface); color: var(--ink-accent);
  border: 1px solid color-mix(in srgb, var(--ink-accent) 35%, transparent);
  border-radius: var(--radius-pill);
  font: 600 12px/18px var(--font-sans);
  padding: 0 var(--space-3);
  margin: 1px 2px 1px 0;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nhan-chip.more { background: var(--surface-sunken); color: var(--ink-muted); border-color: var(--border); }

.badge {
  display: inline-block;
  border: 1px solid transparent;
  background: var(--surface-sunken);
  color: var(--ink-secondary);
  border-radius: var(--radius-pill);
  font: 600 12px/18px var(--font-sans);
  padding: 1px var(--space-3);
  white-space: nowrap;
}
.badge.ok { background: var(--success-surface); color: var(--success); border-color: color-mix(in srgb, var(--success) 30%, transparent); }
.badge.warn { background: var(--warning-surface); color: var(--warning); border-color: color-mix(in srgb, var(--warning) 30%, transparent); }
.badge.bad { background: var(--danger-surface); color: var(--danger); border-color: color-mix(in srgb, var(--danger) 30%, transparent); }
.badge.info { background: var(--info-surface); color: var(--info); border-color: color-mix(in srgb, var(--info) 30%, transparent); }
.badge.muted { background: var(--surface-sunken); color: var(--ink-secondary); border-color: var(--border); }

/* Theme tối: chữ trên nền *-surface dùng ink cho đủ tương phản (spec/05). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .badge.ok,
  :root:not([data-theme="light"]) .badge.warn,
  :root:not([data-theme="light"]) .badge.bad,
  :root:not([data-theme="light"]) .badge.info { color: var(--ink); }
}
:root[data-theme="dark"] .badge.ok,
:root[data-theme="dark"] .badge.warn,
:root[data-theme="dark"] .badge.bad,
:root[data-theme="dark"] .badge.info { color: var(--ink); }

.done-no { color: var(--ink-muted); font-variant-numeric: tabular-nums; white-space: nowrap; font-size: 13px; }
.done-yes {
  display: inline-block; white-space: nowrap;
  padding: 1px var(--space-3); border-radius: var(--radius-pill);
  font: 600 12px/18px var(--font-sans); font-variant-numeric: tabular-nums;
  background: var(--success-surface); color: var(--success);
  border: 1px solid color-mix(in srgb, var(--success) 30%, transparent);
}
.done-yes.unknown, .done-yes.truoc-moc {
  background: var(--surface-sunken); color: var(--ink-muted);
  border-color: var(--border); font-weight: 400;
}
.done-yes.late {
  background: var(--danger-surface); color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 30%, transparent);
}
.late-pill {
  display: inline-block; white-space: nowrap;
  padding: 1px var(--space-3); border-radius: var(--radius-pill);
  font: 600 12px/18px var(--font-sans);
  background: var(--danger-surface); color: var(--danger);
  border: 1px solid color-mix(in srgb, var(--danger) 30%, transparent);
}

.person { display: flex; align-items: center; gap: var(--space-2); }
.avatar {
  width: 28px; height: 28px; flex: none;
  border-radius: var(--radius-pill);
  background: var(--brand-surface); color: var(--ink-accent);
  display: flex; align-items: center; justify-content: center;
  font: 600 11px/1 var(--font-sans);
}
.bar { height: 4px; background: var(--border); border-radius: var(--radius-pill); overflow: hidden; }
.bar i { display: block; height: 100%; background: var(--brand-red); border-radius: var(--radius-pill); }

.pager { display: flex; align-items: center; gap: var(--space-2); flex: none; }
.pager .pg { padding: 2px var(--space-3); }
.pg-now { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------ chân pane - */

.pane-foot { display: flex; align-items: center; gap: var(--space-3); flex: none; flex-wrap: wrap; }
.pane-foot .dich { font: 600 13px/20px var(--font-sans); color: var(--ink-accent); }
.pane-foot .note { flex: 1; }

.result {
  flex: none; max-height: 40vh; overflow: auto;
  background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--v-r-lon);
  padding: var(--space-4);
}
.stats { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.stat {
  background: var(--surface-raised); border: 1px solid var(--border);
  border-radius: var(--v-r-lon);
  padding: var(--space-3) var(--space-5); min-width: 128px;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-sm);
}
.stat b { font: 700 28px/34px var(--font-sans); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.stat span { color: var(--ink-muted); font: 400 12px/18px var(--font-sans); }

.log {
  margin: var(--space-3) 0 0;
  background: var(--surface-sunken);
  border: 1px solid var(--border); border-radius: var(--v-r);
  padding: var(--space-3);
  font: 400 12px/1.65 var(--font-mono);
  white-space: pre-wrap; word-break: break-word;
  max-height: 320px; overflow: auto;
}
.log .e { color: var(--danger); }
.log .o { color: var(--success); }
.log .w { color: var(--warning); }
.log .dim { color: var(--ink-muted); }

/* -------------------------------------------------------- ô tìm người --- */

.ac { position: relative; }
.ac-input.set { font-weight: 600; }
.ac-list {
  /* 🔴 z-index phải TRÊN modal (80) và ngăn chi tiết yêu cầu (71).
   * Trước để 70 nên ô chọn người trong hai chỗ đó sổ xuống mà nằm PHÍA SAU — gõ gì cũng
   * như không có gì, người dùng báo "tìm theo email không được" 19/09/2026.
   * Danh sách này gắn vào <body> chứ không nằm trong ô, nên nó không ăn theo lớp cha. */
  position: fixed; z-index: 95;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--v-r);
  box-shadow: var(--shadow-lg);
  max-height: 260px; overflow-y: auto;
  padding: var(--space-1);
}
.ac-item {
  padding: var(--space-2) var(--space-3); cursor: pointer;
  display: flex; flex-direction: column; border-radius: var(--v-r-nho);
}
.ac-item:hover, .ac-item.on { background: var(--brand-surface); }
.ac-item b { font: 600 13px/20px var(--font-sans); }
.ac-item span { color: var(--ink-muted); font: 400 12px/18px var(--font-sans); }
.ac-empty { padding: var(--space-3); color: var(--ink-muted); font: 400 13px/20px var(--font-sans); }

/* ------------------------------------------------------------- modal ---- */

.modal-nen {
  position: fixed; inset: 0; z-index: 80;
  background: rgba(0, 0, 0, .45);
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-6);
}
.modal {
  background: var(--surface-raised);
  border-radius: var(--v-r-lon);
  box-shadow: var(--shadow-lg);
  padding: var(--space-6);
  max-width: 520px; width: 100%;
  max-height: calc(100vh - var(--space-12)); overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--space-4);
}
.modal > strong { font: 600 20px/28px var(--font-sans); }
.modal p { margin: 0; color: var(--ink-secondary); max-width: 62ch; }
.modal-foot { display: flex; gap: var(--space-2); align-items: center; justify-content: flex-end; }

.yc-modal { max-width: 640px; }
.f-grid { display: flex; flex-direction: column; gap: var(--space-3); }
.f-row { display: flex; flex-direction: column; gap: var(--space-1); }
.f-row > label { font: 600 14px/22px var(--font-sans); }
.f-row .goi-y { color: var(--ink-muted); font: 400 12px/18px var(--font-sans); }
.yc-acts { display: flex; gap: var(--space-2); }

.khoi-trong {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--info);
  border-radius: var(--v-r-lon);
  padding: var(--space-6);
  display: flex; flex-direction: column; gap: var(--space-3);
  align-items: flex-start; max-width: 70ch;
  box-shadow: var(--shadow-sm);
}
.khoi-trong strong { font: 600 16px/24px var(--font-sans); }
.khoi-trong p { margin: 0; color: var(--ink-secondary); }

/* ----------------------------------------------- popover chọn việc cha -- */

.pop {
  position: fixed; z-index: 75;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--v-r-lon);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.cay-pop {
  max-height: 340px; overflow-y: auto;
  display: flex; flex-direction: column;
  min-width: 340px; max-width: 520px;
  padding: var(--space-1);
}
.cay-pop-dau, .cay-pop-chan {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
}
.cay-pop-dau { border-bottom: 1px solid var(--border); }
.cay-pop-dau strong { flex: 1; font: 600 14px/22px var(--font-sans); }
.cay-pop-dau .x { border: 0; background: none; color: var(--ink-muted); padding: 0 var(--space-1); }
.cay-pop-chan { border-top: 1px solid var(--border); justify-content: flex-end; }
.cay-pop-chan .ghost { font: 400 12px/18px var(--font-sans); padding: var(--space-1) var(--space-3); }

/* Dòng là <div role="option"> chứ không phải <button> — xem ghi chú trong app.js. */
.cay-dong {
  display: flex; align-items: center; gap: var(--space-1);
  width: 100%; text-align: left;
  padding: var(--space-1) var(--space-3);
  font: 400 13px/20px var(--font-sans); color: var(--ink);
  cursor: pointer; user-select: none;
  border-radius: var(--v-r-nho);
  transition: background var(--v-nhanh);
}
.cay-dong:hover:not(.khoa) { background: var(--brand-surface); }
.cay-dong.on { background: var(--brand-surface); color: var(--ink-accent); font-weight: 600; }
.cay-dong.goc { color: var(--ink-muted); }
.cay-dong.khoa { color: var(--ink-muted); opacity: .55; cursor: not-allowed; }
.cay-ten { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cay-dem {
  flex: none; font: 600 11px/16px var(--font-sans);
  color: var(--ink-muted); background: var(--surface-sunken);
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  padding: 0 var(--space-2); font-variant-numeric: tabular-nums;
}
.cay-gap, .cay-gap-cho { flex: none; width: 16px; text-align: center; }
.cay-gap {
  border: 0; background: none; padding: 0;
  color: var(--ink-muted); font-size: 11px; line-height: 20px;
}
.cay-gap:hover { color: var(--ink-accent); background: none; }

/* --------------------------------------------------- thanh chờ lưu ------ */

.pending-bar {
  position: fixed; left: 50%; bottom: var(--space-5); transform: translateX(-50%);
  z-index: 60;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-lg);
  padding: var(--space-2) var(--space-3) var(--space-2) var(--space-5);
  display: flex; align-items: center; gap: var(--space-3);
}
.pending-text { font: 600 14px/22px var(--font-sans); }
.pending-bar button { border-radius: var(--radius-pill); }

/* Việc chạy nền — engine Project mất 8–41 giây, KHÔNG dùng spinner mù: hiện nhãn
 * việc đang chờ kèm đồng hồ đếm giây (spec/01). */
.jobs { position: fixed; right: var(--space-5); bottom: var(--space-5); z-index: 55; display: flex; flex-direction: column; gap: var(--space-2); }
.job {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand-red);
  border-radius: var(--v-r);
  box-shadow: var(--shadow-md);
  padding: var(--space-2) var(--space-4);
  display: flex; align-items: center; gap: var(--space-2);
  font: 400 13px/20px var(--font-sans);
}
.job b { font-variant-numeric: tabular-nums; }
.spin {
  width: 13px; height: 13px; flex: none;
  border: 2px solid var(--border);
  border-top-color: var(--brand-red);
  border-radius: var(--radius-pill);
  animation: quay 900ms linear infinite;
}
@keyframes quay { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .spin { animation-duration: 3s; }
  * { transition-duration: 1ms !important; }
}

/* --------------------------------------------------------------- toast -- */

.toast {
  position: fixed; right: var(--space-5); bottom: var(--space-5); z-index: 90;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-left: 3px solid var(--info);
  border-radius: var(--v-r);
  box-shadow: var(--shadow-lg);
  padding: var(--space-3) var(--space-5);
  max-width: 430px;
  font: 400 14px/22px var(--font-sans);
  white-space: pre-wrap;
}
.toast.ok { border-left-color: var(--success); }
.toast.warn { border-left-color: var(--warning); }
.toast.err { border-left-color: var(--danger); }

/* Màn hẹp: app này dùng trên máy bàn với bảng số liệu, nhưng đừng vỡ hẳn. */
@media (max-width: 980px) {
  .app { grid-template-columns: 1fr; height: auto; }
  .sidebar { border-bottom: 1px solid var(--border); }
  .pane { padding: var(--space-3); }
}

/* ======================================================= yêu cầu khách hàng
 *
 * Chi tiết mở ở NGĂN BÊN PHẢI, không phải modal: người tiếp nhận vừa đọc một yêu
 * cầu vừa cần nhìn danh sách để biết còn gì đang treo. Modal che hết bảng là mất
 * chỗ dựa đó. Lớp nền phía sau chỉ để bắt cú bấm ra ngoài — để mờ nhẹ thôi, đậm
 * như modal thì hoá ra vẫn là modal.
 * ------------------------------------------------------------------------- */

.yc-hang { cursor: pointer; }
.yc-hang:hover > td { background: var(--brand-surface); }
.yc-hang.dang-mo > td { background: var(--brand-surface); }
/* Dải đỏ chỉ ở Ô ĐẦU. Đặt trên `> td` thì mọi ô đều có vạch trái ⇒ cả hàng thành lưới
   vạch dọc, lộ rõ khi nhiều hàng cùng được tô (gặp thật 20/09/2026). */
.yc-hang.dang-mo > td:first-child { box-shadow: inset 3px 0 0 var(--brand-red); }
.ink-accent { color: var(--ink-accent); font-weight: 600; }

.yc-nen { position: fixed; inset: 0; z-index: 70; background: rgba(0, 0, 0, .18); }

.yc-ngan {
  position: fixed; z-index: 71; top: 0; right: 0; bottom: 0;
  width: min(560px, 100vw);
  background: var(--surface-raised);
  border-left: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  overflow-y: auto;
  padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-4);
}
/* Ngăn là flex-column có cuộn: con MẶC ĐỊNH co lại được, nên khối nội dung bị bóp
   còn một dòng. Khoá co lại, để chính ngăn cuộn. */
.yc-ngan > * { flex: none; }
.yc-ngan-dau { display: flex; align-items: center; gap: var(--space-2); }
.yc-ngan-dau > div { display: flex; align-items: center; gap: var(--space-2); flex: 1; }
.yc-tieu-de { margin: 0; font: 600 18px/26px var(--font-sans); }

.yc-meta { display: flex; flex-direction: column; gap: var(--space-1); }
.yc-dong { display: flex; gap: var(--space-3); align-items: baseline; }
.yc-nhan {
  flex: none; width: 110px;
  color: var(--ink-muted); font: 400 12px/20px var(--font-sans);
}

.yc-noi-dung {
  white-space: pre-wrap;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--v-r);
  padding: var(--space-3);
  font: 400 14px/22px var(--font-sans);
  max-height: 340px; overflow-y: auto;
}
.yc-ghi-chu { font: 400 13px/20px var(--font-sans); color: var(--ink-secondary); }

.yc-hanh-dong {
  display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center;
  padding: var(--space-3) 0;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}

.yc-khoi { display: flex; flex-direction: column; gap: var(--space-2); }
.yc-khoi-dau {
  display: flex; align-items: center; gap: var(--space-2);
  font: 600 11px/18px var(--font-sans); letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-muted);
}
.yc-viec-ds { margin: 0; padding-left: var(--space-4); font: 400 13px/22px var(--font-sans); }

.yc-tep { display: flex; align-items: center; gap: var(--space-2); }
.lien-ket {
  border: 0; background: none; padding: 0;
  color: var(--ink-accent); text-decoration: underline; cursor: pointer;
  font: 400 13px/20px var(--font-sans);
}
.lien-ket:hover { background: none; color: var(--brand-red); }

.yc-td {
  border: 1px solid var(--border);
  border-radius: var(--v-r);
  padding: var(--space-2) var(--space-3);
  background: var(--surface);
}
.yc-td-dau { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.yc-td-dau b { font: 600 13px/20px var(--font-sans); }
.yc-td-noi { white-space: pre-wrap; font: 400 13px/20px var(--font-sans); margin-top: var(--space-1); }
.yc-td-nhap { display: flex; flex-direction: column; gap: var(--space-2); }
.yc-td-nhap .hang { display: flex; gap: var(--space-2); align-items: center; }
.yc-td-nhap select { flex: 1; }

@media (max-width: 720px) {
  .yc-ngan { width: 100vw; padding: var(--space-4); }
  .yc-nhan { width: 92px; }
}

/* ------------------------------------------- popover "Ai bấm xong?" (audit) -- */

.c-done.hoi-duoc { cursor: help; }
.c-done.hoi-duoc:hover { background: var(--brand-surface); }

.pop-audit {
  min-width: 340px; max-width: 460px;
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
}
.pop-audit .pop-dau { display: flex; flex-direction: column; gap: 2px; }
.pop-audit .pop-than { display: flex; flex-direction: column; gap: var(--space-2); }
.pop-audit .pop-hang { display: flex; gap: var(--space-3); align-items: baseline; }
.pop-audit p { margin: 0; }
.pop-audit .pop-chan {
  display: flex; align-items: center; gap: var(--space-2);
  border-top: 1px solid var(--border); padding-top: var(--space-2);
}
.note.ok { color: var(--success); }

/* Ô giao tiếp nhận trong ngăn chi tiết yêu cầu. */
.yc-giao { display: flex; align-items: center; gap: var(--space-3); padding-top: var(--space-2); }
.yc-giao .ac { flex: 1; }

/* ------------------------------------------------ trường bắt buộc + khách -- */

.sao { color: var(--danger); font-weight: 700; }

/* Chế độ khách: chỉ còn một tab nên thanh tab không cần trông như thanh điều hướng. */
.che-do-khach .tabs .tab { cursor: default; }

/* Xem trước file Excel nhập yêu cầu: modal rộng + dòng hỏng tô đỏ. */
.modal-rong { max-width: min(1180px, 94vw); }
.yc-dong-hong > td { background: var(--danger-surface); }

/* Số giờ suy từ thời lượng (task chưa có msdyn_effort) — nghiêng + mờ để phân biệt với
   số do người dùng nhập. Xem gioHienThi() trong manage.js. */
.c-hrs input.tu-duration { font-style: italic; color: var(--ink-secondary); }

/* Thay cho thuộc tính style="" trong index.html — Content-Security-Policy trên bản
 * deploy đặt `style-src 'self'`, thuộc tính style trong markup bị chặn thẳng. */
.w-210 { width: 210px; }
.w-250 { width: 250px; }
.minw-200 { min-width: 200px; }

/* ======================================= chọn nhiều yêu cầu + menu tiện ích */

/* Cột tick ở đầu bảng Yêu cầu. Hẹp và canh giữa — nó không phải dữ liệu, chỉ là tay cầm. */
.c-chon { width: 34px; text-align: center; padding-left: var(--space-2); padding-right: 0; }
.c-chon input { margin: 0; cursor: pointer; accent-color: var(--brand-red); }

/* 🔴 Dòng đang chọn KHÔNG tô gì — ô tick là dấu hiệu duy nhất (người dùng chốt 20/09/2026).
   Bản đầu đặt `box-shadow: inset 3px 0 0` lên `.yc-hang.da-chon > td`: inset áp cho MỌI ô
   trong hàng chứ không riêng ô đầu, nên chọn cả bảng là thành một lưới vạch đỏ dọc.
   Muốn đánh dấu dòng thì tô nền (`background`), đừng dùng dải inset trên td. */

/* Nút Tiện ích khi đang có lựa chọn — viền nhấn, KHÔNG dùng brand-red: mặt này đã có
   một điểm nhấn đỏ ở nút "+ Yêu cầu mới" (luật một điểm nhấn của spec/05). */
#yc-tien-ich.co-chon { border-color: var(--ink-accent); color: var(--ink-accent); font-weight: 600; }

/* Menu sổ xuống, dùng chung khung `.pop`. */
.menu-pop { min-width: 300px; max-width: 380px; padding: var(--space-1); display: flex; flex-direction: column; }
.menu-dau {
  padding: var(--space-2) var(--space-3);
  font: 600 11px/16px var(--font-sans); letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-muted);
}
.menu-muc {
  display: flex; flex-direction: column; gap: 1px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--v-r); cursor: pointer;
  transition: background 120ms ease;
}
.menu-muc:hover, .menu-muc:focus-visible { background: var(--brand-surface); outline: none; }
.menu-muc.khoa { opacity: .45; cursor: not-allowed; }
.menu-muc.khoa:hover { background: none; }
.menu-nhan { font: 600 14px/22px var(--font-sans); }
.menu-mota { font: 400 12px/18px var(--font-sans); color: var(--ink-muted); }
.menu-ngan { border-top: 1px solid var(--border); margin: var(--space-1) 0; }

/* Bản kê các yêu cầu sắp bị tác động, trong modal hàng loạt. Cuộn được vì lô có thể
   vài chục dòng, mà modal thì không được dài quá màn hình. */
.yc-ke {
  border: 1px solid var(--border); border-radius: var(--v-r);
  background: var(--surface-sunken);
  max-height: 220px; overflow-y: auto;
}
.yc-ke-dau {
  position: sticky; top: 0; background: var(--surface-sunken);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border);
  font: 600 11px/16px var(--font-sans); letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-muted);
}
.yc-ke-dong {
  display: flex; gap: var(--space-3); align-items: baseline;
  padding: var(--space-1) var(--space-3);
}
.yc-ke-dong code { color: var(--ink-secondary); flex: none; }
.yc-ke-ten { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* `.callout` của spec/05 — lớp này vốn chỉ có ở css/ui.css (trang Thiết lập), app chưa
   dùng đến bao giờ. Dải trái đổi màu theo trạng thái, nền giữ nguyên (ghi chú M0). */
.callout {
  border: 1px solid var(--border); border-left: 3px solid var(--border-strong);
  border-radius: var(--v-r); background: var(--surface-sunken);
  padding: var(--space-3) var(--space-4);
  color: var(--ink-secondary);
}
.callout.warn { border-left-color: var(--warning); }
.callout.bad { border-left-color: var(--danger); }
