/* Biến bổ sung không có sẵn trong landing.css (--red/--bg/--card/--border/--text/
   --hidden đã có từ đó, link cùng trang) - giữ đồng bộ với admin/style.css nếu đổi
   màu thương hiệu. */
:root {
  --ok: #2e7d32;
  --warn-bg: #FFF6E5;
  --warn-border: #FFC94A;
}

.portal-header {
  background: var(--red);
  color: #fff;
  padding: 8px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.portal-header-right { display: flex; align-items: center; gap: 14px; font-size: 10.5pt; }

.portal-main { max-width: 1300px; margin: 0 auto; padding: 32px 28px 60px; width: 100%; }

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px;
  margin-bottom: 20px;
}
.card h2 { margin-top: 0; font-size: 14.5pt; color: var(--red); }

/* Sidebar dọc - copy nguyên từ admin/style.css .settings-nav để đồng nhất trải
   nghiệm giữa /admin và /portal (2 static root riêng, không link chéo CSS). */
.settings-layout { display: flex; gap: 24px; align-items: flex-start; }
.settings-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 240px;
  flex-shrink: 0;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px;
}
.settings-nav button {
  text-align: left;
  border: none;
  background: transparent;
  padding: 12px 14px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 11pt;
  color: var(--text);
  border-left: 3px solid transparent;
}
.settings-nav button:hover { background: var(--bg); }
.settings-nav button.active { background: var(--warn-bg); color: var(--red); font-weight: 700; border-left-color: var(--red); }
.settings-content { flex: 1; min-width: 0; }

/* Biến thể NGANG (2026-08-29, phản hồi "các tab dọc theo ảnh tôi gửi chuyển thành tab menu
   ngang") - dùng cho nav Tầng 1 của trang tài khoản (Đơn hàng của tôi/Kích hoạt.../Tạo
   video/...), tái dùng NGUYÊN style nút/active/hover ở trên, chỉ đổi hướng xếp. portal.js
   không có handler generic theo class (chỉ dùng "[data-account-tab]"), nên an toàn thêm
   modifier NGAY trên class ".settings-nav" gốc, không cần tách class riêng như bên admin. */
.settings-nav.horizontal { flex-direction: row; flex-wrap: wrap; width: auto; }
.settings-nav.horizontal button { text-align: center; border-left: none; border-bottom: 3px solid transparent; }
.settings-nav.horizontal button.active { border-left-color: transparent; border-bottom-color: var(--red); }
/* Menu chính portal "bám sát" đúng style thanh nav phẳng của admin (2026-08-29, phản hồi kèm
   ảnh chụp thanh nav admin "cho đẹp và gọn"; 2026-09-03, chủ dự án nhắc lại rõ hơn: "làm như
   menu admin... nền trắng bám sát bên trên" - trước đó nav vẫn NẰM TRONG <main> có padding
   32px nên chưa thật sự "bám sát" header như admin) - ".portal-topnav" (index.html, con TRỰC
   TIẾP #account-app, NGAY SAU header, KHÔNG còn trong .portal-main) đảm nhận nền trắng+viền
   dưới mảnh+padding ngang - copy Y HỆT `nav` ở admin/style.css dòng ~44-56 (2 nơi khác file
   CSS, không link chéo được, nên phải chép giá trị tay). ".settings-nav.top-nav-flat" bên
   trong CHỈ còn lo phần nút (không tự có nền/viền/padding riêng nữa, tránh trùng lặp). */
.portal-topnav { background: var(--card); border-bottom: 2px solid var(--border); padding: 10px 24px 0; }
/* Menu chính ít mục, không cần full khổ (2026-09-03, chủ dự án gửi ảnh: "menu chính này...
   nó ít nên cho vào trong khổ trong ko full hết thì đẹp hơn") - khớp ĐÚNG max-width của
   ".portal-main" (1300px) để hàng nút không bị kéo dài hết cỡ màn hình rộng, nền trắng/viền
   dưới của ".portal-topnav" (cha) vẫn full-bleed sát mép như cũ, chỉ NỘI DUNG bên trong co lại
   + căn giữa. */
.settings-nav.top-nav-flat { background: transparent; border: none; border-radius: 0; padding: 0; gap: 4px; max-width: 1300px; margin: 0 auto; }
.settings-nav.top-nav-flat button { padding: 10px 16px; border-radius: 0; }
.settings-nav.top-nav-flat button:hover { background: transparent; }

/* "Còn X ngày"/"Chi phí AI" lên hàng menu chính, bên phải (2026-09-03, chủ dự án: "cho 2 mục
   này lên bên phải menu Đăng đa kênh/Tạo video/Tin tức Gatiki/Tài khoản") - trước đó 2 widget
   này CHỈ hiện trong nội dung tab "Tạo video" (mất khi qua tab khác) - giờ đặt NGAY trong
   ".settings-nav.top-nav-flat" (đã display:flex sẵn) rồi đẩy sang phải bằng margin-left:auto,
   nên LUÔN hiện ở mọi tab (loadEntitlement()/loadAiCostWidget() vốn đã gọi ở init() TOÀN
   TRANG, không cần đổi gì thêm ngoài thêm 2 id đích vào mảng target trong portal.js). Tái
   dùng NGUYÊN class .plan-expiry-widget/.ai-cost-widget (không tạo biến thể riêng). */
/* align-items: stretch (2026-09-03, chủ dự án: "cho mục gia hạn ô khung to bằng mục chi phí")
   - trước đó "center" khiến khung "Còn X ngày" (1 dòng chữ) THẤP hơn khung "Chi phí AI" (2
   dòng: số tiền + dòng ước tính USD) trông lệch nhau - "stretch" ép cả 2 khung cao BẰNG NHAU
   theo khung cao nhất, không cần biết trước chiều cao cụ thể. */
/* margin: 6px 0 (2026-09-03, chủ dự án gửi ảnh: "vẫn bám sát dưới trên trắng rộng kìa" - "align-
   self: center" thử trước đó KHÔNG đủ vì khối widget CHÍNH LÀ thứ cao nhất trong hàng nav (cao
   hơn cả nút tab), nên nó tự quyết định luôn chiều cao cả hàng - "center" vào 1 khoảng trống
   không hề tồn tại thì vô nghĩa, vẫn chạm sát y hệt. Cách đúng: cho khối widget margin-top/
   bottom THẬT (6px mỗi bên) - khi đó khối widget (tính cả margin) mới là phần "cao nhất", ép
   HÀNG NGOÀI tự giãn thêm ra để chứa đúng margin đó, tạo khoảng hở thật trên/dưới quanh khung
   widget so với mép trên (dưới nút tab) lẫn viền dưới thanh nav. KHÔNG đụng "align-items:
   stretch" bên trong (vẫn giữ 2 khung "Còn X ngày"/"Chi phí AI" cao bằng NHAU). */
.ov-nav-widgets { display: flex; gap: 8px; align-items: stretch; align-self: center; margin: 6px 0 6px auto; }
.ov-nav-widgets .plan-expiry-widget, .ov-nav-widgets .ai-cost-widget { padding: 6px 10px; justify-content: center; }
.settings-nav.top-nav-flat button.active { background: transparent; }

table { width: 100%; border-collapse: collapse; font-size: 11pt; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); white-space: nowrap; }
th { color: var(--red); }
/* overflow-x:auto một mình đủ để cuộn, nhưng trên Windows/Chrome mặc định là "overlay
   scrollbar" ẩn khi không hover - khách báo "mất thanh trượt ngang để xem" (bảng bị cắt
   cột cuối) vì tưởng không cuộn được. Ép hiện thanh cuộn rõ ràng luôn thay vì ẩn. */
.table-scroll { overflow-x: auto; scrollbar-width: thin; }
.table-scroll table { min-width: 560px; }
.table-scroll::-webkit-scrollbar { height: 10px; }
.table-scroll::-webkit-scrollbar-track { background: var(--bg, #f3f3f3); border-radius: 6px; }
.table-scroll::-webkit-scrollbar-thumb { background: var(--border, #ccc); border-radius: 6px; }
.table-scroll::-webkit-scrollbar-thumb:hover { background: var(--red); }
/* Bảng "Danh sách job video động lực" - cột chủ đề/lỗi dài cần xuống dòng thay vì tràn
   ngang (mặc định th/td ở trên là white-space:nowrap). */
.ov-jobs-table td.ov-wrap-cell { white-space: normal; overflow-wrap: anywhere; }

/* Thanh % tiến trình THẬT (2026-08-29) - copy nguyên văn từ admin/style.css để đồng bộ. */
.ov-progress-track { background: var(--bg); border: 1px solid var(--border); border-radius: 6px; height: 14px; width: 100%; min-width: 100px; overflow: hidden; }
.ov-progress-fill { height: 100%; background: linear-gradient(90deg, var(--btn-gold-top), var(--btn-gold-bottom)); transition: width 0.4s ease; }
.ov-progress-label { font-size: 8.5pt; color: #888; margin-top: 2px; }

/* "📋 Bài đăng" video động lực - cùng bộ class với admin/style.css (xem chú thích đầy đủ ở
   đó), 1 job = 1 hàng flexbox gọn gàng thay vì bảng nhiều cột phải cuộn ngang. */
.motivation-post-list { display: flex; flex-direction: column; gap: 10px; }
/* Mỗi bài GỌN trong ĐÚNG 1 hàng, không vỡ dòng dù tiêu đề dài (2026-09-03, xem chú thích đầy
   đủ ở admin/style.css) - tiêu đề CẮT 1 dòng ellipsis, các cột trạng thái/kênh/giờ thu hẹp. */
.motivation-post-row { display: flex; align-items: center; gap: 12px; padding: 10px 14px; border: 1px solid var(--border); border-radius: 10px; background: var(--card); flex-wrap: wrap; }
.motivation-post-idx { font-weight: 700; color: #aaa; min-width: 20px; flex-shrink: 0; font-size: 9.5pt; }
.motivation-post-title { flex: 1 1 0%; min-width: 0; overflow: hidden; }
.motivation-post-title-main { display: flex; align-items: center; gap: 6px; min-width: 0; }
.motivation-post-title-main b { flex: 1 1 auto; min-width: 0; font-size: 10pt; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.motivation-post-title-main button { flex: 0 0 auto; }
.motivation-post-title pre, .motivation-post-title > div { display: block; width: 100%; }
.motivation-post-status { flex: 0 0 96px; min-width: 0; font-size: 8.5pt; }
.motivation-post-channels { flex: 0 0 90px; min-width: 0; font-size: 8.5pt; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.motivation-post-time { flex: 0 0 78px; min-width: 0; font-size: 8pt; color: #666; white-space: nowrap; }
/* Hàng ngang thay vì xếp dọc (2026-09-03, xem chú thích đầy đủ ở admin/style.css - CHUNG 1
   rule cho MỌI bảng Bài đăng dùng class này, cả "Tạo video" lẫn "📰 Video tin tức"). */
.motivation-post-actions { flex: 0 0 auto; display: flex; flex-direction: row; flex-wrap: wrap; gap: 6px; margin-left: auto; }

label { font-size: 10.5pt; color: #555; display: block; margin-bottom: 2px; }
input, select, textarea {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 11.5pt;
  margin-bottom: 12px;
  font-family: inherit;
}

button.primary {
  background: linear-gradient(180deg, var(--btn-red-top), var(--btn-red-bottom));
  color: #fff;
  border: none;
  padding: 12px 22px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 11.5pt;
  font-weight: 600;
}
button.primary:hover { background: linear-gradient(180deg, var(--btn-red-bottom), var(--btn-red-top)); }
button.secondary {
  background: #fff;
  color: var(--red);
  border: 1px solid var(--red);
  padding: 11px 18px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 11.5pt;
}

/* Hàng menu PHẲNG "🎬 Tạo thủ công/🤖 Tạo tự động/🎵 Tạo video nhạc/📰 Video tin tức/⚙️ Cài
   đặt" (2026-09-03, xem chú thích đầy đủ ở admin/style.css - CÙNG lý do: chủ dự án thích kiểu
   nút viên tròn viền đỏ tách rời hơn kiểu pill dán sát trong khung). Scope RIÊNG
   ".ov-flow-toggle-row button.active" (không phải "button.secondary.active" trần trụi) để
   không ảnh hưởng nút .secondary khác dùng "active" cho việc khác nơi khác trong trang. */
.ov-flow-toggle-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.ov-flow-toggle-row button.active { background: var(--warn-bg); font-weight: 700; }
button.google {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: #fff;
  color: #3c4043;
  border: 1px solid #dadce0;
  padding: 10px 18px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 11pt;
  font-weight: 500;
  width: 100%;
  margin-bottom: 10px;
}
button.google svg { flex-shrink: 0; }
button.google:hover { background: #f7f8f8; box-shadow: 0 1px 2px rgba(0,0,0,0.08); }
.btn-block { display: block; width: 100%; box-sizing: border-box; text-align: center; }

.msg {
  padding: 10px 14px;
  border-radius: 8px;
  margin: 0 0 14px;
  font-size: 10pt;
  line-height: 1.5;
  border: 1px solid transparent;
}
.msg.ok { background: #E9F7EC; color: var(--ok); border-color: #bfe3c6; }
.msg.error { background: #FDECEC; color: #a53737; border-color: #f3c6c6; }

.badge { display: inline-block; padding: 2px 10px; border-radius: 20px; font-size: 10pt; font-weight: 700; }
.badge.paid { background: #E9F7EC; color: var(--ok); border: 1px solid var(--ok); }
.badge.pending { background: var(--warn-bg); color: #8a6d00; border: 1px solid var(--warn-border); }

/* Khối đăng nhập/đăng ký khi CHƯA đăng nhập - căn giữa như admin #login-screen. */
/* Header đứng riêng, tự nhiên trên cùng trang (không nằm trong khối căn giữa dọc) -
   #auth-app-body mới là phần căn giữa, có khoảng cách rõ ràng với header phía trên
   thay vì dính sát nhìn rối như trước. */
#auth-app { display: block; }
#auth-app-body {
  min-height: 72vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 56px 20px 40px;
}
.auth-card { background: var(--card); border: 1px solid var(--border); border-radius: 14px; padding: 28px; width: 380px; max-width: 92vw; }
.auth-tabs {
  display: flex;
  gap: 3px;
  margin-bottom: 20px;
  background: var(--bg);
  border-radius: 10px;
  padding: 4px;
}
.auth-tabs button {
  flex: 1;
  border: none;
  background: transparent;
  padding: 9px 4px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 10.5pt;
  color: #8a7a6a;
  font-weight: 600;
}
.auth-tabs button.active { background: var(--card); color: var(--red); box-shadow: 0 1px 3px rgba(42, 26, 26, 0.12); }
.auth-link { font-size: 10pt; text-align: center; margin-top: 4px; }
.auth-link a { color: var(--red); cursor: pointer; text-decoration: underline; }


/* Đèn trạng thái xanh/vàng/đỏ cạnh tên tab con - xanh = đã kết nối/cấu hình xong,
   vàng = chưa cấu hình (bình thường, không phải lỗi), đỏ = có lỗi thật cần chú ý. */
.status-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #ccc;
  flex-shrink: 0;
}
.status-dot.status-green { background: var(--ok); }
.status-dot.status-yellow { background: var(--warn-border); }
.status-dot.status-red { background: #d32f2f; }

.quick-datetime-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.quick-dt-btn {
  padding: 7px 14px !important; font-size: 9.8pt !important;
  background: linear-gradient(180deg, var(--btn-orange-top), var(--btn-orange-bottom)) !important;
  color: #fff !important; border: none !important;
}
.quick-dt-btn:hover { background: linear-gradient(180deg, var(--btn-orange-bottom), var(--btn-orange-top)) !important; }

/* Hành động huỷ/ngắt kết nối (Ngắt kết nối kênh, Huỷ lịch đăng) - đồng bộ đúng tông
   cam-đỏ đã dùng bên app desktop cho cùng 2 hành động này, thay vì nút viền đỏ
   nhạt "secondary" chung chung. */
.btn-danger {
  background: linear-gradient(180deg, var(--btn-orange-top), var(--btn-orange-bottom)) !important;
  color: #fff !important; border: none !important;
}
.btn-danger:hover { background: linear-gradient(180deg, var(--btn-orange-bottom), var(--btn-orange-top)) !important; }

/* Nút bật/tắt "🤖 Đăng bài tự động" TỰ ĐỔI màu+chữ theo đúng trạng thái ĐANG LƯU trên server
   (2026-09-08, chủ dự án: "nút tạm dừng nên thay đổi khi chạy thì hiện xanh và ghi đang chạy,
   còn khi tắt thì màu đỏ và ghi đang tắt") - vừa là nút bấm (bấm để đảo trạng thái) vừa là chỉ
   báo trạng thái luôn, khỏi cần dòng chữ trạng thái tách riêng. class .is-on/.is-off toggle
   bằng JS (renderAutopostToggle() trong portal.js), không dùng switch-row/ios-switch có sẵn vì
   component đó có nhãn CỐ ĐỊNH "BẬT/TẮT" - ở đây cần đúng chữ "Đang chạy"/"Đang tắt" theo yêu cầu. */
.autopost-toggle-btn { border: none; border-radius: 8px; padding: 12px 22px; font-size: 11.5pt; font-weight: 600; color: #fff; cursor: pointer; }
.autopost-toggle-btn.is-on { background: var(--ok); }
.autopost-toggle-btn.is-on:hover { background: #256428; }
.autopost-toggle-btn.is-off { background: #d32f2f; }
.autopost-toggle-btn.is-off:hover { background: #b71c1c; }

/* Công tắc gạt BẬT/TẮT "🤖 AI TỰ LÀM" (mục "🔥 Video động lực") - copy NGUYÊN VĂN từ
   admin/style.css để hành vi kéo/bấm giống hệt (xem portal.js cho JS điều khiển). */
.switch-row { display: inline-flex; align-items: center; gap: 8px; margin: 4px 0 10px; user-select: none; }
.switch-row .switch-label { font-size: 10pt; font-weight: 700; color: #bbb; transition: color 0.2s; cursor: pointer; }
.switch-row .switch-label.off { color: #A02424; }
.switch-row.checked .switch-label.off { color: #bbb; }
.switch-row .switch-label.on { color: #bbb; }
.switch-row.checked .switch-label.on { color: var(--ok); }
.ios-switch { position: relative; width: 46px; height: 24px; background: #A02424; border-radius: 24px; transition: background 0.25s; flex-shrink: 0; cursor: grab; touch-action: none; }
.ios-switch.dragging { cursor: grabbing; }
.switch-row.checked .ios-switch { background: var(--ok); }
.ios-switch-knob { position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; background: #fff; border-radius: 50%; transition: transform 0.25s; box-shadow: 0 1px 3px rgba(0,0,0,.35); pointer-events: none; }
.switch-row.checked .ios-switch-knob { transform: translateX(22px); }
.ios-switch.dragging .ios-switch-knob { transition: none; box-shadow: 0 2px 6px rgba(0,0,0,.5); }

/* "📰 Tin tức Gatiki" (2026-08-30, đổi dạng bảng email + popup xem nội dung 2026-09-03,
   chủ dự án: "cho danh sách dạng bảng email, khi bấm vào thì hiện popup to rộng ra xem nội
   dung bên trong... có phải gọn không") - bảng 1 dòng/tin (tái dùng "table"/".table-scroll"
   chung), bấm vào 1 dòng mở popup ".ai-cost-box" có sẵn (xem "#news-detail-modal" ở dưới).
   Badge số chưa đọc cạnh tên tab lớn - hiện NGAY LÚC ĐĂNG NHẬP (loadNewsTab() gọi sớm
   trong showAccountApp(), không đợi khách bấm vào tab) để khách luôn thấy có tin mới. */
.news-unread-badge {
  display: inline-block;
  background: var(--red);
  color: #fff;
  font-size: 8pt;
  font-weight: 700;
  min-width: 16px;
  height: 16px;
  line-height: 16px;
  text-align: center;
  border-radius: 8px;
  padding: 0 4px;
  margin-left: 4px;
  vertical-align: middle;
}
.news-row { cursor: pointer; }
.news-row:hover { background: var(--bg); }
.news-row-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--red); visibility: hidden; }
.news-row.unread .news-row-dot { visibility: visible; }
.news-row-subject { white-space: normal; overflow-wrap: anywhere; }
.news-row.unread .news-row-subject { font-weight: 700; }
.news-item-html { font-size: 10.5pt; line-height: 1.6; overflow-wrap: anywhere; margin-top: 10px; }
.news-item-html img { max-width: 100%; }

/* Hạn dùng gói (2026-08-30, "1 mục hạn sử dụng lúc nào cũng hiện... để khách thấy liên
   tục") - đặt NGAY DƯỚI menu dọc của "Đăng đa kênh"/"Tạo video" (xem .settings-nav-col
   bọc quanh .settings-nav + widget này trong index.html) chứ không phải cột riêng, nên
   .settings-nav-col chỉ cần flex-column, KHÔNG set width (đã ăn theo width 240px cố định
   của .settings-nav bên trong). 3 màu trạng thái tái dùng biến có sẵn: xanh=còn nhiều
   ngày, vàng=sắp hết hạn (≤3 ngày), đỏ=đã hết hạn - xem renderEntitlementWidget() portal.js. */
.settings-nav-col { display: flex; flex-direction: column; gap: 10px; flex-shrink: 0; }
.plan-expiry-widget {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  font-size: 9pt;
  line-height: 1.4;
  padding: 10px 12px;
  border-radius: 8px;
  text-align: center;
  background: var(--card);
  border: 1px solid var(--border);
}
.plan-expiry-text { overflow-wrap: anywhere; }
.plan-expiry-widget.status-active, .plan-expiry-widget.status-lifetime { color: var(--ok); border-color: var(--ok); }
.plan-expiry-widget.status-expiring_soon { color: #8a6d00; background: var(--warn-bg); border-color: var(--warn-border); }
.plan-expiry-widget.status-expired, .plan-expiry-widget.status-none { color: var(--red); background: #FDECEC; border-color: #f3c6c6; }
/* Nút gia hạn xuống dòng riêng, thu gọn thành pill đặc màu trạng thái thay vì link
   gạch chân nối inline - gọn và dễ bấm hơn trong cột hẹp. */
.plan-expiry-renew-btn {
  display: inline-block;
  padding: 3px 12px;
  border-radius: 999px;
  font-size: 8.5pt;
  font-weight: 700;
  text-decoration: none;
  color: #fff !important;
  background: var(--red);
  white-space: nowrap;
}
.plan-expiry-renew-btn:hover { opacity: 0.88; }
.plan-expiry-widget.status-expiring_soon .plan-expiry-renew-btn { background: #8a6d00; }

/* "💰 Chi phí AI" (2026-09-03) - khung nhỏ NGAY DƯỚI hạn dùng gói, cùng cột .settings-nav-col
   nên dùng chung style khung với .plan-expiry-widget nhưng KHÔNG đổi màu theo trạng thái (đây
   chỉ là thông tin tham khảo, không phải cảnh báo) - bấm được (cursor pointer) để mở popup chi
   tiết, xem loadAiCostWidget()/openAiCostModal() trong portal.js. */
.ai-cost-widget {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  font-size: 9pt;
  line-height: 1.4;
  padding: 10px 12px;
  border-radius: 8px;
  text-align: center;
  background: var(--card);
  border: 1px solid var(--border);
  cursor: pointer;
}
.ai-cost-widget:hover { border-color: var(--red); }
.ai-cost-widget:empty { display: none; } /* chưa tải xong/lỗi - ẩn hẳn thay vì chừa khung trống */
.ai-cost-text { overflow-wrap: anywhere; }
.ai-cost-sub { font-size: 8pt; color: #888; }

/* Popup chi tiết - tái dùng khung .plan-lock-box/card nhưng RỘNG HƠN (bảng nhiều cột) và có
   nút đóng × (KHÁC plan-lock-modal - đây chỉ xem thông tin, không khoá gì nên phải đóng được).
   Selector GHÉP ".plan-lock-box.ai-cost-box" (không chỉ ".ai-cost-box" đơn) - bắt buộc vì
   ".plan-lock-box{width:440px}" định nghĩa SAU trong file này (mục "Modal khóa toàn trang"
   bên dưới), cùng độ đặc hiệu (1 class) nên "width" của nó THẮNG theo thứ tự sau-đè-trước,
   khiến popup bị kẹt ở khổ 440px dù đã set 720px (bug thật, chủ dự án báo "khổ khung...bé
   quá" 2026-09-03) - ghép thêm class nâng độ đặc hiệu lên 2 để LUÔN thắng bất kể thứ tự. */
.plan-lock-box.ai-cost-box { width: 960px; max-width: 96vw; position: relative; }
.ai-cost-desc { font-size: 11pt; color: #888; margin-top: -6px; }
.ai-cost-modal-close {
  position: absolute;
  top: 14px;
  right: 16px;
  border: none;
  background: none;
  font-size: 24pt;
  line-height: 1;
  color: #999;
  cursor: pointer;
  padding: 0;
}
.ai-cost-modal-close:hover { color: var(--red); }
.ai-cost-filter-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 14px 0; font-size: 11pt; }
.ai-cost-filter-row select { font-size: 11pt; padding: 6px 8px; }
.ai-cost-custom-range { display: flex; align-items: center; gap: 6px; }
.ai-cost-custom-range input[type="date"] { padding: 6px 8px; font-size: 11pt; }
.ai-cost-detail-summary { font-size: 13pt; margin: 4px 0 14px; }
.ai-cost-box table { font-size: 12.5pt; }
.ai-cost-note { font-size: 10pt; color: #999; margin-top: 12px; }

/* Modal khóa toàn trang khi hết hạn (2026-08-30) - overlay che kín, giữa màn hình, không
   bo theo .settings-layout/.portal-main (đặt NGOÀI <main>, con trực tiếp của #account-app)
   để không bị ảnh hưởng bởi max-width/padding của trang. */
.plan-lock-overlay {
  position: fixed;
  inset: 0;
  background: rgba(42, 26, 26, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
}
.plan-lock-box { width: 440px; max-width: 100%; max-height: 88vh; overflow-y: auto; }
.plan-lock-box h2 { margin-top: 0; color: var(--red); }
.plan-lock-plans { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.plan-lock-plan-btn {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  cursor: pointer;
  font-size: 10.5pt;
  text-align: left;
}
.plan-lock-plan-btn:hover { border-color: var(--red); }
.plan-lock-plan-btn b { color: var(--red); }

@media (max-width: 700px) {
  .portal-main { padding: 16px; }
  .settings-layout { flex-direction: column; }
  .settings-nav { width: 100%; flex-direction: row; flex-wrap: wrap; }
  .settings-nav-col { width: 100%; }
}

/* ================================================================
   LỚP TINH CHỈNH GIAO DIỆN (2026-09-08) - cảm hứng từ dashboard LadiPage
   (app.ladipage.com, ảnh chụp chủ dự án gửi): card có độ nổi (shadow) thay vì
   chỉ viền phẳng, header/topnav có chiều sâu nhẹ, bảng/nút/ô nhập mượt hơn khi
   hover/focus. CHỦ Ý đặt thành 1 khối RIÊNG ở cuối file thay vì sửa rải rác các
   rule cũ - vì các rule cũ mang rất nhiều lịch sử quyết định pixel-level đã chốt
   với chủ dự án (đọc comment phía trên biết rõ lý do từng dòng); ghi đè cùng
   selector ở ĐÂY (sau trong file, cùng độ đặc hiệu = luôn thắng) VẪN NGUYÊN VẸN
   toàn bộ lịch sử đó, không xoá/sửa 1 dòng nào ở trên - CHỈ layer thêm phần nhìn
   (shadow/transition/màu bảng), KHÔNG đổi bố cục/kích thước/hành vi JS phụ thuộc
   vào các rule cũ (width/display/flex-direction giữ nguyên 100%). Không đổi màu
   thương hiệu (--red/--gold/--bg) - đó là bản sắc riêng, LadiPage dùng tông
   tím/xanh nhưng đó không phải điều chủ dự án khen, mà là bố cục sạch/độ nổi/
   khoảng trắng thoáng - nên chỉ mượn đúng phần đó. */
:root {
  /* Bóng đậm hơn bản đầu (2026-09-08, chủ dự án: "không thấy thay đổi gì cả" - bản
     đầu quá nhẹ, khó thấy khác biệt trên nền --bg gần trắng) - tăng rõ độ mờ/độ lan
     để card "nổi" thấy ngay không cần nhìn kỹ. Giữ đồng bộ giá trị với landing.css/
     admin/style.css. */
  --shadow-sm: 0 2px 8px rgba(42, 26, 26, 0.11), 0 1px 3px rgba(42, 26, 26, 0.07);
  --shadow-md: 0 10px 28px rgba(42, 26, 26, 0.15);
  --shadow-lg: 0 20px 50px rgba(42, 26, 26, 0.22);
}

/* Card bo tròn hơn (10px -> 14px) + rộng rãi hơn (padding 20px -> 24px) - đúng
   kiểu "thoáng, ít góc cạnh" của LadiPage thay vì bo nhẹ/chật như bản gốc. */
.card { border-radius: 14px; padding: 24px; }

/* Card: từ viền phẳng -> có độ nổi nhẹ (giống card trắng nổi trên nền xám nhạt
   của LadiPage) - vẫn giữ viền mảnh sẵn có để không "trôi" trên nền --bg gần
   trắng, shadow chỉ thêm chiều sâu chứ không thay thế viền. (.lp-feature/
   .lp-faq-item/.lp-plan-card không lặp lại ở đây nữa - đã chuyển sang
   landing.css, file GỐC định nghĩa các class đó, portal.css chỉ link tới nó
   nên không cần khai trùng.) */
.card, .auth-card {
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.2s ease;
}
.motivation-post-row { box-shadow: var(--shadow-sm); }

/* Header đỏ + thanh menu trắng: thêm bóng mảnh để tách khỏi nội dung bên dưới
   (LadiPage cũng dùng header trắng phẳng nhưng có shadow rất nhẹ, không chỉ
   dựa vào viền 1px) - KHÔNG đổi màu/kích thước, chỉ thêm chiều sâu. */
.portal-header { box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12); position: relative; z-index: 5; }
.portal-topnav { box-shadow: 0 2px 6px rgba(42, 26, 26, 0.05); }

/* Tab menu chính: mượt hơn khi hover/chuyển active, thêm nền bo góc nhẹ khi hover
   (trước đó hover chỉ có ở biến thể dọc ".settings-nav button:hover", biến thể
   "top-nav-flat" đang bị override "background:transparent" ở hover kế thừa từ
   base nên KHÔNG có phản hồi hover nào - thêm lại đúng cho biến thể này). */
.settings-nav button { transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease; }
.settings-nav.top-nav-flat button { border-radius: 8px 8px 0 0; }
.settings-nav.top-nav-flat button:hover:not(.active) { background: var(--bg); }

/* Bảng: header chữ hoa nhỏ, màu trung tính thay vì đỏ đặc (LadiPage để header
   bảng rất nhã, màu nhấn chỉ dùng cho hành động/trạng thái) + hover từng dòng rõ
   ràng hơn để dễ dò theo hàng ngang trên bảng nhiều cột. */
th { color: #8a7568; font-size: 9.5pt; text-transform: uppercase; letter-spacing: 0.03em; font-weight: 700; }
tbody tr:hover, .table-scroll tbody tr:hover { background: var(--bg); }

/* Nút: thêm bóng nhẹ đúng tông thương hiệu để nút chính nổi bật như nút hành
   động chính của LadiPage (nút tím nổi giữa nền trắng) - nhấn xuống nhẹ khi
   hover/active để có cảm giác "bấm được" rõ ràng hơn nút phẳng trước đây. */
button.primary { box-shadow: 0 3px 10px rgba(179, 38, 30, 0.28); transition: box-shadow 0.15s ease, transform 0.15s ease; }
button.primary:hover { box-shadow: 0 5px 14px rgba(179, 38, 30, 0.34); transform: translateY(-1px); }
button.primary:active { transform: translateY(0); box-shadow: 0 2px 6px rgba(179, 38, 30, 0.28); }
button.secondary { transition: background 0.15s ease, box-shadow 0.15s ease; }
button.secondary:hover { background: var(--bg); box-shadow: var(--shadow-sm); }

/* Ô nhập: viền đổi màu + quầng mờ theo màu thương hiệu khi focus, thay vì viền
   xanh mặc định trình duyệt (không đồng bộ với bản sắc đỏ/vàng) - đúng kiểu
   focus ring rõ ràng nhưng nhã của các dashboard SaaS hiện đại. */
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--red);
  box-shadow: 0 0 0 3px rgba(143, 33, 33, 0.13);
}
button:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

/* Thông báo ok/error: thêm vạch màu bên trái để nhận ra loại thông báo nhanh
   hơn (quét bằng mắt) ngay cả khi không kịp đọc chữ, không đổi màu nền/chữ đã
   có sẵn. */
.msg.ok { border-left: 3px solid var(--ok); }
.msg.error { border-left: 3px solid #a53737; }

/* Khung "Còn X ngày"/"Chi phí AI" + hàng job "Bài đăng": nổi nhẹ đồng bộ với
   card, khung bấm được (.ai-cost-widget) nhấc nhẹ khi hover để rõ là bấm được. */
.plan-expiry-widget, .ai-cost-widget { box-shadow: var(--shadow-sm); transition: box-shadow 0.15s ease, transform 0.15s ease; }
.ai-cost-widget:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }

/* Modal (popup chi tiết/khoá gói): bóng sâu hơn card thường để tách hẳn khỏi
   lớp overlay tối phía sau, rõ ràng đây là lớp nổi trên cùng. (".lp-checkout-
   box" không khai ở đây - cùng lý do .lp-feature ở trên, xem landing.css.) */
.plan-lock-box { box-shadow: var(--shadow-lg); }

/* ================================================================
   LỚP BỐ CỤC SIDEBAR (2026-09-08) - chủ dự án phản hồi "ý là về phần bố cục"
   sau đợt tinh chỉnh shadow/màu ở trên - LadiPage dùng sidebar dọc bên trái,
   yêu cầu đổi menu ngang hiện tại ("🔥 Tạo video/📢 Đăng đa kênh/...") thành
   sidebar dọc. LƯU Ý: đây là ĐẢO NGƯỢC quyết định 2026-08-29/2026-09-03 (khi
   đó đổi TỪ dọc SANG ngang theo đúng yêu cầu lúc đó "làm như menu admin...
   nền trắng bám sát bên trên") - chủ dự án đã xác nhận lại muốn sidebar qua
   AskUserQuestion phiên này nên áp dụng lại.
   CÁCH LÀM (an toàn, không sửa HTML/JS): dùng CSS Grid trên #account-app (3
   con trực tiếp: header/.portal-topnav/main - xem index.html dòng ~106-136)
   để xếp lại VỊ TRÍ hiển thị mà KHÔNG di chuyển vị trí thật trong DOM - click
   handler portal.js dùng document.querySelectorAll("[data-account-tab]") quét
   TOÀN TRANG (không phụ thuộc cha nào chứa nó), nên xếp lại layout thuần CSS
   không ảnh hưởng hành vi chuyển tab. Mọi selector mới đều lồng trong
   "#account-app"/".portal-topnav" (độ đặc hiệu cao hơn rule gốc dùng chung ở
   trên nên tự thắng, không cần !important, không sửa 1 dòng rule cũ nào). */
#account-app {
  display: grid;
  grid-template-columns: 232px 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas: "header header" "nav main";
  min-height: 100vh;
}
#account-app > .portal-header { grid-area: header; }
#account-app > .portal-topnav { grid-area: nav; }
#account-app > .portal-main { grid-area: main; }

.portal-topnav {
  border-bottom: none;
  border-right: 1px solid var(--border);
  padding: 20px 14px;
  overflow-y: auto;
}
.portal-topnav .settings-nav.top-nav-flat {
  flex-direction: column;
  align-items: stretch;
  max-width: none;
  margin: 0;
  gap: 3px;
}
.portal-topnav .settings-nav.top-nav-flat button {
  text-align: left;
  border-bottom: none;
  border-left: 3px solid transparent;
  border-radius: 0 10px 10px 0;
  padding: 11px 14px;
}
.portal-topnav .settings-nav.top-nav-flat button.active {
  border-bottom-color: transparent;
  border-left-color: var(--red);
  background: var(--warn-bg);
}
/* Widget "Còn X ngày"/"Chi phí AI": trước đẩy sang phải bằng margin-left:auto
   trong hàng ngang - giờ xếp DƯỚI danh sách menu trong cột dọc thay vì cố ép
   dính đáy (đơn giản, ít rủi ro hơn dùng flex space-between). */
.portal-topnav .ov-nav-widgets {
  flex-direction: column;
  align-self: stretch;
  margin: 16px 0 0;
}
.portal-topnav .ov-nav-widgets .plan-expiry-widget, .portal-topnav .ov-nav-widgets .ai-cost-widget {
  padding: 10px 12px;
}

@media (max-width: 900px) {
  #account-app { grid-template-columns: 1fr; grid-template-rows: auto auto 1fr; grid-template-areas: "header" "nav" "main"; }
  .portal-topnav { border-right: none; border-bottom: 2px solid var(--border); padding: 10px 16px 0; }
  .portal-topnav .settings-nav.top-nav-flat { flex-direction: row; flex-wrap: wrap; }
  .portal-topnav .settings-nav.top-nav-flat button { border-radius: 8px 8px 0 0; text-align: center; border-left: none; border-bottom: 3px solid transparent; }
  .portal-topnav .settings-nav.top-nav-flat button.active { border-left-color: transparent; border-bottom-color: var(--red); }
  .portal-topnav .ov-nav-widgets { flex-direction: row; margin: 6px 0; }
}
