:root {
  /* Dark theme with a gold/neon-yellow accent — matches anh's actual brand
     (phongmenlyai.com: black background, gold-to-neon-yellow gradient CTAs)
     instead of the earlier light orange/gold "Clipsale.ai" pass. */
  --bg: #0a0a0c;
  --bg-elevated: #131316;
  --surface: #1a1a1e99;
  --surface-solid: #18181c;
  --surface-2: #212126;
  --surface-3: #2b2b31;
  --accent: #e8b400;
  --accent-2: #eeff00;
  --neon: #eeff00;
  --neon-text: #eeff00;
  --cyan: #22d3ee;
  --success: #22c55e;
  --danger: #ef4444;
  --danger-soft: #f87171;
  --warning: #f59e0b;
  --text: #f5f6f7;
  --text-2: #bcc1cc;
  --text-3: #969baa;
  --border: rgba(255, 255, 255, 0.09);
  --border-strong: rgba(255, 255, 255, 0.16);
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 20px;
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.35);
  --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.5);
  --glow-accent: 0 0 0 1px rgba(232, 180, 0, 0.4), 0 4px 20px rgba(232, 180, 0, 0.25);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  /* "Segoe UI Variable Text" is Windows 11's own refined system font (crisper
     weight rendering than classic Segoe UI at small sizes) — app chỉ chạy
     Windows nên dùng thẳng, không cần tải font ngoài. Rớt về Segoe UI
     thường trên máy chưa có bản Variable. */
  --font: "Segoe UI Variable Text", "Segoe UI", "Inter", -apple-system, sans-serif;
  /* Optical size "Display" — nét dày/rộng hơn ở cỡ chữ lớn (tiêu đề, số giá),
     dùng cho heading thay vì --font thường để chữ lớn không bị mảnh/yếu. */
  --font-display: "Segoe UI Variable Display", "Segoe UI Variable Text", "Segoe UI", -apple-system, sans-serif;
  --font-mono: "Cascadia Code", "Consolas", monospace;
  --sidebar-w: 224px;
  /* 10px padding trên + 56px logo (phần tử cao nhất) + 10px padding dưới */
  --topbar-h: 76px;
}

* { box-sizing: border-box; }
::selection { background: rgba(232, 180, 0, 0.28); }

html, body {
  margin: 0;
  min-height: 100vh;
  /* Chặn rung/lắc ngang trên mobile (anh Phong): mọi phần tử lỡ rộng hơn
     viewport (wordmark nền, lưới, bảng...) bị cắt thay vì tạo scroll ngang. */
  max-width: 100%;
  overflow-x: hidden;
  background:
    radial-gradient(1200px 600px at 15% -10%, rgba(232, 180, 0, 0.07), transparent 60%),
    radial-gradient(1000px 600px at 100% 0%, rgba(238, 255, 0, 0.06), transparent 55%),
    var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

button, input, select, textarea { font-family: inherit; }
/* Replace the browser's default (often a blunt black rectangle on Windows)
   focus ring with a soft brand-colored one, and only show it for keyboard
   navigation — not on every mouse click. */
button:focus { outline: none; }
button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-sm); }

/* ---------- Page shell ----------
   body stacks two rows: the full-width .app-topbar (logo — page title —
   profile, all one row per anh's request) on top, then .app-shell (sidebar
   + main content) filling the rest of the viewport underneath it. */
body { display: flex; flex-direction: column; }

/* ---------- App topbar (logo, page title, profile — one row, full width) */
.app-topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 10px 28px;
  /* Same page background tint (not pure black) so the header keeps just
     enough legibility when content scrolls under it, without reading as a
     separate boxed strip. */
  background: rgba(10, 10, 12, 0.72);
  backdrop-filter: blur(10px);
  /* A soft gold edge — same accent glow language as the logo itself —
     gives the whole bar a crisp, lit border instead of just fading into
     the page, and the glow spilling downward helps the white slogan text
     centered in it read as sitting inside a lit banner, not floating on
     plain black. */
  border-bottom: 1px solid rgba(232, 180, 0, 0.4);
  box-shadow: 0 1px 0 rgba(238, 255, 0, 0.15), 0 6px 24px -6px rgba(232, 180, 0, 0.35);
}
.app-topbar-left { display: flex; align-items: center; gap: 24px; min-width: 0; }
.brand { display: flex; align-items: center; flex-shrink: 0; }
/* A warm gold glow around the actual logo silhouette (drop-shadow follows
   the PNG's alpha shape, not its rectangular box) so it visually pops off
   the dark topbar instead of just sitting there at the same visual weight
   as plain text next to it. */
/* Logo lockup là bản DỌC (icon trên, chữ dưới) — 32px cũ làm chữ "Clipsale"
   bé không đọc nổi. 56px là cỡ để logo thật sự là thứ đầu tiên đập vào mắt ở
   góc trên-trái (anh Phong: "logo phải nằm trên đầu, bên trái, đẹp nhất");
   topbar hạ padding dọc xuống 10px để thanh không phình theo (--topbar-h 76). */
.brand-logo {
  display: block; height: 56px; width: auto;
  cursor: pointer; /* bấm logo = về Trang chủ (app.js nối) — chuẩn thói quen web */
  filter: drop-shadow(0 0 10px rgba(232, 180, 0, 0.55)) drop-shadow(0 0 22px rgba(238, 255, 0, 0.25)) drop-shadow(0 2px 6px rgba(0, 0, 0, 0.5));
}

/* ---------- App shell (left sidebar + main column) ---------- */
.app-shell { display: flex; align-items: flex-start; flex: 1; min-height: 0; }

.sidebar {
  width: var(--sidebar-w); flex-shrink: 0;
  /* Sticks just below the now-external .app-topbar, not the viewport top —
     --topbar-h is the topbar's own measured height (16px padding + 40px
     tallest row content [.account-chip] + 16px padding). */
  position: sticky; top: var(--topbar-h); height: calc(100vh - var(--topbar-h)); overflow-y: auto;
  display: flex; flex-direction: column;
  background: transparent;
  padding: 22px 14px;
}

.side-nav { display: flex; flex-direction: column; gap: 2px; }
.tab {
  position: relative;
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  border: none; background: transparent; color: var(--text-2);
  padding: 9px 12px; border-radius: var(--radius-sm); font-size: 14.5px; font-weight: 600;
  cursor: pointer; transition: all 0.15s var(--ease);
}
.tab:hover { color: var(--text); background: var(--surface-2); }
/* Refined active state — a soft tint + colored label/icon and a thin accent
   bar in the sidebar's own gutter, instead of a loud filled gradient pill.
   Reads as "selected" without shouting. */
.tab.active { background: rgba(232, 180, 0, 0.09); color: var(--accent); box-shadow: none; font-weight: 700; }
.tab.active::before {
  content: "";
  position: absolute; left: -14px; top: 9px; bottom: 9px; width: 3px;
  border-radius: 0 3px 3px 0;
  background: linear-gradient(180deg, var(--accent), var(--accent-2));
}
.tab-icon { width: 17px; height: 17px; flex-shrink: 0; display: flex; }
.tab-icon .icon { width: 17px; height: 17px; }

/* ---------- Main column ---------- */
.main-col { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar-title { font-family: var(--font-display); font-weight: 700; font-size: 16px; letter-spacing: -0.005em; }

/* Brand slogan — centered independent of the left (logo/title) and right
   (profile) groups either side of it, so it stays visually centered on the
   page regardless of how wide either side group is. .app-topbar is already
   position:sticky, which also establishes the containing block this needs
   for position:absolute centering. */
.app-slogan {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  font-size: 14px; font-weight: 800; letter-spacing: 0.03em; color: var(--text);
  text-shadow: 0 0 16px rgba(232, 180, 0, 0.5);
  white-space: nowrap; pointer-events: none;
}
@media (max-width: 900px) {
  .app-slogan { display: none; }
}

/* Hồ sơ rút gọn về đúng avatar — tên/email trước đây luôn hiện cạnh avatar,
   giờ ẩn trong account-popover, chỉ bấm mới thấy (anh Phong: "ấn vào hồ sơ
   mới thấy email" — topbar bớt 1 khối chữ luôn choán chỗ). */
/* width/height CỐ ĐỊNH (không để flex tự co giãn theo nội dung) — Chrome tính
   sai kích thước "fit-content" của flex container khi có cháu position:
   absolute lồng sâu bên trong (popover email), dù cháu đó không hề nằm
   trong luồng bố cục bình thường; khoá cứng kích thước là cách né chắc chắn
   nhất, không phụ thuộc hành vi tính toán intrinsic-size của từng bản Chrome. */
.account-chip { display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; cursor: pointer; padding: 0; border-radius: 50%; transition: box-shadow 0.15s var(--ease); }
.account-chip:hover { box-shadow: 0 0 0 3px var(--surface-2); }
/* VÒNG NĂNG LƯỢNG CREDIT quanh avatar (học theo Seedream, anh Phong chốt):
   conic-gradient vẽ cung vàng theo % credit còn lại (--credit-pct do
   refreshCreditUI đặt), phần đã tiêu là cung xám mờ. Sắp cạn (.ring-low)
   thì cung chuyển đỏ. Không hiện số trên topbar — bấm avatar mới thấy. */
.account-avatar-wrap {
  position: relative; flex-shrink: 0;
  border-radius: 50%; padding: 3px;
  background: conic-gradient(from -90deg, var(--accent) calc(var(--credit-pct, 100) * 1%), rgba(255, 255, 255, 0.13) 0);
  box-shadow: 0 0 12px rgba(232, 180, 0, 0.3);
  transition: box-shadow 0.2s var(--ease);
}
.account-avatar-wrap.ring-low {
  background: conic-gradient(from -90deg, var(--danger-soft) calc(var(--credit-pct, 100) * 1%), rgba(255, 255, 255, 0.13) 0);
  box-shadow: 0 0 12px rgba(239, 68, 68, 0.35);
}
.account-avatar {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  border: 2px solid var(--bg); /* khe hở tách avatar khỏi vòng — vòng đọc rõ là vòng */
  background: linear-gradient(150deg, var(--accent), var(--accent-2));
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 14px; color: #1a0f06;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
/* Huy hiệu gói (vương miện Pro / kim cương Business / tia sét Starter) đè lên
   góc dưới-phải avatar — đúng vị trí "biểu tượng nằm trên logo người dùng"
   anh Phong yêu cầu. Free không có huy hiệu (rỗng = ẩn hẳn, không viền thừa). */
/* Huy hiệu gói (vương miện/kim cương) đè GÓC TRÊN-TRÁI avatar — anh Phong:
   "logo để lên đầu ảnh hồ sơ, phía bên trái" (trước nằm góc dưới-phải). */
.account-plan-icon {
  position: absolute; top: -4px; left: -4px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--surface-solid);
  border: 1.5px solid var(--bg);
  display: flex; align-items: center; justify-content: center;
  font-size: 9.5px; line-height: 1;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
.account-plan-icon:empty { display: none; }
/* Popover tên/email — nổi bên dưới avatar, chỉ neo trong topbar nên không
   cần tính toán tràn màn hình (avatar luôn ở góc phải-trên cùng). */
.account-popover {
  position: absolute; top: calc(100% + 10px); right: 0;
  min-width: 240px;
  background: var(--surface-solid);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: 12px 16px;
  text-align: left;
  cursor: default;
  z-index: 60;
  animation: accountPopoverIn 0.15s var(--ease);
}
@keyframes accountPopoverIn {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}
.account-popover-name { font-family: var(--font-display); font-size: 14px; font-weight: 700; color: var(--text); }
.account-popover-email { font-size: 12.5px; color: var(--text-3); margin-top: 2px; }

/* Đầu hồ sơ: logo thương hiệu bên TRÁI, tên/email bên phải (anh Phong:
   "logo để lên đầu ảnh hồ sơ, phía bên trái"). */
.account-popover-head { display: flex; align-items: center; gap: 11px; }
.account-popover-logo {
  height: 36px; width: auto; flex-shrink: 0;
  filter: drop-shadow(0 0 8px rgba(232, 180, 0, 0.45)) drop-shadow(0 1px 4px rgba(0, 0, 0, 0.5));
}
.account-popover-id { min-width: 0; flex: 1; }

/* Ảnh đại diện trong đầu popover (thay chỗ logo app trước đây) — có ảnh thì
   <img> phủ kín, chưa có thì chữ cái đầu tên trên nền gradient vàng như
   avatar topbar. JS refreshCreditUI đồng bộ cả hai chỗ. */
.account-popover-avatar {
  width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0;
  background: linear-gradient(150deg, var(--accent), var(--accent-2));
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 16px; color: #1a0f06;
  overflow: hidden;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35), 0 0 8px rgba(232, 180, 0, 0.25);
}
.account-popover-avatar img,
.account-avatar img {
  width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block;
}

/* Nút bút chì mở modal chỉnh hồ sơ — nhỏ gọn góc phải đầu popover */
.account-popover-edit {
  flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%;
  background: transparent; border: 1px solid var(--border);
  font-size: 12px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s var(--ease), border-color 0.15s var(--ease);
}
.account-popover-edit:hover { background: var(--surface-2); border-color: var(--border-strong); }

/* Nhãn gói đang dùng dưới tên (kiểu "Gói Miễn phí" của Seedream) */
.account-popover-plan { font-size: 12px; color: var(--text-3); margin-top: 2px; }

/* Khối credit trong hồ sơ — trên: số còn lại; giữa: thanh năng lượng CHẤM
   TRÒN 2 màu (mask radial cắt thanh thành chuỗi chấm — vàng = còn lại, xám =
   đã tiêu); dưới: dòng "Đã dùng x/y". */
.account-popover-credit { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.account-credit-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  font-size: 12.5px; color: var(--text-2);
}
.account-credit-row b { font-size: 16px; color: var(--accent); font-variant-numeric: tabular-nums; text-shadow: 0 0 8px rgba(232, 180, 0, 0.35); }
.account-credit-row-used { margin-top: 6px; }
.account-credit-row-used { color: var(--text-3); }
.account-credit-row-used b { font-size: 12px; color: var(--text-3); text-shadow: none; }
.account-credit-bar {
  margin-top: 9px; height: 8px;
  background: #454a55;
  -webkit-mask: radial-gradient(circle at 4px 50%, #000 3.1px, transparent 3.7px) 0 0 / 9px 100% repeat-x;
  mask: radial-gradient(circle at 4px 50%, #000 3.1px, transparent 3.7px) 0 0 / 9px 100% repeat-x;
  overflow: hidden;
}
.account-credit-bar-fill {
  display: block; height: 100%; width: 100%;
  background: linear-gradient(90deg, var(--accent), #eeff00);
  transition: width 0.3s var(--ease);
}

/* Dòng nâng cấp: nhãn + nút vàng bo tròn (bấm nhảy sang tab Nâng cấp).
   Gói Business (đỉnh bảng) thì refreshCreditUI ẩn cả dòng. */
.account-popover-upgrade {
  margin-top: 12px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 11px;
  border: 1px solid rgba(232, 180, 0, 0.25);
  border-radius: 10px;
  background: rgba(232, 180, 0, 0.07);
  font-size: 12.5px; color: var(--text-2);
}
.account-upgrade-btn {
  border: none; border-radius: 999px; padding: 6px 14px;
  background: linear-gradient(135deg, var(--accent), #eeff00);
  color: #1a0f06; font-weight: 800; font-size: 12.5px; cursor: pointer;
  transition: filter 0.15s var(--ease);
}
.account-upgrade-btn:hover { filter: brightness(1.1); }

.account-popover .account-popover-email { margin-top: 10px; font-size: 11.5px; }

/* ---------- Layout ---------- */
main { max-width: 860px; margin: 0 auto; padding: 32px 20px 100px; width: 100%; transition: max-width 0.2s var(--ease); }
/* No cap at all — anh specifically wants grid-heavy screens (library, the
   long-form candidate picker) to use the FULL browser window instead of
   sitting in one centered box with big empty margins on a wide monitor.
   The translateX recenter trick below is also cancelled here: it exists
   only to center the narrow hero box on the true viewport (not just within
   main-col's leftover space next to the sidebar) — once main isn't capped
   and narrow, there's no leftover space to recenter within, and applying
   the same shift would just push wide content left, off-center the other
   way. Higher specificity than the bare `main` rule below, so it wins
   regardless of source order. */
main.wide { max-width: none; transform: none; }

/* Upload hero screen: drops the 860px cap (like `.wide` above) so its own
   sections (.feature-strip, .sample-videos, etc. — each already self-capped
   at 1500px) have room to actually reach that width, but — unlike `.wide` —
   does NOT cancel the sidebar-recentering transform below. Those sections
   are centered content, not edge-to-edge grids, so they still need the same
   "shift left by half the sidebar's width" correction the narrow 860px case
   gets; sharing plain `.wide` here read as the whole hero block pushed
   visibly right of center on a wide monitor. */
main.wide-hero { max-width: none; }

/* `margin: 0 auto` above only centers main WITHIN main-col — but main-col
   is the leftover space after the sidebar, so its center sits sidebar-w/2
   to the right of the true window center, and the whole hero block reads
   as pushed right. Shifting back left by half the sidebar's width
   re-centers it on the actual browser window instead of just the leftover
   column. Only applied once there's enough width to spare (viewport well
   past the point main's own margin:auto slack could disappear) so it can
   never push content's left edge under the sidebar on a narrower window. */
@media (min-width: 900px) {
  main { transform: translateX(calc(var(--sidebar-w) / -2)); }
}

/* Library breaks out of the editor's narrow 860px form-column width — a
   thumbnail grid should use the room a multi-step form doesn't need. With a
   fixed-width sidebar now occupying the left edge, "escape to the true
   viewport edge" no longer means anything sensible — instead `main` itself
   just widens (see `main.wide` below, toggled by the tab click handler in
   app.js) while staying within the main column next to the sidebar. */
.view { animation: fadeIn 0.25s var(--ease); }
.hidden { display: none !important; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---------- Stepper ---------- */
.stepper { display: flex; align-items: center; margin-bottom: 28px; gap: 4px; }
.stepper-back-btn { margin-right: 18px; padding: 8px 14px; flex-shrink: 0; }
.step { display: flex; align-items: center; gap: 9px; color: var(--text-3); font-size: 14px; font-weight: 600; }
.step-num {
  width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); border: 1px solid var(--border-strong);
  font-size: 13px; font-weight: 800; color: var(--text-2);
  transition: all 0.25s var(--ease);
}
.step.active .step-num { background: linear-gradient(150deg, var(--accent), var(--accent-2)); border-color: transparent; color: #1a0f06; box-shadow: var(--glow-accent); }
.step.active { color: var(--text); }
.step.done .step-num { background: var(--success); border-color: transparent; color: #fff; }
.step.done .step-num::after { content: "✓"; }
.step.done .step-num > span { display: none; }
/* Bước đã đi qua bấm được để quay lại xem/kiểm tra giai đoạn đó — panel giữ
   nguyên trạng thái, chỉ chuyển hiển thị. */
.step.clickable { cursor: pointer; }
.step.clickable:hover { color: var(--text); }
.step.clickable:hover .step-num { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(232, 180, 0, 0.14); }
.step-line { flex: 1; height: 1px; background: var(--border-strong); margin: 0 4px; }
.step-line.done { background: var(--success); }

/* ---------- Panel / Card ---------- */
.panel {
  background: linear-gradient(180deg, var(--surface-solid), var(--bg-elevated));
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 26px;
  margin-bottom: 20px;
  box-shadow: var(--shadow-md);
}
.panel-title { font-size: 17px; font-weight: 800; margin: 0 0 4px; }
.panel-desc { font-size: 13.5px; font-weight: 500; color: var(--text-2); margin: 0 0 18px; }
.section-label {
  font-size: 12px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-3); margin: 22px 0 10px;
}
.section-label:first-child { margin-top: 0; }

/* ---------- Upload hero page ----------
   This is a spacious landing screen, not a boxed form panel — no card
   border/shadow/background. The wordmark sits in its own absolutely
   positioned layer behind everything; wherever real content (the link bar,
   the mode pills) has its own opaque background it fully occludes the
   wordmark, so the faint letters only ever show through in the empty
   space around those elements — never fighting with readable text. */
/* Flex + align-items:center is a belt-and-suspenders centering guarantee for
   .hero-inner/.feature-strip below, independent of whatever width `main`
   itself ends up resolving to — margin:auto centering on those children
   alone was leaving them visibly off-center on very wide screens. */
.hero-page { position: relative; padding: 36px 20px 8px; display: flex; flex-direction: column; align-items: center; }
.hero-wordmark-layer {
  position: absolute;
  top: 0; left: 0; right: 0; height: 340px;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}
/* Sizes to just the rendered "Clipsale" text (only in-flow child is
   .hero-wordmark; .wordmark-sparks below is absolutely positioned, so it
   doesn't add to this box's size) and gives .wordmark-sparks a containing
   block to position its dots against by percentage — WITHOUT reducing
   opacity itself. .hero-wordmark's own low opacity used to sit on the same
   element as the sparks' containing block; nesting the sparks inside it
   meant their already-faint animated opacity got multiplied by 0.075 too
   (a stacking-context child inherits a parent's opacity in its compositing),
   which is why they stopped being visible at all. Sparks are now a SIBLING
   of the dim text, inside this separate full-opacity wrapper, so they're no
   longer crushed by it. */
.hero-wordmark-wrap { position: relative; display: inline-block; }
.hero-wordmark {
  font-size: clamp(90px, 15vw, 210px);
  font-weight: 900;
  letter-spacing: -0.04em;
  color: var(--text);
  opacity: 0.075;
  white-space: nowrap;
  /* Back to the original faint letters (anh: "quay lại gốc") — the previous
     big-radius glow spilled way past the letters into a bright wash across
     the whole page, which reads as broken/ugly, not subtle. This is a tiny,
     tight edge-highlight instead — very small blur radius, and deliberately
     left subject to the element's own opacity (unlike the reverted attempt)
     since anh wants this part barely-there ("viền nhỏ").
     Opacity nudged 0.065 -> 0.075 (+15%, anh asked for the text a bit
     sharper/clearer). */
  text-shadow: 0 0 2px rgba(232, 180, 0, 0.5);
}

/* Small rising ember particles along the wordmark — anh asked for tiny
   "hạt lửa" (fire-particle) dots drifting up and fading, not a broad glow,
   and for a mix of colors (gold/yellow + red), confined to just the
   "Clipsale" letters. Plain <i> tags (no semantic meaning, purely
   decorative — hero-wordmark-layer already has aria-hidden), each
   rising/fading on its own staggered timer so they don't all pulse in sync. */
.wordmark-sparks { position: absolute; inset: 0; pointer-events: none; }
.wordmark-sparks i {
  position: absolute;
  bottom: 22%;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: var(--accent-2);
  box-shadow: 0 0 3px 1px rgba(238, 255, 0, 0.55), 0 0 6px 2px rgba(232, 180, 0, 0.3);
  opacity: 0;
  animation: wordmark-spark-rise 4.6s ease-in infinite;
}
/* Ember red, mixed in with the gold/yellow ones above — a handful of the 12
   dots (see index.html) get this class instead, so the rising particles read
   as a natural mix of flame colors rather than one flat tone. */
.wordmark-sparks i.red {
  background: #ff5a3c;
  box-shadow: 0 0 3px 1px rgba(255, 90, 60, 0.55), 0 0 6px 2px rgba(239, 68, 68, 0.3);
}
.wordmark-sparks i:nth-child(1) { left: 10%; animation-delay: 0.1s; animation-duration: 4.1s; }
.wordmark-sparks i:nth-child(2) { left: 19%; animation-delay: 1.3s; animation-duration: 5.2s; }
.wordmark-sparks i:nth-child(3) { left: 27%; animation-delay: 2.6s; animation-duration: 4.5s; }
.wordmark-sparks i:nth-child(4) { left: 34%; animation-delay: 0.8s; animation-duration: 5.4s; }
.wordmark-sparks i:nth-child(5) { left: 42%; animation-delay: 3.1s; animation-duration: 4.0s; }
.wordmark-sparks i:nth-child(6) { left: 50%; animation-delay: 1.9s; animation-duration: 4.8s; }
.wordmark-sparks i:nth-child(7) { left: 57%; animation-delay: 0.5s; animation-duration: 5.0s; }
.wordmark-sparks i:nth-child(8) { left: 64%; animation-delay: 2.2s; animation-duration: 4.3s; }
.wordmark-sparks i:nth-child(9) { left: 72%; animation-delay: 3.6s; animation-duration: 5.3s; }
.wordmark-sparks i:nth-child(10) { left: 80%; animation-delay: 1.1s; animation-duration: 4.7s; }
.wordmark-sparks i:nth-child(11) { left: 87%; animation-delay: 2.9s; animation-duration: 4.2s; }
.wordmark-sparks i:nth-child(12) { left: 94%; animation-delay: 0.4s; animation-duration: 5.5s; }
@keyframes wordmark-spark-rise {
  0% { transform: translateY(0) scale(0.7); opacity: 0; }
  12% { opacity: 0.8; }
  55% { opacity: 0.5; }
  /* Anh asked for the sparks to actually clear the top of the letters, not
     just drift a little within them — -64px barely moved inside the
     wordmark's own height (the font is up to 210px tall). -190px carries
     them well past the top edge before they finish fading out. */
  100% { transform: translateY(-190px) scale(0.25); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .wordmark-sparks i { animation: none; opacity: 0; }
}
.hero-inner { position: relative; z-index: 1; max-width: 620px; margin: 0 auto; text-align: center; }
.hero-tagline {
  font-size: 15.5px;
  font-weight: 500;
  color: var(--text-2);
  margin: 0 auto 22px;
  line-height: 1.55;
}
/* The mode pills + tagline stay centered (matches the reference's centered
   hero), but each mode's actual form content reads naturally left-aligned
   like any normal form — only the two headline elements above are centered. */
.hero-inner #uploadBodyTalkinghead,
.hero-inner #uploadBodyMulticlip,
.hero-inner #uploadBodyLongform {
  text-align: left;
}

/* ---------- Mode pills (Talking-head / Nhiều clip+Nhạc / Video dài) ----------
   Deliberately NOT a boxed segmented control — the link/upload box above is
   the one thing meant to draw the eye first. This is a light, secondary
   "switch tool" control that sits below it, styled as plain underlined text
   links rather than a competing pill-shaped button group. */
.mode-pills {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 12px; margin: 26px 0 4px;
}
.mode-pills-label { font-size: 12.5px; font-weight: 600; color: var(--text-3); }
.mode-pill {
  border: none; background: transparent; color: var(--text-2);
  padding: 2px 1px 4px; font-size: 13.5px; font-weight: 600;
  cursor: pointer; transition: color 0.15s var(--ease); white-space: nowrap;
  border-bottom: 2px solid transparent;
}
.mode-pill:hover { color: var(--text); }
.mode-pill.active { color: var(--accent); border-bottom-color: var(--accent); }

/* ---------- Feature strip ---------- */
/* Widened from an earlier 920px cap — on a wide monitor that read as a small
   centered block floating in a mostly-empty page instead of using the room
   the reference tool's dashboard does (icon row + project grid both span
   most of the content width there, not just a narrow middle column). */
.feature-strip { margin: 44px auto 24px; max-width: 1500px; text-align: center; }
.feature-strip-label {
  font-size: 12px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 18px;
}
/* A running strip, not a wrapping grid — purely informational (feature
   "announcements"), so the whole list scrolls in one continuous lane
   instead of wrapping to a second row. The item list is duplicated in the
   HTML; looping -50% of the track's own width lands exactly back on the
   start of the (identical) second copy, so the seam is invisible. Paused
   on hover so anh can actually read one without it sliding away. */
.feature-marquee {
  overflow: hidden;
  width: 100%;
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.feature-track {
  display: flex; align-items: flex-start; gap: 34px;
  width: max-content;
  animation: feature-scroll 32s linear infinite;
}
.feature-marquee:hover .feature-track { animation-play-state: paused; }
@keyframes feature-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .feature-track { animation: none; }
}
.feature-item {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  width: 92px; flex-shrink: 0;
  color: var(--text-2);
}
.feature-icon {
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--surface-2); border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  color: var(--accent);
}

.feature-icon .icon { width: 20px; height: 20px; }
.feature-label { font-size: 12px; font-weight: 700; color: var(--text-2); text-align: center; line-height: 1.3; }

/* ---------- Sample videos (home screen) ----------
   Sits where "Dự án gần đây" used to — real output examples anh curated,
   not a live user-data feed, so it's plain static HTML + <video controls>
   per clip rather than a fetched grid. Same centered wide column as the
   feature strip above it. */
/* width:100% BẮT BUỘC: hero-page là flex column align-items:center nên khối
   này mặc định co theo nội dung — 6 thẻ video làm nó phình rộng hơn màn hình,
   nhãn bay khỏi tầm nhìn và thanh kéo ngang chết (khối to lên thay vì cuộn). */
.sample-videos { margin: 48px auto 8px; max-width: 1500px; width: 100%; }

/* ---------- Tất cả các dự án / Dự án đã lưu (toàn bộ kho, mọi chế độ) ----------
   Chỉ là bản xem trước trên trang chủ — luôn cắt còn 4 thẻ gần nhất (xem
   renderHomeArchive() trong app.js), 16:9 xếp thành 1 hàng ngang kiểu
   dashboard, khác với .library-grid 9:16 nhiều cột của trang "Dự án" đầy đủ.
   Bấm "Xem tất cả" chuyển sang tab sidebar "Dự án" để xem hết. */
.home-archive { margin: 40px auto 8px; max-width: 1500px; }
.home-archive-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.home-archive-tabs { display: flex; gap: 22px; }
.home-archive-tab {
  border: none; background: transparent; color: var(--text-3);
  padding: 2px 1px 8px; font-size: 14px; font-weight: 700;
  cursor: pointer; transition: color 0.15s var(--ease);
  border-bottom: 2px solid transparent;
}
.home-archive-tab:hover { color: var(--text-2); }
.home-archive-tab.active { color: var(--text); border-bottom-color: var(--accent); }
.home-archive-tab span { color: var(--text-3); font-weight: 600; }
/* Hàng tab "Dự án | Nháp" ở trang Dự án — dùng lại style tab của trang chủ,
   chỉ cần khoảng cách riêng vì nó đứng dưới thanh công cụ chứ không nằm trong
   .home-archive-head. */
.library-tabs { margin: -6px 0 20px; border-bottom: 1px solid var(--border); }
.home-archive-actions { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.home-archive-viewall {
  border: none; background: transparent; color: var(--text-3);
  font-size: 13px; font-weight: 700; cursor: pointer; padding: 4px 2px;
  transition: color 0.15s var(--ease);
  flex-shrink: 0;
}
.home-archive-viewall:hover { color: var(--accent); }
.home-archive-empty { text-align: center; padding: 20px 0; }
.home-archive-grid {
  /* 1 HÀNG NGANG 5 dự án gần nhất, kéo tay phải→trái (anh Phong 17/07 —
     "5 dự án gần nhất + kéo thủ công là toàn vẹn"): PC màn rộng thấy đủ
     5 thẻ lấp kín hàng; màn hẹp lại thì min-width giữ cỡ thẻ và hàng tự
     tràn ngang — kéo chuột (drag-scroll trong enableMarqueeSelect) hoặc
     vuốt ngón tay để xem tiếp. Thẻ cố ý NHỎ hơn hàng video mẫu phía trên:
     video mẫu là khu trình diễn (hero), đây là dashboard quản lý. */
  display: flex;
  gap: 14px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  padding-bottom: 8px; /* chỗ cho bóng thẻ + thanh cuộn mảnh */
  scrollbar-width: thin;
}
.home-archive-grid > * {
  flex: 0 0 calc((100% - 56px) / 5); /* 5 thẻ + 4 khe 14px = kín 1 hàng */
  min-width: 190px;
  scroll-snap-align: start;
}
.home-archive-grid .lib-thumb {
  /* Khung 16:9 ngang thay vì 9:16 dọc của thư viện đầy đủ — dùng aspect-ratio
     trực tiếp (không cần trick padding-top%) vì 4 cột ở đây luôn co giãn đều
     nhau, không bị grid stretch bất thường như .library-grid auto-fit. */
  height: auto;
  padding-top: 0;
  aspect-ratio: 16 / 9;
}
.home-archive-grid .lib-thumb img {
  /* Nguồn video ở đây phần lớn là dọc 9:16 (talking-head, nhiều clip) —
     object-fit: cover (mặc định của .lib-thumb img, dùng cho khung 9:16 của
     thư viện đầy đủ) sẽ cắt mất 2 bên khi nhồi vào khung 16:9 ngang này.
     contain giữ nguyên toàn khung hình, viền tối 2 bên (letterbox) từ chính
     nền gradient của .lib-thumb thay vì cắt hình. */
  object-fit: contain;
  object-position: center;
}
/* (Các override grid-template 900px/480px cũ đã bỏ — hàng giờ là flex cuộn
   ngang ở MỌI cỡ màn; ≤640px có override riêng thẻ 56vw ở khối mobile.) */
/* Chữ/badge/padding trong thẻ co theo cỡ thẻ mới (~233px) — giữ nguyên cỡ
   chữ của thẻ to cũ trên thẻ nhỏ làm thân thẻ cao hơn cả thumbnail, mất
   cân đối. Chỉ scope trong .home-archive-grid, trang "Dự án" đầy đủ giữ cỡ cũ. */
.home-archive-grid .lib-body { padding: 9px 11px 11px; }
.home-archive-grid .lib-title { font-size: 12.5px; line-height: 1.35; }
.home-archive-grid .lib-meta { font-size: 10.5px; gap: 6px; margin-top: 4px; }
.home-archive-grid .lib-mode-badge { font-size: 9.5px; padding: 2px 7px; }
.home-archive-grid .lib-save-btn { width: 26px; height: 26px; font-size: 12px; }
.home-archive-grid .lib-processing-status { font-size: 11px; }
/* Star toggle on each card's thumbnail — same corner-overlay pattern as
   .lib-actions, always visible (not hover-only) since it's the only way to
   tell at a glance which projects are saved. */
.lib-save-btn {
  position: absolute; top: 8px; right: 8px; z-index: 1;
  width: 30px; height: 30px; border-radius: 50%; border: none;
  background: rgba(0, 0, 0, 0.55); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: all 0.15s var(--ease);
}
.lib-save-btn:hover { background: rgba(0, 0, 0, 0.75); }
.lib-save-btn.active { color: var(--accent); background: rgba(0, 0, 0, 0.75); }
.lib-save-btn .icon { width: 15px; height: 15px; }
.lib-save-btn.active .icon { fill: var(--accent); }
/* Delete button — bottom-right corner, separate from ★ save (top-right) so
   the two overlay actions never crowd the same spot. Hidden until hover so
   the thumbnail isn't cluttered with a destructive action at rest. */
.lib-delete-btn {
  position: absolute; bottom: 8px; right: 8px; z-index: 1;
  width: 30px; height: 30px; border-radius: 50%; border: none;
  background: rgba(0, 0, 0, 0.55); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: all 0.15s var(--ease);
}
.lib-thumb:hover .lib-delete-btn { opacity: 1; }
.lib-delete-btn:hover { background: var(--danger); color: #fff; }
.lib-delete-btn .icon { width: 15px; height: 15px; }

.sample-videos-label {
  font-size: 12px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-3); text-align: center; margin-bottom: 18px;
}
/* DÃY KÉO NGANG đứng yên (anh Phong chốt sau sự cố băng chuyền trên iPhone:
   Safari vẽ video "trồi" khỏi khung bo góc khi khối cha đang animate). Video
   tự phát lặp TẠI CHỖ, kéo ngang tay để xem tiếp — scroll-snap dừng đúng
   mép thẻ, mượt như lướt story. */
.sample-videos-grid {
  display: flex;
  flex-wrap: nowrap;
  /* Căn giữa dãy thẻ khi màn rộng (6 thẻ ~1300px < khung 1500px) để cân đối,
     nhìn chuyên nghiệp: fit-content co khít bề rộng 6 thẻ rồi margin auto đẩy
     vào giữa. Khi viewport hẹp hơn tổng bề rộng thẻ, max-width:100% chặn lại
     và overflow-x cuộn ngang TỪ THẺ ĐẦU (không cắt mép trái như justify
     center). */
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
  overflow-x: auto;
  gap: 20px;
  padding: 4px 4px 10px;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.sample-video-card {
  background: var(--surface-solid); border: 1px solid var(--border); border-radius: var(--radius-lg);
  overflow: hidden;
  flex: 0 0 200px; width: 200px;
  scroll-snap-align: start;
}
.sample-video-card video {
  display: block; width: 100%; aspect-ratio: 9 / 16; object-fit: cover; background: #000;
  /* Chạm vào video KHÔNG làm gì được (anh Phong: "video luôn mặc định
     chạy") — không pause nhầm, không bật gì. Toàn màn hình đi qua nút ⛶
     + hộp xác nhận bên dưới. */
  pointer-events: none;
}
.sample-video-card {
  scroll-snap-align: start; position: relative;
  /* contain:paint — mọi nét vẽ của video bị nhốt TRONG thẻ, kể cả khi trình
     duyệt mobile vẽ ẩu (nguồn gốc vụ "video trồi ra ngoài khung"). */
  contain: paint;
}
/* LỚP CẢN (anh Phong: "chạy nhưng có lớp cản để không bị văng ra"): tấm kính
   trong suốt phủ kín video, nuốt mọi cú chạm — chạm/vuốt/giữ đều KHÔNG chạm
   được vào video nên không trình duyệt nào có cớ bật trình phát riêng.
   Vuốt ngang vẫn cuộn dãy bình thường (sự kiện nổi lên khung cuộn).
   Nút ⛶ (z2) và hộp xác nhận (z3) nằm TRÊN kính nên vẫn bấm được. */
.sample-video-card::after {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  background: transparent;
}

/* LỚP LỌC CHỐNG CHẠM trong suốt (anh Phong): tấm kính thật phủ kín video —
   mọi cú chạm dừng tại đây, không xem/dừng/tua gì được. Duy nhất nút loa
   (z-index cao hơn) xuyên qua được. */
.sample-video-shield {
  position: absolute; inset: 0; z-index: 2;
  background: transparent;
}
/* Nút loa — THỨ DUY NHẤT được tác động (anh Phong): bật tiếng video này,
   app.js tự tắt tiếng các video còn lại để không chồng 6 tiếng. */
.sample-audio-btn {
  position: absolute; top: 8px; right: 8px; z-index: 3;
  width: 30px; height: 30px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.25);
  background: rgba(0, 0, 0, 0.55); color: #fff;
  font-size: 13px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s var(--ease), border-color 0.15s var(--ease);
}
.sample-audio-btn:hover { background: rgba(0, 0, 0, 0.8); border-color: var(--accent); }
.sample-audio-btn.audio-on { border-color: var(--accent); box-shadow: 0 0 8px rgba(232, 180, 0, 0.45); }

/* Nút ▶ giữa thẻ — CHỈ mobile (app.js chỉ gắn khi ≤640px): video không tự
   phát, bấm mới chạy, bấm lại dừng. Đang phát thì nút thu nhỏ mờ xuống góc
   dưới để không che hình. */
.sample-play-btn {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 3;
  width: 44px; height: 44px; border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.4);
  background: rgba(0, 0, 0, 0.55); color: #fff;
  font-size: 16px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  padding-left: 3px; /* tam giác ▶ lệch quang học, nhích nhẹ cho cân */
  transition: all 0.2s var(--ease);
}
.sample-play-btn.playing {
  top: auto; left: auto; bottom: 34px; right: 8px; transform: none;
  width: 26px; height: 26px; font-size: 9px; padding-left: 0;
  opacity: 0.75;
}
.sample-video-title { padding: 10px 12px; font-size: 12.5px; font-weight: 700; color: var(--text-2); }

/* ---------- Site footer (every tab) ----------
   Lives as a direct sibling of .app-shell (sidebar + main-col), both direct
   children of <body> — NOT nested inside .main-col. It used to live inside
   main-col, which put the sticky .sidebar's column directly to its left for
   the footer's whole height; no background/gradient tuning on the footer
   itself can fill a gap that's actually a separate sibling element, so this
   is a structural fix, not just a color one, and gives a truly full-bleed
   strip with nothing beside it on either side.
   Also outside the tab-switched <main> (which panels toggle `.hidden`
   inside), so it renders at the bottom of every tab — home, review, render,
   library — instead of only the home screen.
   3-column nav (brand+social / Khám phá / Liên hệ) over a darkened photo
   backdrop (public/assets/footer-banner.jpg). Full-bleed — anh specifically
   asked this NOT read as a rounded card floating in the content column;
   .site-footer is a plain edge-to-edge strip (no border-radius, no border,
   no max-width) filling the whole page width, and only the text *inside* it
   (.site-footer-top/.site-footer-bottom) is width-capped + centered so lines
   of text don't stretch absurdly wide on a big monitor. */
/* `<body>` (this element's parent) is a plain column flex container
   (default `align-items: stretch`, no max-width) so `.app-footer` — a direct
   sibling of `.app-shell` — naturally fills the full page width without
   needing an explicit `width: 100%` here; kept anyway as a defensive
   default. */
.app-footer { width: 100%; align-self: stretch; margin: 56px 0 0; }

.site-footer {
  position: relative;
  overflow: hidden;
  /* No border-top — a hard 1px gold line sitting right on top of the ::before
     fade below read as an awkward extra seam of its own ("hở khá vô duyên"),
     competing with the fade instead of blending into it. The fade alone is
     the whole transition now, so there's exactly one soft edge, not a hard
     line plus a soft one stacked together.
     Base color is `--bg`'s own rgb (10,10,12) — matches the rest of the page
     now that the footer is a full-page-width strip with nothing beside it
     (see the structural note above).
     Darkened another ~20% (0.68-0.74 -> 0.82-0.88) on top of the earlier
     pass — anh asked for the text to stand out further; still short of the
     original near-opaque scrim, so the photo stays clearly visible. */
  background:
    linear-gradient(90deg, rgba(10, 10, 12, 0.88) 0%, rgba(10, 10, 12, 0.82) 50%, rgba(10, 10, 12, 0.88) 100%),
    url("assets/footer-banner.jpg") right center / cover no-repeat;
}
/* Soft cinematic fade where the footer begins, blending it into whatever's
   directly above (the page's own `--bg`, by this scroll depth) instead of a
   hard dividing line. */
.site-footer::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 72px;
  background: linear-gradient(to bottom, var(--bg), transparent);
  pointer-events: none;
  z-index: 0;
}
.site-footer-top {
  position: relative; z-index: 1;
  max-width: 1500px; margin: 0 auto;
  display: flex; align-items: flex-start; justify-content: space-between; gap: 40px;
  text-align: left;
  padding: 40px 48px 28px;
}
.site-footer-brand { flex: 1 1 320px; max-width: 380px; }
.site-footer-logo { margin-bottom: 10px; }
.site-footer-logo img { display: block; height: 44px; width: auto; }
.site-footer-brand-tag { font-size: 10.5px; font-weight: 800; letter-spacing: 0.08em; color: var(--accent); margin-bottom: 12px; }
.site-footer-desc { font-size: 12.5px; color: var(--text-2); line-height: 1.6; margin: 0 0 16px; max-width: 320px; }
.site-footer-social { display: flex; gap: 10px; }
.site-footer-social-icon {
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--border-strong); display: flex; align-items: center; justify-content: center;
  color: var(--text-2); transition: all 0.15s var(--ease);
}
.site-footer-social-icon:hover { border-color: var(--accent); color: var(--accent); background: rgba(232, 180, 0, 0.08); }
.site-footer-social-icon .icon { width: 15px; height: 15px; }

.site-footer-col { flex: 0 0 auto; min-width: 150px; }
.site-footer-col-title { font-size: 13.5px; font-weight: 800; color: var(--text); margin-bottom: 14px; }
.site-footer-link {
  display: flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 600; color: var(--text-2);
  text-decoration: none; margin-bottom: 11px;
  cursor: pointer;
}
.site-footer-link:hover { color: var(--accent); }
.site-footer-link .icon { width: 14px; height: 14px; flex-shrink: 0; }
.site-footer-link.site-footer-static { cursor: default; }
.site-footer-link.site-footer-static:hover { color: var(--text-2); }

.site-footer-bottom {
  position: relative; z-index: 1;
  max-width: 1500px; margin: 0 auto;
  text-align: center; font-size: 11.5px; color: var(--text-3);
  padding: 18px 48px; border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* Footer mobile (anh Phong: "đừng dàn trải"): thương hiệu gọn ở trên, 2 cột
   Khám phá + Liên hệ đứng CẠNH NHAU như PC thu nhỏ — hết cảnh mọi thứ xếp
   một cột dài lê thê phải cuộn mãi. */
@media (max-width: 760px) {
  .site-footer-top {
    flex-wrap: wrap; flex-direction: row;
    align-items: flex-start; justify-content: space-between;
    gap: 20px 16px; padding: 26px 18px 18px;
  }
  /* Khối thương hiệu chiếm trọn hàng đầu, căn giữa */
  .site-footer-brand { flex: 1 1 100%; max-width: none; text-align: center; }
  .site-footer-logo img { height: 36px; margin: 0 auto; }
  .site-footer-desc { margin-left: auto; margin-right: auto; font-size: 11.5px; margin-bottom: 12px; }
  .site-footer-social { justify-content: center; }
  /* 2 cột link đứng cạnh nhau, mỗi cột nửa hàng */
  .site-footer-col { flex: 1 1 40%; min-width: 0; }
  .site-footer-col-title { font-size: 12.5px; margin-bottom: 10px; }
  .site-footer-link { font-size: 11.5px; margin-bottom: 9px; }
  .site-footer-bottom { padding: 14px 16px; font-size: 10.5px; }
}

/* ---------- Dropzone ---------- */
.dropzone {
  position: relative;
  border: 2px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  padding: 56px 20px;
  text-align: center;
  cursor: pointer;
  transition: all 0.2s var(--ease);
  background: rgba(255, 255, 255, 0.03);
}
.dropzone:hover { border-color: var(--accent); background: rgba(232, 180, 0, 0.05); }
.dropzone.drag { border-color: var(--accent-2); background: rgba(238, 255, 0, 0.08); transform: scale(1.005); }
.dropzone-icon {
  width: 52px; height: 52px; margin: 0 auto 14px;
  border-radius: 14px; display: flex; align-items: center; justify-content: center;
  background: var(--surface-3); color: var(--accent);
}
.dropzone strong { font-size: 16px; display: block; margin-bottom: 4px; }
.dropzone p { color: var(--text-2); margin: 2px 0; font-size: 14px; }
.dropzone input { display: none; }

/* ---------- Form controls ---------- */
label.field-label { display: block; font-size: 13.5px; font-weight: 700; color: var(--text-2); margin: 16px 0 7px; }
label.field-label:first-child { margin-top: 0; }
.field-hint { font-size: 12.5px; color: var(--text-3); margin-top: 5px; }

input[type="text"], input[type="number"], textarea, select {
  width: 100%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 13px;
  color: var(--text);
  font-size: 14.5px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
input:focus, textarea:focus, select:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(232, 180, 0, 0.18);
}
textarea { min-height: 100px; resize: vertical; font-family: var(--font-mono); font-size: 13px; }

.checkbox-row { display: flex; align-items: center; gap: 9px; cursor: pointer; user-select: none; font-size: 14px; color: var(--text); }
.checkbox-row input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }

.lf-text-settings { margin: 14px 0; }
.lf-text-settings .row { margin-top: 10px; }

/* Prettier dropdowns for the longform settings panel — anh asked for these
   to look nicer than a bare <select>, not for a full visual preset gallery
   (that's a much bigger Remotion-template project, deliberately out of
   scope here). Custom chevron + hover/focus glow on top of the existing
   base <select> styling. */
.select-pretty {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%23a8a29e'%3E%3Cpath fill-rule='evenodd' d='M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z' clip-rule='evenodd'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 16px;
  padding-right: 36px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.select-pretty:hover { border-color: var(--border-strong); }
.select-pretty:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(232, 180, 0, 0.14); outline: none; }

/* ---------- Longform "detect" box (panel-longform-settings) — video
   thumbnail + duration shown before anh commits to running the heavy
   scan/render pipeline, same idea as Opus's step-2 preview thumbnail. ---------- */
.lf-detect-box {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 20px; margin-bottom: 20px;
}
.lf-detect-thumb {
  position: relative; flex-shrink: 0;
  width: 100%; max-width: 380px; aspect-ratio: 16 / 9; border-radius: var(--radius-md);
  overflow: hidden; background: var(--surface-3);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 8px 28px rgba(0,0,0,0.35);
}
.lf-detect-thumb img, .lf-detect-thumb video { width: 100%; height: 100%; object-fit: cover; }
.lf-detect-thumb-placeholder {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text-3); text-align: center; padding: 0 8px;
}
.lf-detect-info { min-width: 0; width: 100%; max-width: 480px; text-align: center; }
.lf-detect-title {
  font-size: 18px; font-weight: 800; color: var(--text); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.lf-detect-duration { font-size: 13.5px; color: var(--text-3); margin-top: 6px; font-weight: 600; }
.lf-copyright-note { font-size: 11.5px; color: var(--text-3); margin-top: 10px; line-height: 1.45; }

/* Section headings inside the longform settings panel — same visual voice
   as .edit-section-title in the post-render editor. */
.lf-settings-section-title {
  font-size: 11px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-3); margin: 22px 0 10px; padding-top: 14px; border-top: 1px solid var(--border);
}

/* "Phạm vi xử lý" dual slider — two native range inputs stacked on the same
   track. The lower input's thumb picks the start, the upper's the end; the
   track itself only needs to be drawn once so the second input's own track
   is transparent and only its thumb remains interactive. */
.lf-range-block { margin-top: 16px; }
.lf-range-badge {
  font-size: 10px; font-weight: 800; padding: 2px 8px; border-radius: 999px;
  background: rgba(16, 185, 129, 0.15); color: #10b981; margin-left: 8px; letter-spacing: 0.03em;
}
.lf-range-sliders { position: relative; height: 28px; }
.lf-range-sliders input[type="range"] {
  position: absolute; inset: 0; width: 100%; margin: 0; background: transparent;
  -webkit-appearance: none; appearance: none; pointer-events: none; /* thumbs re-enable below */
}
.lf-range-sliders input[type="range"]::-webkit-slider-runnable-track { height: 6px; border-radius: 999px; background: transparent; margin-top: 11px; }
#lfRangeStart::-webkit-slider-runnable-track { background: var(--surface-3); }
.lf-range-sliders input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; pointer-events: auto;
  width: 18px; height: 18px; border-radius: 50%; margin-top: -6px;
  background: var(--accent); border: 2px solid #1a0f06; box-shadow: var(--glow-accent); cursor: grab;
}
.lf-range-labels { display: flex; justify-content: space-between; font-size: 12.5px; font-weight: 700; color: var(--text-2); margin-top: 2px; font-family: var(--font-mono); }

/* Caption style gallery — visual chips (như caption template row của
   OpusClip) thay vì một dropdown chữ khô khan; <em> trong preview mô phỏng
   từ đang được nói (đổi màu accent). */
/* Nhãn nhóm phân cách 4 nhóm phong cách trong gallery 20 kiểu. */
.lf-caption-group-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-3); margin: 4px 0 8px; }
.lf-caption-group-label:not(:first-child) { margin-top: 14px; }
.lf-caption-style-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 10px; margin-bottom: 6px; }

/* ── Chip preview SỐNG: mỗi chip lặp lại đúng hiệu ứng chạy chữ của kiểu đó
   (2.4s/vòng) để người dùng thấy chuyển động + màu nhấn trước khi chọn.
   --chip-accent do app.js đặt inline theo bảng màu của từng kiểu. ── */
.lf-chip-preview { will-change: transform, opacity; }

@keyframes chipPunch { 0%,55%,100% { color:#fff; transform:scale(1); } 62%,86% { color:var(--chip-accent,#FFC72C); transform:scale(1.12); } }
@keyframes chipBounce { 0%,55%,100% { color:#fff; transform:scale(1) translateY(0); } 60% { color:var(--chip-accent,#FFC72C); transform:scale(1.16) translateY(-2px); } 68% { transform:scale(0.96) translateY(0); } 76%,86% { color:var(--chip-accent,#FFC72C); transform:scale(1.06); } }
@keyframes chipSlam { 0% { opacity:0; transform:scale(1.45); filter:blur(4px); } 18% { opacity:1; transform:scale(1); filter:blur(0); } 80% { opacity:1; transform:scale(1); } 92%,100% { opacity:0; transform:scale(1.02); } }
@keyframes chipFill { 0%,45% { color:transparent; } 55%,88% { color:#fff; } 100% { color:transparent; } }
@keyframes chipExtrude { 0%,55%,100% { text-shadow:1px 1px 0 #000,2px 2px 0 #000; transform:translate(0,0); } 62%,86% { text-shadow:1px 1px 0 #000,2px 2px 0 #000,3px 3px 0 #000,4px 4px 0 #000; transform:translate(-2px,-2px); } }
@keyframes chipTrack { 0% { letter-spacing:0.42em; opacity:0; } 35% { opacity:1; } 70%,88% { letter-spacing:0.1em; opacity:1; } 100% { letter-spacing:0.1em; opacity:0; } }
@keyframes chipBlurIn { 0% { opacity:0; filter:blur(6px); transform:scale(1.06); } 30%,85% { opacity:1; filter:blur(0); transform:scale(1); } 100% { opacity:0; filter:blur(3px); } }
@keyframes chipFade { 0% { opacity:0; } 40%,85% { opacity:1; } 100% { opacity:0; } }
@keyframes chipMaskUp { 0% { clip-path:inset(100% 0 0 0); transform:translateY(0.5em); } 30%,85% { clip-path:inset(-10% 0 0 0); transform:translateY(0); } 100% { clip-path:inset(-10% 0 0 0); transform:translateY(0); opacity:0; } }
@keyframes chipRise { 0% { opacity:0; transform:translateY(0.45em); } 35%,85% { opacity:1; transform:translateY(0); } 100% { opacity:0; } }
@keyframes chipWipe { 0%,15% { background-position:100% 0; } 70%,100% { background-position:0% 0; } }
@keyframes chipFocus { 0%,100% { filter:blur(2.5px); opacity:.65; } 45%,75% { filter:blur(0); opacity:1; } }
@keyframes chipSplit { 0% { opacity:0; transform:scaleY(0.15); } 30%,85% { opacity:1; transform:scaleY(1); } 100% { opacity:0; } }
@keyframes chipBrighten { 0%,55%,100% { opacity:.55; } 62%,86% { opacity:1; } }
@keyframes chipPop { 0% { opacity:0; transform:scale(0.8); } 22%,85% { opacity:1; transform:scale(1); } 100% { opacity:0; transform:scale(0.94); } }
@keyframes chipUnderline { 0%,20% { width:0; } 70%,100% { width:100%; } }
@keyframes chipGlow { 0%,55%,100% { text-shadow:0 0 4px var(--chip-accent,#46A9FF); color:#fff; } 62%,86% { text-shadow:0 0 6px var(--chip-accent,#46A9FF),0 0 14px var(--chip-accent,#46A9FF); color:#fff; } }
@keyframes chipType { 0% { width:0; } 55%,88% { width:100%; } 100% { width:100%; opacity:0; } }
@keyframes chipCaret { 0%,49% { border-color:var(--chip-accent,#46A9FF); } 50%,100% { border-color:transparent; } }

.lf-chip-preview[data-anim="punch"]    { animation:chipPunch 2.4s infinite; }
.lf-chip-preview[data-anim="bounce"]   { animation:chipBounce 2.4s infinite; }
.lf-chip-preview[data-anim="slam"]     { animation:chipSlam 2.4s infinite; }
.lf-chip-preview[data-anim="fill"]     { -webkit-text-stroke:1px #fff; animation:chipFill 2.4s infinite; }
.lf-chip-preview[data-anim="extrude"]  { animation:chipExtrude 2.4s infinite; }
.lf-chip-preview[data-anim="track"]    { animation:chipTrack 2.8s infinite; }
.lf-chip-preview[data-anim="blurin"]   { animation:chipBlurIn 2.6s infinite; }
.lf-chip-preview[data-anim="fade"]     { animation:chipFade 3s infinite; }
.lf-chip-preview[data-anim="maskup"]   { animation:chipMaskUp 2.4s infinite; }
.lf-chip-preview[data-anim="rise"]     { animation:chipRise 2.4s infinite; }
.lf-chip-preview[data-anim="wipe"]     {
  background:linear-gradient(90deg, var(--chip-accent,#FFC72C) 50%, #fff 50%);
  background-size:200% 100%; -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent; animation:chipWipe 2.4s infinite;
}
.lf-chip-preview[data-anim="focus"]    { animation:chipFocus 2.8s infinite; }
.lf-chip-preview[data-anim="split"]    { animation:chipSplit 2.4s infinite; }
.lf-chip-preview[data-anim="brighten"] { animation:chipBrighten 2.4s infinite; }
.lf-chip-preview[data-anim="pop"]      { animation:chipPop 2.4s infinite; }
.lf-chip-preview[data-anim="underline"] { position:relative; }
.lf-chip-preview[data-anim="underline"]::after {
  content:""; position:absolute; left:0; bottom:-3px; height:2px; border-radius:2px;
  background:var(--chip-accent,#FFC72C); animation:chipUnderline 2.4s infinite;
}
.lf-chip-preview[data-anim="glow"]     { animation:chipGlow 2.4s infinite; }
.lf-chip-preview[data-anim="type"]     {
  display:inline-block; overflow:hidden; white-space:nowrap; vertical-align:bottom;
  border-right:2px solid var(--chip-accent,#46A9FF);
  animation:chipType 2.8s steps(8) infinite, chipCaret 0.8s infinite;
}

@media (prefers-reduced-motion: reduce) {
  .lf-chip-preview, .lf-chip-preview::after { animation:none !important; }
}
.lf-caption-style-chip {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  background: var(--surface-2); border: 1.5px solid var(--border); border-radius: var(--radius-md);
  padding: 12px 8px; cursor: pointer; transition: border-color 0.15s var(--ease);
}
.lf-caption-style-chip:hover { border-color: var(--border-strong); }
.lf-caption-style-chip.active { border-color: var(--accent); background: rgba(232, 180, 0, 0.07); }
.lf-chip-preview { font-size: 15px; font-weight: 800; color: #fff; font-style: normal; }
.lf-chip-preview em { font-style: normal; color: var(--accent); }
.lf-chip-preview-box { background: rgba(0, 0, 0, 0.75); border-radius: 6px; padding: 2px 8px; }
/* Khối màu ĐẶC (solid_block) — nền chính là màu nhấn của kiểu, chữ trắng dày.
   Khác .lf-chip-preview-box (hộp đen mờ): ở đây màu là nhân vật chính. */
.lf-chip-preview-block {
  background: var(--chip-accent, #f2a81c);
  color: #fff; font-weight: 800;
  border-radius: 5px; padding: 2px 9px;
}
/* Highlight 2 dòng — dòng trên trắng, dòng dưới ăn màu của kiểu (--chip-accent
   do app.js đặt inline). Đây là bộ mặt của kiểu, không phải màu nhấn tuỳ chọn. */
.lf-chip-preview-2line { display: block; line-height: 1.1; }
.lf-chip-preview-2line .lf-2line-top,
.lf-chip-preview-2line .lf-2line-bottom { display: block; }
.lf-chip-preview-2line .lf-2line-bottom { color: var(--chip-accent, #eeff00); }
.lf-chip-preview-upper { text-transform: uppercase; font-weight: 900; letter-spacing: 0.02em; }
.lf-chip-preview-min { font-weight: 500; }
.lf-chip-preview-highlight em { background: var(--accent); color: #111; border-radius: 4px; padding: 0 5px; }
.lf-chip-preview-bounce em { display: inline-block; transform: scale(1.25) translateY(-2px); }
.lf-chip-preview-gradient em {
  background: linear-gradient(90deg, #FFD600, #FF3D71 55%, #00E5FF);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.lf-chip-preview-glitch { text-transform: uppercase; font-weight: 900; }
.lf-chip-preview-glitch em { text-shadow: -2px 0 #FF2D6C, 2px 0 #00E5FF; }
.lf-chip-label { font-size: 10.5px; font-weight: 700; color: var(--text-3); }

/* Word-coverage mode toggle (chạy toàn bộ vs chỉ từ khoá) — a 2-option
   segmented control, visually lighter than the style gallery above it since
   it's a binary choice, not a gallery to browse. */
.lf-wordmode-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 14px; }
.lf-wordmode-chip {
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  background: var(--surface-2); border: 1.5px solid var(--border); border-radius: var(--radius-md);
  padding: 11px 14px; cursor: pointer; text-align: left; transition: border-color 0.15s var(--ease);
}
.lf-wordmode-chip:hover { border-color: var(--border-strong); }
.lf-wordmode-chip.active { border-color: var(--accent); background: rgba(232, 180, 0, 0.07); }
.lf-wordmode-chip-title { font-size: 13px; font-weight: 800; color: var(--text); }
.lf-wordmode-chip-desc { font-size: 11px; color: var(--text-3); line-height: 1.35; }

.lf-review-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.lf-review-header .panel-title { margin-bottom: 0; }

/* ---------- Buttons ---------- */
button { cursor: pointer; border: none; font-weight: 700; transition: all 0.15s var(--ease); }
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border-radius: var(--radius-sm); padding: 11px 20px; font-size: 14.5px;
}
.btn-primary { background: linear-gradient(90deg, var(--accent), var(--accent-2)); color: #1a0f06; box-shadow: var(--glow-accent); }
.btn-primary:hover:not(:disabled) { filter: brightness(1.08); transform: translateY(-1px); }
.btn-secondary { background: var(--surface-3); color: var(--text); border: 1px solid var(--border-strong); }
.btn-secondary:hover:not(:disabled) { background: var(--surface-2); border-color: var(--accent); }
.btn-ghost { background: transparent; color: var(--text-2); }
.btn-ghost:hover:not(:disabled) { color: var(--text); background: var(--surface-2); }
.btn-danger { background: rgba(220, 38, 38, 0.1); color: var(--danger-soft); border: 1px solid rgba(220, 38, 38, 0.3); }
.btn-danger:hover:not(:disabled) { background: rgba(239, 68, 68, 0.2); }
.btn-sm { padding: 7px 13px; font-size: 13px; border-radius: var(--radius-sm); }
.btn-icon { width: 34px; height: 34px; padding: 0; border-radius: var(--radius-sm); background: var(--surface-3); color: var(--text-2); }
.btn-icon:hover:not(:disabled) { color: var(--text); background: var(--surface-2); }
button:disabled { opacity: 0.45; cursor: not-allowed; transform: none !important; }
.btn .spinner { display: none; }
.btn.loading .spinner { display: inline-flex; }
.btn.loading .btn-label { opacity: 0.7; }

.spinner {
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.35); border-top-color: #fff;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 24px; }
.actions.between { justify-content: space-between; }

/* ---------- Video preview ---------- */
/* KHUNG BÁM SÁT VIDEO (anh Phong: "đưa tỷ lệ nào hiển thị đúng khung đó,
   không bao giờ có khoảng đen thừa"): khung co theo đúng kích thước video
   (fit-content), còn video giữ NGUYÊN tỷ lệ gốc — width/height auto + kẹp
   max theo cả 2 chiều thì trình duyệt tự thu phóng ĐÚNG TỶ LỆ, không bao
   giờ letterbox. 16:9 ra khung ngang sát mép, 9:16 ra khung dọc sát mép. */
.video-frame {
  width: fit-content;
  max-width: 100%;
  margin-left: auto; margin-right: auto;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: #000;
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md);
}
.video-frame video {
  width: auto; height: auto;
  max-width: 100%; max-height: 72vh;
  margin: 0 auto;
}
video { width: 100%; display: block; background: #000; max-height: 480px; }

/* ---------- Result: original vs. edited side-by-side comparison ---------- */
.compare-frame { display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start; }
@media (max-width: 640px) { .compare-frame { flex-direction: column; } }
/* flex-basis:100% forces this onto its own row below the two video columns
   instead of squeezing in as a cramped third column next to them. */
.compare-actions { flex-basis: 100%; display: flex; justify-content: center; }
.compare-item { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.compare-label {
  font-size: 12px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-3); text-align: center;
}
.compare-item:last-child .compare-label { color: var(--accent); }
.compare-item video {
  border-radius: var(--radius-md); overflow: hidden; background: #000;
  border: 1px solid var(--border); box-shadow: var(--shadow-md);
  max-height: 420px;
}
.compare-item:last-child video { border-color: var(--accent); box-shadow: var(--glow-accent); }
.compare-download-link {
  align-self: center; font-size: 13.5px; font-weight: 700; color: var(--accent); text-decoration: none;
}
.compare-download-link:hover { text-decoration: underline; }

/* ---------- Timeline ---------- */
.timeline-wrap { margin-top: 14px; }
.timeline {
  position: relative;
  height: 56px;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  cursor: pointer;
  overflow: hidden;
}
.timeline-track { position: absolute; inset: 0; }
.tl-silence { position: absolute; top: 0; bottom: 0; background: rgba(239, 68, 68, 0.28); border-left: 1px solid rgba(239, 68, 68, 0.6); border-right: 1px solid rgba(239, 68, 68, 0.6); }
.tl-silence.excluded { background: rgba(239, 68, 68, 0.08); border-color: rgba(239, 68, 68, 0.25); }
.tl-hook {
  position: absolute; top: 0; bottom: 0;
  background: rgba(238, 255, 0, 0.22);
  border-left: 2px solid var(--neon); border-right: 2px solid var(--neon);
  cursor: grab;
}
.tl-hook:active { cursor: grabbing; }
.tl-handle {
  position: absolute; top: 0; bottom: 0; width: 10px;
  background: var(--neon); cursor: ew-resize; z-index: 3;
}
.tl-handle.start { left: -1px; border-radius: 4px 0 0 4px; }
.tl-handle.end { right: -1px; border-radius: 0 4px 4px 0; }
.tl-playhead { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--text); box-shadow: 0 0 4px rgba(0, 0, 0, 0.5); z-index: 4; pointer-events: none; }
.tl-legend { display: flex; gap: 18px; margin-top: 10px; font-size: 12.5px; color: var(--text-3); }
.tl-legend span { display: inline-flex; align-items: center; gap: 6px; }
.tl-legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.tl-legend .i-silence { background: rgba(239, 68, 68, 0.5); }
.tl-legend .i-hook { background: var(--neon); }
.tl-time-labels { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--text-3); margin-top: 4px; font-family: var(--font-mono); }

/* ---------- Text preview chips ---------- */
.preview-chip {
  display: inline-block; padding: 10px 16px; border-radius: var(--radius-sm);
  font-weight: 800; font-size: 16px; margin-top: 8px;
  background: #000; border: 1px solid var(--border);
}
.preview-chip.hook { color: #fff; }
.preview-chip.hook .hl { color: var(--neon); }
/* This chip previews the OUTPUT VIDEO's own brand text style (Phong Menly
   Style), not the app's UI accent — kept as its own hardcoded hex pair so it
   stays correct even if the app's UI theme colors above change independently. */
.preview-chip.header .hl { background: linear-gradient(90deg, #ff6a2b, #ffb020); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }

/* ---------- Silence list ---------- */
.silence-list { display: flex; flex-direction: column; gap: 6px; }
.silence-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; font-size: 13.5px; color: var(--text-2);
  background: var(--surface-2); border-radius: var(--radius-sm); border: 1px solid var(--border);
}
.silence-item input { width: 15px; height: 15px; accent-color: var(--danger); }
.silence-item .badge-mini { margin-left: auto; font-family: var(--font-mono); color: var(--text-3); }
.empty-note { font-size: 13.5px; color: var(--text-3); font-style: italic; padding: 8px 2px; }
.ai-badge {
  font-size: 11.5px; font-weight: 700; color: var(--accent); background: rgba(232, 180, 0, 0.1);
  border: 1px solid rgba(232, 180, 0, 0.3); border-radius: 999px; padding: 2px 8px; white-space: nowrap;
}

/* ---------- Sales-effectiveness score (read-only reference, no cfg wiring) ---------- */
.sales-score-overall {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px; border-radius: var(--radius-md); margin-bottom: 14px;
  background: var(--surface-2); border: 1px solid var(--border);
}
.sales-score-number { font-size: 32px; font-weight: 800; line-height: 1; }
.sales-score-band { font-size: 14px; font-weight: 700; color: var(--text-2); }
.sales-score-good .sales-score-number, .sales-score-item-num.sales-score-good { color: var(--success); }
.sales-score-ok .sales-score-number, .sales-score-item-num.sales-score-ok { color: var(--warning); }
.sales-score-poor .sales-score-number, .sales-score-item-num.sales-score-poor { color: var(--danger); }
.sales-score-bar-fill.sales-score-good { background: var(--success); }
.sales-score-bar-fill.sales-score-ok { background: var(--warning); }
.sales-score-bar-fill.sales-score-poor { background: var(--danger); }

.sales-score-list { display: flex; flex-direction: column; gap: 8px; }
.sales-score-item {
  padding: 10px 12px; border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px solid var(--border);
}
.sales-score-item-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.sales-score-item-label { font-size: 13.5px; font-weight: 700; color: var(--text); }
.sales-score-item-num { font-size: 13.5px; font-weight: 800; font-family: var(--font-mono); }
.sales-score-bar-track { height: 5px; border-radius: 999px; background: var(--surface-3); overflow: hidden; margin-bottom: 6px; }
.sales-score-bar-fill { height: 100%; border-radius: 999px; }
.sales-score-item-note { font-size: 12.5px; color: var(--text-3); line-height: 1.4; }

/* ---------- Hook candidates ---------- */
.candidate {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 14px; border: 1px solid var(--border);
  border-radius: var(--radius-md); margin-bottom: 8px; cursor: pointer;
  background: var(--surface-2); transition: all 0.15s var(--ease);
}
.candidate:hover { border-color: var(--border-strong); }
.candidate.selected { border-color: var(--neon); background: rgba(238, 255, 0, 0.06); box-shadow: 0 0 0 1px rgba(238, 255, 0, 0.3); }
.candidate .time { color: var(--neon-text); font-size: 12.5px; font-weight: 800; white-space: nowrap; font-family: var(--font-mono); padding-top: 1px; }
.candidate .txt { font-size: 14px; color: var(--text); line-height: 1.4; }
.candidate .score { margin-left: auto; font-size: 11px; color: var(--text-3); }

/* ---------- Slides ---------- */
.slide-item { border: 1px solid var(--border); border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; background: var(--surface-2); }
.slide-item-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.slide-badge { font-size: 11.5px; font-weight: 800; color: var(--accent); text-transform: uppercase; letter-spacing: 0.04em; }
.row { display: flex; gap: 12px; }
.row > * { flex: 1; }
.remove-slide { background: transparent; color: var(--danger-soft); border: none; font-size: 12.5px; margin-top: 10px; padding: 4px 0; }
.remove-slide:hover { text-decoration: underline; }
.add-slide-btn {
  width: 100%; padding: 13px; border: 1.5px dashed var(--border-strong); border-radius: var(--radius-md);
  background: transparent; color: var(--text-2); font-size: 14px; font-weight: 700;
}
.add-slide-btn:hover { border-color: var(--accent); color: var(--text); background: rgba(232, 180, 0, 0.05); }

/* ---------- Progress ---------- */
.progress-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.progress-label { font-size: 14px; font-weight: 700; }
.progress-pct { font-size: 14px; font-weight: 800; color: var(--accent); font-family: var(--font-mono); }
.progress-bar-track { height: 8px; border-radius: 999px; background: var(--surface-2); overflow: hidden; border: 1px solid var(--border); }
.progress-bar-fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transition: width 0.4s var(--ease);
  box-shadow: 0 0 12px rgba(232, 180, 0, 0.45);
}
.progress-steps { display: flex; justify-content: space-between; margin-top: 8px; font-size: 11.5px; color: var(--text-3); }

.log-toggle { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-3); cursor: pointer; margin-top: 16px; user-select: none; }
.log-toggle:hover { color: var(--text-2); }
.log {
  background: #000; border-radius: var(--radius-sm); border: 1px solid var(--border);
  padding: 14px; font-family: var(--font-mono); font-size: 12.5px; color: #7ee787;
  max-height: 220px; overflow-y: auto; white-space: pre-wrap; margin-top: 10px;
}

.status-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 800;
  background: var(--surface-2); color: var(--text-2); margin-bottom: 4px;
}
.status-badge .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--text-3); }
.status-badge.active .dot { background: var(--accent); animation: pulse 1.2s infinite; }
.status-badge.done { color: var(--success); } .status-badge.done .dot { background: var(--success); }
.status-badge.error { color: var(--danger-soft); } .status-badge.error .dot { background: var(--danger); }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }

/* ---------- Result ---------- */
.result-hero { text-align: center; padding: 8px 0 4px; }
.result-icon {
  width: 56px; height: 56px; margin: 0 auto 14px; border-radius: 50%;
  background: rgba(16, 185, 129, 0.15); color: var(--success);
  display: flex; align-items: center; justify-content: center; font-size: 26px;
}
.result-title { font-size: 18px; font-weight: 800; margin-bottom: 4px; }
.result-sub { font-size: 13.5px; color: var(--text-2); margin-bottom: 20px; }
.feature-tags { display: flex; flex-wrap: wrap; gap: 7px; justify-content: center; margin-top: 14px; }
.feature-tag {
  font-size: 12px; font-weight: 700; padding: 5px 11px; border-radius: 999px;
  background: var(--surface-3); color: var(--text-2); border: 1px solid var(--border);
}

/* ---------- Result screen: post-render color filters ---------- */
.result-filters-label {
  font-size: 12px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 14px; text-align: center;
}
.result-filters-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(78px, 1fr)); gap: 8px;
}
.result-filter-item {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  background: transparent; border: none; cursor: pointer; padding: 6px 4px;
  border-radius: var(--radius-md); transition: background 0.15s var(--ease);
}
.result-filter-item:hover { background: var(--surface-2); }
.result-filter-item.active { background: rgba(232, 180, 0, 0.1); }
.result-filter-swatch {
  width: 44px; height: 44px; border-radius: 50%;
  border: 2px solid var(--border); box-shadow: var(--shadow-md);
  transition: border-color 0.15s var(--ease), transform 0.15s var(--ease);
}
.result-filter-item:hover .result-filter-swatch { transform: translateY(-2px); }
.result-filter-item.active .result-filter-swatch { border-color: var(--accent); }
.result-filter-item.loading .result-filter-swatch { opacity: 0.5; }
.result-filter-item-label { font-size: 11px; font-weight: 700; text-align: center; color: var(--text-2); line-height: 1.25; }
#resultFilterStatus a { color: var(--accent); font-weight: 700; text-decoration: none; }
#resultFilterStatus a:hover { text-decoration: underline; }

/* ---------- Result screen: unified post-render editor ---------- */
/* Bộ lọc màu (left) — video preview (right column). "Làm đẹp da" (edit-side-
   right) is hidden via its own .hidden class right now (anh asked to hide
   the feature from the app but keep the code) — 2 columns instead of 3 so
   hiding it doesn't leave a dead empty column on the right. Restore the 3rd
   minmax(220px,1fr) track here if that section ever comes back. */
.edit-layout {
  display: grid; grid-template-columns: minmax(220px, 1fr) minmax(200px, 340px);
  gap: 20px; align-items: start;
}
@media (max-width: 980px) {
  /* Not enough room for 2 side-by-side columns — stack instead, preview
     first so anh sees the video before scrolling past the control group. */
  .edit-layout { grid-template-columns: 1fr; }
  .edit-preview { order: -1; }
}

.edit-preview {
  position: relative; aspect-ratio: 9/16; max-height: 420px; margin: 0 auto;
  background: var(--surface-2); border-radius: var(--radius-md); overflow: hidden;
  display: flex; align-items: center; justify-content: center; border: 1px solid var(--border);
  width: 100%;
}
.edit-preview video { width: 100%; height: 100%; object-fit: contain; }
.edit-preview-empty, .edit-preview-spinner {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  text-align: center; padding: 16px; font-size: 13px; font-weight: 600; color: var(--text-3);
}
.edit-preview-spinner { background: rgba(0, 0, 0, 0.35); color: #fff; }

.edit-side { display: flex; flex-direction: column; gap: 18px; min-width: 0; }

/* Groups the color-filter controls (grid + intensity + LUT upload + manual
   nudge) and the beautify controls into two visually distinct blocks with
   their own headings — previously everything just stacked in one long
   column with no grouping, which read as cluttered/unpolished. */
.edit-section { display: flex; flex-direction: column; gap: 12px; }
.edit-section-title {
  font-size: 11px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-3);
}
.edit-section-divider { height: 1px; background: var(--border); margin: 2px 0; }

/* Collapsed by default ("rút gọn") — anh asked for the filter grid and
   beautify checklist to stay out of the way until anh actually wants to
   touch them, instead of both always fully expanded taking up the whole
   side column. The title itself is the toggle. */
.edit-section-toggle {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  padding: 10px 12px; border-radius: var(--radius-md); border: 1px solid var(--border);
  background: var(--surface-2); cursor: pointer; transition: border-color 0.15s var(--ease);
}
.edit-section-toggle:hover { border-color: var(--accent); }
.edit-section-toggle .edit-section-title { margin: 0; }
.edit-section-toggle-icon {
  font-size: 11px; color: var(--text-3); transition: transform 0.15s var(--ease);
}
.edit-section-toggle[aria-expanded="true"] .edit-section-toggle-icon { transform: rotate(180deg); }
.edit-section-body { display: flex; flex-direction: column; gap: 12px; }

/* Manual color-grade nudge (contrast/saturation/brightness) on top of the
   chosen filter preset — collapsed behind a text-button by default since
   most edits just need a preset, but always available for fine-tuning. */
.edit-manual-toggle-btn {
  align-self: flex-start; background: none; border: none; cursor: pointer;
  font-size: 12.5px; font-weight: 700; color: var(--text-3); text-decoration: underline;
  padding: 0; margin-top: -8px;
}
.edit-manual-toggle-btn:hover { color: var(--accent); }
.edit-lut-upload-row { display: flex; }
.edit-lut-upload-btn {
  width: 100%; padding: 10px 12px; border-radius: var(--radius-md);
  border: 1px dashed var(--border); background: transparent; color: var(--text-3);
  font-size: 12.5px; font-weight: 700; cursor: pointer; transition: border-color 0.15s var(--ease), color 0.15s var(--ease);
}
.edit-lut-upload-btn:hover { border-color: var(--accent); color: var(--accent); }
.result-filter-item.is-custom-lut { position: relative; }
.result-filter-item-lut-badge {
  position: absolute; top: 4px; right: 4px; font-size: 9px; font-weight: 800;
  padding: 1px 5px; border-radius: 999px; background: var(--accent); color: #000;
}
.result-filter-item-remove {
  position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%;
  border: none; background: rgba(0,0,0,0.6); color: #fff; font-size: 11px; line-height: 1;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.edit-filter-intensity {
  display: flex; flex-direction: column; gap: 6px; padding: 12px;
  border-radius: var(--radius-md); border: 1px solid var(--accent); background: var(--surface-2);
}
.edit-filter-intensity label {
  display: flex; justify-content: space-between; font-size: 12.5px; font-weight: 700; color: var(--text-2);
}
.edit-filter-intensity label span { color: var(--accent); font-weight: 800; }
.edit-filter-intensity input[type="range"] { width: 100%; accent-color: var(--accent); }

.edit-manual-color {
  display: flex; flex-direction: column; gap: 10px; padding: 12px;
  border-radius: var(--radius-md); border: 1px solid var(--border); background: var(--surface-2);
}
.edit-manual-color-label { font-size: 12px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-3); }

.edit-mini-slider-row label {
  display: flex; justify-content: space-between; font-size: 12.5px; font-weight: 700;
  color: var(--text-2); margin-bottom: 5px;
}
.edit-mini-slider-row label span { color: var(--accent); font-weight: 800; }
.edit-mini-slider-row input[type="range"] { width: 100%; accent-color: var(--accent); }

.edit-auto-block { display: flex; flex-direction: column; gap: 8px; }
.edit-auto-item { display: flex; flex-direction: column; }
.edit-auto-toggle {
  display: flex; align-items: flex-start; gap: 10px; cursor: pointer;
  padding: 10px 12px; border-radius: var(--radius-md); border: 1px solid var(--border);
  background: var(--surface-2); transition: border-color 0.15s var(--ease), background 0.15s var(--ease);
}
.edit-auto-toggle:hover { border-color: var(--border-strong); }
.edit-auto-toggle:has(input:checked) { border-color: var(--accent); background: rgba(232, 180, 0, 0.08); border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.edit-auto-toggle input[type="checkbox"] { margin-top: 2px; accent-color: var(--accent); width: 16px; height: 16px; flex-shrink: 0; }
.edit-auto-toggle-label { display: flex; flex-direction: column; gap: 2px; }
.edit-auto-toggle-label strong { font-size: 13.5px; font-weight: 700; color: var(--text); }
.edit-auto-toggle-label small { font-size: 12px; color: var(--text-3); line-height: 1.35; }
.edit-auto-slider {
  padding: 10px 12px; border: 1px solid var(--accent); border-top: none;
  border-bottom-left-radius: var(--radius-md); border-bottom-right-radius: var(--radius-md);
  background: rgba(232, 180, 0, 0.04);
}

.edit-export-btn { align-self: flex-start; }
#editExportStatus a { color: var(--accent); font-weight: 700; text-decoration: none; }
#editExportStatus a:hover { text-decoration: underline; }

/* Thẻ dự án gộp (nhiều đoạn cùng 1 lần "Video dài → Short") — badge số
   lượng góc trên-trái, đối xứng với .candidate-score/star ở các góc khác.
   Viền dashed nhẹ phân biệt trực quan với thẻ 1 video đơn (viền solid). */
.lib-card-group .lib-thumb { border: 1px dashed var(--border-strong); }
.lib-group-badge {
  position: absolute; top: 8px; left: 8px; z-index: 1;
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(0, 0, 0, 0.65); color: #fff; font-size: 11.5px; font-weight: 800;
  padding: 4px 9px 4px 7px; border-radius: 999px;
}
.lib-group-badge svg { width: 13px; height: 13px; }

/* Nhãn đếm ngược "Còn N ngày" — video chưa bấm ★ Lưu sẽ tự xoá sau 15 ngày
   (archive.js + cleanup.sweepUnsavedArchive). Đặt góc dưới-trái: 4 góc thumbnail
   đã có chủ (★ trên-phải, nhóm trên-trái, xoá dưới-phải), đây là chỗ trống duy
   nhất còn lại. Bình thường xám kín đáo — đây là thông tin nền, không phải báo
   động. Dưới 3 ngày mới chuyển đỏ + nhấp nháy, vì lúc đó anh THẬT SỰ cần thấy. */
.lib-expiry-badge {
  position: absolute; bottom: 8px; left: 8px; z-index: 1;
  background: rgba(0, 0, 0, 0.68); color: rgba(255, 255, 255, 0.72);
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.01em;
  padding: 3px 8px; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  pointer-events: auto; /* giữ tooltip title= hoạt động */
}
.lib-expiry-badge.urgent {
  background: rgba(180, 24, 24, 0.9); color: #fff;
  border-color: rgba(255, 120, 120, 0.5);
  animation: expiryPulse 2s ease-in-out infinite;
}
@keyframes expiryPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.62; }
}
@media (prefers-reduced-motion: reduce) {
  .lib-expiry-badge.urgent { animation: none; }
}
.home-archive-grid .lib-expiry-badge { font-size: 9.5px; padding: 2px 7px; }
.home-archive-grid.select-mode .lib-expiry-badge { display: none; }

/* ---------- Library ---------- */
.library-toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; gap: 12px; }
/* align-items: center (không phải baseline) — .library-toolbar-title giờ
   còn chứa nút "← Quay lại" (view-project) cùng hàng với <h2>, baseline
   canh theo chữ sẽ đẩy nút lệch khỏi hàng. */
.library-toolbar-title { display: flex; align-items: center; gap: 12px; }
.library-toolbar h2 { font-size: 19px; margin: 0; }
.library-count { font-size: 13.5px; color: var(--text-3); }
.library-toolbar-actions { display: flex; align-items: center; gap: 10px; }

/* Chế độ chọn nhiều: checkbox tròn góc trên-trái mỗi thẻ, chỉ hiện khi
   .select-mode bật trên .library-grid — click vào thẻ lúc này toggle chọn
   thay vì mở modal xem chi tiết. */
.lib-select-check {
  position: absolute; top: 10px; left: 10px; z-index: 3;
  width: 24px; height: 24px; border-radius: 50%;
  background: rgba(15, 12, 8, 0.65); border: 2px solid rgba(255, 255, 255, 0.6);
  display: none; align-items: center; justify-content: center; cursor: pointer;
}
.library-grid.select-mode .lib-select-check,
.home-archive-grid.select-mode .lib-select-check { display: flex; }
.home-archive-grid.select-mode .lib-save-btn,
.home-archive-grid.select-mode .lib-delete-btn { display: none; }
.lib-select-check input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.lib-select-check::after {
  content: ""; width: 12px; height: 12px; border-radius: 50%; background: transparent;
}
.lib-card.selected .lib-select-check { background: var(--accent); border-color: var(--accent); }
.lib-card.selected .lib-select-check::after { background: #1a0f06; }
.lib-card.selected { border-color: var(--accent); box-shadow: var(--glow-accent); }
.library-grid.select-mode .lib-actions { display: none; }
/* Thẻ dự án dở dang trong chế độ chọn nhiều: bấm bất kỳ đâu trên thẻ là tick,
   nên phải ra dáng bấm được (mặc định .lib-card-processing là cursor: default).
   Ẩn nút xoá lẻ đi cho khỏi bấm nhầm khi đang gom nhiều thẻ để xoá một lượt. */
.library-grid.select-mode .lib-card-processing,
.home-archive-grid.select-mode .lib-card-processing { cursor: pointer; }
.library-grid.select-mode .lib-card-processing .lib-delete-btn { display: none; }

/* Khung "bôi đen" khi kéo chuột quét chọn nhiều dự án (enableMarqueeSelect).
   Toạ độ theo TRANG (absolute trên body) chứ không theo màn hình, nên khung
   vẫn neo đúng chỗ khi lưới tự cuộn lúc kéo xuống quá đáy. */
.select-marquee {
  position: absolute; z-index: 60; pointer-events: none;
  border: 1.5px solid var(--accent);
  background: rgba(232, 180, 0, 0.13);
  border-radius: 4px;
}
/* Đang kéo thì đừng để trình duyệt bôi đen chữ trên thẻ — nhìn rất bẩn và
   nhả chuột ra là dính một vùng text được select. */
body.marquee-dragging, body.marquee-dragging * { user-select: none; }

/* ---------- Nút ‹ › nhảy nhanh cho hàng thẻ cuộn ngang ----------
   CHỈ hiện trên điện thoại (nơi hàng dự án là 1 dải cuộn ngang). Trên máy
   tính hàng là lưới nhiều dòng nên không có gì để nhảy — ẩn hẳn. */
.hscroll-wrap { position: relative; }
.hscroll-nav { display: none; }
@media (max-width: 640px) {
  .hscroll-nav {
    display: flex; align-items: center; justify-content: center;
    position: absolute; top: 50%; transform: translateY(-50%); z-index: 4;
    width: 34px; height: 34px; padding: 0; border-radius: 50%;
    border: 1px solid var(--border-strong);
    background: rgba(10, 10, 12, 0.82); backdrop-filter: blur(4px);
    color: #fff; font-size: 17px; line-height: 1; cursor: pointer;
    transition: opacity 0.15s var(--ease);
  }
  .hscroll-prev { left: -6px; }
  .hscroll-next { right: -6px; }
  .hscroll-prev::before { content: "‹"; margin-top: -2px; }
  .hscroll-next::before { content: "›"; margin-top: -2px; }
  /* Tới đầu/cuối hàng thì mờ đi và KHÔNG chặn ngón tay chạm vào thẻ bên dưới
     (JS gắn/gỡ .hscroll-off — xem khối "Nút nhảy nhanh" trong app.js). */
  .hscroll-nav.hscroll-off { opacity: 0; pointer-events: none; }
}
.library-grid {
  display: grid;
  /* auto-fit (not auto-fill) collapses unused tracks, so a handful of
     videos stretch to fill the row instead of staying pinned to the
     minimum width while empty phantom columns eat the rest of the space —
     that phantom-column gap was why the cards looked shrunk. A 240px floor
     (up from 190px) keeps thumbnails big and legible instead of shrinking
     to fit as many columns as possible; the 280px cap keeps the true 9:16
     box from stretching too wide and looking squat on ultra-wide screens. */
  grid-template-columns: repeat(auto-fit, minmax(270px, 330px));
  justify-content: center;
  gap: 24px;
}
.lib-card {
  background: var(--surface-solid); border: 1px solid var(--border); border-radius: var(--radius-lg);
  overflow: hidden; cursor: pointer; transition: all 0.2s var(--ease);
}
.lib-card:hover { border-color: var(--border-strong); transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.lib-thumb {
  /* Bulletproof 9:16 box via the classic "padding-top %" intrinsic-ratio
     trick instead of the `aspect-ratio` property: percentage padding
     resolves against the element's own WIDTH (a CSS quirk, but a reliable
     one), so padding-top: 177.78% (=16/9) always yields a true portrait
     9:16 box regardless of grid stretch, flex quirks, or engine support —
     matching TikTok/Reels/Shorts short-form thumbnail grids. */
  position: relative;
  width: 100%;
  height: 0;
  padding-top: 177.78%;
  background: linear-gradient(135deg, #1c1d20, #131416);
  color: var(--text-3);
  overflow: hidden;
}
.lib-thumb img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center top;
  transition: transform 0.35s var(--ease);
}
.lib-card:hover .lib-thumb img { transform: scale(1.06); }
.lib-thumb::after {
  /* Bottom scrim so the play icon and any future overlay text stay legible
     over bright footage, without darkening the whole thumbnail. */
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0; height: 55%;
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.55));
  pointer-events: none;
}
.lib-thumb .play-icon {
  position: absolute; top: 50%; left: 50%; z-index: 1;
  width: 48px; height: 48px; border-radius: 50%; background: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(6px); display: flex; align-items: center; justify-content: center; color: #fff;
  box-shadow: 0 2px 16px rgba(0, 0, 0, 0.45);
  transition: transform 0.15s var(--ease), background 0.15s var(--ease);
  opacity: 0.9;
  transform: translate(-50%, -50%);
}
.lib-card:hover .play-icon { transform: translate(-50%, -50%) scale(1.12); background: var(--accent); opacity: 1; }
.lib-body { padding: 13px 14px; }
.lib-title { font-size: 14px; font-weight: 700; margin-bottom: 6px; line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.lib-meta { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-3); }
.lib-mode-badge { padding: 2px 8px; border-radius: 999px; background: var(--surface-3); font-weight: 700; }
/* Overlaid on the 9:16 thumbnail itself (not a body row below it) — the card
   no longer grows taller than the thumbnail just to fit a button row. Hidden
   until anh hovers (or taps, on touch) so the thumbnail reads clean at a
   glance and the icons only appear when anh's about to act on that card. */
.lib-actions {
  position: absolute; top: 10px; right: 10px; z-index: 2;
  display: flex; gap: 6px;
  opacity: 0; transform: translateY(-4px);
  transition: opacity 0.15s var(--ease), transform 0.15s var(--ease);
  pointer-events: none;
}
.lib-card:hover .lib-actions, .lib-card:focus-within .lib-actions {
  opacity: 1; transform: none; pointer-events: auto;
}
@media (hover: none) {
  .lib-actions { opacity: 1; transform: none; pointer-events: auto; }
}
.lib-actions button {
  width: 30px; height: 30px; padding: 0; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(4px);
  border: none; color: #fff;
}
.lib-actions button:hover { background: var(--accent); }
.lib-actions button.btn-danger { background: rgba(220, 38, 38, 0.75); }
.lib-actions button.btn-danger:hover { background: var(--danger); }
.lib-actions .icon { width: 15px; height: 15px; }

/* ---------- Long-form candidate grid ---------- */
.lf-candidate-card { cursor: default; }
.lf-candidate-card:hover { transform: none; box-shadow: none; }
.candidate-score {
  position: absolute; top: 10px; left: 10px; z-index: 1;
  min-width: 34px; height: 34px; padding: 0 6px; border-radius: 999px;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: #1a0f06; font-size: 16px; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.4);
}
/* Virality-score band colors — overrides the default gradient so the badge
   itself communicates quality at a glance, same good/ok/poor vocabulary as
   the sales-score UI (style shared, not duplicated). */
.candidate-score-good { background: var(--success); color: #06210f; }
.candidate-score-ok { background: var(--warning); color: #241a00; }
.candidate-score-poor { background: var(--danger); color: #2a0808; }

/* Bốn yếu tố của điểm viral (hook / cảm xúc / giá trị / xu hướng) — xem
   candidateSubscoresHtml trong app.js. Nhãn rộng 52px để "Xu hướng" không bị
   xuống dòng; cột số căn phải để 4 con số thẳng hàng nhau. */
.candidate-subscores { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; }
.candidate-subscore-item { display: flex; align-items: center; gap: 6px; }
.candidate-subscore-label { font-size: 11px; color: var(--text-3); width: 52px; flex-shrink: 0; }
.candidate-subscore-value {
  font-size: 11px; color: var(--text-3); width: 20px; flex-shrink: 0;
  text-align: right; font-variant-numeric: tabular-nums;
}
.candidate-subscore-item .sales-score-bar-track { flex: 1; margin-bottom: 0; }

/* Câu AI giải thích vì sao đoạn được/mất điểm. Nhạt hơn .lf-candidate-reason
   (lý do khớp yêu cầu tìm kiếm) vì đây là ghi chú phụ, không phải tiêu điểm. */
.lf-candidate-scorenote {
  font-size: 12px; color: var(--text-3); line-height: 1.4;
  margin-bottom: 6px; font-style: italic; opacity: 0.9;
}
.lf-candidate-text {
  font-size: 13px; color: var(--text-3); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  margin-bottom: 4px;
}
.lf-candidate-reason {
  font-size: 12px; font-weight: 600; color: var(--accent);
  margin-bottom: 6px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* AI-written clickbait headline per clip (OpusClip-style card title) —
   the card's visual anchor, above the timestamp row. */
.lf-candidate-headline {
  font-size: 15px; font-weight: 800; color: var(--text); line-height: 1.35;
  margin-bottom: 6px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* Grid header: section label left, sort selector right. */
.lf-grid-header {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.lf-grid-header .section-label { margin: 0; }
.lf-sort-select { width: auto; max-width: 240px; font-size: 13px; padding-top: 8px; padding-bottom: 8px; }

/* ---------- Clip detail modal + transcript editor (Opus-style) ---------- */
.lf-clip-modal-box { width: min(1060px, 94vw); max-height: 92vh; overflow: hidden; display: flex; flex-direction: column; }
.lf-clip-modal-body {
  display: flex; gap: 20px; overflow: hidden; min-height: 0; flex: 1;
}
.lf-clip-modal-left { flex: 0 0 340px; display: flex; align-items: flex-start; }
.lf-clip-modal-left video { width: 100%; max-height: 74vh; border-radius: var(--radius-md); background: #000; }
.lf-clip-modal-right { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 12px; overflow: hidden; }
.lf-clip-modal-meta { display: flex; align-items: center; gap: 8px; }
.lf-clip-modal-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.lf-clip-transcript { overflow-y: auto; min-height: 0; padding-right: 6px; }
.lf-transcript-line { font-size: 13.5px; color: var(--text-2); line-height: 1.6; margin-bottom: 8px; }
.lf-transcript-time { color: var(--accent); font-weight: 700; font-family: var(--font-mono); font-size: 12px; }

.lf-clip-editor { display: flex; flex-direction: column; gap: 10px; overflow: hidden; min-height: 0; flex: 1; }
.lf-clip-editor-toolbar { display: flex; gap: 8px; flex-wrap: wrap; }
.lf-clip-words { overflow-y: auto; min-height: 0; line-height: 2.1; padding-right: 6px; }
.te-word {
  display: inline-block; padding: 1px 4px; margin: 0 1px; border-radius: 5px;
  font-size: 14px; color: var(--text-2); cursor: pointer; user-select: none;
  transition: background 0.1s;
}
.te-word:hover { background: var(--surface-3); color: var(--text); }
.te-word.marked { background: rgba(220, 38, 38, 0.22); color: var(--danger); text-decoration: line-through; }
.te-pause-badge {
  display: inline-block; padding: 1px 7px; margin: 0 3px; border-radius: 999px;
  font-size: 11px; font-weight: 700; font-family: var(--font-mono);
  background: var(--surface-3); color: var(--text-3); border: 1px solid var(--border);
  cursor: pointer; user-select: none; vertical-align: middle;
}
.te-pause-badge:hover { border-color: var(--accent); color: var(--text); }
.te-pause-badge.marked { background: rgba(220, 38, 38, 0.22); color: var(--danger); border-color: var(--danger); text-decoration: line-through; }
.lf-editor-progress { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-3); }

@media (max-width: 900px) {
  .lf-clip-modal-body { flex-direction: column; overflow-y: auto; }
  .lf-clip-modal-left { flex: none; }
  .lf-clip-modal-left video { max-height: 40vh; }
}

/* Every candidate is pre-rendered server-side — card shows a spinner while
   waiting, a playable video once ready, or an error, instead of a "pick"
   button that used to trigger processing on click. */
.lf-candidate-video { width: 100%; border-radius: var(--radius-md); margin-top: 6px; background: #000; max-height: 320px; }

/* Khung media chính của thẻ đoạn cắt: video lấp đầy khung 9:16 với poster
   là khung hình đẹp đã trích — 1 khung duy nhất thay vì ảnh và video tách
   đôi. Tắt scrim + hover-zoom của .lib-thumb gốc: scrim che thanh điều
   khiển video, còn transform scale làm video nhấp nháy khi rê chuột. */
.lf-candidate-media video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; background: #000;
}
.lf-candidate-media::after { display: none; }
.lib-card:hover .lf-candidate-media img { transform: none; }
.lf-candidate-overlay {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px; font-size: 12.5px; font-weight: 700; color: #fff;
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.85));
}
.lf-candidate-overlay-error { color: var(--danger-soft, #ff6b6b); }
.lf-candidate-processing {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text-3); padding: 10px 0;
}
.spinner-inline {
  width: 14px; height: 14px; border-radius: 50%; flex-shrink: 0;
  border: 2px solid rgba(232, 180, 0, 0.25); border-top-color: var(--accent);
  animation: spin 0.7s linear infinite;
}
.lf-candidate-error { font-size: 12.5px; color: var(--danger); padding: 10px 0; }

.empty-state { text-align: center; padding: 70px 20px; color: var(--text-3); }
.empty-state .icon { font-size: 40px; margin-bottom: 12px; opacity: 0.5; }
.empty-state p { font-size: 14.5px; }

/* ---------- Modal ---------- */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(0, 0, 0, 0.7); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; z-index: 100; padding: 20px;
}
.modal-box {
  background: var(--surface-solid); border: 1px solid var(--border-strong); border-radius: var(--radius-lg);
  /* No fixed width — the box sizes itself to the video's own intrinsic
     dimensions (via the video element below), up to a viewport-relative
     cap. A portrait short and a landscape long-form video each render at
     their true shape instead of being forced into one fixed frame. */
  display: inline-flex; flex-direction: column;
  max-width: 90vw; padding: 24px; box-shadow: var(--shadow-lg);
}
.modal-box video {
  display: block; border-radius: var(--radius-md);
  max-width: min(85vw, 520px); max-height: 78vh;
  width: auto; height: auto;
}
.modal-title { font-size: 16px; font-weight: 800; margin-bottom: 14px; padding-right: 28px; }
.modal-close { position: absolute; top: 16px; right: 16px; }

/* ---------- Không gian dự án riêng (view-project) ----------
   Trang riêng (không phải modal) cho 1 dự án gộp — kiểu OpusClip: lưới thẻ
   to, mỗi thẻ là 1 video XEM ĐƯỢC TRỰC TIẾP (controls thật, không phải
   click-through-tới-modal-khác) + tên đoạn + ❤️/👎 để AI ghi nhớ phản hồi. */
.project-space-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 280px)); gap: 20px;
}
.project-clip-card {
  background: var(--surface-solid); border: 1px solid var(--border); border-radius: var(--radius-lg);
  overflow: hidden; display: flex; flex-direction: column;
}
.project-clip-media { position: relative; }
.project-clip-card video {
  width: 100%; aspect-ratio: 9 / 16; max-width: none; max-height: none;
  display: block; background: #000; object-fit: cover;
}
.project-clip-body { padding: 12px 14px 14px; }
.project-clip-title { font-size: 13.5px; font-weight: 700; color: var(--text); line-height: 1.35; }

/* Hành động của từng clip (thích / không thích / tải / xoá): NỔI TRÊN khung
   hình ở góc trên-phải và ẩn cho tới khi rê chuột vào thẻ. Trước đây là một
   hàng nút to nằm dưới tiêu đề — chiếm chỗ, phá nhịp lưới, nhìn rất nặng.
   Đặt ở TRÊN (không phải dưới) để không đè lên thanh điều khiển video. */
.project-clip-overlay {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  display: flex; gap: 6px;
}
.clip-action {
  width: 30px; height: 30px; padding: 0; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; cursor: pointer;
  background: rgba(10, 8, 6, 0.55);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.22);
  color: #fff; /* trắng tinh khi chưa chọn */
  opacity: 0; transform: translateY(-4px); pointer-events: none;
  transition: opacity 0.16s var(--ease), transform 0.16s var(--ease),
              background 0.15s var(--ease), border-color 0.15s var(--ease), color 0.15s var(--ease);
}
.clip-action .icon { width: 15px; height: 15px; }
.project-clip-card:hover .clip-action,
.project-clip-card:focus-within .clip-action { opacity: 1; transform: none; pointer-events: auto; }
.clip-action:hover {
  background: rgba(10, 8, 6, 0.85);
  border-color: rgba(255, 255, 255, 0.5);
  transform: translateY(-1px);
}
/* Đã đánh giá → VÀNG, và luôn hiện kể cả khi không rê chuột: nút ẩn mà lại
   mang trạng thái thì anh không tài nào biết clip nào đã chấm rồi. */
.clip-action.active {
  opacity: 1; transform: none; pointer-events: auto;
  color: var(--accent);
  border-color: var(--accent);
  background: rgba(232, 180, 0, 0.18);
}
.clip-action.active:hover { background: rgba(232, 180, 0, 0.3); }
/* Xoá → đỏ (icon đỏ sẵn để nhận ra ngay là hành động phá huỷ, hover thì đỏ đặc) */
.clip-action.danger { color: #ff6b6b; }
.clip-action.danger:hover {
  background: rgba(220, 38, 38, 0.85);
  border-color: var(--danger);
  color: #fff;
}

/* ---------- Toasts ---------- */
.toast-container { position: fixed; bottom: 24px; right: 24px; display: flex; flex-direction: column; gap: 10px; z-index: 200; }
.toast {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface-solid); border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  padding: 13px 16px; font-size: 14px; box-shadow: var(--shadow-lg);
  min-width: 260px; animation: toastIn 0.25s var(--ease);
}
.toast.success { border-left: 3px solid var(--success); }
.toast.error { border-left: 3px solid var(--danger); }
.toast.info { border-left: 3px solid var(--accent); }
@keyframes toastIn { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: none; } }

/* ---------- Misc ---------- */
/* Ghi chú "AI toàn quyền nội dung" trong Dạng mode — nền mờ điểm nhấn vàng,
   nói rõ tiêu đề/điểm nhấn do AI viết lúc render, người dùng chỉ chọn mẫu. */
.preset-ai-note {
  font-size: 12.5px; line-height: 1.5; color: var(--text-2);
  background: rgba(238, 255, 0, 0.06); border: 1px solid rgba(232, 180, 0, 0.28);
  border-radius: var(--radius-sm); padding: 9px 12px; margin: 2px 0 14px;
}
.preset-ai-note b { color: var(--text); }
.icon { width: 16px; height: 16px; flex-shrink: 0; }
.hint { font-size: 13px; font-weight: 500; color: var(--text-3); margin-top: 6px; }
.divider { height: 1px; background: var(--border); margin: 20px 0; }

/* ---------- MOBILE (≤640px) — giữ ĐÚNG bố cục PC cho người dùng không lạc
   lõng (anh Phong): logo trái — Giá cả/Dự án — vòng năng lượng credit phải,
   mọi thứ chỉ THU NHỎ lại cho tinh tế chứ không đổi chỗ. Sidebar ẩn hẳn:
   1 tab Trang chủ không đáng 68px trên màn 375px — BẤM LOGO để về Trang chủ
   (chuẩn thói quen web, app.js đã nối cả PC lẫn mobile). */
@media (max-width: 640px) {
  .app-topbar { padding: 9px 12px; gap: 10px; }
  .app-topbar-left { gap: 10px; }
  .app-topbar-right { gap: 8px; }
  .topbar-title { display: none; } /* tên màn hình nhường chỗ cho nút bấm */
  main { padding: 20px 14px 80px; }
  .row { flex-direction: column; }
  /* Dự án trên mobile: giữ Ô THẺ như PC nhưng xếp 1 HÀNG NGANG vuốt phải→trái
     (anh Phong). Thẻ 9:16 rộng 44vw → thấy ~2 thẻ + hé thẻ 3 làm mồi cho biết
     còn nữa để kéo; scroll-snap dừng đúng mép thẻ cho nhịp vuốt gọn gàng. */
  .library-grid {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    /* Cú vuốt phải→trái phải Ở LẠI trong hàng thẻ (anh Phong 20/07/2026: "khó
       khăn trong việc vuốt"): không có dòng này, vuốt tới mép là trình duyệt
       nuốt cử chỉ thành back-trang / kéo-để-tải-lại, hàng đứng im như bị kẹt. */
    overscroll-behavior-x: contain;
    touch-action: pan-x pan-y;
    padding-bottom: 10px; /* chỗ cho bóng thẻ + thanh cuộn không đè nội dung */
    scrollbar-width: thin;
  }
  .library-grid > * {
    /* 36vw (trước là 44vw) → thấy ~2.7 thẻ mỗi màn thay vì ~2.2: mỗi cú vuốt
       đi được nhiều dự án hơn, tới cuối hàng nhanh hơn hẳn. */
    flex: 0 0 36vw;
    min-width: 36vw;
    scroll-snap-align: start;
  }
  /* Dải dự án 16:9 ở trang chủ: cùng kiểu 1 hàng vuốt ngang, thẻ to hơn
     (16:9 cần bề rộng mới thấy rõ thumbnail). */
  .home-archive-grid {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    overscroll-behavior-x: contain; /* cùng lý do như .library-grid ở trên */
    touch-action: pan-x pan-y;
    padding-bottom: 10px;
    scrollbar-width: thin;
  }
  .home-archive-grid > * {
    flex: 0 0 56vw;
    min-width: 56vw;
    scroll-snap-align: start;
  }
  .sidebar { display: none; }
  :root { --sidebar-w: 0px; --topbar-h: 62px; } /* 9px padding ×2 + avatar 44px */
  .brand-logo { height: 44px; width: auto; }
  /* Nút Giá cả/Dự án nén nhẹ nhưng vùng bấm vẫn ~34px — đủ cho ngón tay */
  .topbar-nav-btn { padding: 7px 11px; font-size: 12px; gap: 6px; }
  .topbar-sale-badge { font-size: 9px; padding: 1.5px 6px; bottom: -8px; left: 8px; }
}
/* ---------- Trang chủ mobile (≤640px): nén CÂN ĐỐI — giữ đúng nhịp bố cục
   PC nhưng thu nhỏ (anh Phong): video mẫu đúng 3 thẻ/màn hình, dải icon AI
   gọn lại, các khoảng trống rút ngắn để màn dọc không bị loãng. */
@media (max-width: 640px) {
  .hero-page { padding: 20px 14px 6px; }
  /* Chữ "Clipsale" nền TO, RÕ NÉT hơn (anh Phong vòng 3: ô link đã nhỏ lại
     nên chữ được lộ nhiều hơn, tăng nhẹ độ hiện để sắc mà vẫn tinh tế). */
  .hero-wordmark-layer { height: 210px; }
  .hero-wordmark { font-size: clamp(96px, 28vw, 150px); opacity: 0.085; }
  .hero-tagline { font-size: 14px; margin-bottom: 14px; }
  .panel-desc { margin-bottom: 10px; font-size: 12.5px; }
  /* (Cỡ ô dán link mobile: xem media query đặt NGAY SAU khối .url-upload-bar
     gốc phía dưới file — đặt ở đây bị rule gốc viết sau đè mất.) */
  .or-divider { margin: 10px 0; font-size: 10.5px; }
  .dropzone-compact { padding: 8px 12px; gap: 9px; }
  .dropzone-compact .dropzone-icon { width: 28px; height: 28px; }
  .dropzone-compact-text strong { font-size: 12.5px; }
  .dropzone-compact-text p { font-size: 11px; }
  /* VIDEO MẪU LÊN TRÊN, dải tính năng AI xuống dưới (anh Phong) — hero-page
     là flex column nên chỉ cần đổi order ở mobile, PC giữ nguyên thứ tự. */
  .sample-videos { order: 1; }
  .feature-strip { order: 2; }
  .home-archive { order: 3; }
  /* Đẩy dải tính năng + video mẫu LÊN SÁT (anh Phong) — nhìn một màn là
     thấy đủ: nhập video → AI làm gì → thành quả mẫu, trực quan như PC. */
  .mode-pills { margin: 14px 0 2px; }
  .feature-strip { margin: 12px auto 4px; }
  .feature-strip-label, .sample-videos-label { margin-bottom: 8px; font-size: 11px; }
  .feature-item { width: 56px; gap: 6px; }
  .feature-track { gap: 12px; }
  .feature-icon { width: 36px; height: 36px; }
  .feature-label { font-size: 10px; }
  /* Hàng tab kho dự án: màn hẹp bóp chữ gãy dọc từng ký tự rất xấu — cho
     xuống dòng thoáng + tab không bao giờ bẻ chữ, thừa thì cuộn ngang */
  .home-archive-head { flex-wrap: wrap; gap: 10px; }
  .home-archive-tabs { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .home-archive-tab { white-space: nowrap; flex-shrink: 0; }
  /* Video mẫu: đúng 3 thẻ lọt màn, kéo ngang là thấy 3 thẻ tiếp theo */
  .sample-videos { margin: 10px auto 2px; }
  .sample-videos-grid { gap: 10px; padding: 2px 2px 6px; }
  .sample-video-card { flex: 0 0 calc((100vw - 48px) / 3); width: auto; border-radius: 12px; }
  .sample-video-title { padding: 6px 8px; font-size: 10.5px; }
  .home-archive { margin: 24px auto 8px; }
}
/* Màn rất hẹp (≤480px): nút topbar rút về ICON TRÒN tinh gọn (tooltip + huy
   hiệu giảm giá vẫn giữ) — đủ chỗ cho logo + 3-4 nút + avatar không chen lấn */
@media (max-width: 480px) {
  .topbar-nav-label { display: none; }
  .topbar-nav-btn { padding: 9px 11px; gap: 0; }
  .topbar-nav-ic { font-size: 15px; }
  /* neo huy hiệu về mép phải nút — không chờm sang logo bên trái */
  .topbar-sale-badge { left: auto; right: -6px; }
  .brand-logo { height: 40px; }
  /* Dải tính năng cực nhỏ hơn trên màn rất hẹp — vừa khít viewport */
  .feature-item { width: 50px; }
  .feature-track { gap: 10px; }
}

/* ---------- Mode switch (Talking-head vs Multi-clip) ---------- */
.mode-switch { display: flex; gap: 12px; margin-bottom: 20px; }
.mode-card {
  flex: 1; text-align: left; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 16px;
  transition: all 0.18s var(--ease); color: var(--text);
}
.mode-card:hover { border-color: var(--border-strong); }
.mode-card.active { border-color: var(--accent); background: rgba(232, 180, 0, 0.08); box-shadow: var(--glow-accent); }
.mode-card-icon { font-size: 22px; margin-bottom: 6px; }
.mode-card-title { font-weight: 800; font-size: 15px; margin-bottom: 3px; }
.mode-card-desc { font-size: 13px; color: var(--text-2); line-height: 1.4; }

/* ---------- Multi-clip media card (clips + music nested together) ----------
   Clips and music used to be two separate full-size dropzones of equal
   visual weight, floating independently — music is a supporting input, not
   a second primary one, so it reads oddly boxy/unbalanced on its own. Nesting
   both inside one shared card, with music styled compact, fixes both: they
   read as one "add your media" step, and music visibly takes a back seat. */
.mc-media-card {
  /* Transparent — anh's other two modes (Talking-head, Video dài) have no
     card background behind their dropzone at all, so the faint "Clipsale"
     wordmark shows through; this one used to sit on an opaque
     var(--surface-solid) panel that fully blocked it. Border kept for
     definition (still grouping "clip video" + dropzone + clip grid as one
     step) since a 1px line doesn't meaningfully block anything behind it;
     box-shadow dropped since a drop shadow cast from a transparent box onto
     the wordmark behind it would itself read as an unwanted dark smudge. */
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px;
  margin-bottom: 16px;
}
.mc-media-card .section-label:first-child { margin-top: 0; }
.mc-music-section { animation: fadeIn 0.3s var(--ease); }

/* "Chỉ 1 video — AI cắt highlight" toggle: nổi nhẹ như một lựa chọn chế độ
   (viền vàng mờ) thay vì lẫn vào các checkbox cấu hình thường. */
.mc-single-toggle {
  margin: 0 0 12px;
  padding: 11px 14px;
  border: 1px solid rgba(232, 180, 0, 0.35);
  border-radius: var(--radius-md);
  background: rgba(232, 180, 0, 0.06);
  text-align: left;
}
.mc-single-toggle:hover { border-color: var(--accent); }
.mc-single-toggle b { color: var(--accent); }
#mcSingleOptions { margin: 0 0 14px; text-align: left; animation: fadeIn 0.3s var(--ease); }

/* Compact variant of .dropzone for secondary inputs (background music) —
   short horizontal row instead of the tall centered primary dropzone. */
.dropzone-compact {
  display: flex; align-items: center; gap: 14px;
  text-align: left; padding: 12px 18px;
}
.dropzone-compact .dropzone-icon { width: 38px; height: 38px; margin: 0; flex-shrink: 0; }
.dropzone-compact-text strong { font-size: 14px; display: block; margin-bottom: 2px; }
.dropzone-compact-text p { margin: 0; font-size: 12.5px; }

/* ---------- Multi-clip: added clips, shown as real video thumbnails ----------
   A filename-only pill tells anh nothing about whether the right clip
   actually landed — a playable-frame thumbnail (via an actual <video> el,
   seeked to its first frame in JS) is the only way to visually confirm
   "yes, that's the right file" before render, and to pick out the wrong
   one to remove at a glance instead of reading a list of filenames. */
.mc-clip-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 10px;
  margin-top: 14px;
}
.mc-clip-file { text-align: left; }
.mc-clip-file-thumb {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface-3);
  border: 1px solid var(--border);
  cursor: pointer;
  transition: border-color 0.15s var(--ease);
}
.mc-clip-file-thumb:hover { border-color: var(--accent); }
.mc-clip-file-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; }
/* Khung hình do SERVER trích (codec trình duyệt không giải mã nổi: HEVC máy
   quay, ProRes, .mkv...) — <video> lúc này chỉ còn là cái khung giữ chỗ, ảnh
   nằm ở thuộc tính poster, nên phải cho poster phủ kín ô như video vẫn phủ. */
.mc-clip-file-thumb video.thumb-from-server { object-fit: cover; }
/* Cả trình duyệt LẪN server đều không đọc được (file hỏng thật) — hiện ô xám
   có icon phim, để anh biết đây là file lỗi chứ không phải app đứng hình. */
.mc-clip-file-thumb video.thumb-failed {
  background: repeating-linear-gradient(45deg, var(--surface-3), var(--surface-3) 8px, var(--surface-2) 8px, var(--surface-2) 16px);
}
.mc-clip-file-order {
  position: absolute; top: 5px; left: 5px; z-index: 1;
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  background: rgba(0, 0, 0, 0.55); color: #fff; font-size: 11px; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
}
.mc-clip-file-remove {
  position: absolute; top: 5px; right: 5px; z-index: 1;
  width: 20px; height: 20px; border-radius: 50%; border: none;
  background: rgba(0, 0, 0, 0.55); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: all 0.15s var(--ease);
}
.mc-clip-file-remove .icon { width: 11px; height: 11px; }
.mc-clip-file-thumb:hover .mc-clip-file-remove { opacity: 1; }
.mc-clip-file-remove:hover { background: var(--danger); }
.mc-clip-file-name {
  margin-top: 5px; font-size: 12px; color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ---------- Multi-clip: added music file ---------- */
.mc-music-file {
  display: flex; align-items: center; gap: 12px;
  margin-top: 12px; padding: 10px 14px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.mc-music-file-icon {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  background: var(--surface-3); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
}
.mc-music-file-info { flex: 1; min-width: 0; }
.mc-music-file-name { font-size: 13.5px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mc-music-file-dur { font-size: 12px; color: var(--text-3); font-family: var(--font-mono); }
.mc-music-file-remove {
  width: 26px; height: 26px; border-radius: 50%; border: none; flex-shrink: 0;
  background: var(--surface-3); color: var(--text-2); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.mc-music-file-remove:hover { color: #fff; background: var(--danger); }

/* ---------- Multi-clip music/beat info ---------- */
.mc-music-info { display: flex; gap: 18px; font-size: 13.5px; color: var(--text-2); margin: 8px 0 4px; }
.mc-music-info b { color: var(--text); }
.mc-beat-timeline {
  position: relative; height: 34px; border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px solid var(--border); overflow: hidden;
}
.mc-beat-tick { position: absolute; top: 0; bottom: 0; width: 1px; background: rgba(238, 255, 0, 0.55); }

/* ---------- Multi-clip clip cards ---------- */
.mc-clip-timeline { display: flex; gap: 4px; overflow-x: auto; padding: 4px 0 10px; }
.mc-clip-block {
  flex-shrink: 0; width: 92px; height: 58px; border-radius: var(--radius-sm);
  background: var(--surface-2) center/cover no-repeat; border: 1px solid var(--border-strong);
  display: flex; align-items: flex-end; justify-content: center; position: relative;
}
.mc-clip-block .mc-clip-order { position: absolute; top: 3px; left: 4px; font-size: 11px; font-weight: 800; color: #fff; text-shadow: 0 1px 3px #000; }
.mc-clip-card { border: 1px solid var(--border); border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; background: var(--surface-2); }
.mc-clip-card-head { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.mc-clip-card-head img { width: 46px; height: 46px; border-radius: var(--radius-sm); object-fit: cover; background: var(--surface-3); }
.mc-clip-card-title { font-weight: 700; font-size: 14px; flex: 1; }
.mc-clip-card-dur { font-size: 12.5px; color: var(--text-3); font-family: var(--font-mono); }
.mc-clip-card-actions { display: flex; gap: 6px; }
.mc-ai-badge {
  display: inline-block; font-size: 12px; font-weight: 700;
  padding: 4px 10px; border-radius: 999px; margin-bottom: 10px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2)); color: #1a0f06;
}

/* ---------- Multi-clip: face picker for per-clip beauty pass ---------- */
.mc-face-picker { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.mc-face-thumb {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  width: 60px; background: transparent; border: 2px solid transparent; cursor: pointer;
  padding: 3px; border-radius: var(--radius-sm); transition: all 0.15s var(--ease);
}
.mc-face-thumb:hover { background: var(--surface-3); }
.mc-face-thumb.active { border-color: var(--accent); background: rgba(232, 180, 0, 0.08); }
.mc-face-thumb img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--radius-sm); background: var(--surface-3); }
.mc-face-thumb span { font-size: 11px; font-weight: 700; color: var(--text-2); }

/* ---------- URL upload bar (link/YouTube/Drive) ----------
   A soft floating card (subtle border + shadow), but deliberately modest in
   size — a small supporting action, not a dominant element competing with
   the wordmark for attention. */
.url-upload-bar {
  display: flex; align-items: center; gap: 6px;
  background: var(--surface-solid); border: 1px solid var(--border);
  border-radius: 999px; padding: 4px 4px 4px 18px;
  box-shadow: var(--shadow-md);
  max-width: 460px;
  margin: 0 auto;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.url-upload-bar:focus-within { border-color: var(--accent); box-shadow: var(--shadow-lg), 0 0 0 3px rgba(232, 180, 0, 0.14); }
.url-upload-bar input {
  flex: 1; min-width: 0; background: transparent; border: none; color: var(--text);
  font-size: 13.5px; padding: 9px 0;
}
.url-upload-bar input:focus { outline: none; box-shadow: none; }
.url-upload-bar input::placeholder { color: var(--text-3); }
.url-upload-bar .btn { border-radius: 999px; padding: 8px 16px; font-size: 13px; white-space: nowrap; flex-shrink: 0; }
/* Mobile: ô dán link + nút Lấy video thu nhỏ ~35% so với bản gọn trước (anh
   Phong) — nhường chỗ cho chữ Clipsale nền hiện rõ, tinh tế. Media query
   phải đứng SAU khối gốc ở trên thì mới thắng (cùng specificity). */
@media (max-width: 640px) {
  .url-upload-bar { max-width: 230px; padding: 2px 2px 2px 11px; }
  .url-upload-bar input { font-size: 11px; padding: 5px 0; }
  .url-upload-bar input::placeholder { font-size: 11px; }
  .url-upload-bar .btn { padding: 5px 11px; font-size: 11px; }
}

/* Prompt-driven candidate search bar (longform) — same pill idiom as
   .url-upload-bar, but full-width and left-aligned since it sits inside the
   wider candidates panel instead of the centered hero. */
.lf-search-bar {
  display: flex; align-items: center; gap: 6px;
  background: var(--surface-solid); border: 1px solid var(--border);
  border-radius: 999px; padding: 4px 4px 4px 18px;
  margin: 14px 0 6px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.lf-search-bar:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(232, 180, 0, 0.14); }
.lf-search-bar input {
  flex: 1; min-width: 0; background: transparent; border: none; color: var(--text);
  font-size: 13.5px; padding: 9px 0;
}
.lf-search-bar input:focus { outline: none; box-shadow: none; }
.lf-search-bar input::placeholder { color: var(--text-3); }
.lf-search-bar .btn { border-radius: 999px; padding: 8px 16px; font-size: 13px; white-space: nowrap; flex-shrink: 0; }

.or-divider {
  display: flex; align-items: center; gap: 14px;
  color: var(--text-3); font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  margin: 18px 0;
}
.or-divider::before, .or-divider::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* ---------- Longform "chi tiết tiến trình" status modal ---------- */
.lf-status-detail-btn {
  display: inline-block; margin-left: 10px; background: none; border: none; cursor: pointer;
  font-size: 12.5px; font-weight: 700; color: var(--accent); text-decoration: underline;
}
.lf-status-detail-btn:hover { color: var(--accent-2); }

.modal-backdrop {
  position: fixed; inset: 0; z-index: 200; background: rgba(0, 0, 0, 0.65);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
/* Scoped under .modal-backdrop — an earlier version of these rules was
   unscoped (.modal-box/.modal-title/.modal-close bare), which silently
   overrode the OTHER, pre-existing .modal-overlay modal system's own
   .modal-box/.modal-title/.modal-close (used by openLibraryModal etc.),
   shrinking its video preview to max-width:480px. Two visually different
   modal systems share generic class names, so both must be ancestor-scoped
   to their own wrapper or one clobbers the other by source order. */
.modal-backdrop .modal-box {
  /* --surface-solid, KHÔNG phải --surface-1: biến đó không tồn tại, nên nền hộp
     thoại thành trong suốt và chữ của trang phía sau đâm xuyên qua modal. */
  width: 100%; max-width: 480px; background: var(--surface-solid); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); overflow: hidden;
}
.modal-backdrop .modal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px; border-bottom: 1px solid var(--border);
}
.modal-backdrop .modal-title { font-size: 15px; font-weight: 800; }
.modal-backdrop .modal-close {
  background: none; border: none; cursor: pointer; font-size: 22px; line-height: 1; color: var(--text-3);
  padding: 0; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center;
}
.modal-backdrop .modal-close:hover { color: var(--text); }
.modal-backdrop .modal-body { padding: 18px 20px; display: flex; flex-direction: column; gap: 10px; }
.lf-status-hint { font-size: 12.5px; color: var(--text-3); line-height: 1.5; margin-bottom: 4px; }
.lf-status-line { font-size: 13.5px; color: var(--text-2); }
.lf-status-line strong { color: var(--text); font-weight: 700; }
.lf-status-progress { display: flex; justify-content: space-between; font-size: 13px; font-weight: 700; margin-top: 8px; }
#lfStatusProgressPct { color: var(--accent); font-family: var(--font-mono); }

/* ---------- Dự án: thẻ dự án đang xử lý ---------- */
.lib-card-processing { cursor: default; }
/* Multiclip/talking-head đã phân tích xong, đang chờ anh xem & chỉnh — hết
   việc chạy nền nên bấm được như thẻ kho thật (resumeProcessingJob ở
   app.js), khác các thẻ processing khác (cursor: default vì bấm vào chỉ
   nhận được toast "đang chạy nền"). */
.lib-card-waiting { cursor: pointer; }
.lib-card-waiting:hover { border-color: var(--border-strong); transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.lib-card-waiting .lib-thumb-processing { border-style: solid; border-color: var(--accent); }
.lib-processing-ready {
  width: 40px; height: 40px; border-radius: 50%; background: var(--accent);
  display: flex; align-items: center; justify-content: center; color: #1a0f06;
}
.lib-processing-ready svg { width: 18px; height: 18px; }
/* 9:16 giống hệt .lib-thumb đã xong (padding-top trick, xem đó để biết lý
   do dùng % thay vì aspect-ratio) — card đang xử lý không còn nhảy kích
   thước khi tự chuyển sang thẻ kho thật lúc render xong. */
.lib-thumb-processing {
  position: relative; width: 100%; height: 0; padding-top: 177.78%;
  background: var(--surface-2); border: 1px dashed var(--border-strong); overflow: hidden;
}
.lib-thumb-processing img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0.5;
}
.lib-thumb-processing-overlay {
  position: absolute; inset: 0; z-index: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  padding: 18px 14px; text-align: center;
  background: linear-gradient(180deg, rgba(10, 8, 6, 0.3), rgba(10, 8, 6, 0.78));
}
.lib-thumb-processing .progress-bar-track { width: 80%; }
.lib-processing-status {
  font-size: 12.5px; font-weight: 700; color: var(--text-2); text-align: center; line-height: 1.4;
}
.lib-processing-pct { font-size: 26px; font-weight: 800; color: var(--accent); font-family: var(--font-mono); }
/* Lớp phủ trạng thái nằm ở z-index 1 và phủ kín cả thumbnail — nút xoá phải cao
   hơn nó, không thì bấm vào là trúng lớp phủ chứ không trúng nút. */
.lib-thumb-processing .lib-delete-btn { z-index: 2; }
/* Dự án render hỏng/bị gián đoạn: viền + chữ đỏ để phân biệt ngay với dự án chỉ
   đang chờ anh xem & chỉnh (viền vàng) — hai thứ này trước đây trông y hệt nhau. */
.lib-card-failed .lib-thumb-processing { border-color: var(--danger); border-style: solid; }
.lib-card-failed .lib-processing-ready { background: var(--danger); color: #fff; }
.lib-card-failed .lib-processing-status { color: #ff9c8f; }

/* ===========================================================
   Bộ chọn nhạc nền — kho của anh / đang hot / nhạc free / từ link
   =========================================================== */

.music-browse-btn {
  width: 100%; margin-top: 10px; padding: 11px 14px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  background: var(--surface-2); color: var(--text-2);
  border: 1px dashed var(--border-strong); border-radius: var(--radius-md);
  font-size: 13px; font-weight: 600; cursor: pointer;
  transition: color .15s, border-color .15s, background .15s;
}
.music-browse-btn:hover { color: var(--accent); border-color: var(--accent); background: rgba(232, 180, 0, 0.07); }
.music-browse-icon { display: flex; width: 16px; height: 16px; }
.music-browse-icon .icon { width: 16px; height: 16px; }

/* ---------- Nhạc nền gắn thẳng vào job (Talking-head & Video dài → Short) ----
   Dùng lại thẻ bài nhạc .mc-music-file của chế độ Nhiều clip + Nhạc, chỉ thêm
   phần khung + thanh âm lượng riêng cho hai luồng có LỜI NÓI (nhạc là nền,
   không phải nhân vật chính, nên mặc định 18% và có ducking). */
/* Bố cục thumbnail nền ĐEN TRẮNG (mono trong thumbStyles.json) — khung xem
   trước phải cho thấy đúng điều đó, vì video render ra cũng chuyển đen trắng
   trong mấy giây thẻ hiện (ThumbnailCard: backdrop-filter grayscale). */
.live-overlay-mono { backdrop-filter: grayscale(1) contrast(1.06); }
.thumb-chip-mono { filter: grayscale(1) contrast(1.06); }

/* ---------- AI đề xuất tiêu đề + từ khoá đắt giá cho header ---------- */
.header-ai {
  margin: 12px 0 4px; padding: 12px 14px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.header-ai-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.header-ai-title { font-size: 12.5px; font-weight: 800; color: var(--accent); }
.header-ai-topic { margin-top: 6px; font-size: 12.5px; color: var(--text-3); line-height: 1.45; }
.header-ai-keywords { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.header-ai-kw {
  padding: 2px 8px; border-radius: 999px; font-size: 11.5px; font-weight: 700;
  background: rgba(232, 180, 0, 0.12); color: var(--accent);
  border: 1px solid rgba(232, 180, 0, 0.3);
}
.header-ai-options { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.header-ai-option {
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  padding: 9px 12px; cursor: pointer;
  background: var(--surface-3); color: var(--text-1);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  transition: border-color 0.15s var(--ease), background 0.15s var(--ease);
}
.header-ai-option:hover { border-color: var(--accent); background: rgba(232, 180, 0, 0.06); }
.header-ai-option.active { border-color: var(--accent); background: rgba(232, 180, 0, 0.1); }
.header-ai-option-title { font-size: 14px; font-weight: 700; }
.header-ai-option-title .hl { color: var(--accent); }
.header-ai-option-why { font-size: 11.5px; color: var(--text-3); }

/* ---------- Dải clip xem trước sớm (trong lúc còn đang phân tích) ---------- */
.mc-clips-preview { margin: 16px 0 4px; }
.mc-clips-preview-label {
  font-size: 12px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 8px;
}
.mc-clips-preview-strip { display: flex; gap: 8px; flex-wrap: wrap; }
.mc-clips-preview-item {
  position: relative; width: 96px; aspect-ratio: 9 / 16;
  border-radius: var(--radius-sm); overflow: hidden;
  background: var(--surface-3); border: 1px solid var(--border);
}
.mc-clips-preview-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mc-clips-preview-order {
  position: absolute; top: 4px; left: 4px; min-width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 999px; background: rgba(0, 0, 0, 0.7); color: #fff;
  font-size: 11px; font-weight: 800;
}
.mc-clips-preview-dur {
  position: absolute; bottom: 4px; right: 4px; padding: 1px 5px;
  border-radius: 4px; background: rgba(0, 0, 0, 0.7); color: #fff;
  font-size: 10.5px; font-weight: 700;
}

.job-music { margin-bottom: 14px; }
.job-music .music-browse-btn { margin-top: 0; }
.job-music-upload-btn {
  width: 100%; margin-top: 8px; padding: 8px 12px;
  background: transparent; color: var(--text-3);
  border: none; border-radius: var(--radius-sm);
  font-size: 12.5px; font-weight: 600; cursor: pointer;
  transition: color .15s;
}
.job-music-upload-btn:hover { color: var(--accent); }
.job-music-volume { margin-top: 10px; }
.job-music-volume input[type="range"] { width: 100%; }

/* Phải bám .modal-backdrop: rule ".modal-backdrop .modal-box" (2 class) có độ ưu
   tiên cao hơn ".music-modal-box" (1 class) nên nếu viết trần thì chiều rộng bị
   đè mất, modal co lại ~480px và nhãn 4 tab vỡ xuống 2 dòng. */
.modal-backdrop .music-modal-box { width: min(760px, 94vw); max-width: min(760px, 94vw); }
.modal-backdrop .music-modal-body { padding: 0; }

.music-tabs { display: flex; gap: 4px; padding: 0 20px; border-bottom: 1px solid var(--border); }
.music-tab {
  padding: 11px 14px; background: none; border: none; cursor: pointer;
  color: var(--text-3); font-size: 13px; font-weight: 700;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  white-space: nowrap;
}
.music-tab:hover { color: var(--text-2); }
.music-tab.active { color: var(--accent); border-bottom-color: var(--accent); }

.music-pane { padding: 16px 20px 20px; }

/* Danh sách cuộn trong khung cố định: bảng xếp hạng có 50 bài, để nó đẩy dài
   cả modal thì nút đóng trôi mất khỏi màn hình. */
.music-list {
  display: flex; flex-direction: column; gap: 6px;
  max-height: 46vh; overflow-y: auto; margin-top: 12px;
}

.music-item {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--radius-md);
}
.music-item:hover { border-color: var(--border-strong); }

.music-rank { width: 22px; text-align: center; font-size: 13px; font-weight: 800; color: var(--text-3); flex-shrink: 0; }
.music-art { width: 38px; height: 38px; border-radius: var(--radius-sm); object-fit: cover; flex-shrink: 0; }

.music-play {
  width: 32px; height: 32px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-3); color: var(--text-2);
  border: none; border-radius: 50%; cursor: pointer;
}
.music-play .icon { width: 14px; height: 14px; }
.music-play:hover:not(:disabled) { background: var(--accent); color: #000; }
.music-play:disabled { opacity: .3; cursor: default; }
.music-play.playing { background: var(--accent); color: #000; }

.music-item-info { flex: 1; min-width: 0; }
.music-item-title {
  font-size: 13px; font-weight: 700; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.music-item-meta { font-size: 11px; color: var(--text-3); margin-top: 2px; }

.music-item .music-use { flex-shrink: 0; padding: 6px 13px; font-size: 12px; }

.music-star {
  width: 28px; height: 28px; flex-shrink: 0;
  background: none; border: none; cursor: pointer;
  color: var(--text-3); font-size: 15px; line-height: 1;
}
.music-star:hover { color: var(--accent); }
.music-star.on { color: var(--accent); }

.music-del {
  width: 28px; height: 28px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer; color: var(--text-3);
}
.music-del .icon { width: 13px; height: 13px; }
.music-del:hover { color: var(--danger-soft); }

.music-empty {
  padding: 26px 18px; text-align: center;
  font-size: 13px; color: var(--text-3); line-height: 1.6;
}

.music-search-row { display: flex; gap: 8px; }
.music-search-input {
  flex: 1; padding: 10px 13px;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-md);
  font-size: 13px;
}
.music-search-input:focus { outline: none; border-color: var(--accent); }

.music-note { font-size: 12px; color: var(--text-3); line-height: 1.6; margin-top: 10px; }
.music-note b { color: var(--text-2); }

/* Cảnh báo bản quyền ở tab "đang hot" — cố ý dùng màu cảnh báo chứ không phải
   màu phụ mờ nhạt: đây là chỗ dễ khiến video bán hàng của khách bị tắt tiếng. */
.music-warn {
  padding: 11px 13px; border-radius: var(--radius-md);
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.28);
  color: var(--text-2); font-size: 12px; line-height: 1.65;
}
.music-warn b { color: var(--warning); }

.music-status { font-size: 12px; color: var(--text-3); margin-top: 12px; min-height: 16px; }

.music-genres { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.music-genre {
  padding: 5px 11px; border-radius: 999px;
  background: var(--surface-2); color: var(--text-2);
  border: 1px solid var(--border); cursor: pointer;
  font-size: 12px; font-weight: 600;
}
.music-genre:hover { color: var(--accent); border-color: var(--accent); background: rgba(232, 180, 0, 0.07); }

.music-free-head { display: flex; align-items: flex-start; gap: 12px; }
.music-free-head .music-note { flex: 1; margin-top: 0; }
.music-free-head .btn-sm { flex-shrink: 0; padding: 6px 12px; font-size: 12px; }
.music-genre.on { color: #000; background: var(--accent); border-color: var(--accent); }
.music-more { margin-top: 14px; border-top: 1px solid var(--border); padding-top: 12px; }
.music-more summary {
  cursor: pointer; font-size: 12px; font-weight: 700; color: var(--text-3);
  list-style: none; margin-bottom: 10px;
}
.music-more summary:hover { color: var(--accent); }
.music-more summary::-webkit-details-marker { display: none; }
.music-more summary::before { content: "+ "; color: var(--accent); }
.music-more[open] summary::before { content: "− "; }
.music-more .music-list { max-height: 30vh; }

.music-hot {
  display: inline-block; margin-right: 6px; padding: 1px 7px;
  border-radius: 999px; font-size: 10px; font-weight: 800;
  background: rgba(232, 180, 0, 0.15); color: var(--accent);
  border: 1px solid rgba(232, 180, 0, 0.35); vertical-align: middle;
}

/* ---------- Preview stage (panel-review) ----------
   Một khung video duy nhất kiêm 3 vai: nhận diện (poster + tên + thời lượng
   ngay khi tải lên), xem trước sau phân tích, và sân khấu demo — 2 lớp
   .live-overlay đè lên video để chữ header/caption chạy thử NGAY khi bấm
   chọn kiểu bên dưới, đúng font/màu/vị trí, trước khi render thật. */
.preview-stage { margin-bottom: 16px; }
.preview-frame { position: relative; max-width: 420px; margin: 0 auto; }

/* VÒNG SÁNG "AI ĐANG NGHĨ" quanh khung video trong lúc phân tích (anh Phong:
   tải lên là thấy video ngay, và phải có tín hiệu nhẹ nhàng cho biết AI đang
   làm việc). Một vệt sáng vàng-neon chạy vòng quanh viền khung, kèm quầng
   glow thở chậm. JS bật/tắt class qua setAiThinking(). */
@property --ai-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
.preview-frame.ai-analyzing::after {
  content: ""; position: absolute; inset: -4px; z-index: 4;
  border-radius: 16px; padding: 3px; pointer-events: none;
  background: conic-gradient(
    from var(--ai-angle),
    transparent 0 62%,
    rgba(232, 180, 0, 0.35) 74%,
    #eeff00 86%,
    rgba(232, 180, 0, 0.35) 96%,
    transparent 100%
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
  animation: ai-ring-spin 2.4s linear infinite;
}
.preview-frame.ai-analyzing {
  animation: ai-glow-breathe 2.4s ease-in-out infinite;
  border-radius: 14px;
}
@keyframes ai-ring-spin { to { --ai-angle: 360deg; } }
@keyframes ai-glow-breathe {
  0%, 100% { box-shadow: 0 0 14px rgba(232, 180, 0, 0.18); }
  50% { box-shadow: 0 0 26px rgba(238, 255, 0, 0.32); }
}
/* Video NGANG (16:9, 4:3...) — bật bởi syncPreviewOrientation() sau khi đọc
   videoWidth/videoHeight thật. Khung 420px vốn dành cho short dọc 9:16; giữ
   nó cho video ngang thì hình chỉ còn 420×236, nhìn không ra chi tiết gì.
   Cho tràn hết chiều rộng khu làm việc, cao tối đa 70% màn hình để vẫn thấy
   được các nút bên dưới mà không phải cuộn. */
.preview-frame.is-landscape { max-width: 100%; }
.preview-frame.is-landscape video { max-height: 70vh; }
.preview-meta {
  display: flex; justify-content: center; align-items: baseline; gap: 12px;
  margin-top: 8px; text-align: center;
}
.live-overlay {
  position: absolute; inset: 0; pointer-events: none; overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 6% 7%; z-index: 3;
}
.live-overlay.pos-top { justify-content: flex-start; }
.live-overlay.pos-middle { justify-content: center; }
.live-overlay.pos-bottom { justify-content: flex-end; }
.live-overlay .lp-line { width: 100%; text-align: center; }
.live-overlay.align-left .lp-line { text-align: left; }
.live-overlay.align-right .lp-line { text-align: right; }
/* video controls của trình duyệt chiếm ~40px đáy — caption demo đặt bottom
   phải nhích lên để không bị thanh play che mất */
#liveCaptionOverlay.pos-bottom { padding-bottom: 15%; }
.lp-header-pop { animation: lpHeaderPop 0.3s cubic-bezier(0.16, 1, 0.3, 1); }
@keyframes lpHeaderPop {
  from { opacity: 0; transform: scale(0.9); }
  to { opacity: 1; transform: scale(1); }
}

/* === BỐ CỤC XEM & CHỈNH — kiểu CapCut: icon trái · video giữa · panel phải ===
   Bấm icon bên trái → khu tương ứng (.rv-active) hiện ở panel phải.
   Mặc định (màn hẹp 761–1100px): xếp dọc, hiện tất cả các khu. */
.review-layout {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 0;
}
.review-left-col .divider { display: none; }

/* Khung <main> mặc định khoá 860px, căn giữa → lề đen 2 bên là "đất chết".
   CHỈ ở bước Xem & chỉnh mới gỡ khoá để icon/panel trải ra 2 bên video. */
main:has(#panel-review:not(.hidden)) { max-width: none; }

/* ----- Desktop rộng (≥1101px): 3 cột thật ----- */
@media (min-width: 1101px) {
  /* 4 CỘT (anh Phong 20/07): [icon] [KHUNG SỬA PHỤ ĐỀ] [video] [cài đặt].
     Khoảng trống chết bên trái video giờ thành khung sửa phụ đề; panel cài đặt
     phải thu lại chút (380→344) cho cân. */
  .review-layout {
    display: grid;
    /* VIDEO Ở GIỮA, KHUNG CỐ ĐỊNH (anh Phong 20/07): cột video giữa có bề rộng
       KHOÁ THEO MÀN HÌNH (clamp), KHÔNG phụ thuộc tỷ lệ video — nên đổi 9:16 ↔
       16:9 ↔ 1:1 thì 2 panel hai bên ĐỨNG YÊN, không xê dịch. 16:9 lấp đầy khung
       (cũ 640 → 960px, to thêm 50%); tỷ lệ dọc/vuông nằm GIỮA trong cùng khung
       đó. 2 cột hai bên cùng 1fr → luôn cân bằng, video cân giữa. Layout nới
       ~1860px căn giữa để chứa khung 960 + 2 panel đọc thoải mái. */
    grid-template-columns: 56px 1fr clamp(520px, 50vw, 720px) 1fr;
    gap: 20px;
    align-items: start;
    max-width: 1960px;
    margin-inline: auto;
  }
  /* DOM order = center, transcript, left, right → ghim từng cột đúng chỗ bằng grid-column */
  .review-left-col      { grid-column: 1; grid-row: 1; position: sticky; top: 88px; }
  .review-transcript-col{ grid-column: 2; grid-row: 1; position: sticky; top: 88px;
                          max-height: calc(100vh - 120px); display: flex; flex-direction: column; min-width: 0; }
  .review-center-col    { grid-column: 3; grid-row: 1; position: sticky; top: 88px; height: fit-content; min-width: 0; }
  .review-right-col  {
    grid-column: 4; grid-row: 1; position: sticky; top: 88px;
    max-height: calc(100vh - 120px); overflow-y: auto;
    padding: 2px 10px 40px;
  }

  /* Panel phải: mỗi lúc chỉ hiện KHU đang chọn (tabbed) */
  .review-right-col .rv-sec { display: none; }
  .review-right-col .rv-sec.rv-active { display: block; }

  /* Tiêu đề khu + nút ✓ gọn trên đầu panel */
  .review-right-col .rv-sec-header {
    display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;
  }
  .review-right-col .rv-sec-header h3 { font-size: 15px; font-weight: 800; margin: 0; }
  .review-right-col .rv-sec-confirm {
    width: 30px; height: 30px; border-radius: 8px; cursor: pointer;
    background: rgba(255,215,0,0.15); border: none; color: var(--accent);
    font-size: 15px; font-weight: 800;
  }
  .review-right-col .rv-sec-confirm:hover { background: rgba(255,215,0,0.28); }
}

/* ===== Desktop CapCut: hiện dải icon trái + nền tối + cỡ video vừa khung ===== */
@media (min-width: 1101px) {
  /* 1) DẢI ICON TRÁI — mặc định .rv-tabbar bị ẩn (chỉ mobile), bật lại ở đây */
  .review-left-col .rv-tabbar {
    display: flex; flex-direction: column; gap: 6px; align-items: stretch;
    padding: 0; position: sticky; top: 88px;
  }
  .review-left-col .rv-tab {
    width: 100%; min-height: 56px; padding: 6px 2px;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    background: none; border: none; border-radius: 12px; cursor: pointer;
    color: var(--text-2); transition: background .15s ease, color .15s ease;
  }
  .review-left-col .rv-tab .rv-tab-ic { font-size: 22px; line-height: 1; }
  .review-left-col .rv-tab .rv-tab-label {
    display: block; font-size: 9.5px; font-weight: 600; line-height: 1.1; text-align: center;
  }
  .review-left-col .rv-tab:hover { background: rgba(255,255,255,0.06); color: var(--text); }
  .review-left-col .rv-tab.active { background: rgba(255,215,0,0.15); color: var(--accent); }

  /* 2) NỀN TỐI — bỏ nền trắng/xám của #reviewForm, đồng màu giao diện */
  #reviewForm {
    --bg: #0a0a0c; --bg-elevated: #131316; --surface: rgba(24,24,28,0.75);
    --surface-solid: #18181c; --surface-2: #212126; --surface-3: #212126;
    --text: #f5f6f7; --text-2: #bcc1cc; --text-3: #969baa;
    --border: rgba(255,255,255,0.09); --border-strong: rgba(255,255,255,0.18);
    background: transparent; border: none; padding: 0; margin-top: 0;
  }
  #reviewForm input[type="text"], #reviewForm input[type="number"],
  #reviewForm textarea, #reviewForm select {
    background: #18181c; border-color: rgba(255,255,255,0.14); color: var(--text);
  }
  #reviewForm .btn-ghost { color: var(--text-2); }
  #reviewForm .btn-ghost:hover:not(:disabled) { color: #fff; background: rgba(255,255,255,0.08); }
  #reviewForm .lf-chip-label { color: #cdd3dd; }

  /* 3) CỠ VIDEO — to nhất trong khung giữa nhưng KHÔNG tràn (giới hạn cả
     chiều cao màn hình lẫn bề rộng để landscape/cropped không phình ra) */
  /* SÂN KHẤU VIDEO CHIỀU CAO CỐ ĐỊNH (anh Phong 20/07: "đổi tỷ lệ thì khung nền
     trắng vẫn cố định như 9:16, không làm trải nghiệm tệ"). Khung sân khấu khoá
     cả bề rộng (cột clamp) LẪN chiều cao (min(78vh,760px)) → mọi tỷ lệ (9:16,
     16:9, 1:1, 4:5) nằm GIỮA khung này, thẻ trắng KHÔNG co giãn khi đổi tỷ lệ. */
  .review-center-col .preview-stage {
    height: min(78vh, 760px);
    /* CĂN LÊN TRÊN (anh Phong 20/07): video dồn sát mép trên khung → cạnh trên
       thẳng hàng với khung phụ đề & khung cài đặt (1 đường ngang). 16:9 lùn thì
       chừa khoảng trống PHÍA DƯỚI, không "hụt xuống giữa" như trước. Khung vẫn
       cao cố định nên thẻ trắng không co giãn khi đổi tỷ lệ. */
    display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
    gap: 8px; margin-bottom: 14px;
  }
  .review-center-col .preview-frame { max-width: 440px; margin: 0 auto; }
  .review-center-col .preview-frame.is-landscape,
  .review-center-col .preview-frame.is-cropped { max-width: 100%; }
  /* Video luôn vừa trong chiều cao sân khấu (trừ ~44px cho tên file bên dưới) —
     9:16 dọc lấp gần trọn chiều cao, 16:9 lùn hơn thì căn giữa để lại đệm trên/dưới. */
  .review-center-col .preview-frame video,
  .review-center-col #previewVideo { max-height: calc(min(78vh, 760px) - 44px); }
}

/* ===== KHUNG SỬA PHỤ ĐỀ (cột trái màn Xem & chỉnh) — anh Phong 20/07 ===== */
/* Mặc định (mobile, bố cục flex dọc) ẨN — ở màn hẹp không có khoảng trống này,
   thêm khối phụ đề dài chỉ làm rối. Bật lại ở desktop ≥1101px bên dưới. */
.review-transcript-col { display: none; }
/* Timeline kiểu CapCut CHỈ dành cho mobile talking-head — desktop ẩn hoàn toàn
   (bật lại trong khối body.rv-tabs-on). */
.rv-timeline { display: none; }

/* Ô màu xem trước cạnh ô nhập hex (tab 🎨 Màu thương hiệu): hiện ĐÚNG màu đang
   được dùng — gạch chéo đỏ = mã sai, kẻ caro = đang để AI tự đo. */
.brand-swatch {
  flex: 0 0 auto; width: 38px; align-self: stretch; min-height: 38px;
  border-radius: var(--radius-md); border: 1px solid var(--border-strong);
}
.brand-swatch.is-invalid {
  background: repeating-linear-gradient(45deg, #ff5c5c 0 6px, transparent 6px 12px) !important;
}
.brand-swatch.is-auto {
  background: repeating-conic-gradient(rgba(255,255,255,.18) 0% 25%, transparent 0% 50%) 50%/12px 12px !important;
}

/* BẢNG MÀU bấm chọn — lưới ô màu tròn, ô đang chọn có vòng sáng */
.brand-swatches {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(34px, 1fr));
  gap: 8px; margin-top: 6px;
}
.brand-sw {
  aspect-ratio: 1; border-radius: 50%; cursor: pointer; padding: 0;
  border: 1px solid rgba(128,128,128,0.35);
  transition: transform .12s var(--ease), box-shadow .12s var(--ease);
}
.brand-sw:hover { transform: scale(1.12); }
.brand-sw.active {
  box-shadow: 0 0 0 2px var(--bg-elevated), 0 0 0 4px var(--accent);
  transform: scale(1.1);
}
/* THANH MÀU — dải cầu vồng đủ 360° tông màu, kéo để dò */
.brand-hue {
  width: 100%; height: 22px; margin-top: 6px; padding: 0;
  -webkit-appearance: none; appearance: none; border-radius: 11px; outline: none;
  border: 1px solid var(--border-strong); cursor: pointer;
  background: linear-gradient(90deg, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%);
}
.brand-hue::-webkit-slider-thumb {
  -webkit-appearance: none; width: 20px; height: 20px; border-radius: 50%;
  background: #fff; border: 2px solid rgba(0,0,0,0.45); cursor: pointer;
  box-shadow: 0 1px 4px rgba(0,0,0,0.5);
}
.brand-hue::-moz-range-thumb {
  width: 18px; height: 18px; border-radius: 50%; background: #fff;
  border: 2px solid rgba(0,0,0,0.45); cursor: pointer;
}
/* Nút mở bảng màu đầy đủ của hệ điều hành */
.brand-picker {
  flex: 0 0 auto; width: 44px; align-self: stretch; min-height: 38px; padding: 2px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  background: var(--surface-2); cursor: pointer;
}

/* Khung sửa phụ đề (.te-*): KHÔNG bọc media query — dùng chung cho cả desktop
   (cột riêng, ≥1101px) LẪN mobile (anh Phong 20/07 vòng 2: đưa vào tab "Văn
   bản" trong sheet CapCut, xem #transcriptCol trong index.html + khối
   body.rv-tabs-on .rv-sec[data-sec="transcript"] bên dưới). Toàn bộ màu đọc
   qua var(--text)/(--border)/... nên tự đổi đúng tông theo nền sáng (desktop)
   hay tối (sheet mobile) mà không cần viết 2 bộ. */
.te-head { flex: 0 0 auto; margin-bottom: 8px; }
.te-title { display: block; font-size: 13px; font-weight: 800; color: var(--text); }
.te-status { display: block; font-size: 11.5px; line-height: 1.5; color: var(--text-3); margin-top: 3px; }
.te-warn-inline { color: #b8860b; font-weight: 800; }

/* Danh sách câu — CÓ KHUNG RÕ RÀNG (anh Phong: "để không bị vượt & cân đối"):
   viền + bo góc + nền tối liền app, cuộn riêng trong khung, chữ không tràn. */
.te-body {
  flex: 1 1 auto; overflow-y: auto; min-height: 0;
  display: flex; flex-direction: column; gap: 1px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.015);
  padding: 8px 6px 8px 8px;
}
.te-seg {
  display: grid; grid-template-columns: 40px 1fr; gap: 8px; align-items: baseline;
  padding: 5px 6px; border-radius: 8px; transition: background .12s ease;
}
.te-seg:hover { background: rgba(255,255,255,0.04); }
.te-time {
  font-size: 10.5px; font-weight: 700; color: var(--text-3);
  font-variant-numeric: tabular-nums; padding-top: 2px; user-select: none;
}
.te-text {
  font-size: 13.5px; line-height: 1.6; color: var(--text); outline: none;
  border-radius: 6px; padding: 1px 4px; margin: -1px -4px;
  white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; min-width: 0;
}
.te-text:hover { background: rgba(255,255,255,0.05); cursor: text; }
.te-text:focus { background: rgba(255,215,0,0.05); box-shadow: inset 0 0 0 1px rgba(255,215,0,0.3); }

/* TỪ SAI — AI nghe không chắc: CHỈ TÔ CHỮ VÀNG (không nền), màu vàng-hổ phách
   đậm để đọc RÕ trên cả nền sáng (desktop) lẫn nền tối (sheet mobile). Sửa
   khác bản gốc là tự hết vàng. */
.te-warn { color: #c79200; font-weight: 800; }
.te-body::-webkit-scrollbar { width: 8px; }
.te-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 4px; }

@media (min-width: 1101px) {
  .review-transcript-col { display: flex; }
}

/* Header text input + nút AI đề xuất nằm cùng hàng */
.header-input-row { display: flex; gap: 8px; align-items: stretch; }
.header-input-row input { flex: 1; }
.header-input-row .btn { white-space: nowrap; }
.checkbox-inline-row { display: flex; gap: 18px; padding-top: 9px; }
.checkbox-inline-row .checkbox-row { margin: 0; }

/* ---------- Style picker thu gọn (kiểu chữ header / kiểu caption) ----------
   Mặc định chỉ hiện ĐÚNG nhóm chứa kiểu đang chọn (1 hàng chip) cho không
   gian làm việc gọn; "Xem thêm" mở đủ 4 phân loại. Chỉ picker nào được gắn
   .collapsed mới thu gọn — bộ chọn bên tab Video dài giữ nguyên dạng đầy đủ. */
.style-picker.collapsed .style-group:not(.has-active) { display: none; }
.style-picker.collapsed .style-group.has-active .lf-caption-group-label { display: none; }
.style-more-btn {
  display: block; margin-top: 8px; padding: 6px 12px;
  background: transparent; border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm); color: var(--text-2);
  font-size: 12.5px; font-weight: 600; cursor: pointer;
  transition: color 0.15s var(--ease), border-color 0.15s var(--ease);
}
.style-more-btn:hover { color: var(--accent); border-color: var(--accent); }

/* Header kéo tự do trên khung xem trước */
.lp-header-drag { pointer-events: auto; cursor: move; user-select: none; }
.live-overlay.pos-custom { display: block; padding: 0; }
.header-defaults-cell { display: flex; align-items: flex-end; padding-bottom: 2px; }
input[type="range"]#thHeaderWidth { width: 100%; accent-color: var(--accent); }

/* ---------- Kiểu video — chip bố cục thumbnail (Dạng 1) ----------
   Mỗi chip là 1 "sân khấu" nền tối mô phỏng khung video, bên trong vẽ đúng
   lockup chữ bằng thumbLockupHtml — chip trông sao render ra đúng vậy. */
.thumb-style-chip { width: 168px; }
.thumb-chip-stage {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 74px; overflow: hidden;
  background: linear-gradient(160deg, #23282f 0%, #14171c 100%);
  border-radius: 6px; padding: 4px 6px;
}
.thumb-chip-stage > div { transform: scale(0.92); }

/* ---------- Chip nền lớp phủ (overlay scrim) — Dạng 1 ---------- */
.overlay-bg-chip { width: 108px; }
.overlay-bg-swatch {
  display: block; width: 100%; height: 60px; border-radius: 6px;
  border: 1px solid rgba(255,255,255,0.12);
}

/* Ô chọn ẢNH NỀN Dạng 2 (anh Phong 21/07) — lưới ô vuông ảnh thật, bấm chọn.
   Ô "Tự động" đứng đầu (viền nét đứt). Ô đang chọn viền accent + dấu ✓. */
.dang2-bg-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(78px, 1fr));
  gap: 8px; margin: 8px 0 4px;
}
.dang2-bg-chip {
  position: relative; aspect-ratio: 9 / 16; border-radius: 8px; cursor: pointer;
  background-size: cover; background-position: center; background-color: #1a1a20;
  border: 2px solid transparent; padding: 0; overflow: hidden;
  -webkit-tap-highlight-color: transparent;
}
.dang2-bg-chip.active { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(255,215,0,0.35); }
.dang2-bg-chip.active::after {
  content: "✓"; position: absolute; top: 4px; right: 4px;
  width: 18px; height: 18px; border-radius: 50%; background: var(--accent); color: #111;
  font-size: 12px; font-weight: 900; display: flex; align-items: center; justify-content: center;
}
.dang2-bg-auto {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  background: var(--surface-2, #1a1a20); border: 2px dashed rgba(255,255,255,0.28);
  color: var(--text-2, #cbcbd4); font-size: 11px; font-weight: 700;
}
.dang2-bg-auto.active { border-style: solid; border-color: var(--accent); color: var(--accent); }
.dang2-bg-auto-ic { font-size: 20px; }

/* ---------- Khung thu gọn cho các phần cài đặt dài (Text Header, Caption,
   Gợi ý AI, Slide) — mặc định ĐÓNG để không gian làm việc gọn; Kiểu video /
   Khung hình / Nhạc nền vẫn mở vì là lựa chọn chính. ---------- */
details.settings-fold { border-top: 1px solid var(--border); padding-top: 4px; margin-top: 14px; }
details.settings-fold > summary {
  cursor: pointer; list-style: none; user-select: none;
  display: flex; align-items: center; gap: 8px;
}
details.settings-fold > summary::-webkit-details-marker { display: none; }
details.settings-fold > summary::before {
  content: "▸"; color: var(--accent); font-size: 12px;
  transition: transform 0.15s var(--ease);
}
details.settings-fold[open] > summary::before { transform: rotate(90deg); }
details.settings-fold > summary:hover { color: var(--accent); }

/* Dòng mẫu caption — câu thật trong video, chạy bằng kiểu đang chọn */
.caption-sample {
  margin: 10px 0 14px; padding: 14px 16px;
  background: linear-gradient(180deg, rgba(0,0,0,0.5), rgba(0,0,0,0.25));
  border: 1px solid var(--border); border-radius: var(--radius-md);
}
.caption-sample-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.caption-sample-tag {
  padding: 2px 8px; border-radius: 999px; font-size: 10px; font-weight: 800;
  background: rgba(232,180,0,0.15); color: var(--accent);
  border: 1px solid rgba(232,180,0,0.3);
}
.caption-sample-src { font-size: 11px; color: var(--text-3); }
.caption-sample-stage {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  min-height: 42px;
}
.caption-sample-chunk { display: inline-flex; }
.caption-sample-stage .lf-chip-preview { font-size: 20px; }

/* ============================================================
   MÀN "NÂNG CẤP GÓI" (view-upgrade)
   Ngôn ngữ thị giác: nền tối + accent vàng gold→neon như toàn app.
   Thẻ Pro là tâm điểm: viền gradient vàng, glow, badge, nhích cao hơn
   các thẻ còn lại — mắt phải rơi vào đó đầu tiên (giống OpusClip).
   ============================================================ */

/* Tab sidebar "Nâng cấp" — nhuộm vàng nhẹ để nổi giữa các tab thường
   nhưng không chói tới mức tranh chấp với nút CTA chính của app. */
.tab-upgrade .tab-label { color: var(--accent); font-weight: 600; }
.tab-upgrade .tab-icon { color: var(--accent); }
.tab-upgrade.active .tab-label, .tab-upgrade.active .tab-icon { color: var(--neon); }

/* ---------- Hero ---------- */
.pricing-hero { text-align: center; padding: 34px 20px 6px; }
.pricing-hero-badge {
  display: inline-block;
  /* letter-spacing 0.08em khớp quy ước eyebrow-label toàn app (feature-strip-
     label, video-mẫu-label...) — bản trước 0.22em quá rộng, chữ rời rạc
     trông thiếu chăm chút thay vì sang trọng. */
  font-size: 11.5px; font-weight: 800; letter-spacing: 0.08em;
  color: var(--accent);
  border: 1px solid rgba(232, 180, 0, 0.35);
  background: rgba(232, 180, 0, 0.08);
  border-radius: 999px;
  padding: 6px 14px;
  margin-bottom: 18px;
}
.pricing-hero-title {
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-size: 36px; font-weight: 800; letter-spacing: -0.02em;
  background: linear-gradient(120deg, #fff 30%, var(--accent) 70%, var(--neon));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.pricing-hero-sub { margin: 0 auto 24px; max-width: 560px; color: var(--text-2); font-size: 15.5px; }

/* ---------- Nút gạt Tháng / Năm ---------- */
.billing-toggle {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px; padding: 4px;
  margin-bottom: 30px;
}
.billing-opt {
  display: inline-flex; align-items: center; gap: 8px;
  border: none; cursor: pointer;
  background: transparent; color: var(--text-2);
  font-size: 14px; font-weight: 600;
  padding: 9px 18px; border-radius: 999px;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.billing-opt:hover { color: var(--text); }
.billing-opt.active {
  background: linear-gradient(135deg, var(--accent), var(--neon));
  color: #14120a;
  box-shadow: 0 2px 12px rgba(232, 180, 0, 0.35);
}
.billing-save {
  font-size: 11px; font-weight: 800; letter-spacing: 0.02em;
  background: rgba(34, 197, 94, 0.18); color: var(--success);
  border-radius: 999px; padding: 3px 8px;
}
.billing-opt.active .billing-save { background: rgba(0, 0, 0, 0.22); color: #0c2e18; }

/* ---------- Lưới 4 thẻ giá ---------- */
.pricing-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 18px;
  align-items: stretch;
  max-width: 1280px; margin: 0 auto; padding: 8px 4px 6px;
}
@media (max-width: 1200px) { .pricing-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .pricing-grid { grid-template-columns: 1fr; } }

.plan-card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: 26px 22px;
  transition: transform 0.3s var(--ease), border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.plan-card:hover { transform: translateY(-4px); border-color: var(--border-strong); box-shadow: var(--shadow-md); }

/* Thẻ Pro — tâm điểm của cả màn. Viền gradient vàng thật (border-image
   không bo góc được nên dùng lớp nền kép: gradient ngoài + nền đặc trong). */
.plan-card-featured {
  border: 1.5px solid transparent;
  background:
    linear-gradient(var(--surface-solid), var(--surface-solid)) padding-box,
    linear-gradient(160deg, var(--accent), rgba(238, 255, 0, 0.85) 45%, rgba(232, 180, 0, 0.4)) border-box;
  box-shadow: 0 0 0 1px rgba(232, 180, 0, 0.12), 0 18px 50px -18px rgba(232, 180, 0, 0.35);
}
@media (min-width: 1201px) { .plan-card-featured { transform: translateY(-10px); } }
.plan-card-featured:hover {
  transform: translateY(-14px);
  box-shadow: 0 0 0 1px rgba(232, 180, 0, 0.2), 0 24px 60px -18px rgba(232, 180, 0, 0.45);
}
@media (max-width: 1200px) {
  .plan-card-featured { transform: none; }
  .plan-card-featured:hover { transform: translateY(-4px); }
}
.plan-badge {
  position: absolute; top: -12px; left: 50%; transform: translateX(-50%);
  white-space: nowrap;
  font-size: 11px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase;
  background: linear-gradient(135deg, var(--accent), var(--neon));
  color: #14120a;
  border-radius: 999px; padding: 5px 14px;
  box-shadow: 0 4px 14px rgba(232, 180, 0, 0.45);
}

.plan-name { font-family: var(--font-display); font-size: 21px; font-weight: 800; letter-spacing: -0.01em; }
.plan-card-featured .plan-name { color: var(--neon); }
.plan-desc { color: var(--text-3); font-size: 13px; margin: 3px 0 16px; }

.plan-price { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; min-height: 44px; }
.plan-strike { color: var(--text-3); font-size: 16px; font-weight: 600; text-decoration: line-through; text-decoration-thickness: 2px; }
.plan-amount { font-family: var(--font-display); font-size: 32px; font-weight: 800; letter-spacing: -0.02em; color: var(--text); font-variant-numeric: tabular-nums; }
.plan-card-featured .plan-amount { color: var(--neon); text-shadow: 0 0 24px rgba(238, 255, 0, 0.25); }
.plan-amount-contact { font-size: 28px; }
.plan-per { color: var(--text-3); font-size: 14px; font-weight: 600; }
.plan-bill-note { color: var(--text-3); font-size: 12.5px; margin: 4px 0 18px; min-height: 18px; }

/* ---------- Nút chọn gói ---------- */
.plan-cta {
  width: 100%;
  border-radius: var(--radius-md);
  padding: 12px 16px;
  font-size: 14.5px; font-weight: 700;
  cursor: pointer;
  transition: filter 0.2s var(--ease), background 0.2s var(--ease), box-shadow 0.2s var(--ease);
  margin-bottom: 20px;
}
.plan-cta-primary {
  border: none;
  background: linear-gradient(135deg, var(--accent), var(--neon));
  color: #14120a;
  box-shadow: 0 6px 22px rgba(232, 180, 0, 0.35);
}
.plan-cta-primary:hover { filter: brightness(1.08); box-shadow: 0 8px 28px rgba(232, 180, 0, 0.5); }
.plan-cta-outline {
  background: transparent;
  border: 1px solid rgba(232, 180, 0, 0.5);
  color: var(--accent);
}
.plan-cta-outline:hover { background: rgba(232, 180, 0, 0.1); }
.plan-cta-ghost {
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-3);
  cursor: default;
}

.plan-includes { font-size: 12.5px; font-weight: 700; color: var(--text-2); margin-bottom: 10px; }

/* ---------- Danh sách tính năng trong thẻ ---------- */
.plan-features { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.plan-features li {
  position: relative;
  padding-left: 26px;
  font-size: 13.5px; color: var(--text-2); line-height: 1.45;
}
.plan-features li b { color: var(--text); font-weight: 700; }
.plan-features li::before {
  content: "✓";
  position: absolute; left: 0; top: 0;
  width: 17px; height: 17px;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 800;
  color: var(--accent);
  background: rgba(232, 180, 0, 0.12);
  border: 1px solid rgba(232, 180, 0, 0.3);
  border-radius: 50%;
}
.plan-card-featured .plan-features li::before {
  color: #14120a;
  background: linear-gradient(135deg, var(--accent), var(--neon));
  border-color: transparent;
}

/* ---------- Dải cam kết + chú thích credit ---------- */
.pricing-perks {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
  max-width: 1280px; margin: 26px auto 0; padding: 0 4px;
}
.pricing-perk {
  font-size: 13px; color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px; padding: 9px 16px;
}
.pricing-perk b { color: var(--text); }
.pricing-credit-note {
  text-align: center; color: var(--text-3); font-size: 12.5px;
  margin: 14px auto 0; max-width: 640px;
}

/* ---------- Bảng so sánh ---------- */
.pricing-compare { max-width: 1080px; margin: 48px auto 0; padding: 0 4px; }
.pricing-compare-title {
  text-align: center; font-size: 22px; font-weight: 800; letter-spacing: -0.01em;
  margin: 0 0 20px;
}
.pricing-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-solid);
}
.pricing-table { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 660px; }
.pricing-table th, .pricing-table td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  text-align: center; color: var(--text-2);
}
.pricing-table th {
  font-size: 13px; font-weight: 800; color: var(--text);
  background: var(--surface-2);
  position: sticky; top: 0;
}
.pricing-table th:first-child, .pricing-table td:first-child { text-align: left; color: var(--text); font-weight: 500; }
.pricing-table tbody tr:last-child td { border-bottom: none; }
.pricing-table tbody tr:hover td { background: rgba(255, 255, 255, 0.02); }
/* Cột Pro được nhuộm vàng nhạt suốt chiều dọc — nhắc lại "đây là gói nên chọn". */
.pricing-table .col-pro { background: rgba(232, 180, 0, 0.07); color: var(--text); font-weight: 600; }
.pricing-table th.col-pro { color: var(--neon); }
.pricing-table-note { text-align: center; color: var(--text-3); font-size: 12px; margin-top: 10px; }

/* ---------- FAQ ---------- */
.pricing-faq { max-width: 760px; margin: 48px auto 40px; padding: 0 4px; }
.pricing-faq-item {
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  margin-bottom: 10px;
  overflow: hidden;
}
.pricing-faq-item summary {
  cursor: pointer; list-style: none;
  padding: 15px 18px;
  font-size: 14.5px; font-weight: 700; color: var(--text);
  transition: background 0.2s var(--ease);
  position: relative;
}
.pricing-faq-item summary::-webkit-details-marker { display: none; }
.pricing-faq-item summary::after {
  content: "+";
  position: absolute; right: 18px; top: 50%; transform: translateY(-50%);
  color: var(--accent); font-size: 18px; font-weight: 700;
  transition: transform 0.25s var(--ease);
}
.pricing-faq-item[open] summary::after { transform: translateY(-50%) rotate(45deg); }
.pricing-faq-item summary:hover { background: rgba(255, 255, 255, 0.03); }
.pricing-faq-item p { margin: 0; padding: 0 18px 16px; color: var(--text-2); font-size: 13.5px; line-height: 1.6; }

/* ============================================================
   KHÓA TÍNH NĂNG THEO GÓI (mô phỏng qua localStorage — xem app.js
   getPlan()/planAtLeast()). Ngôn ngữ: mờ đi + khóa vàng nhỏ góc trên phải,
   không xoá layout, không đổi kích thước phần tử khi khóa/mở.
   ============================================================ */

/* Cụm bên phải topbar: [badge gói+credit] — [tên/email + avatar], tách rời
   hẳn 2 nhóm bằng gap riêng, không nhét chung vào .account-chip (đó là lý do
   bản trước bị rối: 4 phần tử rời rạc chen nhau trong cùng 1 hàng gap:10px). */
.app-topbar-right { display: flex; align-items: center; gap: 14px; }

/* Lối tắt Giá cả / Dự án trên topbar (học theo Seedream) — pill tối viền
   nhẹ, hover nhuộm vàng neon đúng tông thương hiệu (accent → neon). */
.topbar-nav-btn {
  position: relative;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 18px; border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  color: var(--text);
  font-family: var(--font-display);
  font-weight: 700; font-size: 13.5px; letter-spacing: 0.01em;
  white-space: nowrap; flex-shrink: 0; /* không bao giờ xuống dòng/đè logo */
  cursor: pointer;
  transition: border-color 0.15s var(--ease), background 0.15s var(--ease), box-shadow 0.15s var(--ease), color 0.15s var(--ease);
}
.topbar-nav-btn:hover {
  border-color: rgba(232, 180, 0, 0.55);
  background: linear-gradient(135deg, rgba(232, 180, 0, 0.14), rgba(238, 255, 0, 0.06));
  box-shadow: 0 0 14px rgba(238, 255, 0, 0.18);
  color: var(--neon-text);
}
.topbar-nav-ic { font-size: 14px; line-height: 1; }
/* Huy hiệu khuyến mãi đè mép dưới-trái nút Giá cả — hồng rực nổi bật trên nền
   vàng/đen (đúng lối Seedream), là ưu đãi THẬT "theo năm tiết kiệm 35%". */
.topbar-sale-badge {
  position: absolute; left: 10px; bottom: -9px;
  background: linear-gradient(135deg, #ff2d78, #ff5e3a);
  color: #fff; font-size: 10px; font-weight: 800; letter-spacing: 0.02em;
  padding: 2px 8px; border-radius: 999px;
  border: 1.5px solid var(--bg);
  box-shadow: 0 2px 8px rgba(255, 45, 120, 0.45);
  pointer-events: none; white-space: nowrap;
}
/* Màn hẹp: sidebar vẫn còn 2 tab này (dạng icon) — giấu lối tắt cho topbar thoáng */
/* Tab "Dự án" + "Nâng cấp" trong sidebar: ẨN ở MỌI cỡ màn (anh Phong — lối
   tắt Giá cả/Dự án trên topbar giờ hiện cả mobile lẫn PC, không cần bản đúp),
   nhưng GIỮ NGUYÊN trong DOM vì toàn bộ điều hướng (nút topbar, nút Nâng cấp
   trong hồ sơ, các luồng "lưu xong nhảy về Dự án"...) đều .click() vào 2 tab
   này. */
.side-nav .tab[data-view="library"],
.side-nav .tab[data-view="upgrade"] { display: none; }

/* Badge gói+credit GỘP LÀM MỘT: biểu tượng gói (rỗng ở Free — không cần huy
   hiệu cho bậc miễn phí) + số credit, không còn chữ tên gói (anh Phong:
   "chữ Pro nên là biểu tượng... chỉ cần hiển thị credit bên cạnh"). */
/* Viên số credit trên topbar đã BỎ (vòng 3) — credit giờ là vòng năng lượng
   quanh avatar (.account-avatar-wrap phía trên), chi tiết trong popover. */

/* Thẻ giá đang là gói hiện tại — viền neon nhẹ để phân biệt với "Phổ biến nhất" */
.plan-card-current { border-color: rgba(34, 197, 94, 0.5); }
.plan-cta-current {
  background: rgba(34, 197, 94, 0.12) !important;
  border: 1px solid rgba(34, 197, 94, 0.4) !important;
  color: var(--success) !important;
  cursor: default !important;
}

/* Chip caption/thumbnail bị khóa (Free vượt hạn mức) */
.lf-caption-style-chip.chip-locked {
  position: relative;
  opacity: 0.42;
  cursor: not-allowed;
  filter: grayscale(0.6);
}
.lf-caption-style-chip.chip-locked:hover { opacity: 0.55; }
.lf-caption-style-chip.chip-locked::after {
  content: "🔒";
  position: absolute; top: 4px; right: 6px;
  font-size: 12px;
  filter: none;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

/* Nút/pill đơn lẻ bị khóa theo gói (B-roll, multiclip, tải LUT...) */
.locked-by-plan {
  opacity: 0.5;
  cursor: not-allowed !important;
  filter: grayscale(0.5);
  position: relative;
}
.locked-by-plan::after {
  content: "🔒";
  margin-left: 6px;
  font-size: 12px;
  filter: none;
}

/* ── Màn đăng nhập/đăng ký (Giai đoạn 2) ──────────────────────────────── */
.auth-modal-box {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  padding: 32px 28px; text-align: center;
}
.auth-modal-logo { height: 32px; margin-bottom: 4px; }
.auth-modal-tabs { display: flex; gap: 4px; background: var(--surface-3); border-radius: var(--radius-md); padding: 4px; width: 100%; }
.auth-modal-tab {
  flex: 1; padding: 8px 0; border-radius: var(--radius-sm); background: transparent; color: var(--text-2);
  border: none; cursor: pointer; font-size: 14px; font-weight: 600;
}
.auth-modal-tab.active { background: var(--surface-solid); color: var(--text); }
.btn-google {
  width: 100%; padding: 11px; border-radius: var(--radius-md); background: var(--surface-solid);
  border: 1px solid var(--border-strong); color: var(--text); font-weight: 600; cursor: pointer;
}
.btn-google:hover { border-color: var(--accent); }
.auth-modal-divider { width: 100%; display: flex; align-items: center; gap: 10px; color: var(--text-3); font-size: 12px; }
.auth-modal-divider::before, .auth-modal-divider::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.auth-modal-form { width: 100%; display: flex; flex-direction: column; gap: 10px; }
.auth-modal-form input {
  width: 100%; padding: 11px 14px; border-radius: var(--radius-md); border: 1px solid var(--border-strong);
  background: var(--surface-3); color: var(--text); font-size: 14px;
}
.auth-modal-form input:focus { outline: none; border-color: var(--accent); }
.auth-modal-form .btn { width: 100%; margin-top: 4px; }
.auth-modal-error { color: var(--danger-soft); font-size: 13px; }
.auth-modal-link {
  background: none; border: none; color: var(--text-3); font-size: 13px; cursor: pointer;
  text-decoration: underline; padding: 2px; align-self: center;
}
.auth-modal-link:hover { color: var(--accent); }
.account-verify-banner {
  display: flex; align-items: center; gap: 8px; justify-content: space-between;
  padding: 8px 10px; margin-top: 10px; border-radius: var(--radius-sm);
  background: rgba(238, 255, 0, 0.08); border: 1px solid rgba(238, 255, 0, 0.25);
  font-size: 12px; color: var(--text-2);
}
.account-verify-banner button {
  background: none; border: none; color: var(--accent); font-size: 12px; cursor: pointer;
  text-decoration: underline; padding: 0; white-space: nowrap;
}
.account-popover-logout {
  width: 100%; margin-top: 10px; padding: 8px; border-radius: var(--radius-sm); background: transparent;
  border: 1px solid var(--border); color: var(--text-2); cursor: pointer; font-size: 13px;
}
.account-popover-logout:hover { color: var(--text); border-color: var(--danger-soft); }

/* ---------- Modal chỉnh sửa hồ sơ (ảnh đại diện + tên hiển thị) ---------- */
.profile-modal-box { max-width: 380px; }
.profile-avatar-row { display: flex; align-items: center; gap: 16px; margin-bottom: 16px; }
.profile-avatar-preview {
  width: 84px; height: 84px; border-radius: 50%; flex-shrink: 0;
  background: linear-gradient(150deg, var(--accent), var(--accent-2));
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 32px; color: #1a0f06;
  overflow: hidden; border: 2px solid var(--border-strong);
}
.profile-avatar-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.profile-avatar-actions { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.profile-field-label { display: block; font-size: 12.5px; color: var(--text-3); margin-bottom: 6px; }
.profile-name-input {
  width: 100%; padding: 10px 12px; border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px solid var(--border-strong);
  color: var(--text); font-size: 14px;
}
.profile-name-input:focus { outline: none; border-color: var(--accent); }
.profile-modal-actions { margin-top: 16px; display: flex; justify-content: flex-end; gap: 8px; }

/* Vùng nguy hiểm — gấp lại mặc định, chỉ 1 dòng chữ đỏ nhỏ để khỏi lấn át
   nút Lưu hồ sơ. Bấm mới mở khối xác nhận (gõ lại email + cảnh báo rõ). */
.profile-danger-zone { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border); }
.profile-delete-toggle {
  background: transparent; border: none; padding: 0; cursor: pointer;
  font-size: 12.5px; color: var(--text-3); text-decoration: underline; text-underline-offset: 2px;
}
.profile-delete-toggle:hover { color: var(--danger); }
.profile-delete-confirm { margin-top: 12px; }
.profile-delete-warning {
  font-size: 12.5px; line-height: 1.5; color: var(--danger-soft);
  background: rgba(239, 68, 68, 0.1); border: 1px solid rgba(239, 68, 68, 0.3);
  border-radius: var(--radius-sm); padding: 10px 12px; margin: 0 0 10px;
}
.profile-delete-warning strong { color: var(--text); }


/* ============================================================
   KHU "XEM & CHỈNH" NỀN SÁNG (anh Phong 17/07: "màu nền ở chỗ sửa đổi là màu
   sáng để người dùng dễ nhìn — hiện tại khá tối và nhiều").
   Cách làm: re-declare bộ biến màu trong scope #reviewForm — mọi phần tử bên
   trong đọc var() nên tự đổi theo, không phải viết lại từng rule. Riêng các
   "sân khấu" mô phỏng khung video (chip caption/thumbnail, dòng mẫu) GIỮ nền
   tối — chữ mẫu màu trắng phải đứng trên nền tối mới đúng như lên video.
   ============================================================ */
#reviewForm {
  --bg: #eef0f4;
  --bg-elevated: #ffffff;
  --surface: #ffffffb8;
  --surface-solid: #ffffff;
  --surface-2: #ffffff;
  --surface-3: #e9ebf1;
  --text: #191b20;
  --text-2: #454c59;
  --text-3: #6a7181;
  --border: rgba(20, 24, 34, 0.14);
  --border-strong: rgba(20, 24, 34, 0.28);
  --shadow-md: 0 4px 16px rgba(15, 18, 28, 0.08);
  --shadow-lg: 0 16px 40px rgba(15, 18, 28, 0.12);
  background: linear-gradient(180deg, #f7f8fa, #edeff3);
  color: var(--text);
  border: 1px solid rgba(20, 24, 34, 0.08);
  border-radius: var(--radius-lg);
  padding: 4px 18px 18px;
  margin-top: 14px;
}
/* Ô nhập trên nền sáng: viền rõ hơn một chút để không "tan" vào nền trắng. */
#reviewForm input[type="text"], #reviewForm input[type="number"],
#reviewForm textarea, #reviewForm select {
  background: #fff;
  border-color: rgba(20, 24, 34, 0.18);
}
/* Chip kiểu chữ (caption/header/thumbnail/nền lớp phủ): chữ mẫu trắng — giữ
   sân khấu TỐI như khung video thật, chỉ phần nhãn dưới chip đổi theo nền. */
#reviewForm .lf-caption-style-chip {
  background: linear-gradient(160deg, #23282f 0%, #14171c 100%);
  border-color: rgba(20, 24, 34, 0.25);
}
#reviewForm .lf-caption-style-chip.active {
  border-color: var(--accent);
  background: linear-gradient(160deg, #2a2d26 0%, #17170f 100%);
}
#reviewForm .lf-chip-label { color: #cdd3dd; }
/* Dòng mẫu caption — câu thật chạy thử: cũng là "màn hình video" thu nhỏ. */
#reviewForm .caption-sample {
  background: linear-gradient(160deg, #23282f 0%, #14171c 100%);
}
#reviewForm .caption-sample-src { color: #9aa2b1; }
/* Nút ghost trên nền sáng cần chữ đậm hơn để còn thấy. */
#reviewForm .btn-ghost { color: #454c59; }
#reviewForm .btn-ghost:hover:not(:disabled) { color: #191b20; background: #e5e8ee; }

/* ============================================================
   KHUNG HÌNH XUẤT — hàng chip tỷ lệ (2026-07-17, học từ app clip mobile).
   Chip kéo ngang được trên màn hẹp; icon là khung nhỏ đúng tỷ lệ thật.
   ============================================================ */
.aspect-row {
  /* XUỐNG DÒNG thay vì cuộn ngang (anh Phong 20/07: "không tính năng nào bị
     lấp") — 5 nút tỷ lệ tự dàn đều, thiếu chỗ thì rớt xuống hàng dưới, KHÔNG
     bao giờ bị cắt mất nút 16:9 ở mép phải như trước. */
  display: flex; flex-wrap: wrap; gap: 8px; padding: 2px 2px 6px; margin-bottom: 6px;
}
.aspect-chip {
  flex: 1 1 70px; min-width: 64px;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 7px;
  padding: 10px 10px 9px;
  background: var(--surface-2); border: 1.5px solid var(--border); border-radius: var(--radius-md);
  cursor: pointer; font-size: 11.5px; font-weight: 700; color: var(--text-3);
  transition: border-color 0.15s var(--ease);
}
.aspect-chip:hover { border-color: var(--border-strong); }
.aspect-chip.active { border-color: var(--accent); background: rgba(232, 180, 0, 0.07); color: var(--text); }
.aspect-ic { display: block; border: 2px solid currentColor; border-radius: 4px; opacity: 0.85; }
/* "Giữ nguyên" — khung nét đứt: không ép về tỷ lệ nào cả */
.aspect-ic-source { width: 22px; height: 18px; border-style: dashed; }
.aspect-ic-916 { width: 15px; height: 26px; }
.aspect-ic-11  { width: 21px; height: 21px; }
.aspect-ic-45  { width: 20px; height: 25px; }
.aspect-ic-169 { width: 26px; height: 15px; }

/* Mô phỏng crop trên khung xem trước: khung đúng tỷ lệ đích (inline
   aspect-ratio do app.js đặt), video object-fit cover — thấy ngay phần nào
   sẽ bị cắt. !important để thắng .is-landscape do syncPreviewOrientation
   đặt lại theo video gốc sau mỗi lần đổi nguồn. */
.preview-frame.is-cropped { overflow: hidden; margin: 0 auto; max-width: none; }
.preview-frame.is-cropped video {
  width: 100% !important; height: 100% !important;
  object-fit: cover; display: block; max-height: none !important;
}
/* (Kích thước khung crop do app.js đặt thẳng bằng px — applyAspectPreview
   tính theo cỡ màn + tỷ lệ đích, tránh CSS max-width bóp méo tỷ lệ.) */

/* ============================================================
   MOBILE "CHẾ ĐỘ EDITOR" kiểu CapCut — bước "Xem & chỉnh" (≤760px).
   Vòng 2 (anh Phong 17/07: "chưa thoáng và gọn như CapCut"):
   · Vào editor là ẨN topbar (logo/tài khoản/giảm giá — chưa cần thiết,
     tập trung tính năng) + stepper: chỉ còn thanh mảnh ✕ thoát (trái)
     và nút Xuất (phải) — body.editor-focus, app.js bật khi panel-review
     hiện trên màn ≤760px.
   · VIDEO LÀ NHÂN VẬT CHÍNH giữa nền tối, không chữ thừa (tên file ẩn);
     trạng thái "đang phân tích..." là CHIP NỔI ngay trên video.
   · Tính năng nằm ở THANH ĐÁY cố định (icon + nhãn nhỏ như CapCut);
     bấm tab là Ô TUỲ CHỌN TRƯỢT TỪ DƯỚI LÊN, ĐỨNG YÊN 1 CHỖ (fixed),
     cuộn bên trong ô — nền trang không trôi, không trượt thả lung tung.
     Bấm lại tab đang mở là ô hạ xuống, trả sân khấu cho video.
   PC không có body.rv-tabs-on nên giữ nguyên 100% bố cục cũ.
   ============================================================ */
.rv-tabbar { display: none; }
.rv-editbar { display: none; }
/* Nút ✓ chỉ dùng trong bottom-sheet mobile — ẩn trên desktop */
.rv-sec-confirm { display: none; }

@media (max-width: 760px) {
  /* ----- Chế độ editor: dọn sạch chrome, chỉ còn ✕ và Xuất ----- */
  body.editor-focus .app-topbar { display: none; }
  body.editor-focus #view-editor .stepper { display: none !important; }
  /* Footer marketing (Khám phá/Liên hệ/ảnh nền) không có việc gì trong
     editor — panel giờ gần như 0px trong flow nên footer trồi lên lộ sau
     video, phải ẩn hẳn. Thông báo nâng cấp/khuyến mãi cũng vậy: chỉ ở
     màn hình chính, trong editor tập trung tính năng. */
  body.editor-focus .app-footer { display: none; }
  body.editor-focus main { padding: 0 0 40px; }
  body.editor-focus #panel-review {
    background: transparent; border: none; box-shadow: none;
    border-radius: 0; margin: 0; padding: 52px 0 0; position: relative;
  }
  body.editor-focus .rv-editbar {
    display: flex; position: fixed; top: 0; left: 0; right: 0; z-index: 60;
    align-items: center; justify-content: space-between;
    padding: 8px 12px;
    background: linear-gradient(180deg, rgba(10, 10, 12, 0.94) 55%, rgba(10, 10, 12, 0));
  }
  .rv-editbar-btn {
    width: 38px; height: 38px; border-radius: 50%;
    background: var(--surface-2); border: 1px solid var(--border);
    color: var(--text); font-size: 16px; font-weight: 700; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
  }
  .rv-editbar-render {
    padding: 9px 20px; border-radius: 10px; border: none; cursor: pointer;
    background: linear-gradient(150deg, var(--accent), var(--accent-2, #e8b400));
    color: #1a0f06; font-weight: 800; font-size: 13.5px;
  }
  .rv-editbar-render:disabled { opacity: 0.45; }
  .rv-editbar-render.hidden { display: none; }

  /* ----- VIDEO NẰM IM MỘT KHU, KHÔNG BAO GIỜ CO GIÃN (anh Phong vòng 3:
     "khung cố định chưa được fix cứng, cứ thu lên thu xuống khi ấn tính
     năng"): sân khấu video là khung fixed có CHIỀU CAO CỐ ĐỊNH = phần màn
     còn lại sau khi đã CHỪA SẴN chỗ cho ô tuỳ chọn — bật tắt tính năng
     thoải mái, ô trượt lên trượt xuống ở vùng dưới, video đứng yên tuyệt
     đối. Các con số dùng chung qua biến --rv-* để 3 tầng luôn khớp nhau. */
  body.rv-tabs-on {
    --rv-top: 52px;    /* thanh ✕ / Xuất */
    --rv-bar: 72px;    /* thanh tính năng đáy (đã nâng cao cho dễ bấm) */
    --rv-sheet: 40dvh; /* vùng chừa sẵn cho ô tuỳ chọn */
    --rv-tl: 164px;    /* TIMELINE kiểu CapCut ngay dưới video (làn nhạc/phụ đề đã to hơn 20/07) */
  }
  body.rv-tabs-on #panel-review .panel-title { display: none; }
  /* CHIỀU CAO VIDEO (anh Phong 20/07 — sửa cho giống CapCut):
     · Sheet ĐÓNG  → video chiếm TRỌN chỗ trống xuống tới timeline (KHÔNG trừ
       --rv-sheet nữa; trước đây luôn trừ 40dvh nên video bị bóp nhỏ oan dù
       chưa mở tính năng nào).
     · Sheet MỞ    → nhường đúng chiều cao sheet; sheet (z-index 50) TRÙM LÊN
       timeline nhạc/phụ đề, y như CapCut kéo bảng công cụ lên. */
  body.rv-tabs-on #panel-review .preview-stage {
    position: fixed; top: var(--rv-top); left: 0; right: 0; z-index: 20;
    height: calc(100dvh - var(--rv-top) - var(--rv-bar) - var(--rv-tl) - env(safe-area-inset-bottom));
    display: flex; align-items: center; justify-content: center;
    margin: 0; padding: 4px 0;
    background: var(--bg); /* nền đặc — che sạch mọi nội dung trang phía sau */
    transition: height 0.26s var(--ease);
  }
  body.rv-sheet-open #panel-review .preview-stage {
    height: calc(100dvh - var(--rv-top) - var(--rv-bar) - var(--rv-sheet) - env(safe-area-inset-bottom));
  }
  body.rv-tabs-on #panel-review .preview-frame {
    width: fit-content; max-width: 100%; margin: 0 auto;
  }
  body.rv-tabs-on #panel-review .preview-frame video {
    display: block; width: auto; height: auto;
    max-height: calc(100dvh - var(--rv-top) - var(--rv-bar) - var(--rv-tl) - 20px - env(safe-area-inset-bottom));
    max-width: calc(100vw - 24px);
  }
  body.rv-sheet-open #panel-review .preview-frame video {
    max-height: calc(100dvh - var(--rv-top) - var(--rv-bar) - var(--rv-sheet) - 20px - env(safe-area-inset-bottom));
  }
  /* ===== TIMELINE KIỂU CAPCUT (mobile talking-head) =====
     Nằm ngay dưới video, trên vùng sheet. ĐẦU ĐỌC ghim cố định giữa khung, kéo
     timeline để tua — đúng cảm giác CapCut. 3 làn: hình / nhạc / phụ đề. */
  /* Timeline nhạc/phụ đề nằm SÁT NGAY TRÊN thanh tính năng (trước đây bị đẩy
     lên cao 40dvh vì cộng --rv-sheet, chừa một khoảng đen trống vô nghĩa).
     Sheet có z-index 50 > 21 nên khi mở tính năng sẽ TRÙM LÊN nó — đúng ý
     "hiển thị và che đi phần nhạc và phụ đề như CapCut". */
  body.rv-tabs-on #panel-review .rv-timeline {
    display: flex; flex-direction: column;
    position: fixed; left: 0; right: 0; z-index: 21;
    bottom: calc(var(--rv-bar) + env(safe-area-inset-bottom));
    height: var(--rv-tl);
    background: #0e0e11; border-top: 1px solid rgba(255,255,255,0.08);
  }
  .rvtl-head {
    flex: 0 0 auto; display: flex; align-items: center; gap: 10px;
    padding: 4px 12px; height: 30px;
  }
  .rvtl-play, .rvtl-full {
    width: 26px; height: 26px; flex: 0 0 auto; border-radius: 50%;
    background: rgba(255,255,255,0.12); border: none; color: #fff;
    font-size: 11px; line-height: 1; cursor: pointer; padding: 0;
    display: flex; align-items: center; justify-content: center;
  }
  .rvtl-play:active, .rvtl-full:active { background: rgba(255,255,255,0.24); }
  .rvtl-time { flex: 1 1 auto; font-size: 11px; font-weight: 700; color: #9aa0ad; font-variant-numeric: tabular-nums; }
  .rvtl-time b { color: #fff; }
  /* Vùng cuộn: đệm trái/phải 50% để mốc 0s và mốc cuối chạm được ĐẦU ĐỌC giữa */
  .rvtl-scroll {
    flex: 1 1 auto; overflow-x: auto; overflow-y: hidden; min-height: 0;
    scrollbar-width: none; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain;
  }
  .rvtl-scroll::-webkit-scrollbar { display: none; }
  .rvtl-inner { position: relative; padding: 0 50vw; height: 100%; }
  .rvtl-ruler {
    position: relative; height: 14px; margin-bottom: 3px;
    font-size: 8.5px; color: #6d7280;
  }
  .rvtl-ruler span {
    position: absolute; top: 2px; transform: translateX(-50%);
    white-space: nowrap; font-variant-numeric: tabular-nums;
  }
  .rvtl-ruler span::before {
    content: ""; position: absolute; top: -2px; left: 50%; width: 1px; height: 4px;
    background: rgba(255,255,255,0.22);
  }
  .rvtl-track {
    position: relative; border-radius: 5px; margin-bottom: 4px;
    display: flex; align-items: center; overflow: hidden;
  }
  /* Làn HÌNH — dải ảnh thu nhỏ như CapCut */
  .rvtl-video { height: 42px; background: #1b1b20; }
  .rvtl-video img {
    height: 100%; width: auto; display: block; object-fit: cover;
    pointer-events: none; flex: 0 0 auto;
  }
  .rvtl-video.is-empty { background: linear-gradient(90deg,#2a2a33,#1b1b20); }
  /* Làn NHẠC (xanh ngọc như CapCut) & làn PHỤ ĐỀ (tím) — cao hơn bản đầu
     (22px) cho dễ đọc/dễ bấm (anh Phong 20/07: "to hơn một chút"). */
  .rvtl-audio { height: 28px; background: rgba(45,190,180,0.22); box-shadow: inset 0 0 0 1px rgba(45,190,180,0.5); }
  .rvtl-cap   { height: 28px; background: rgba(150,110,240,0.22); box-shadow: inset 0 0 0 1px rgba(150,110,240,0.5); }
  .rvtl-chip {
    font-size: 10.5px; font-weight: 700; color: #e6e9f0; padding: 0 8px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    position: sticky; left: 8px;
  }
  /* Từng câu phụ đề THẬT nằm đúng mốc thời gian (anh Phong 20/07: "phụ đề
     trên điện thoại hiển thị bên dưới" — trước chỉ có 1 nhãn tĩnh "Phụ đề"
     đứng yên, giờ đổ transcript thật vào làn, cuộn qua đầu đọc y như dải ảnh
     thu nhỏ). Dựng bởi renderCaptions() trong app.js khu TIMELINE MOBILE. */
  .rvtl-cap-seg {
    position: absolute; top: 2px; bottom: 2px; border-radius: 4px;
    background: rgba(150,110,240,0.35); box-shadow: inset 0 0 0 1px rgba(150,110,240,0.6);
    color: #f1eefc; font-size: 9.5px; font-weight: 600; line-height: 1;
    display: flex; align-items: center; padding: 0 6px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    cursor: pointer; /* bấm để chọn — xem .rvtl-actions */
  }
  /* Câu ĐANG CHỌN — viền vàng nổi bật */
  .rvtl-cap-seg.sel {
    background: rgba(255,212,0,0.30);
    box-shadow: inset 0 0 0 1.5px var(--accent), 0 0 0 1px rgba(0,0,0,.5);
    color: #fff;
  }
  /* Câu ĐÃ ĐÁNH DẤU CẮT — đỏ + gạch ngang, sẽ bị bỏ khi render */
  .rvtl-cap-seg.cut {
    background: rgba(255,70,70,0.28);
    box-shadow: inset 0 0 0 1.5px rgba(255,90,90,0.85);
    color: #ffd9d9; text-decoration: line-through; opacity: 0.85;
  }
  /* Làn nhạc bấm được → mở tab Nhạc */
  .rvtl-audio { cursor: pointer; }

  /* THANH THAO TÁC nổi trên timeline khi chọn 1 câu */
  .rvtl-actions {
    position: absolute; left: 8px; right: 8px; top: 2px; z-index: 6;
    display: flex; align-items: center; gap: 6px;
    background: rgba(18,18,22,0.96); border: 1px solid rgba(255,255,255,0.14);
    border-radius: 10px; padding: 4px 6px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.5);
  }
  .rvtl-actions.hidden { display: none; }
  .rvtl-act-time {
    font-size: 10px; font-weight: 800; color: var(--accent);
    font-variant-numeric: tabular-nums; padding: 0 4px; flex: 0 0 auto;
  }
  .rvtl-act {
    flex: 1 1 auto; min-width: 0; padding: 6px 4px;
    background: rgba(255,255,255,0.10); border: none; border-radius: 7px;
    color: #fff; font-size: 11px; font-weight: 700; cursor: pointer;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .rvtl-act:active { background: rgba(255,255,255,0.22); }
  .rvtl-act-cut { background: rgba(255,80,80,0.22); color: #ffc9c9; }
  .rvtl-act-cut.is-undo { background: rgba(90,200,120,0.22); color: #c6f5d4; }
  .rvtl-act-x { flex: 0 0 auto; width: 28px; padding: 6px 0; background: none; color: var(--text-3); }
  /* ĐẦU ĐỌC ghim giữa khung — timeline chạy qua nó (đúng kiểu CapCut) */
  .rvtl-playhead {
    position: absolute; left: 50%; top: 30px; bottom: 0; width: 2px;
    background: #fff; transform: translateX(-50%); pointer-events: none; z-index: 3;
    box-shadow: 0 0 0 1px rgba(0,0,0,0.4);
  }
  .rvtl-playhead::before {
    content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
    width: 9px; height: 9px; border-radius: 2px; background: #fff;
  }

  body.rv-tabs-on #panel-review .preview-meta { display: none; } /* tên file — không cần */
  body.rv-tabs-on #panel-review .log-toggle,
  body.rv-tabs-on #panel-review .log { display: none; }
  body.rv-tabs-on #reviewForm > .divider { display: none; }

  /* Trạng thái phân tích lên THANH TRÊN CÙNG, canh giữa giữa nút ✕ và Xuất
     (anh Phong vòng 4: "chữ đang phân tích phải đi lên trên cùng, không che
     video") — hoà vào thanh, không phải chip nổi đè lên khung hình. */
  body.rv-tabs-on #panel-review #analyzeStatus {
    position: fixed; top: 0; height: var(--rv-top); left: 60px; right: 96px;
    z-index: 61; margin: 0; padding: 0;
    display: flex; align-items: center; justify-content: center;
    background: none; box-shadow: none; font-size: 12px; font-weight: 700;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  /* Tiến trình = vạch mảnh ở đường ranh thanh trên / video — feedback tinh
     tế kiểu YouTube, không chiếm chỗ, không che hình. */
  body.rv-tabs-on #panel-review #analyzeProgressBox {
    position: fixed; top: calc(var(--rv-top) - 2px); left: 0; right: 0;
    z-index: 30; margin: 0; padding: 0;
  }
  body.rv-tabs-on #panel-review #analyzeProgressBox .progress-bar-track {
    height: 2.5px; border-radius: 0; border: none; background: transparent;
  }
  /* Phân tích xong → vạch tiến trình biến mất, chỉ còn "Phân tích xong" xanh
     trên thanh (dùng general-sibling: progress box đứng sau #analyzeStatus). */
  body.rv-tabs-on #panel-review #analyzeStatus.done ~ #analyzeProgressBox { display: none; }

  /* ----- Thanh tính năng ĐÁY cố định — icon trên, nhãn nhỏ dưới. Nâng
     CAO + THOÁNG hơn (anh Phong vòng 3: "sát quá khó chọn"): vùng bấm
     mỗi tab ~56px, icon to 22px, đệm đáy rộng khỏi mép màn/thanh vuốt. */
  /* KHUNG CHIA ĐẦY ĐỦ (anh Phong 19/07): 6 tab chia đều hết chiều ngang,
     KHÔNG cuộn — mỗi tính năng "xếp hàng" một ô bằng nhau cho dễ bấm, giống
     thanh công cụ CapCut. flex:1 1 0 + min-width:0 để ô hẹp vẫn không tràn. */
  body.rv-tabs-on .rv-tabbar {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 55;
    height: calc(var(--rv-bar) + env(safe-area-inset-bottom));
    /* KÉO NGANG ĐƯỢC (anh Phong 20/07): trước đây overflow:hidden + flex:1 1 0
       nên các icon bị BÓP NHỎ cho vừa màn — thêm icon là chữ chen nhau, không
       kéo được. Giờ mỗi icon giữ bề rộng dễ bấm, thừa thì VUỐT PHẢI→TRÁI để tới
       các tính năng còn lại (thanh cuộn ẩn, có scroll-snap cho dừng gọn).
       Cử chỉ vuốt đổi tab của form đã loại trừ .rv-tabbar nên không đá nhau. */
    gap: 0; overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    padding: 9px 4px calc(11px + env(safe-area-inset-bottom));
    background: rgba(10, 10, 12, 0.97); border-top: 1px solid var(--border);
    scrollbar-width: none;
  }
  body.rv-tabs-on .rv-tabbar::-webkit-scrollbar { display: none; }
  body.rv-tabs-on .rv-tab {
    flex: 0 0 auto; min-width: 68px; scroll-snap-align: center;
    display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 5px;
    background: none; border: none; padding: 4px 2px; cursor: pointer;
    color: var(--text-3); font-size: 9.5px; font-weight: 700;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
  }
  body.rv-tabs-on .rv-tab .rv-tab-label {
    max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  }
  body.rv-tabs-on .rv-tab .rv-tab-ic { font-size: 22px; line-height: 1; }
  body.rv-tabs-on .rv-tab.active { color: var(--accent); }

  /* ----- Ô tuỳ chọn: bottom sheet TRƯỢT TỪ DƯỚI LÊN, đứng yên 1 chỗ.
     NỀN TỐI như CapCut (anh Phong vòng 4) — cùng tông với sân khấu video,
     và để chữ mẫu (caption/tiêu đề) hiện đúng màu như lên video mà KHÔNG
     cần khung hộp. Đảo bộ biến màu về tối ngay tại .rv-sec nên mọi phần tử
     con tự đọc lại var(); riêng ô nhập/select set nền tối tường minh vì
     #reviewForm ép nền trắng cho chúng. ----- */
  body.rv-tabs-on #reviewForm .rv-sec {
    display: block;
    position: fixed; left: 0; right: 0; z-index: 50;
    bottom: calc(var(--rv-bar) + env(safe-area-inset-bottom));
    height: var(--rv-sheet); max-height: var(--rv-sheet);
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    --bg: #0f0f12; --bg-elevated: #17171c;
    --surface: #1c1c22; --surface-solid: #17171c; --surface-2: #212126; --surface-3: #2b2b31;
    --text: #f4f4f6; --text-2: #cbcbd4; --text-3: #8f8f9a;
    --border: rgba(255,255,255,0.10); --border-strong: rgba(255,255,255,0.20);
    color: var(--text);
    background: linear-gradient(180deg, #17171c, #101013);
    border-radius: 18px 18px 0 0; padding: 8px 14px 14px;
    box-shadow: 0 -12px 34px rgba(0, 0, 0, 0.6);
    transform: translateY(110%); visibility: hidden;
    transition: transform 0.26s var(--ease), visibility 0.26s;
  }
  body.rv-tabs-on #reviewForm .rv-sec.rv-active { transform: translateY(0); visibility: visible; }
  /* Tay nắm kéo (grabber) ở đỉnh sheet — dấu hiệu quen thuộc của bottom sheet */
  body.rv-tabs-on #reviewForm .rv-sec::before {
    content: ""; display: block; width: 38px; height: 4px; border-radius: 999px;
    background: rgba(255,255,255,0.22); margin: 0 auto 12px;
  }
  /* ✓ XONG (anh Phong 19/07: "dấu v đánh dấu hoàn thành để kết thúc chỉnh
     sửa"): ghim góc phải ĐỈNH sheet, DÍNH khi cuộn (sticky) nên khu dài cỡ
     nào cũng thấy nút. Bấm = hạ sheet, trả sân khấu cho video. Wiring: app.js
     khu "MOBILE ... EDITOR" nối .rv-sec-confirm → activate(null). */
  body.rv-tabs-on #reviewForm .rv-sec .rv-sec-confirm {
    display: flex; align-items: center; justify-content: center;
    float: right; position: sticky; top: 0; z-index: 3;
    width: 34px; height: 34px; margin: -4px 0 6px 10px; border-radius: 50%;
    background: rgba(255,215,0,0.16); border: none; color: var(--accent);
    font-size: 17px; font-weight: 800; line-height: 1; cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  body.rv-tabs-on #reviewForm .rv-sec .rv-sec-confirm:active {
    background: rgba(255,215,0,0.30);
  }
  body.rv-tabs-on #reviewForm .rv-sec input[type="text"],
  body.rv-tabs-on #reviewForm .rv-sec input[type="number"],
  body.rv-tabs-on #reviewForm .rv-sec textarea,
  body.rv-tabs-on #reviewForm .rv-sec select {
    background: #1e1e24; color: var(--text); border-color: var(--border-strong);
  }
  /* Nhãn khu: BỎ IN HOA, viết thường nhẹ nhàng như tiêu đề phụ CapCut —
     không còn "hô to" 2 dòng chữ hoa. */
  body.rv-tabs-on #reviewForm .rv-sec .section-label {
    font-size: 12px; letter-spacing: 0; text-transform: none; font-weight: 700;
    color: var(--text-2); margin: 0 0 10px;
  }
  body.rv-tabs-on #reviewForm .rv-sec label.field-label { font-size: 12.5px; margin: 12px 0 6px; }
  body.rv-tabs-on #reviewForm .rv-sec .empty-note { font-size: 12px; padding: 8px 0 2px; }
  body.rv-tabs-on #reviewForm .rv-sec .checkbox-row { font-size: 13px; }

  /* Tab đáy đã thay vai trò gập: bỏ đường kẻ + tiêu đề gập của <details> */
  body.rv-tabs-on #reviewForm .rv-sec details.settings-fold { border-top: none; margin-top: 0; padding-top: 0; }
  body.rv-tabs-on #reviewForm .rv-sec details.settings-fold > summary { display: none; }

  /* Nút Render dưới form ẩn đi — "Xuất" nằm cố định góc trên phải */
  body.rv-tabs-on #reviewForm #renderBar { display: none; }

  /* ===== Ô CHỌN BỎ KHUNG — hiện KIỂU CHỮ trực tiếp (anh Phong vòng 4:
     "các ô chọn hiển thị kiểu chữ luôn chứ không cần khung, tối ưu diện
     tích"). Trên nền tối, chữ mẫu tự đứng được nên bỏ hết hộp/viền; ô đang
     chọn nhận diện bằng MÀU NHẤN + gạch chân, không phải khung. ===== */
  body.rv-tabs-on .lf-caption-style-row {
    display: flex; overflow-x: auto; -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity; padding-bottom: 6px; scrollbar-width: none; gap: 6px;
  }
  body.rv-tabs-on .lf-caption-style-row::-webkit-scrollbar { display: none; }
  body.rv-tabs-on #reviewForm .rv-sec .lf-caption-style-chip {
    flex: 0 0 auto; min-width: 88px; scroll-snap-align: start;
    background: none; border: none; border-radius: 0; padding: 8px 6px 7px;
    border-bottom: 2px solid transparent;
  }
  body.rv-tabs-on #reviewForm .rv-sec .lf-caption-style-chip.active {
    background: none; border-color: transparent; border-bottom-color: var(--accent);
  }
  body.rv-tabs-on #reviewForm .rv-sec .lf-caption-style-chip.active .lf-chip-label { color: var(--accent); }
  /* Hộp đen mờ quanh chữ mẫu cũng bỏ — chữ mẫu nằm thẳng trên nền sheet tối */
  body.rv-tabs-on #reviewForm .rv-sec .lf-chip-preview-box { background: none; padding: 2px 2px; }

  /* Nhãn phân loại kiểu (Cơ bản/Nổi bật...) gọn lại */
  body.rv-tabs-on #reviewForm .rv-sec .lf-caption-group-label { font-size: 10px; margin: 2px 0 6px; }

  /* Kiểu video (Tự do / Dạng 1) + nền lớp phủ: khung nhẹ đi, active = viền
     nhấn mảnh thay vì hộp đậm */
  /* CHỈ 3 kiểu (Tự do / Dạng 1 / Dạng 2) → chia ĐỀU 1 hàng, KHÔNG cuộn ngang
     (bắt lỗi 20/07: cuộn ngang làm chip Dạng 2 bị cắt khỏi khung khi chọn). */
  body.rv-tabs-on .lf-wordmode-row {
    display: flex; gap: 8px; padding-bottom: 4px;
  }
  body.rv-tabs-on #reviewForm .rv-sec .lf-wordmode-chip {
    flex: 1 1 0; min-width: 0; justify-content: center; text-align: center;
    background: rgba(255,255,255,0.05); border: 1px solid transparent;
    border-radius: 12px; padding: 12px 6px;
  }
  body.rv-tabs-on #reviewForm .rv-sec .lf-wordmode-chip.active {
    background: rgba(232,180,0,0.12); border-color: var(--accent);
  }
  body.rv-tabs-on #reviewForm .rv-sec .lf-wordmode-chip-title { font-size: 12.5px; white-space: nowrap; }
  /* Mô tả dài ẩn đi trên mobile — tiêu đề đã tự rõ nghĩa, ô gọn thành viên
     chip 1 dòng như CapCut (anh Phong vòng 4: tối ưu diện tích). */
  body.rv-tabs-on #reviewForm .rv-sec .lf-wordmode-chip-desc { display: none; }

  /* Tỷ lệ khung: cũng bỏ khung hộp — chỉ còn icon khung nhỏ + nhãn, active
     tô màu nhấn (icon + chữ), đúng tinh thần "không cần khung". */
  body.rv-tabs-on #reviewForm .rv-sec .aspect-chip {
    background: none; border: none; min-width: 62px; padding: 6px 8px;
  }
  body.rv-tabs-on #reviewForm .rv-sec .aspect-chip.active { background: none; color: var(--accent); }

  /* Stepper nén 1 dòng cho các bước KHÁC (upload/render — nơi topbar vẫn còn) */
  body.rv-tabs-on #view-editor .stepper { margin-bottom: 12px; gap: 3px; flex-wrap: nowrap; }
  body.rv-tabs-on #view-editor .stepper-back-btn { margin-right: 8px; padding: 6px 10px; font-size: 12px; }
  body.rv-tabs-on #view-editor .step { font-size: 0; gap: 0; }
  body.rv-tabs-on #view-editor .step-num { margin: 0; }
  body.rv-tabs-on #view-editor .step.active { font-size: 12.5px; gap: 7px; }
}

/* ---------- Bộ nhận diện thương hiệu ---------- */
.account-popover-brand {
  width: 100%; text-align: left; background: none; border: none;
  color: var(--text-2); font-size: 13px; padding: 9px 12px; cursor: pointer;
  border-radius: var(--radius-sm);
}
.account-popover-brand:hover { background: var(--surface-3); color: var(--text-1); }

.brandkit-box { max-width: 520px; width: 100%; }
.brandkit-section { margin-top: 18px; }
.brandkit-label { font-size: 13px; font-weight: 700; margin-bottom: 8px; color: var(--text-1); }
.brandkit-hint { font-size: 12px; color: var(--text-3); line-height: 1.5; margin-top: 8px; }

.brandkit-toggle { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; }
.brandkit-toggle input { margin-top: 3px; flex-shrink: 0; }
.brandkit-toggle span { display: flex; flex-direction: column; gap: 2px; font-size: 13px; }
.brandkit-toggle i { font-style: normal; font-size: 12px; color: var(--text-3); }
.brandkit-toggle-sm { margin-top: 12px; font-size: 13px; }

.brandkit-color-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.brandkit-color-row input[type="color"] {
  width: 44px; height: 34px; padding: 2px; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--surface-2); cursor: pointer; flex-shrink: 0;
}
.brandkit-color-row .input { width: 110px; font-family: ui-monospace, Consolas, monospace; }

.brandkit-logo-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.brandkit-logo-preview {
  width: 96px; height: 96px; flex-shrink: 0; border: 1px dashed var(--border);
  border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center;
  /* Ô carô để logo nền trong suốt nhìn rõ là trong suốt, không tưởng nền trắng. */
  background-color: var(--surface-2);
  background-image: linear-gradient(45deg, var(--surface-3) 25%, transparent 25%),
    linear-gradient(-45deg, var(--surface-3) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--surface-3) 75%),
    linear-gradient(-45deg, transparent 75%, var(--surface-3) 75%);
  background-size: 12px 12px;
  background-position: 0 0, 0 6px, 6px -6px, -6px 0;
  overflow: hidden;
}
.brandkit-logo-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }
.brandkit-logo-preview span { font-size: 11px; color: var(--text-3); text-align: center; padding: 6px; }
.brandkit-logo-actions { display: flex; flex-direction: column; gap: 8px; }

.brandkit-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin-top: 14px; }
.brandkit-grid label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; color: var(--text-2); }
.brandkit-grid input[type="range"] { width: 100%; }
.brandkit-num { color: var(--text-3); font-variant-numeric: tabular-nums; }

.brandkit-footer {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border);
}
.brandkit-status { font-size: 12px; color: var(--text-3); }
