/* Nexa Mini App SDK — LỚP 3: component (`.nx-*`).
 *
 * CỐ Ý CHƯA CÓ RULE NÀO ở Task 9. Bộ component (Input/Select/Button/Modal/Table/
 * TreeList…, xem spec §4.4) do Task 10 dựng cùng `ui.mjs`. File này tồn tại NGAY BÂY
 * GIỜ chỉ để khoá đúng thứ tự nạp trong index.html do `nexa gen-index` sinh:
 *   tokens.css → base.css → components.css → app.css
 * Thêm rule ở Task 10 không cần sửa lại thứ tự nạp hay index.html — chỉ ghi đè file
 * này.
 *
 * Quy ước bắt buộc cho MỌI rule thêm sau này:
 *   - Tiền tố `.nx-`, KHÔNG class trần. room-booking trộn `.btn`/`.icon-btn` với hai
 *     tiền tố khác (`.kb-*`, `.rm-*`) trong cùng file và phải vá bằng ba rule gỡ va
 *     chạm ở cuối styles.css (`room-booking/frontend/public/styles.css:422-424`).
 *   - Rule đè nền của `.nx-input` PHẢI dùng `background-color:`, KHÔNG phải shorthand
 *     `background:` — shorthand xoá sạch mũi tên nền (`--chevron`) của <select>.
 *     `_sdk/cli/lint-css.mjs` (rule no-background-shorthand-on-input) đã chặn ca này.
 *   - Không literal màu — chỉ var(--token) hoặc color-mix() dẫn xuất từ token.
 *
 * Task 10 — bộ component của `ui.mjs` (Button/IconButton/Input/Select/Textarea/Switch/
 * Checkbox/Modal/Drawer/Card/Toolbar/Table/PlainRow/Pagination/EmptyState/Skeleton/Toast/
 * ConfirmDialog/TreeList) đổ rule ở đây. `.nx-app-root { display: contents }` là điểm mount
 * của `app.mjs` (bootApp) — `display: contents` để wrapper không chiếm layout (app tự lo
 * height 100% của #root qua CSS riêng của mình).
 */

.nx-app-root { display: contents; }

/* ── Button / IconButton ─────────────────────────────────────────────────── */
.nx-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-1);
  height: 34px; padding: 0 var(--sp-4); border-radius: var(--r-md); border: 1px solid transparent;
  font-size: var(--text-13); font-weight: 600; cursor: pointer; transition: background var(--d-fast) var(--ease);
}
.nx-btn:disabled { cursor: not-allowed; opacity: 0.5; }
.nx-btn-primary { background-color: var(--accent); color: var(--on-accent); }
.nx-btn-primary:not(:disabled):hover { background-color: var(--accent-strong); }
.nx-btn-ghost { background-color: transparent; color: var(--text); border-color: var(--border); }
.nx-btn-ghost:not(:disabled):hover { background-color: var(--bg-hover); }
.nx-btn-danger { background-color: transparent; color: var(--danger); border-color: var(--danger); }
.nx-btn-danger:not(:disabled):hover { background-color: color-mix(in srgb, var(--danger) 10%, var(--bg)); }

.nx-iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--r-md); border: none;
  background-color: transparent; color: var(--text-muted); cursor: pointer;
  transition: background var(--d-fast) var(--ease), color var(--d-fast) var(--ease);
}
.nx-iconbtn:not(:disabled):hover { background-color: var(--bg-hover); color: var(--text); }
.nx-iconbtn:disabled { cursor: not-allowed; opacity: 0.5; }

/* ── Input / Select / Textarea ───────────────────────────────────────────── */
.nx-input {
  width: 100%; height: 34px; padding: 0 var(--sp-3); border-radius: var(--r-md);
  border: 1px solid var(--border); background-color: var(--bg); color: var(--text); font-size: var(--text-13);
}
.nx-input:read-only { color: var(--text-muted); background-color: var(--bg-hover); }
.nx-input:disabled { opacity: 0.6; }
.nx-textarea { height: auto; padding: var(--sp-2) var(--sp-3); resize: vertical; }
.nx-select {
  appearance: none; padding-right: var(--sp-8);
  background-image: var(--chevron); background-repeat: no-repeat; background-position: right var(--sp-2) center;
}

/* ── Switch / Checkbox ───────────────────────────────────────────────────── */
.nx-switch, .nx-checkbox { display: inline-flex; align-items: center; gap: var(--sp-2); cursor: pointer; }
.nx-switch input, .nx-checkbox input { position: absolute; width: 1px; height: 1px; opacity: 0; }

.nx-switch-track {
  position: relative; width: 34px; height: 20px; border-radius: var(--r-full);
  background-color: var(--border-strong); transition: background var(--d-base) var(--ease);
}
.nx-switch-knob {
  position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%;
  background-color: var(--knob); box-shadow: var(--shadow-sm); transition: transform var(--d-base) var(--ease);
}
.nx-switch input:checked + .nx-switch-track { background-color: var(--accent); }
.nx-switch input:checked + .nx-switch-track .nx-switch-knob { transform: translateX(14px); }
.nx-switch input:focus-visible + .nx-switch-track { outline: 2px solid var(--accent); outline-offset: 2px; }

.nx-checkbox-box {
  display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px;
  border-radius: var(--r-xs); border: 1px solid var(--border-strong); background-color: var(--bg); color: var(--on-accent);
}
.nx-checkbox input:checked + .nx-checkbox-box { background-color: var(--accent); border-color: var(--accent); }
.nx-checkbox input:focus-visible + .nx-checkbox-box { outline: 2px solid var(--accent); outline-offset: 2px; }
.nx-switch-label, .nx-checkbox-label { font-size: var(--text-13); color: var(--text); }

/* ── Card / Toolbar / PlainRow / Table ───────────────────────────────────── */
.nx-card { border: 1px solid var(--border); border-radius: var(--r-lg); background-color: var(--bg); }
.nx-card-hd { display: flex; align-items: center; justify-content: space-between; padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--border-subtle); }
.nx-card-title { font-size: var(--text-14); font-weight: 600; color: var(--text); }
.nx-card-body { padding: var(--sp-4); }

.nx-toolbar { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }

.nx-plainrow {
  display: flex; align-items: center; gap: var(--sp-3); width: 100%; text-align: left;
  padding: var(--sp-2) var(--sp-3); border: none; border-radius: var(--r-md); background-color: transparent;
  color: var(--text); font: inherit; cursor: pointer;
}
button.nx-plainrow:hover { background-color: var(--bg-hover); }

.nx-table-wrap { width: 100%; overflow-x: auto; }
.nx-table { width: 100%; border-collapse: collapse; font-size: var(--text-13); }
.nx-table th { text-align: left; padding: var(--sp-2) var(--sp-3); color: var(--text-muted); font-weight: 600; border-bottom: 1px solid var(--border); }
.nx-table td { padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--border-subtle); }

/* ── Modal / Drawer ───────────────────────────────────────────────────────── */
.nx-modal-scrim, .nx-drawer-scrim {
  position: fixed; inset: 0; background-color: var(--scrim); display: flex; z-index: 1000;
  animation: neFadeIn var(--d-base) var(--ease-out);
}
.nx-modal-scrim { align-items: center; justify-content: center; padding: var(--sp-4); }
.nx-modal {
  width: min(520px, 100%); max-height: 86vh; overflow-y: auto; display: flex; flex-direction: column;
  background-color: var(--bg); border-radius: var(--r-xl); box-shadow: var(--shadow-pop);
  animation: neScaleIn var(--d-base) var(--ease-out);
}
.nx-modal-hd { display: flex; align-items: flex-start; gap: var(--sp-2); padding: var(--sp-4); border-bottom: 1px solid var(--border-subtle); }
.nx-modal-hd-tx { flex: 1; min-width: 0; }
.nx-modal-title { font-size: var(--text-16); font-weight: 700; color: var(--text); }
.nx-modal-sub { font-size: var(--text-12); color: var(--text-muted); margin-top: 2px; }
.nx-modal-body { padding: var(--sp-4); }
.nx-modal-ft { display: flex; justify-content: flex-end; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--border-subtle); }

.nx-drawer-scrim { justify-content: flex-end; }
.nx-drawer {
  width: min(420px, 100%); height: 100%; display: flex; flex-direction: column;
  background-color: var(--bg); box-shadow: var(--shadow-pop);
}
.nx-drawer-left { order: -1; }
.nx-drawer-hd { display: flex; align-items: center; justify-content: space-between; padding: var(--sp-4); border-bottom: 1px solid var(--border-subtle); }
.nx-drawer-title { font-size: var(--text-15); font-weight: 700; color: var(--text); }
.nx-drawer-body { flex: 1; overflow-y: auto; padding: var(--sp-4); }
.nx-drawer-ft { display: flex; justify-content: flex-end; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--border-subtle); }

.nx-confirm-body { display: flex; gap: var(--sp-3); align-items: flex-start; color: var(--text); font-size: var(--text-13); }
.nx-confirm-icon {
  flex: none; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px;
  border-radius: 50%; background-color: var(--accent-soft); color: var(--accent);
}
.nx-confirm-icon.is-danger { background-color: color-mix(in srgb, var(--danger) 16%, var(--bg)); color: var(--danger); }

/* ── Toast ────────────────────────────────────────────────────────────────── */
.nx-toast-wrap {
  position: fixed; left: 50%; bottom: var(--sp-6); transform: translateX(-50%);
  display: flex; flex-direction: column; gap: var(--sp-2); z-index: 1100;
}
.nx-toast {
  display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-md); background-color: var(--accent-strong); color: var(--on-accent);
  font-size: var(--text-13); box-shadow: var(--shadow-lg); animation: neFadeIn var(--d-base) var(--ease-out);
}
.nx-toast-success { background-color: var(--success); color: var(--on-accent); }
.nx-toast-error { background-color: var(--danger); color: var(--on-accent); }

/* ── Pagination ───────────────────────────────────────────────────────────── */
.nx-pager { display: flex; align-items: center; gap: var(--sp-1); }
.nx-pager-btn {
  display: inline-flex; align-items: center; justify-content: center; min-width: 28px; height: 28px;
  padding: 0 var(--sp-1); border: 1px solid transparent; border-radius: var(--r-sm);
  background-color: transparent; color: var(--text-muted); font-size: var(--text-12); cursor: pointer;
}
.nx-pager-btn:hover:not(:disabled) { background-color: var(--bg-hover); color: var(--text); }
.nx-pager-btn.on { background-color: var(--accent-soft); color: var(--accent); font-weight: 700; }
.nx-pager-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.nx-pager-gap { color: var(--text-muted); padding: 0 var(--sp-1); }

/* ── EmptyState / Skeleton ────────────────────────────────────────────────── */
.nx-empty { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); padding: var(--sp-8); text-align: center; }
.nx-empty-title { font-size: var(--text-14); font-weight: 600; color: var(--text); }
.nx-empty-hint { font-size: var(--text-13); color: var(--text-muted); }

.nx-skel {
  display: inline-block; border-radius: var(--r-sm);
  background: linear-gradient(90deg, var(--bg-hover) 25%, var(--border-subtle) 50%, var(--bg-hover) 75%);
  background-size: 200% 100%; animation: neShimmer 1.4s ease-in-out infinite;
}

/* ── TreeList ─────────────────────────────────────────────────────────────── */
.nx-tree { display: flex; flex-direction: column; gap: var(--sp-2); }
.nx-tree-list { list-style: none; margin: 0; padding: 0; }
.nx-tree-list:not(.is-root) { padding-left: var(--sp-6); border-left: 1px dashed var(--border); margin-left: 11px; }
.nx-tree-item { margin: var(--sp-1) 0; }
.nx-tree-row {
  display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-md); border: 1px solid transparent;
}
.nx-tree-row:hover { background-color: var(--bg-hover); }
.nx-tree-row:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent-ring); }
.nx-tree-kind {
  flex: none; font-size: var(--text-11); font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  padding: 2px var(--sp-1); border-radius: var(--r-xs); background-color: var(--accent-soft); color: var(--accent);
}
.nx-tree-title { flex: 1; min-width: 0; height: 30px; }
.nx-tree-weight { flex: none; width: 70px; height: 30px; }
.nx-tree-add { flex: none; }
.nx-tree-addroot { align-self: flex-start; }

/* ── Tabs (Shell nav, Task 12 — nav thuộc SDK, xem app.mjs) ─────────────────── */
.nx-tabs { display: flex; align-items: center; gap: var(--sp-1); padding: 0 var(--sp-4); border-bottom: 1px solid var(--border); background-color: var(--bg); }
.nx-tab {
  display: inline-flex; align-items: center; height: 40px; padding: 0 var(--sp-3);
  border: none; border-bottom: 2px solid transparent; background-color: transparent;
  color: var(--text-muted); font-size: var(--text-13); font-weight: 600; cursor: pointer;
  transition: color var(--d-fast) var(--ease), border-color var(--d-fast) var(--ease);
}
.nx-tab:hover { color: var(--text); }
.nx-tab.is-active { color: var(--accent); border-bottom-color: var(--accent); }

/* ── boot (bootApp — trước cả khi Shell mount) ───────────────────────────── */
.nx-boot { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; gap: var(--sp-2); padding: var(--sp-8); text-align: center; }
.nx-boot-title { font-size: var(--text-16); font-weight: 700; color: var(--text); }
.nx-boot-hint { font-size: var(--text-13); color: var(--text-muted); max-width: 420px; }

