/* ═══════════════════════════════════════════════════════════════════════════
 * bulbal-forms.css — Phase 06: NHÓM BIỂU MẪU (tab TÌM/NHÓM MỚI/THEO ID, ô nhập,
 * nút, checkbox, avatar upload, QR, ô tìm kiếm). Nạp SAU css/base.css +
 * bulbal-tokens.css (thứ tự nạp file do phase tích hợp quyết định — file này
 * CHƯA được <link> trong index.html/index-dev.html, cần agent tích hợp thêm).
 *
 * Sở hữu độc quyền: css/bulbal-forms.css (file MỚI, không sửa file nào khác).
 * CHỈ dùng var(--bb-*) khai báo ở bulbal-tokens.css — KHÔNG hardcode màu.
 * KHÔNG !important trừ khi base.css đã dùng !important ở đúng thuộc tính đó.
 * Toàn file này KHÔNG dùng !important nào — mọi override (kể cả hover/focus
 * đè state mặc định ở mục 5) đều thắng qua specificity bằng nhau + đứng SAU
 * trong nguồn (source order), không cần ép.
 *
 * PHẠM VI THỰC TẾ — quan trọng để hiểu tại sao selector ở đây là "toàn cục":
 * Các class base.css dùng cho biểu mẫu (ul.tabbar, .panel-form*, .group,
 * input[type=text/email/password/tel], label.small, button.primary/.outline,
 * .avatar-upload, .qr-code, .chip-input) KHÔNG có wrapper ID/class riêng cho
 * màn "Bắt đầu cuộc trò chuyện mới" — SidepanelView bọc newtpk/settings/
 * security/wallpapers/support/reset/cred... TRONG CÙNG 1 <div id="sidepanel">
 * (xem src/views/sidepanel-view.jsx:141-320). Do đó các rule dưới đây thành
 * "hệ thống thiết kế biểu mẫu" dùng chung cho MỌI màn phụ, không riêng màn
 * tạo mới — đúng tinh thần "sở hữu độc quyền 1 file CSS mới cho nhóm biểu
 * mẫu". Đã kiểm tra: KHÔNG có rule nào trong 4 file bulbal-{shell,contacts,
 * messages,composer}.css đụng các selector này (grep xác nhận trước khi viết).
 *
 * RỦI RO ĐÃ XỬ LÝ — #send-message-input (composer, P04 sở hữu):
 * Cố tình KHÔNG dùng selector `textarea` ở đây (chỉ input[type=text/email/
 * password/tel]) vì mọi field trong phạm vi phase này (new-topic-group,
 * new-topic-by-id, chip-input, search-contacts) đều là <input>, KHÔNG có
 * <textarea> nào — loại trừ hoàn toàn nguy cơ đụng #send-message-input (là
 * <textarea>, composer.css cảnh báo cấm thêm transition lên nó).
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ── 0. Cầu nối token bổ sung — chỉ phần "form" chưa có trong bridge của P01 ──
 * placeholder input vẫn dùng #bbb/#555 cứng từ base.css (không qua --bb-*) —
 * nối sang --bb-txt-3 (đã tính tương phản ở P01) cho nhất quán + rõ hơn. */
:root {
  --clr-text-placeholder: var(--bb-txt-3);
}

/* ── 1. TAB BAR (ul.tabbar) — "TÌM / NHÓM MỚI / THEO ID" ──────────────────
 * base.css: mỗi <li> tự vẽ 1 đường kẻ dưới riêng (trông đứt đoạn) + box-shadow
 * inset (viền nổi khối cũ). Đổi sang 1 đường kẻ liền dưới cả thanh + chỉ tab
 * đang chọn có gạch chân màu thương hiệu (giữ animation width-expand gốc). */
ul.tabbar {
  background: var(--bb-bg-side);
  border-bottom: 1px solid var(--bb-line);
  padding: 0 8px;
  gap: 2px;
}

ul.tabbar > li {
  height: auto;
  box-shadow: none;
}

/* Đường kẻ riêng từng tab (bản gốc) tắt đi — container đã có border-bottom */
ul.tabbar li:after {
  display: none;
}

ul.tabbar li.active {
  background: transparent;
}

/* Gạch chân tab đang chọn: giữ animation gốc, chỉ dày + bo nhẹ hơn.
 * Màu đã bridge sẵn var(--clr-tabbar-active-border) = light-dark(var(--bb-brand),
 * #60a5fa) ở tokens.css — không cần khai lại màu ở đây. */
ul.tabbar li.active:after {
  display: block;
  height: 3px;
  border-radius: 3px 3px 0 0;
}

ul.tabbar > li > a {
  padding: 13px 14px 12px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .03em;
  border-radius: 8px 8px 0 0;
  transition: color var(--bb-dur) var(--bb-ease), background-color var(--bb-dur) var(--bb-ease);
}

/* Hover mượt cho tab chưa chọn (tab đang chọn không cần hover riêng) */
ul.tabbar > li:not(.active) > a:hover {
  color: var(--bb-txt-1);
  background: var(--bb-hover);
}

/* ── 2. Ô TÌM KIẾM trong tab TÌM (search-contacts.jsx) ─────────────────────
 * DOM: .panel-form-row > i.material-icons.search + input.search[type=text]
 * + (a > i "highlight_off" khi có chữ | span > i rỗng khi chưa gõ).
 * Biến .panel-form-row bao ngoài thành viên thuốc; input.search bên trong
 * mất khung (khung thật nằm ở .panel-form-row cha) — tránh khung lồng khung. */
.panel-form-row:has(> input.search) {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 12px;
  padding: 0 14px;
  height: 44px;
  background: var(--bb-bg-chat);
  border: 1px solid var(--bb-line);
  border-radius: var(--bb-r-pill);
  transition: border-color var(--bb-dur) var(--bb-ease), box-shadow var(--bb-dur) var(--bb-ease);
}

.panel-form-row:has(> input.search:focus) {
  border-color: var(--bb-brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--bb-brand) 18%, transparent);
}

.panel-form-row:has(> input.search) > i.search {
  position: static;
  font-size: 20px;
  color: var(--bb-txt-3);
  flex: 0 0 auto;
}

.panel-form-row input.search {
  flex: 1;
  min-width: 0;
  height: 100%;
  text-indent: 0;
  padding: 0;
  margin: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  font-size: var(--bb-fs-base);
  color: var(--bb-txt-1);
}

.panel-form-row:has(> input.search) > a,
.panel-form-row:has(> input.search) > span {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  color: var(--bb-txt-3);
  transition: background-color var(--bb-dur) var(--bb-ease), color var(--bb-dur) var(--bb-ease);
}

.panel-form-row:has(> input.search) > a:hover {
  background: var(--bb-hover);
  color: var(--bb-txt-1);
}

/* ── 3. Ô NHẬP BIỂU MẪU — Tên nhóm / Mô tả / Chỉ mình bạn thấy / ID nhóm ────
 * base.css dùng gạch chân kiểu Material cũ (border-bottom). Đổi sang khung bo
 * góc có viền đầy đủ. Cố tình KHÔNG gồm textarea/input[type=search] — xem
 * cảnh báo composer ở đầu file + input.search đã xử lý riêng ở mục 2.
 * SỬA 260729 (điều phối): ô tìm kiếm là `input class="search" type="text"` (KHÔNG
 * phải type=search như giả định ban đầu — xem widgets/search-contacts.jsx:60) nên
 * nó dính CẢ luật này LẪN khung viên thuốc bao ngoài => VIỀN ĐÔI trên màn thật.
 * Thêm :not(.search) để loại trừ. */
input[type="text"]:not(.search),
input[type="email"],
input[type="password"],
input[type="tel"] {
  height: auto;
  min-height: var(--bb-touch);
  padding: 10px 14px;
  border: 1px solid var(--bb-line);
  border-radius: 12px;
  background: var(--bb-bg-chat);
  box-shadow: none;
  transition: border-color var(--bb-dur) var(--bb-ease),
              box-shadow var(--bb-dur) var(--bb-ease),
              background-color var(--bb-dur) var(--bb-ease);
}

input[type="text"]:not(.search):focus,
input[type="email"]:focus,
input[type="password"]:focus,
input[type="tel"]:focus {
  border: 1px solid var(--bb-brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--bb-brand) 18%, transparent);
  background: var(--bb-bg-side);
}

/* --clr-input-invalid-* (không phải --bb-*) vì tokens.css P01 chưa định nghĩa
 * màu "lỗi/danger" riêng — dùng lại ĐÚNG token ngữ nghĩa base.css đã có sẵn
 * cho state .invalid (không hardcode hex mới, không lệch màu đỏ với phần còn
 * lại của app). */
input[type="text"].invalid,
input[type="email"].invalid,
input[type="password"].invalid,
input[type="tel"].invalid {
  border: 1px solid var(--clr-input-invalid-border);
  box-shadow: 0 0 0 3px var(--clr-input-invalid-shadow);
}

/* Khôi phục input.search (mục 2) và input trong .chip-input (mục 7) — 2 rule
 * ở dưới có specificity cao hơn nhờ ngữ cảnh cha nên tự thắng, không cần lặp
 * lại ở đây; chỉ ghi chú để người đọc khỏi ngỡ 2 nơi "đá" nhau. */

/* Label phía trên field — base.css label.small dùng var(--clr-primary-action)
 * = light-dark(var(--bb-brand), var(--bb-brand-600)); ở SÁNG là #3B82F6 + nền
 * trắng ⇒ 3.68:1, TRƯỢT AA cho text (đã đo, xem đầu bulbal-tokens.css — cùng
 * lỗi gốc mà P01 từng vá cho header). Ép về --bb-brand-600 (#2563EB) không
 * đổi theo theme (token này không light-dark hoá) ⇒ trên nền trắng
 * #FFFFFF: 5.17:1 — ĐẠT AA. Trên nền tối field (--bb-bg-chat #0F172A) màu
 * brand-600 vẫn đủ sáng để đạt tương phản (nền tối làm mẫu số nhỏ hơn ⇒ tỷ lệ
 * càng cao) — không cần tính riêng vì luôn ưu thế hơn trường hợp nền trắng
 * đã tính. Tự tính bằng công thức relative luminance WCAG chuẩn, xem chi
 * tiết phép tính trong report kèm phase. */
label.small {
  display: block;
  margin: 0 0 6px;
  color: var(--bb-brand-600);
  font-weight: 600;
  font-size: 12.5px;
  letter-spacing: .01em;
}

/* Khối [label + input] xếp dọc, khoảng cách đều giữa các field */
.group {
  display: flex;
  flex-direction: column;
  margin: 0 0 16px;
}

.panel-form-column > .group:last-child {
  margin-bottom: 0;
}

/* ── 4. NÚT — "TẠO" / "THEO DÕI" / "Cancel" / "OK" ─────────────────────────
 * base.css: button.primary nền = var(--clr-button-primary-bg) = light-dark(
 * var(--bb-brand), var(--bb-brand-600)) ⇒ SÁNG dùng #3B82F6 + chữ trắng =
 * 3.68:1, TRƯỢT AA (cùng lỗi #3B82F6/trắng đã ghi ở tokens.css). Ép nền nút
 * primary về --bb-brand-600 (hằng số, không đổi theo theme) ⇒ trắng/#2563EB
 * = 5.17:1 — ĐẠT AA; hover đậm hơn 1 nấc --bb-brand-700 = trắng/#1D4ED8 =
 * 6.70:1 (tự tính công thức WCAG relative luminance, ghi chi tiết trong
 * report). Bo góc 12px thay góc vuông 4px cũ, bỏ box-shadow đen nặng cũ. */
button {
  font-weight: 600;
  border-radius: 12px;
  box-shadow: none;
  transition: background-color var(--bb-dur) var(--bb-ease),
              color var(--bb-dur) var(--bb-ease),
              transform var(--bb-dur) var(--bb-ease),
              box-shadow var(--bb-dur) var(--bb-ease);
}

button:active:not([disabled]) {
  transform: scale(.97);
  box-shadow: none;
}

button.primary {
  background-color: var(--bb-brand-600);
  color: var(--bb-txt-on-brand);
}

button.primary:hover:not([disabled]) {
  background-color: var(--bb-brand-700);
  box-shadow: var(--bb-sh-2);
}

button.outline {
  border-radius: 12px;
  border-color: var(--bb-line);
  color: var(--bb-brand-600);
}

button.outline:hover:not([disabled]) {
  background-color: var(--bb-hover);
  border-color: var(--bb-brand-600);
}

.dialog-buttons {
  padding: 14px 4px 4px;
  gap: 4px;
}

/* ── 5. VÙNG TẢI ẢNH ĐẠI DIỆN NHÓM — vòng tròn nét đứt + nút upload ───────
 * DOM: div.avatar-upload > div.blank (trạng thái trống, hiện "384×384") |
 * img.preview (đã chọn ảnh) + label.round (nút tải, đè góc phải-dưới). */
.avatar-upload {
  margin: 4px auto 8px;
}

.avatar-upload .blank {
  border: 2px dashed var(--bb-line);
  background: var(--bb-bg-chat);
  color: var(--bb-txt-3);
  font-size: 13px;
  font-weight: 600;
  transition: border-color var(--bb-dur) var(--bb-ease), background-color var(--bb-dur) var(--bb-ease);
}

.avatar-upload:hover .blank {
  border-color: var(--bb-brand);
  background: var(--bb-hover);
}

.avatar-upload img.preview {
  box-shadow: var(--bb-sh-1);
}

/* Nút tròn tải ảnh (label.round đè góc phải-dưới) — đổi nền trắng cũ (không
 * đổi theo theme) sang nền thương hiệu đặc, icon trắng, dễ nhận diện hơn. */
.avatar-upload .inputfile + label.round {
  background-color: var(--bb-brand-600);
  color: var(--bb-txt-on-brand);
  box-shadow: var(--bb-sh-2);
}

.avatar-upload .inputfile:focus + label,
.avatar-upload .inputfile + label:hover {
  /* Specificity bằng đúng rule nền ở trên (3 class + 1 type) — không cần
     !important, thắng nhờ đứng SAU trong CHÍNH file này (thứ tự nguồn). */
  background-color: var(--bb-brand-700);
  color: var(--bb-txt-on-brand);
}

/* ── 6. CHECKBOX — "Đây là một kênh" — vùng chạm ≥44px ────────────────────
 * DOM: .panel-form-row > i.material-icons.blue.clickable (hoặc .lt-blue) +
 * label. Icon đã đủ tương phản sẵn (var(--clr-primary-accent) bridge = brand,
 * icon là đồ hoạ không phải chữ ⇒ ngưỡng 3:1 theo WCAG 1.4.11, #3B82F6/nền
 * trắng = 3.68:1 ĐẠT) — không đổi màu icon ở đây.
 *
 * ⚠️ TRÙNG PHẠM VI VỚI bulbal-panels.css (agent song song, cùng đợt phase-06):
 * file đó đã có `.panel-form-row > i.material-icons.clickable{width/height:
 * var(--bb-touch); border-radius:pill; hover/active}` — ĐÚNG yêu cầu 44×44px
 * touch target, quét DOM 3 nguồn (info-view/acc-general/new-topic-group) nên
 * bao quát hơn bản này. KHÔNG lặp lại phần đó ở đây (tránh 2 nguồn cùng set
 * width/height/border-radius trên đúng 1 selector, dễ trôi khi 1 bên sửa mà
 * bên kia quên). Ở ĐÂY chỉ bổ sung phần panels.css CHƯA đụng: con trỏ tay +
 * cỡ chữ cho <label> đứng cạnh checkbox (panels.css chỉ style icon, không
 * đụng label). Xem report mục "Trùng lặp cross-file" để tích hợp quyết định
 * giữ 1 hay cả 2 khi wire index.html. */
.panel-form-row:has(> i.material-icons.clickable) label {
  cursor: pointer;
  font-size: var(--bb-fs-base);
  margin: 0;
}

/* ── 7. THẺ (tags) — ChipInput trong TagManager ───────────────────────────
 * .chip-input là khung Material cũ (border-bottom) bọc các .chip + 1
 * input[type=text] KHÔNG class riêng. Biến .chip-input thành khung bo góc
 * chuẩn field (đồng bộ mục 3); input con bên trong phải mất khung để không
 * lồng khung trong khung (selector con cụ thể hơn nên tự thắng mục 3). */
.chip-input {
  border: 1px solid var(--bb-line);
  border-radius: 12px;
  background: var(--bb-bg-chat);
  box-shadow: none;
  padding: 6px 8px;
  gap: 4px;
}

.chip-input.focused {
  border: 1px solid var(--bb-brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--bb-brand) 18%, transparent);
  background: var(--bb-bg-side);
}

.chip-input > input[type="text"] {
  border: 0;
  box-shadow: none;
  background: transparent;
  min-height: 0;
  padding: 0 0.25rem;
}

/* ── 8. QR — tab THEO ID, "Quét mã của tôi" ───────────────────────────────
 * KHÔNG viết rule ở đây: bulbal-panels.css (agent song song) đã có
 * `.panel-form-column > .qr-code{...}` — specificity (0,2,0) cao hơn 1 selector
 * `.qr-code` bất kỳ tôi viết ở đây (0,1,0) sẽ luôn thua bất kể thứ tự nạp file,
 * nên viết thêm cũng vô nghĩa (dead code). ĐÃ THỬ ban đầu dùng
 * `background: var(--bb-txt-on-brand)` (trắng cố định, không đổi theme) vì
 * mã QR cần nền trắng tuyệt đối để máy quét đọc được — nhưng rule của
 * panels.css lại dùng `background-color: var(--bb-bg-side)` (ĐỔI THEO THEME,
 * tối ở dark mode) và sẽ thắng. CẢNH BÁO cho agent tích hợp: cần verify bằng
 * browser thật ở chế độ Tối xem qrcodejs có tự vẽ nền trắng RIÊNG bên trong
 * canvas/img hay không — nếu KHÔNG, module QR đen sẽ nằm trên nền
 * --bb-bg-side tối (#111827), tương phản kém, có thể không quét được. Xem
 * report mục "Trùng lặp cross-file". */

/* ── 9. "Tin nhắn đã lưu" (self topic, tab TÌM khi chưa gõ tìm kiếm) ──────
 * KHÔNG viết rule ở đây: Contact.jsx render item='slf' ra ĐÚNG cấu trúc
 * <li> trong <ul class="contact-box"> (avatar-box + text-box + contact-title
 * + contact-comment) giống hệt hàng liên hệ sidebar — đã được
 * bulbal-contacts.css (P02, sở hữu ".contact-box và MỌI THỨ BÊN TRONG") style
 * đầy đủ (bo góc 16px, hover, avatar 52px tròn). Thêm rule trùng ở đây vừa vi
 * phạm ranh giới sở hữu file vừa tạo nguy cơ trôi (drift) 2 nguồn. Nếu ảnh
 * audit-01 cho thấy hàng này còn phẳng/nhỏ, khả năng ảnh chụp TRƯỚC khi
 * bulbal-contacts.css được nạp cho màn newtpk — agent tích hợp verify lại
 * bằng browser thật sau khi wire đủ 6 file CSS (xem "Chỗ chưa chắc" trong
 * report kèm phase). */

/* ── 10. Mobile ≤640px — vùng chạm rộng hơn, tab/nút full-width dễ bấm ───── */
@media (max-width: 640px) {
  ul.tabbar > li > a {
    padding: 15px 12px 14px;
    font-size: 13.5px;
  }

  .panel-form-row:has(> input.search) {
    margin: 8px 10px;
  }

  .panel-form-column,
  .panel-form-row {
    padding: 0.5rem 1rem;
  }

  .dialog-buttons {
    padding: 14px 12px 16px;
  }

  .dialog-buttons button {
    flex: 1;
    min-height: var(--bb-touch);
  }

  .avatar-upload .inputfile + label.round {
    width: var(--bb-touch);
    height: var(--bb-touch);
    line-height: var(--bb-touch);
  }
}

/* =============================================================================
 * BỔ SUNG (điều phối viên, 260729 đợt 2) — khối mã QR.
 * CẢ HAI agent song song đều GỠ luật .qr-code của mình vì tưởng bên kia giữ →
 * kết quả không ai style. Đặt tại đây (tab "THEO ID" thuộc nhóm biểu mẫu).
 * NỀN CỐ ĐỊNH TRẮNG, không theo chế độ màu: mã QR nền tối thì máy quét không
 * đọc được — đây là yêu cầu chức năng, không phải thẩm mỹ.
 * ========================================================================== */
.panel-form-column > .qr-code,
.qr-code {
  background: #FFFFFF;
  padding: 14px;
  border-radius: var(--bb-r-md, 12px);
  border: 1px solid var(--bb-line);
  display: inline-block;
  line-height: 0;
}
