/* ZenPn — phần giao diện viết tay, xếp sau bộ CSS đã khôi phục để ghi đè được.
 * Tách riêng khỏi perf.styles.*.css vì bộ CSS đó là baseline đã khôi phục,
 * được kiểm tra sha256 khi build (scripts/build-frontend.cjs) nên không sửa được.
 * Biến --zc-* do baseline khai báo, tự đổi theo light/dark. */

.zc-auth-socials {
  display: grid;
  gap: 10px;
  margin-bottom: 14px;
}

.zc-auth-social {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 500;
  color: var(--zc-text);
  background: var(--zc-raised);
  border: 1px solid var(--zc-line);
  border-radius: 6px;
  cursor: pointer;
  transition: background .2s, border-color .2s, opacity .2s;
}

.zc-auth-social:hover:not(:disabled) { background: var(--zc-hover, rgba(255, 255, 255, .06)); }
.zc-auth-social:focus-visible { outline: 2px solid var(--zc-blue); outline-offset: 2px; }
.zc-auth-social:disabled { cursor: default; opacity: .65; }

/* Ô icon giữ kích thước cố định để logo và vòng quay không làm nhãn nhảy chỗ. */
.zc-auth-social-icon {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
}

.zc-auth-social-mark { display: block; }
.zc-auth-social-spinner { display: none; }

/* Trạng thái đang gọi backend: thay logo bằng vòng quay. */
.zc-auth-social.is-busy .zc-auth-social-mark { display: none; }
.zc-auth-social.is-busy .zc-auth-social-spinner {
  display: block;
  width: 14px;
  height: 14px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: zenpn-spin .7s linear infinite;
}

@keyframes zenpn-spin { to { transform: rotate(360deg); } }

/* Màu báo lỗi: baseline không khai biến nào cho mức nguy hiểm. */
:root { --zc-danger: #e5484d; }
[data-zenpn-mode="light"] { --zc-danger: #cf2b31; }

/* Toast nằm ngoài #root nên React rerender không xoá mất. Đây là kiểu thông báo
   duy nhất của giao diện — mọi lỗi API, mọi thông báo thành công đều đi qua đây
   (public/zenpn/toast.js). Không bao giờ nhận chuột: toast ẩn vẫn nằm trong DOM,
   để bắt chuột thì nó che mất phần đầu trang. */
.zenpn-toast {
  position: fixed;
  left: 50%;
  top: 24px;
  z-index: 2000;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  max-width: min(420px, calc(100vw - 32px));
  padding: 11px 16px;
  pointer-events: none;
  font-family: var(--zc-font, Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif);
  font-size: 13px;
  line-height: 1.45;
  color: var(--zc-text);
  background: var(--zc-card);
  border: 1px solid var(--zc-line);
  border-radius: 8px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, .28);
  transform: translate(-50%, -12px);
  opacity: 0;
  transition: opacity .2s, transform .2s;
}

.zenpn-toast.is-visible { transform: translate(-50%, 0); opacity: 1; }
/* margin-top canh chấm tròn theo dòng chữ đầu tiên, kể cả khi toast có 2 dòng. */
.zenpn-toast-icon { flex-shrink: 0; width: 14px; height: 14px; margin-top: 2px; }
.zenpn-toast-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.zenpn-toast-title { font-weight: 600; }

.zenpn-toast-busy .zenpn-toast-icon {
  border: 2px solid var(--zc-blue);
  border-right-color: transparent;
  border-radius: 50%;
  animation: zenpn-spin .7s linear infinite;
}

.zenpn-toast-error .zenpn-toast-icon { border-radius: 50%; background: var(--zc-danger); }
.zenpn-toast-warning .zenpn-toast-icon { border-radius: 50%; background: var(--zc-orange); }
.zenpn-toast-success .zenpn-toast-icon { border-radius: 50%; background: var(--zc-green); }
.zenpn-toast-info .zenpn-toast-icon { border-radius: 50%; background: var(--zc-blue); }

@media (prefers-reduced-motion: reduce) {
  .zc-auth-social.is-busy .zc-auth-social-spinner,
  .zenpn-toast-busy .zenpn-toast-icon { animation-duration: 2.4s; }
  .zenpn-toast { transition: none; }
}

/* Lỗi nhập liệu hiện ngay dưới ô sai. Ô trống là lỗi của biểu mẫu, không phải
   sự cố hệ thống: báo tại chỗ để người dùng biết phải sửa ở đâu, và không tốn
   một vòng gọi backend chỉ để nhận lại "thiếu email". */
.zc-field { display: flex; flex-direction: column; gap: 5px; }

.zc-field-error {
  width: 100%;
  margin: 5px 0 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--zc-danger);
}

.zc-field > .zc-field-error { margin-top: 0; }
/* Ô mã xác minh nằm trong lưới 2 cột, còn ô email có hậu tố là một hàng flex:
   cả hai đều cần dòng lỗi chiếm trọn một dòng riêng bên dưới. */
.form-row > .zc-field-error { grid-column: 1 / -1; }
.v2board-email-whitelist-enable { flex-wrap: wrap; }

.zc-input.zc-field-invalid,
.zc-auth-field-control.zc-field-invalid { border-color: var(--zc-danger); }

.zc-input.zc-field-invalid:focus-within,
.zc-auth-field-control.zc-field-invalid:focus-within {
  border-color: var(--zc-danger);
  box-shadow: 0 0 0 2px rgba(229, 72, 77, .2);
}

/* Đăng ký là hành động phụ: một dòng văn bản có link, không phải nút to
   ngang hàng với nút "Đăng nhập". */
.zc-auth-signup {
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--zc-muted);
  text-align: center;
}

.zc-auth-signup-link {
  color: var(--zc-blue) !important;
  font-weight: 500;
  text-decoration: none !important;
}

/* Khối xem trước ở trang chủ: gradient gốc có 3 điểm dừng, điểm đầu dùng biến theo
   theme nhưng hai điểm sau hardcode màu tối (#141b2bbf, #0b1526a6). Ở light mode nền
   hoá tối trong khi chữ bên trong vẫn màu tối, đọc không ra. Trả lại màu sáng cho
   đúng theme. (Ảnh Unsplash trong gradient gốc bị CSP chặn — xem ghi chú ở lib/zenpn/html.ts.) */
[data-zenpn-mode="light"] .zc-product-preview {
  background-image: linear-gradient(120deg, var(--zc-bg) 0, #dde6f5 48%, #ccdaee 100%);
}

/* Logo trong trang sau đăng nhập chỉ là chữ ZenPn: baseline vẽ thêm ký tự ◇ bằng ::before. */
#sidebar .content-header > a::before { content: none; }
/* Logo sidebar nằm giữa (thẻ a là flex nên căn bằng justify-content); nút ✕ đóng sidebar (chỉ mobile) nằm tuyệt đối bên phải để
 * chữ ZenPn vẫn đúng tâm. */
#sidebar .content-header {
  position: relative;
  justify-content: center;
}
#sidebar .content-header > a {
  flex: 1;
  justify-content: center;
  text-align: center;
}
#sidebar .content-header > .d-lg-none {
  position: absolute;
  right: 16px;
}

/* Modal đồng bộ máy chủ: CSS gốc của V2Board đẩy chữ xuống 10px (padding-top) và icon
 * Font Awesome mang lề phải mr-2 nên lệch khỏi tâm ô vuông. */
[class*="oneClickSubscribe"] [class*="item"] > div:last-child { padding-top: 0; }
[class*="oneClickSubscribe"] [class*="item"] > div:first-child i { margin: 0; }
/* Huy hiệu chữ cho app thêm sau bản gốc, cùng cỡ với CX/H/S của stylesheet baseline. */
[class*="oneClickSubscribe"] .clash-verge-rev > div:first-child::before {
  content: "CV";
  font-size: 10px;
  font-weight: 750;
  letter-spacing: .1px;
}

/* Danh sách đơn hàng: bấm cả dòng mở chi tiết; nút Hủy có khung, đứng cách link. */
.zc-row-link { cursor: pointer; }
.zc-order-actions {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
/* CSS gốc đặt .btn { border: 0 } nên btn-outline-danger mất viền: đặt lại cho nút Hủy. */
.zc-order-cancel.btn {
  min-height: 30px;
  padding: 4px 12px;
  border: 1px solid #e5484d99;
  border-radius: 6px;
  background: #e5484d14;
  color: #e5484d;
  white-space: nowrap;
}
.zc-order-cancel.btn:hover:not(:disabled) {
  background: #e5484d29;
  color: #e5484d;
}
.zc-order-cancel.btn:disabled {
  opacity: .4;
  cursor: not-allowed;
}

/* Panel xem nhanh đơn hàng: luôn nằm trong DOM để còn thu lại khi đóng. */
.zc-order-quick {
  position: fixed;
  inset: 0;
  z-index: 1010;
  display: grid;
  place-items: center;
  padding: 16px;
  visibility: hidden;
  pointer-events: none;
}
.zc-order-quick[data-open] {
  visibility: visible;
  pointer-events: auto;
}
.zc-order-quick-mask {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .45);
}
.zc-order-quick-sheet {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: min(460px, 100%);
  max-height: calc(100vh - 32px);
  padding: 20px;
  overflow-y: auto;
  color: var(--zc-text);
  background: var(--zc-card, var(--zc-raised));
  border: 1px solid var(--zc-line);
  border-radius: 14px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .35);
  outline: none;
}
.zc-order-quick-head {
  display: flex;
  align-items: center;
  gap: 6px;
}
.zc-order-quick-head h3 {
  flex: 1;
  margin: 0;
  font-size: 18px;
  color: var(--zc-heading, inherit);
}
.zc-order-quick-step,
.zc-order-quick-close {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--zc-line);
  border-radius: 8px;
  color: inherit;
  background: transparent;
  cursor: pointer;
}
.zc-order-quick-step:hover:not(:disabled),
.zc-order-quick-close:hover { background: var(--zc-hover, rgba(127, 127, 127, .12)); }
.zc-order-quick-step:disabled { opacity: .35; cursor: not-allowed; }
.zc-order-quick-info { margin: 0; }
.zc-order-quick-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 0;
  border-bottom: 1px solid var(--zc-line);
}
.zc-order-quick-row dt {
  font-weight: 400;
  color: var(--zc-muted, inherit);
}
.zc-order-quick-row dd {
  margin: 0;
  text-align: right;
  word-break: break-all;
}
.zc-order-quick-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
.zc-order-quick-actions .btn { min-height: 38px; padding: 6px 16px; }

/* Trang chi tiết đơn: nút về danh sách đơn hàng. */
.zc-order-back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 12px;
  padding: 6px 12px;
  border: 1px solid var(--zc-line);
  border-radius: 8px;
  color: inherit;
  background: transparent;
  cursor: pointer;
}
.zc-order-back:hover { background: var(--zc-hover, rgba(127, 127, 127, .12)); }

/* Header: các nút canh theo baseline nên nút tên (chữ + icon) lệch khỏi nút chỉ có icon. */
#page-header .content-header > div:last-child {
  display: flex;
  align-items: center;
}
#page-header .dropdown > .btn {
  display: inline-flex;
  align-items: center;
  height: 36px;
}

/* Thông báo dashboard: dải một hàng đứng yên trên cùng + nút Xem tất cả; modal danh sách.
 * Màu lấy theo theme; chỉ thông báo có ảnh nền mới phủ lớp tối và dùng chữ trắng. */
.zc-notice-row { margin-bottom: 16px; }
.zc-notice {
  overflow: hidden;
  border: 1px solid var(--zc-line);
  border-radius: 12px;
  background: var(--zc-card, var(--zc-raised));
  background-position: center;
  background-size: cover;
}
.zc-notice .zc-notice-body {
  display: flex;
  align-items: center;
  gap: 12px;
}
.zc-notice-image .zc-notice-body { background: rgba(0, 0, 0, .55); }
.zc-notice-main {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 1;
  min-width: 0;
  padding: 14px 18px;
  border: 0;
  color: var(--zc-text);
  background: none;
  text-align: left;
  cursor: pointer;
}
.zc-notice-image :is(.zc-notice-main, .zc-notice-all) { color: #fff; }
.zc-notice .badge { flex: none; }
.zc-notice-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.zc-notice-title {
  overflow: hidden;
  font-size: 15px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.zc-notice-preview {
  overflow: hidden;
  font-size: 13px;
  opacity: .7;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.zc-notice-date {
  flex: none;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  opacity: .6;
}
.zc-notice-arrow {
  flex: none;
  font-size: 20px;
  line-height: 1;
  opacity: .7;
}
.zc-notice-all {
  flex: none;
  margin-right: 14px;
  padding: 6px 12px;
  border: 1px solid var(--zc-line);
  border-radius: 8px;
  color: var(--zc-text);
  background: transparent;
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
}
.zc-notice-dots {
  display: flex;
  flex: none;
  gap: 6px;
}
.zc-notice-dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: currentColor;
  color: var(--zc-text);
  opacity: .25;
  cursor: pointer;
}
.zc-notice-dot[aria-current] { opacity: .85; transform: scale(1.25); }
.zc-notice-image .zc-notice-dot { color: #fff; }
.zc-notice-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.zc-notice-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--zc-line);
  border-radius: 10px;
  color: inherit;
  background: transparent;
  text-align: left;
  cursor: pointer;
}
.zc-notice-back {
  margin-bottom: 12px;
  padding: 0;
  border: 0;
  color: var(--zc-primary, #165dff);
  background: none;
  cursor: pointer;
}
@media (max-width: 575.98px) {
  .zc-notice-date,
  .zc-notice-dots { display: none; }
  .zc-notice-main { padding: 12px 14px; gap: 10px; }
  .zc-notice-all { margin-right: 10px; padding: 6px 10px; }
}

/* Trang Quản lý thiết bị (khách): portal dùng bộ màu riêng ngả xanh ngọc, trỏ về token của site. */
#zenpn-device-portal.zdp-page {
  --zdp-bg: transparent;
  --zdp-card: var(--zc-card, var(--zc-raised));
  --zdp-soft: var(--zc-card, var(--zc-raised));
  --zdp-text: var(--zc-text);
  --zdp-muted: var(--zc-muted);
  --zdp-line: var(--zc-line);
  --zdp-accent: var(--zc-primary, #165dff);
  --zdp-ink-accent: var(--zc-primary, #165dff);
  max-width: none;
}
#zenpn-device-portal.zdp-page .zc-page-metrics { margin: 0 0 18px; }

/* Dòng copyright canh giữa ở đáy mọi trang. #page-footer của Dashmix tự lùi theo sidebar
 * bằng padding-left nên ở đây chỉ đặt padding trên/dưới. */
.zc-copyright {
  margin: 0;
  padding-top: 16px;
  padding-bottom: 16px;
  color: var(--zc-muted, #8a94a6);
  font-size: 12px;
  text-align: center;
}
#page-footer.zc-copyright {
  justify-content: center;
  min-height: 0;
}
:is(.zc-auth-page, .zc-auth-secondary) { position: relative; }
:is(.zc-auth-page, .zc-auth-secondary) > .zc-copyright {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
}

/* Ô chọn tự dựng (ZenpnCloud.select, dùng ở khối SNI trang tài khoản): nút trông như ô nhập,
 * danh sách thả ngay dưới, cùng màu card. Hiệu ứng mở/thu lại nằm ở motion.css. */
.zc-select { position: relative; }
.zc-select-button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  text-align: left;
  cursor: pointer;
}
.zc-select-button::after {
  content: "";
  flex-shrink: 0;
  border-top: 6px solid currentColor;
  border-right: 5px solid transparent;
  border-left: 5px solid transparent;
  opacity: .6;
}
.zc-select-placeholder { color: var(--zc-muted); }
.zc-select-list {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 30;
  max-height: 280px;
  margin: 0;
  padding: 6px;
  overflow-y: auto;
  list-style: none;
  text-align: left;
  background: var(--zc-card, var(--zc-raised));
  border: 1px solid var(--zc-line);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .28);
}
.zc-select-option {
  padding: 8px 12px;
  border-radius: 6px;
  color: var(--zc-text);
  cursor: pointer;
  outline: none;
}
.zc-select-option:hover,
.zc-select-option:focus { background: var(--zc-hover); }
.zc-select-option[aria-selected="true"] { color: var(--zc-blue); font-weight: 600; }

/* Trang auth: nút theme + nút ngôn ngữ xếp cạnh nhau trên topbar. Topbar gom vào khung 80% ở
 * giữa thay vì dạt ra hai mép; mobile giữ lề của baseline. */
.zc-auth-tools {
  display: flex;
  align-items: center;
  gap: 8px;
}
.zc-auth-tools .zc-lang-toggle { margin: 0; }
@media (min-width: 601px) {
  .zc-auth-topbar { left: 10% !important; right: 10% !important; }
}

/* Nút tài khoản trên header: avatar tròn (icon người SVG) + phần trước @ của email + mũi tên. */
#page-header .zc-account { gap: 8px; }
.zc-account-avatar {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  color: var(--zc-blue);
  background: color-mix(in srgb, var(--zc-blue) 16%, transparent);
}
.zc-account-avatar svg { display: block; }
#page-header .zc-account .fa-angle-down { margin-left: 0 !important; }

/* Trang tài khoản: dấu ◇ trước tiêu đề khối là ký tự chữ, lấy từ font dự phòng nên theo baseline
 * của font đó và tụt thấp hơn chữ. Vẽ lại bằng CSS (ô vuông xoay 45°), canh giữa theo dòng. */
.zc-page-profile .block-header .block-title {
  display: flex;
  align-items: center;
}
.zc-page-profile .block-header .block-title::before {
  content: "";
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  margin-right: 12px;
  border: 1.5px solid var(--zc-blue);
  border-radius: 1px;
  transform: rotate(45deg);
}

.custom-html-style,
.custom-html-style blockquote { color: var(--zc-text); }
.custom-html-style pre,
.custom-html-style code { background-color: var(--zc-raised); }

/* Đăng nhập Telegram qua app (public/zenpn/oauth.js): hộp chờ bấm Bắt đầu trong bot. */
.zc-tg-overlay {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(8, 12, 20, .55);
  animation: zc-tg-fade .2s ease both;
}
.zc-tg-overlay.is-closing { animation: zc-tg-fade-out .2s ease forwards; }
.zc-tg-card {
  width: 100%;
  max-width: 380px;
  padding: 24px;
  color: var(--zc-text);
  text-align: center;
  background: var(--zc-card);
  border: 1px solid var(--zc-line);
  border-radius: 14px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, .35);
  animation: zc-tg-rise .25s cubic-bezier(.2, .8, .2, 1) both;
}
.zc-tg-overlay.is-closing .zc-tg-card { animation: zc-tg-sink .2s ease forwards; }
.zc-tg-title { margin: 0 0 8px; color: var(--zc-heading); font-size: 18px; font-weight: 700; }
.zc-tg-body { margin: 0 0 16px; color: var(--zc-muted); font-size: 14px; line-height: 1.55; }
.zc-tg-open {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  color: #fff !important;
  font-weight: 600;
  text-decoration: none !important;
  background: #2aabee;
  border-radius: 10px;
  transition: filter .2s, transform .12s;
}
.zc-tg-open:hover { filter: brightness(1.08); }
.zc-tg-open:active { transform: scale(.98); }
.zc-tg-web { display: inline-block; margin-top: 10px; font-size: 13px; }
.zc-tg-status { margin: 16px 0 0; color: var(--zc-muted); font-size: 13.5px; transition: color .2s; }
.zc-tg-status.is-error { color: #e5484d; }
.zc-tg-warn { margin: 10px 0 0; color: var(--zc-muted); font-size: 12px; opacity: .85; }
.zc-tg-actions { display: flex; justify-content: center; gap: 10px; margin-top: 16px; }
.zc-tg-retry,
.zc-tg-cancel {
  min-width: 96px;
  padding: 8px 14px;
  color: var(--zc-text);
  font: inherit;
  font-size: 13px;
  background: var(--zc-raised);
  border: 1px solid var(--zc-line);
  border-radius: 8px;
  cursor: pointer;
  transition: background .2s;
}
.zc-tg-retry { color: #fff; background: #2aabee; border-color: #2aabee; }
.zc-tg-cancel:hover { background: var(--zc-hover, rgba(255, 255, 255, .06)); }
@keyframes zc-tg-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes zc-tg-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes zc-tg-rise { from { opacity: 0; transform: translateY(12px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes zc-tg-sink { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(8px) scale(.98); } }
@media (prefers-reduced-motion: reduce) {
  .zc-tg-overlay, .zc-tg-card { animation: none !important; }
}
