/* GemCommunity News — trang tab mới.
   Đây là PHẦN NỐI DÀI của GemCommunity, không phải một sản phẩm thứ hai: mọi bo góc,
   bóng, cỡ chữ, sắc accent và sắc chủ đề đều lấy từ `tokens.css`, tệp sinh ra từ
   chính gemcommunity/app/globals.css (xem scripts/sync-tokens.mjs). Tệp này KHÔNG
   được đặt thêm một giá trị thô nào mà design system đã có tên cho nó.

   Khác web đúng một tầng: BỀ MẶT. Web là nền sáng; tab mới là nền tối, vì nó bật lên
   hàng trăm lần một ngày và một cú loé trắng mỗi lần là thứ làm người ta gỡ tiện ích.
   Cùng lúc, chính nền tối đó trả lời câu "mình đang ở tiện ích hay đang ở cộng đồng"
   trong một phần mười giây — cùng thương hiệu, khác chỗ đứng. Nhãn "tab mới" cạnh
   wordmark và dấu ↗ trên mọi thẻ mở sang web là hai lời nhắc còn lại. */

/* Khai đè MÀU BỀ MẶT cho nền tối, giữ nguyên TÊN token của design system. */
:root[data-theme="dark"] {
  --bg:#0b0c10; --bg2:#0f1117; --card:#14161d; --card2:#1a1d26;
  --line:#242834; --line-strong:#333949;
  --txt:#edeef3; --muted:#9ba1b0;
  --accent-ink:#8b93ff;                  /* accent đọc được trên nền đậm */
  --sh-resting: 0 1px 2px rgba(0,0,0,.42);
  --sh-raised: 0 4px 16px rgba(0,0,0,.38);
  --sh-overlay: 0 16px 48px rgba(0,0,0,.55);
  /* Sắc `-soft` của Library là pastel cho nền trắng; trên nền đậm chúng thành sáu
     ô trắng bệch. Cùng sắc, kéo tối lại — cùng họ, khác độ sáng. */
  --t-cro:#9ea2ff; --t-cro-soft:#1b1d39;
  --t-ai:#5fd3bd;  --t-ai-soft:#11241f;
  --t-tools:#e39bd0; --t-tools-soft:#2a1826;
  --t-res:#e0b45a; --t-res-soft:#2a2008;
  --t-wf:#6fd0ae;  --t-wf-soft:#132922;
  --t-jr:#dba873;  --t-jr-soft:#271a0f;
  --warn:#e0b45a; --warn-soft:rgba(224,180,90,.12);
  --muted-bg:#2a2e3a;
}
:root { --muted-bg:#eceef3; }

* { box-sizing:border-box; }
/* html cũng theo nền của theme: <style> trong newtab.html ghim nó tối để trang không bao giờ
   trắng khi CSS chưa về; từ đây nó theo --bg (nền sáng cũng đúng khi cuộn quá đà). */
:root[data-theme="light"] { color-scheme:light; }
html { background:var(--bg); height:100%; }
/* body KHÔNG được height:100%: phần tử sticky không ra khỏi được hộp của cha, nên body cao đúng
   một màn hình thì thanh trên (và hàng chip) trôi mất khi cuộn quá một màn (đo 27/09/2026). */
body {
  margin:0; background:var(--bg); color:var(--txt);
  font:var(--fs-body)/1.55 var(--serif);
  -webkit-font-smoothing:antialiased;
  display:flex; flex-direction:column; min-height:100%;
}
a { color:inherit; text-decoration:none; }
button { font:inherit; cursor:pointer; }
:focus-visible { outline:2px solid var(--accent); outline-offset:2px; border-radius:var(--r-sm); }
.skip { position:absolute; left:-9999px; }
.skip:focus { left:16px; top:12px; z-index:60; background:var(--card); padding:10px 14px; border-radius:var(--r-md); }

/* ── Thanh trên ───────────────────────────────────────────────────────────────
   Chỉ còn thương hiệu bên trái, TÌM + TÀI KHOẢN bên phải (Chris 27/09/2026: "giữ lại account
   và search thôi"). Ngôn ngữ, nền, About, Tuỳ chọn nằm trong menu của nút tài khoản; bộ lọc
   loại bài xuống đầu feed. Một dòng ở MỌI khổ, nên không còn bảng ⋯ và không còn cú lặn khi
   cuộn trên điện thoại. Chiều cao cố định (--top-h) để hàng chip biết dính ở đâu. */
:root { --top-h:69px; }
@media (max-width:560px) { :root { --top-h:65px; } }
.top {
  display:flex; align-items:center; gap:12px; height:var(--top-h);
  padding:12px 16px; border-bottom:1px solid var(--line); background:var(--bg2);
  position:sticky; top:0; z-index:20;
}
.brand { display:flex; align-items:center; gap:9px; min-height:44px; flex:0 0 auto; min-width:0; }
.mark { width:26px; height:27px; flex:0 0 auto; color:var(--txt); }
.wordmark { font-size:var(--fs-h3); font-weight:700; letter-spacing:-.015em; white-space:nowrap; }
.wordmark b { color:var(--accent-ink); font-weight:700; margin-left:5px; }
.wm-short { display:none; }
/* Không co: tìm + tài khoản giữ nguyên cỡ, hàng mục (.tabs) là phần co giãn. Để nó co thì nút tài
   khoản bị đẩy ra ngoài màn (đo 390px: tràn 21px, 27/09/2026). */
.top-right { display:flex; align-items:center; gap:8px; margin-left:auto; flex:0 0 auto; }

/* Nút tìm: màn rộng là một ô "Tìm bài ⌘K" để người ta thấy nó là việc chính; hẹp thì còn icon. */
.search-btn { min-height:44px; min-width:44px; padding:0 10px 0 12px; border-radius:var(--r-md);
  border:1px solid var(--line); background:var(--card); color:var(--muted);
  display:inline-flex; align-items:center; gap:10px; font-size:var(--fs-body);
  transition:color var(--t-fast) ease, border-color var(--t-fast) ease; }
.search-btn:hover { color:var(--txt); border-color:var(--line-strong); }
.search-lbl { min-width:120px; text-align:left; }
.search-btn kbd { font:inherit; font-size:11px; padding:2px 6px; border:1px solid var(--line); border-radius:4px;
  background:var(--card2); color:var(--muted); }
@media (max-width:767px) {
  .search-btn { width:44px; padding:0; justify-content:center; }
  .search-lbl, .search-btn kbd { display:none; }
}

.icon-btn {
  width:44px; height:44px; border-radius:var(--r-md); border:1px solid var(--line);
  background:var(--card); color:var(--muted);
  display:inline-flex; align-items:center; justify-content:center; font-size:16px;
  transition:color var(--t-fast) ease, border-color var(--t-fast) ease;
}
.icon-btn:hover { color:var(--txt); border-color:var(--line-strong); }

/* Nút tài khoản. CÙNG hình với nút tài khoản trên thanh GemCommunity (.hdr-me trong
   gemcommunity/app/globals.css): viên thuốc bo tròn, ảnh đại diện tròn 28px, tên 14px/600.
   Khách: icon người + chữ "Tài khoản", có sẵn trong HTML nên không bao giờ rỗng. */
.acct { position:relative; flex:0 0 auto; }
/* Nút ngôn ngữ: mẫu .hdr-lang-* của gemcommunity (globals.css): tiêu đề nhỏ in hoa, hàng endonym, hàng đang
   chọn nền nhạt + chữ accent + ✓ ở mép phải. Hộp menu dùng chung khung .acct-menu. */
.lang { position:relative; flex:0 0 auto; }
.acct-menu.lang-menu { width:220px; padding:6px; }   /* không lấy width 320px của .acct-menu: ở 390px nó tràn mép trái (đo 01/10) */
.lang-head { padding:8px 10px 6px; font-size:var(--fs-micro); font-weight:800; letter-spacing:.07em;
  text-transform:uppercase; color:var(--muted); }
.lang-row { display:flex; align-items:center; gap:10px; width:100%; min-height:44px; padding:0 10px;
  border:0; border-radius:var(--r-md); background:none; color:var(--txt); font:inherit; font-size:var(--fs-body);
  text-align:left; cursor:pointer; }
.lang-row:hover, .lang-row:focus-visible { background:var(--card2); }
.lang-row[aria-checked="true"] { background:color-mix(in srgb, var(--accent) 14%, transparent); color:var(--accent-ink); font-weight:600; }
.lang-row .ck { margin-left:auto; color:var(--accent-ink); font-size:var(--fs-caption); }
.who {
  min-height:44px; padding:4px 10px 4px 4px; border-radius:var(--r-full); border:1px solid var(--line);
  background:var(--card); color:var(--txt); display:inline-flex; align-items:center; gap:8px;
  font:inherit; font-size:var(--fs-body); font-weight:600; white-space:nowrap;
  transition:border-color var(--t-fast) ease, background var(--t-fast) ease;
}
.who:hover { border-color:var(--line-strong); }
.who[aria-expanded="true"] { border-color:var(--line-strong); background:var(--card2); }
.who .name { max-width:140px; overflow:hidden; text-overflow:ellipsis; }
.who .chev { color:var(--muted); flex:0 0 auto; transition:transform var(--t-fast) ease; }
.who[aria-expanded="true"] .chev { transform:rotate(180deg); }
.who-ico { width:28px; height:28px; flex:0 0 28px; border-radius:var(--r-full); display:inline-grid; place-items:center;
  background:var(--muted-bg); color:var(--txt); }
.av { position:relative; overflow:hidden; width:28px; height:28px; flex:0 0 28px; border-radius:var(--r-full);
  background:linear-gradient(135deg, #3a3b42, #1b1c1e); color:#fff;
  display:inline-grid; place-items:center; font-size:var(--fs-caption); font-weight:700; }
.av .photo { position:absolute; inset:0; background-size:cover; background-position:center; }
.badge { font-size:10px; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
  padding:3px 7px; border-radius:var(--r-full); background:var(--warn-soft); color:var(--warn); }
/* Điện thoại: tên người dài không vừa một dòng cạnh thương hiệu + ô tìm (đo 320px), nên chỉ
   còn ảnh/icon + mũi tên. Tên vẫn ở aria-label và ở đầu menu. */
@media (max-width:420px) { .who:not(.guest) .name { display:none; } .who:not(.guest) { padding-right:8px; gap:4px; } }
/* Khách: chữ "Tài khoản" ngắn, vừa tới 361px (đo 390: thương hiệu 105 + tìm 44 + nút 130 trên 366). */
/* Từ khi hàng mục lên thanh trên (27/09/2026), chữ "Tài khoản" nhường chỗ sớm hơn: dưới 480px chỉ còn icon. */
@media (max-width:480px) { .who.guest .name { display:none; } .who.guest { padding-right:8px; gap:4px; } }
@media (max-width:360px) { .wordmark { display:none; } }
/* Nút ngôn ngữ (01/10/2026) chiếm thêm 52px của thanh trên: ở 390px tab đang xem bị cắt còn "Ho…". Dưới 420px
   nhường lại: thương hiệu còn dấu đá + "GC", nút tài khoản bỏ mũi tên (menu vẫn mở bằng chạm, aria vẫn đủ). */
@media (max-width:420px) {
  .wm-short + b { display:none; }
  .who .chev { display:none; }
  .who { min-width:44px; justify-content:center; }   /* bỏ mũi tên thì nút khách còn 42px (visual-gate 01/10) */
  .top-right { gap:6px; }
}
/* 320px: vẫn thiếu ~15px cho "Hot News". Thu khe: mọi nút ở đây đều ≥ 44px, nên luật khe ≥ 8px (§9.1, chỉ áp
   khi một target < 44px) không áp. */
@media (max-width:360px) {
  .top { gap:6px; padding-left:10px; padding-right:10px; }
  .top-right { gap:4px; }
}

/* Menu tài khoản: MỘT chỗ cho mọi thứ không phải tìm bài. */
.acct-menu { position:absolute; right:0; top:calc(100% + 8px); z-index:30;
  width:320px; max-width:calc(100vw - 24px); max-height:calc(100vh - var(--top-h) - 16px); overflow-y:auto;
  display:flex; flex-direction:column; gap:2px; padding:6px;
  background:var(--card); border:1px solid var(--line); border-radius:var(--r-lg); box-shadow:var(--sh-overlay); }
.acct-menu[hidden] { display:none; }
.am-head { display:flex; align-items:center; gap:10px; padding:10px 12px 8px; min-width:0; }
.am-who { display:flex; align-items:center; gap:8px; min-width:0; flex-wrap:wrap; }
.am-who strong { font-size:var(--fs-body); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:220px; }
.am-item { display:flex; flex-direction:column; align-items:flex-start; gap:3px; width:100%; min-height:44px;
  padding:10px 12px; border:0; border-radius:var(--r-md); background:none; color:var(--txt); text-align:left;
  font:inherit; font-size:var(--fs-body); font-weight:600; justify-content:center; }
.am-item:hover, .am-item:focus-visible { background:var(--card2); }
.am-item.primary .am-main { color:var(--accent-ink); }
.am-sub { font-size:var(--fs-caption); font-weight:400; color:var(--muted); line-height:1.45; }
.am-sep { height:1px; background:var(--line); margin:4px 6px; flex:0 0 auto; }
.am-group { display:flex; flex-direction:column; gap:6px; padding:6px 12px 8px; }
.am-label { font-size:var(--fs-micro); font-weight:800; letter-spacing:.07em; text-transform:uppercase; color:var(--muted); }
.am-seg { display:flex; gap:6px; }
/* Cỡ theo chữ (flex-basis auto), không chia đều: chia đều thì ở 320px "Tiếng Việt" bị cắt thành
   "Tiếng V…" (đo 27/09/2026) trong khi "中文" thừa chỗ. */
.am-seg button { flex:1 1 auto; min-width:0; min-height:44px; padding:0 6px; border-radius:var(--r-md);
  border:1px solid var(--line); background:none; color:var(--muted); font:inherit; font-size:var(--fs-body);
  font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.am-seg button:hover { color:var(--txt); border-color:var(--line-strong); }
.am-seg button[aria-checked="true"] { background:var(--accent); border-color:var(--accent); color:#fff; }

/* Dưới 1024px tên dài ăn chỗ của ô tìm: "GemCommunity News" → "GC News". */
@media (max-width:1023px) { .wm-long { display:none; } .wm-short { display:inline; } }
@media (prefers-reduced-motion: reduce) { .who .chev { transition:none; } }

/* ── Mục trên thanh trên (27/09/2026) ─────────────────────────────────────────
   Chris: "menu nằm trên topbar thôi ko 2 dòng được đâu". Ba mục chính + nút ⋯ đứng giữa thương
   hiệu và nút tìm. Dưới 900px không đủ chỗ cho ba chip cạnh thương hiệu + tìm + tài khoản (đo:
   ba chip ≈ 420px), nên cả nhóm gom thành MỘT nút "mục đang xem ▾" liệt kê mọi mục. */
.tabs { display:flex; align-items:center; gap:6px; flex:1 1 auto; min-width:0; overflow:hidden; }
.tab {
  min-height:44px; padding:0 14px; border-radius:var(--r-full); border:1px solid var(--line);
  background:transparent; color:var(--muted); font-size:var(--fs-body); font-weight:600;
  white-space:nowrap; display:inline-flex; align-items:center; gap:7px; flex:0 1 auto; min-width:0;
  transition:background var(--t-fast) ease, color var(--t-fast) ease, border-color var(--t-fast) ease;
}
.tab .lb { overflow:hidden; text-overflow:ellipsis; }
.tab:hover { background:var(--card); color:var(--txt); border-color:var(--line-strong); }
.tab[aria-selected="true"] { background:var(--accent); border-color:var(--accent); color:#fff; }
.tab .n { font-size:var(--fs-micro); font-weight:700; opacity:.72; font-variant-numeric:tabular-nums; }
.tab-more { flex:0 0 auto; font-weight:700; }
.tab-more .chev { display:none; }
@media (max-width:1199px) { .tabs .tab .n { display:none; } .tab { padding:0 12px; } }
@media (max-width:1023px) { .tabs .tab .ic { display:none; } .tab-more .more-lbl { display:none; } }
/* Gọn: chỉ còn nút ⋯ mang tên mục đang xem. Nền trung tính (không tô accent): nó là chỗ ĐỔI mục,
   không phải một mục đang được chọn giữa nhiều mục. */
@media (max-width:899px) {
  .tabs .tab:not(.tab-more) { display:none; }
  .tab-more { flex:0 1 auto; min-width:0; gap:6px; }
  .tab-more .dots { display:none; }
  .tab-more .more-lbl { display:inline; overflow:hidden; text-overflow:ellipsis; }
  .tab-more .chev { display:inline; flex:0 0 auto; }
  .tab-more[aria-selected="true"] { background:var(--card); border-color:var(--line-strong); color:var(--txt); }
}
@media (max-width:420px) { .tab-more .more-lbl .ic { display:none; } .tab-more { padding:0 10px; } }

/* Menu của nút ⋯: position:fixed, toạ độ tính lúc mở (lib: newtab.js toggleTabMenu). */
.tab-menu { position:fixed; z-index:40; width:220px; display:flex; flex-direction:column; gap:2px; padding:6px;
  background:var(--card); border:1px solid var(--line); border-radius:var(--r-lg); box-shadow:var(--sh-overlay); }
.tab-menu[hidden] { display:none; }
.tm-item { display:flex; align-items:center; gap:8px; min-height:44px; padding:0 12px; border:0; border-radius:var(--r-md);
  background:none; color:var(--txt); font:inherit; font-size:var(--fs-body); font-weight:600; text-align:left; }
.tm-item .n { margin-left:auto; font-size:var(--fs-micro); font-weight:700; color:var(--muted); font-variant-numeric:tabular-nums; }
.tm-item .ic { width:20px; flex:0 0 20px; text-align:center; }
.tm-item:hover, .tm-item:focus-visible { background:var(--card2); }
.tm-item[aria-checked="true"] { color:var(--accent-ink); }

/* Dải chào sau khi cài (newtab.html#welcome, một lần). Cùng khuôn với lời mời đánh giá. */
.welcome { display:flex; align-items:center; gap:16px; flex-wrap:wrap; margin-bottom:20px;
  padding:14px 16px 14px 18px; background:var(--card); border:1px solid var(--line);
  border-left:3px solid var(--accent); border-radius:var(--r-lg); }
.welcome[hidden] { display:none; }
.welcome-txt { flex:1 1 280px; display:flex; flex-direction:column; gap:3px; min-width:0; }
.welcome-txt strong { font-size:var(--fs-body); }
.welcome-txt span { color:var(--muted); font-size:var(--fs-caption); line-height:1.5; }
.welcome-ok { min-height:44px; padding:0 18px; border-radius:var(--r-md); border:0; background:var(--accent);
  color:#fff; font-weight:700; font-size:var(--fs-body); }
.welcome-ok:hover { filter:brightness(1.08); }

/* ── Khung nội dung ───────────────────────────────────────────────────────── */
main { flex:1; width:100%; max-width:1240px; margin:0 auto; padding:24px 16px 40px; }

/* Lời mời đánh giá (rate.js). Mảnh, nằm trên feed, không che gì. Viền accent bên trái là
   dấu hiệu duy nhất: nó phải thấy được mà không to hơn tin. */
.rate { display:flex; align-items:center; gap:16px; flex-wrap:wrap; margin-bottom:20px;
  padding:14px 16px 14px 18px; background:var(--card); border:1px solid var(--line);
  border-left:3px solid var(--accent); border-radius:var(--r-lg); }
.rate[hidden] { display:none; }
.rate-txt { flex:1 1 280px; display:flex; flex-direction:column; gap:3px; min-width:0; }
.rate-txt strong { font-size:var(--fs-body); }
.rate-txt span { color:var(--muted); font-size:var(--fs-caption); line-height:1.5; }
.rate-acts { display:flex; gap:8px; flex-wrap:wrap; }
.rate-later { min-height:44px; padding:0 14px; border-radius:var(--r-full); border:1px solid var(--line);
  background:transparent; color:var(--muted); font-size:var(--fs-caption); font-weight:600; }
.rate-later:hover { color:var(--txt); border-color:var(--line-strong); }
.sec { font-size:var(--fs-micro); font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--muted); margin:28px 0 12px; }

.lead { margin-bottom:24px; }
.lead-card {
  display:grid; grid-template-columns:minmax(0,.78fr) minmax(0,1fr);
  background:var(--card); border:1px solid var(--line); border-radius:var(--r-xl);
  overflow:hidden; box-shadow:var(--sh-resting); text-align:left; width:100%;
  padding:0; color:inherit; font:inherit;
}
.lead-card:hover { border-color:var(--accent); box-shadow:var(--sh-raised); }
.lead-body { padding:26px 28px; display:flex; flex-direction:column; gap:12px;
  justify-content:center; min-width:0; }
.lead-body h1 { margin:0; font-family:var(--serif); font-size:clamp(var(--fs-h1), 2.1vw, var(--fs-display));
  line-height:1.24; letter-spacing:-.02em; }
.lead-body p { margin:0; color:var(--muted); font-size:var(--fs-body-lg); line-height:1.6; }
.lead-cta { margin-top:4px; display:inline-flex; align-items:center; gap:8px;
  color:var(--accent-ink); font-weight:700; font-size:var(--fs-body); }
/* Bìa của ô dẫn đầu là một TẤM PANEL lấp đầy cột, không phải thumbnail 16:9. Giữ
   `aspect-ratio:16/9` ở đây thì chiều rộng được suy ra TỪ chiều cao — và khi tiêu đề
   dài làm hàng cao lên, bìa phình rộng hơn cột của nó rồi đè lên chữ. Đo 23/09/2026
   trên dữ liệu prod thật: tiêu đề 3 dòng → chữ đầu câu bị bìa che mất. Dữ liệu seed
   có tiêu đề ngắn nên không bao giờ lộ.
   Cùng luật mà Cover.jsx của web đã ghi: bìa CẠNH chữ thì fill, bìa TRÊN chữ thì 16:9. */
.lead-card .cov { aspect-ratio:auto; height:100%; min-height:200px; }
.lead-card .cov[data-mono]::after { font-size:52px; opacity:.13; }

/* ── Lưới thẻ ─────────────────────────────────────────────────────────────── */
/* Thẻ + nút ★ đứng cạnh nhau trong một khung (nút không được lồng trong nút). */
.card-wrap { position:relative; display:flex; min-width:0; }
.card-wrap > .card { flex:1; min-width:0; }
.lead { position:relative; }
/* Nút lưu: vùng bấm 44px, hình tròn 32px nổi trên bìa. Ẩn tới khi rê chuột (như dấu ↗), trừ
   khi bài ĐÃ lưu (thì nó là thông tin, phải luôn thấy) hoặc trên màn cảm ứng. Ổ khoá của bài
   bị khoá dời sang góc trái để nhường góc phải cho nút này. */
.fav { position:absolute; top:4px; right:4px; z-index:2; width:44px; height:44px; padding:0; border:0;
  background:none; display:grid; place-items:center; color:var(--txt); cursor:pointer;
  opacity:0; transition:opacity var(--t-fast) ease; }
.fav-dot { width:32px; height:32px; border-radius:var(--r-full); display:grid; place-items:center;
  background:color-mix(in srgb, var(--bg) 76%, transparent); backdrop-filter:blur(4px);
  border:1px solid color-mix(in srgb, var(--line-strong) 70%, transparent); }
.fav:hover .fav-dot { border-color:var(--accent); }
.fav.on { color:var(--accent-ink); opacity:1; }
.card-wrap:hover .fav, .lead:hover .fav, .fav:focus-visible { opacity:1; }
@media (hover:none) { .fav { opacity:1; } }
.lead > .fav { top:8px; right:8px; }
.fav-r.on { color:var(--accent-ink); border-color:var(--accent); }
.fav-r .fav-dot { width:auto; height:auto; background:none; border:0; backdrop-filter:none; }

.grid { display:grid; gap:16px; grid-template-columns:repeat(auto-fill, minmax(268px, 1fr)); }
.card {
  display:flex; flex-direction:column; background:var(--card); border:1px solid var(--line);
  border-radius:var(--r-lg); overflow:hidden; text-align:left; padding:0;
  color:inherit; font:inherit; min-height:100%; box-shadow:var(--sh-resting);
}
.card:hover { background:var(--card2); border-color:var(--line-strong);
  transform:translateY(-2px); box-shadow:var(--sh-raised); }
.card, .lead-card { transition:transform var(--t-fast) ease, border-color var(--t-fast) ease,
  background var(--t-fast) ease, box-shadow var(--t-base) ease; }
@media (prefers-reduced-motion: reduce) {
  .card, .lead-card { transition:none; } .card:hover { transform:none; }
}

/* Bìa — cùng khuôn với Cover.jsx của Library: ảnh thật nếu có, nếu không thì ô sắc
   chủ đề + tên kệ + chữ lồng, để hai nơi không vẽ hai thứ cho cùng một bài. */
.cov { position:relative; aspect-ratio:16/9; background-color:var(--t-res-soft);
  overflow:hidden; flex:0 0 auto; }
.cov img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
.cov:not(:has(img))::before { content:''; position:absolute; inset:0;
  background:repeating-linear-gradient(135deg, rgba(255,255,255,.045) 0 2px, transparent 2px 9px); }
:root:not([data-theme="dark"]) .cov:not(:has(img))::before {
  background:repeating-linear-gradient(135deg, rgba(255,255,255,.55) 0 2px, transparent 2px 9px); }
.cov[data-mono]::after { content:attr(data-mono); position:absolute; right:12px; bottom:0;
  font-size:64px; font-weight:800; letter-spacing:-.05em; line-height:.92; opacity:.22;
  color:var(--t-res); }
.cov-tag { position:absolute; left:13px; bottom:10px; font-size:10px; font-weight:800;
  letter-spacing:.08em; text-transform:uppercase; opacity:.9; color:var(--t-res); }
.cov.t-cro { background-color:var(--t-cro-soft); }
.cov.t-cro::after, .cov.t-cro .cov-tag { color:var(--t-cro); }
.cov.t-ai { background-color:var(--t-ai-soft); }
.cov.t-ai::after, .cov.t-ai .cov-tag { color:var(--t-ai); }
.cov.t-tools { background-color:var(--t-tools-soft); }
.cov.t-tools::after, .cov.t-tools .cov-tag { color:var(--t-tools); }
.cov.t-res { background-color:var(--t-res-soft); }
.cov.t-wf { background-color:var(--t-wf-soft); }
.cov.t-wf::after, .cov.t-wf .cov-tag { color:var(--t-wf); }
.cov.t-jr { background-color:var(--t-jr-soft); }
.cov.t-jr::after, .cov.t-jr .cov-tag { color:var(--t-jr); }
.cov .emoji { position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  font-size:42px; line-height:1; }
.cov-lock { position:absolute; left:10px; top:9px; width:28px; height:28px;
  border-radius:var(--r-full); display:grid; place-items:center; color:var(--txt);
  background:color-mix(in srgb, var(--bg) 72%, transparent); backdrop-filter:blur(3px); }

.card-body { padding:14px 16px 16px; display:flex; flex-direction:column; gap:8px; flex:1; min-width:0; }
.eyebrow { display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  font-size:var(--fs-micro); font-weight:800; letter-spacing:.07em; text-transform:uppercase; color:var(--muted); }
.eyebrow .kind { color:var(--accent-ink); }
.eyebrow .kind.hot { color:var(--warn); }
.card h3 { margin:0; font-family:var(--serif); font-size:var(--fs-h3); line-height:1.35;
  letter-spacing:-.011em; display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; }
.card .dek { margin:0; color:var(--muted); font-size:13.5px; line-height:1.5;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.meta { margin-top:auto; padding-top:6px; display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  font-size:var(--fs-caption); color:var(--muted); }
/* Dấu rời-khỏi-tiện-ích. Thẻ mở sang web thì nói ra; tin đọc ngay tại chỗ thì không. */
.out { margin-left:auto; opacity:0; font-size:var(--fs-caption); font-weight:600; white-space:nowrap;
  transition:opacity var(--t-fast) ease; }
.out.in { color:var(--accent-ink); }
/* Chữ "Đọc ngay →" / "Mở ↗" chỉ hiện khi rê chuột hoặc khi bàn phím đứng trên thẻ (Chris 26/09/2026: luôn hiện thì
   rối). Màn cảm ứng không có "rê", nên ở đó nó hiện mờ như cũ: đó là lời báo duy nhất rằng
   bấm vào sẽ rời tab mới. */
.card:hover .out, .card:focus-visible .out, .card:focus-within .out { opacity:.8; }
.card:hover .out.in, .card:focus-visible .out.in { opacity:1; }
@media (hover:none) { .out { opacity:.8; } }

.pill { display:inline-flex; align-items:center; gap:6px; padding:4px 9px; border-radius:var(--r-full);
  font-size:var(--fs-micro); font-weight:700; background:var(--muted-bg); color:var(--muted); }
.pill.paid { background:var(--warn-soft); color:var(--warn); }
.pill.free { background:var(--good-soft); color:var(--good); }
/* Bản dịch máy: nhãn KÍN TIẾNG có chủ ý — nó là ghi chú xuất xứ, không phải cảnh báo,
   và một bài dịch tốt không đáng bị đóng dấu đỏ. Bản ĐÃ CŨ thì ngược lại: nó dùng đúng
   sắc cảnh báo mà thẻ trả phí đang dùng, vì ở đó người đọc cần dừng lại một nhịp. */
.pill.trans { background:var(--muted-bg); color:var(--muted); font-weight:600; }
.pill.trans.stale { background:var(--warn-soft); color:var(--warn); font-weight:700; }

/* Dải báo trong trình đọc. Nằm giữa phụ đề và thân bài — đọc được TRƯỚC khi đọc bài,
   chứ không phải một dòng chân trang mà mắt đã lướt qua. */
.r-trans { display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 10px;
  margin:0 0 20px; padding:10px 14px; border-radius:var(--r-md);
  background:var(--muted-bg); color:var(--muted); font-size:var(--fs-caption); }
.r-trans.stale { background:var(--warn-soft); color:var(--warn); }
.r-trans a { color:inherit; font-weight:700; text-decoration:underline; text-underline-offset:2px;
  /* §9.1: link trong dải chữ ≥ 24px chiều cao chạm được (WCAG 2.5.8 AA) */
  display:inline-flex; align-items:center; min-height:24px; }

.empty { text-align:center; color:var(--muted); padding:60px 16px; font-size:var(--fs-body-lg); }

.sk { background:var(--card); border:1px solid var(--line); border-radius:var(--r-lg); overflow:hidden;
  animation:pulse 1.4s ease-in-out infinite; }
.sk .cov { background:var(--card2); }
.sk .l { height:11px; border-radius:var(--r-sm); background:var(--card2); margin:0 16px 10px; }
.sk .l:first-of-type { margin-top:16px; width:70%; }
.sk .l.s { width:45%; }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:.55} }
@media (prefers-reduced-motion: reduce) { .sk { animation:none; } }

/* ── Dải "Sắp diễn ra" ────────────────────────────────────────────────────── */
.ev-row { display:grid; gap:10px; grid-template-columns:repeat(auto-fill, minmax(320px, 1fr)); }
.ev { display:flex; align-items:center; gap:14px; width:100%; text-align:left;
  padding:10px 14px 10px 10px; border:1px solid var(--line); border-radius:var(--r-lg);
  background:var(--card); color:inherit; font:inherit; min-height:64px;
  transition:border-color var(--t-fast) ease, background var(--t-fast) ease; }
.ev:hover { border-color:var(--line-strong); background:var(--card2); }
.ev-date { flex:0 0 auto; width:44px; height:44px; border-radius:var(--r-md);
  background:var(--t-cro-soft); color:var(--t-cro); display:grid; place-items:center; line-height:1; }
.ev-date b { font-size:17px; font-weight:800; font-variant-numeric:tabular-nums; }
.ev-date i { font-size:9.5px; font-style:normal; font-weight:700; letter-spacing:.05em;
  text-transform:uppercase; opacity:.85; }
.ev-body { display:flex; flex-direction:column; gap:3px; min-width:0; flex:1; }
.ev-title { font-size:var(--fs-body); font-weight:650; line-height:1.35;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.ev-meta { font-size:var(--fs-caption); color:var(--muted); }
.ev .pill { flex:0 0 auto; }

/* ── Chân trang ───────────────────────────────────────────────────────────── */
.foot { padding:16px; border-top:1px solid var(--line); color:var(--muted);
  font-size:var(--fs-caption); display:flex; gap:8px; justify-content:center; flex-wrap:wrap; }
/* Link trong một hàng như thế này là target "danh sách": ngưỡng WCAG 2.5.8 là 24px,
   không phải 44px của điều khiển (Gems/CLAUDE.md §9.1). */
.stamp { background:none; border:0; padding:0; font:inherit; color:inherit; cursor:pointer; }
.foot a, .foot button { min-height:24px; display:inline-flex; align-items:center;
  color:var(--muted); background:none; border:0; padding:0; font:inherit; }
.foot a:hover, .foot button:hover { color:var(--txt); text-decoration:underline; }
.dot { opacity:.5; }
.foot [hidden] { display:none; }
/* Banner mời cài (chỉ web): cùng khuôn với thẻ mời đánh giá (.rate) để hai thứ cùng một giọng, cộng icon tiện ích
   bên trái cho người ta nhận ra đúng cái sẽ hiện trên thanh công cụ. */
.invite { display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin:0 0 16px; padding:14px 16px;
  background:var(--card); border:1px solid var(--line); border-left:3px solid var(--accent); border-radius:var(--r-lg); }
.invite[hidden] { display:none; }
/* Cửa sổ hẹp hơn 640px: banner lấy mất màn đầu (visual-gate 01/10/2026 ở 320×568: ô dẫn đầu rơi xuống dưới).
   Điện thoại đã không thấy banner (invite.js); đây là cửa sổ desktop bị kéo hẹp. */
@media (max-width:640px) { .invite { display:none; } }
.invite-ico { width:44px; height:44px; flex:0 0 auto; border-radius:10px; }
.invite-txt { display:flex; flex-direction:column; gap:3px; flex:1 1 260px; min-width:0; }
.invite-txt strong { font-size:var(--fs-body-lg); }
.invite-txt span { color:var(--muted); font-size:var(--fs-body); line-height:1.5; }
.invite-acts { display:flex; align-items:center; gap:8px; flex:0 0 auto; }
.invite-cta { display:inline-flex; align-items:center; gap:8px; min-height:44px; padding:0 16px; border-radius:var(--r-md);
  background:var(--accent); color:#fff; font-weight:700; text-decoration:none; }
.invite-cta:hover { filter:brightness(1.08); }
.invite-later { min-height:44px; padding:0 12px; border:1px solid var(--line); border-radius:var(--r-md);
  background:none; color:var(--muted); font:inherit; cursor:pointer; }
.invite-later:hover { color:var(--txt); border-color:var(--line-strong); }
/* Nút "Cập nhật … trước" là ĐIỀU KHIỂN (bấm để tải lại), không phải link trong danh sách: ngưỡng 44px (§9.1).
   visual-gate 01/10/2026 đo nó 24px ở 320/390/768. Vùng bấm cao ra, chữ không đổi. */
.foot .stamp { min-height:44px; }   /* `.foot a` đặt display, nên phải nói lại cho [hidden] (mục Tuỳ chọn ẩn trên web) */

/* ── Cửa đọc (chỉ cho tin miễn phí) ───────────────────────────────────────────
   Bài chiếm trọn khung. Hai thanh nằm ĐÈ lên bài, nền mờ dần sang trong suốt, và lặn
   đi (.calm) khi đang cuộn xuống đọc — xem initReader() trong newtab.js. */
.reader { width:min(780px, calc(100vw - 32px)); height:min(92vh, 980px); max-height:none; padding:0;
  border:1px solid var(--line); border-radius:var(--r-xl); background:var(--card); color:var(--txt);
  box-shadow:var(--sh-overlay); overflow:hidden; }
.reader::backdrop { background:rgba(4,5,8,.72); }
.reader[open] { display:block; position:fixed; }
.r-prog { position:absolute; left:0; right:0; top:0; height:3px; z-index:3; pointer-events:none; }
.r-prog i { display:block; height:100%; background:var(--accent); transform:scaleX(0); transform-origin:left; }
.reader-bar, .reader-foot { position:absolute; left:0; right:0; z-index:2; display:flex; align-items:center; gap:12px;
  transition:opacity .22s ease, transform .22s ease; }
.reader-bar { top:0; padding:14px 14px 26px 22px;
  background:linear-gradient(to bottom, var(--card) 58%, transparent); }
.reader-foot { bottom:0; padding:30px 16px 16px; justify-content:space-between;
  background:linear-gradient(to top, var(--card) 62%, transparent); }
.reader.calm .reader-bar { opacity:0; transform:translateY(-10px); pointer-events:none; }
.reader.calm .reader-foot { opacity:0; transform:translateY(10px); pointer-events:none; }
/* Chỉ giữ thanh hiện khi BÀN PHÍM đang đứng trong nó (:focus-visible). :focus-within thì
   ghim luôn thanh trên, vì showModal() tự đặt focus vào nút đóng. */
.reader.calm .reader-bar:has(:focus-visible), .reader.calm .reader-foot:has(:focus-visible) { opacity:1; transform:none; pointer-events:auto; }
.reader-body:focus { outline:none; }
/* Trang phía sau không cuộn theo, và thanh cuộn của nó không lộ ra cạnh cửa đọc. */
html:has(.reader[open]) { overflow:hidden; }
.reader-eyebrow { font-size:var(--fs-micro); font-weight:800; letter-spacing:.07em; flex:1; min-width:0;
  text-transform:uppercase; color:var(--accent-ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.reader-eyebrow.is-hot { color:var(--warn); }
.r-count { font-size:var(--fs-caption); color:var(--muted); font-variant-numeric:tabular-nums; white-space:nowrap; }
.reader-body { height:100%; overflow-y:auto; overscroll-behavior:contain; padding:68px 44px 104px;
  /* Thanh cuộn mảnh, rãnh trong suốt: rãnh mặc định màu sáng lộ ra như một dải trắng
     dưới hai thanh mờ dần (thấy trên ảnh chụp 1280, 26/09/2026). */
  scrollbar-width:thin; scrollbar-color:var(--line-strong) transparent; }
.reader-body > * { max-width:680px; margin-left:auto; margin-right:auto; }
.reader-body h1 { margin:0 auto 8px; font-family:var(--serif);
  font-size:clamp(var(--fs-h1), 2.4vw, var(--fs-display)); line-height:1.26; letter-spacing:-.02em; }
.reader-body .dek { margin:0 auto 22px; color:var(--muted); font-size:var(--fs-body-lg); line-height:1.6; }
.reader-body h2 { margin:28px 0 8px; font-family:var(--serif); font-size:18px; letter-spacing:-.01em; }
.reader-body h3 { margin:22px 0 6px; font-family:var(--serif); font-size:var(--fs-h3); }
.reader-body p { margin:0 0 15px; font-size:16px; line-height:1.72; }
/* URL dài (mục Sources) không có chỗ ngắt: không cho phép ngắt thì cả thân bài cuộn ngang ở 390/320. */
.reader-body p, .reader-body li { overflow-wrap:anywhere; }
.reader-body ul, .reader-body ol { margin:0 0 15px; padding-left:22px; }
.reader-body li { margin:0 0 7px; line-height:1.68; font-size:16px; }
.reader-body a { color:var(--accent-ink); text-decoration:underline; }
/* Link trong danh sách (mục "Nguồn" cuối bài) là target danh sách: ≥ 24px (WCAG 2.5.8, §9.1). Đo 01/10/2026: 18px.
   Padding dọc của phần tử inline nới vùng bấm mà không đổi dòng: 18 + 2×3 = 24, khe giữa hai mục còn ~10px. */
.reader-body li a { padding-block:3px; }
.reader-body code { background:var(--card2); padding:2px 5px; border-radius:var(--r-xs); font-size:var(--fs-caption); }
.reader-body img { max-width:100%; border-radius:var(--r-md); margin:6px 0 14px; }
/* Thẻ trích bài trên X: chữ do feed gửi (embeds), không tải gì từ X. */
.reader-body .x-quote { margin:6px auto 18px; padding:14px 16px; background:var(--card2);
  border:1px solid var(--line); border-left:3px solid var(--line-strong); border-radius:var(--r-md); }
.reader-body .x-quote blockquote { margin:0 0 10px; }
.reader-body .x-quote p { margin:0; font-size:15px; line-height:1.6; overflow-wrap:anywhere; }
.reader-body .x-quote figcaption { font-size:var(--fs-caption); color:var(--muted); overflow-wrap:anywhere; }
.reader-body .xq-who { color:var(--txt); font-weight:700; }
.reader-body .xq-who span { color:var(--muted); font-weight:400; }
.reader-body .x-quote a { display:inline-block; padding:13px 0; margin:-13px 0; }
/* Bảng cuộn ngang trong khung của nó, không đẩy cả trang tràn ở 320px. */
.reader-body .md-table { overflow-x:auto; margin:4px auto 18px; max-width:min(680px, 100%); min-width:0; }
.reader-body table { border-collapse:collapse; width:100%; font-size:15px; }
.reader-body th, .reader-body td { padding:9px 10px; min-width:6.5em; border-bottom:1px solid var(--line); text-align:left; vertical-align:top; }
.reader-body th { font-size:var(--fs-caption); font-weight:800; color:var(--muted); letter-spacing:.02em; }
/* Mốc cuối bài cho bộ đếm lượt đọc (views.js) — vô hình, cao 1px để IntersectionObserver thấy. */
.r-end { display:block; height:1px; }
.r-upnext { display:flex; flex-direction:column; gap:4px; width:100%; margin:34px auto 0; padding:16px 18px;
  text-align:left; background:var(--card2); border:1px solid var(--line); border-radius:var(--r-lg); color:var(--txt); }
.r-upnext:hover { border-color:var(--accent); }
.r-upnext span { font-size:var(--fs-micro); font-weight:800; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.r-upnext strong { font-size:var(--fs-body-lg); line-height:1.4; }
.r-nav { flex-shrink:0; }   /* ở 320px thanh dưới bóp nút ‹ › còn 39,5px (đo 01/10/2026); điều khiển ≥ 44px */
.r-nav:disabled { opacity:.35; cursor:default; }
.r-open { flex:0 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Điện thoại: trọn màn hình, không bo góc, không viền. */
@media (max-width:560px) {
  .reader { width:100vw; height:100dvh; max-width:100vw; max-height:100dvh; margin:0; inset:0;
    border:0; border-radius:0; }
  .reader-bar { padding:10px 10px 24px 16px; }
  .reader-foot { padding:26px 12px calc(12px + env(safe-area-inset-bottom)); }
  .reader-body { padding:62px 18px 100px; }
  .reader-body h1 { font-size:var(--fs-h1); }
}
@media (prefers-reduced-motion: reduce) { .reader-bar, .reader-foot { transition:none; } }
.btn { display:inline-flex; align-items:center; justify-content:center; gap:8px; min-height:44px;
  padding:0 18px; border-radius:var(--r-md); background:var(--accent); color:#fff;
  font-weight:700; font-size:var(--fs-body); border:0; }
.btn:hover { filter:brightness(1.08); text-decoration:none; }

/* ── Khổ hẹp ──────────────────────────────────────────────────────────────── */
@media (max-width:900px) {
  .lead-card { grid-template-columns:1fr; }
  .lead-body { padding:20px; }
  /* Ở đây bìa nằm TRÊN chữ, nên theo đúng luật ghi ở .lead-card .cov: 16:9, không fill. Để fill cao 200px thì khung
     dẹt theo bề rộng: đo 27/09/2026 ở cửa sổ 900px là 866×200 (4,3:1), chỉ còn dải y 176–453 của ảnh bìa 1200×630,
     và dòng trên của tiêu đề trên ảnh bìa bị cắt. */
  .lead-card .cov { aspect-ratio:16/9; height:auto; min-height:0; }
}
@media (max-width:560px) {
  /* Màn điện thoại: mô tả của ô dẫn đầu chỉ giữ 2 dòng, để "Đọc ngay" còn trong màn đầu. visual-gate 01/10/2026 ở
     320×568: mô tả 6 dòng đẩy đáy ô xuống y=742. Bản đầy đủ nằm ngay trong trình đọc. */
  .lead-body p { display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
  .top { gap:10px; padding:10px 12px; }
  main { padding:16px 12px 32px; }
  .grid { grid-template-columns:1fr; gap:12px; }
  .ev-row { grid-template-columns:1fr; }
  .ev .pill { display:none; }
}


/* ── đoạn mở đầu của hàng bị khoá ──────────────────────────────────────────
   Mờ dần chứ không cắt phựt: một khối chữ cụt đọc ra như lỗi tải, còn mờ dần đọc ra
   như "còn nữa". Dùng mask nên chữ vẫn là chữ — trình đọc màn hình đọc được đủ đoạn,
   không bị mất theo hiệu ứng thị giác. */
.teaser { position:relative; margin: 8px 0 10px; }
.teaser p { margin:0; font-size:var(--fs-caption); line-height:1.5; color:var(--muted);
  max-height: 4.5em; overflow:hidden;
  -webkit-mask-image: linear-gradient(180deg,#000 40%,transparent 100%);
          mask-image: linear-gradient(180deg,#000 40%,transparent 100%); }
.teaser-more { display:inline-block; margin-top: 2px; font-size:var(--fs-micro);
  font-weight:700; letter-spacing:.04em; text-transform:uppercase; color:var(--muted); opacity:.75; }
@media (prefers-reduced-motion: reduce) { .teaser p { max-height:none; -webkit-mask-image:none; mask-image:none; } }

/* ── hộp thoại: cửa khoá và giới thiệu ─────────────────────────────────── */
.sheet { width:min(520px, calc(100vw - 32px)); border:1px solid var(--line); border-radius:var(--r-xl);
  background:var(--card); color:var(--txt); padding: 28px 26px 22px; box-shadow:var(--sh-overlay); }
.sheet::backdrop { background:rgba(0,0,0,.55); backdrop-filter: blur(3px); }
.sheet h2 { margin:0 0 10px; font-size:var(--fs-h); line-height:1.25; letter-spacing:-.01em; }
.sheet p { margin:0 0 12px; font-size:var(--fs-body); line-height:1.6; color:var(--muted); }
.sheet-x { position:absolute; top:12px; right:12px; }
/* §9.1: đây là ĐIỀU KHIỂN, ngưỡng 44px của Apple HIG / WCAG 2.5.5 — không phải 24px */
.sheet-cta { display:inline-flex; align-items:center; justify-content:center;
  min-height:44px; padding: 0 20px; margin-top: 6px; font-weight:700; }
.sheet-note { margin: 12px 0 0; font-size:var(--fs-micro); opacity:.7; }
@media (max-width: 420px) { .sheet { padding: 24px 18px 18px; } }


/* ── Bảng tìm ⌘K ──────────────────────────────────────────────────────────────
   Số đo chép từ bảng lệnh của GemBoss (apps/admin/.../CommandPalette.module.css): rộng tối đa
   600, cách đỉnh 80, bo 12, dòng bo 8, chữ dòng 13 / phụ 11, tiêu đề nhóm 11 viết hoa. Màu thì
   đi qua token của tiện ích, nên cùng một bảng đúng cả nền tối lẫn nền sáng. */
.pal { width:min(600px, calc(100vw - 32px)); max-height:calc(100vh - 160px); margin:80px auto auto; padding:0;
  background:var(--card); color:var(--txt); border:1px solid var(--line); border-radius:12px;
  box-shadow:0 32px 64px rgba(0,0,0,.35); overflow:hidden; }
.pal[open] { display:flex; flex-direction:column; }
.pal::backdrop { background:rgba(15,23,42,.4); backdrop-filter:blur(2px); }
.pal-search { display:flex; align-items:center; gap:12px; padding:14px 16px; border-bottom:1px solid var(--line); }
.pal-search svg { flex:0 0 auto; color:var(--muted); }
.pal-search input { flex:1; min-width:0; min-height:28px; border:0; background:none; color:var(--txt);
  font:inherit; font-size:15px; outline:none; }
.pal kbd { font:inherit; font-size:11px; padding:2px 6px; border:1px solid var(--line); border-radius:4px;
  background:var(--card2); color:var(--muted); }
.pal-list { flex:1; overflow-y:auto; padding:8px; display:flex; flex-direction:column; gap:4px;
  scrollbar-width:thin; scrollbar-color:var(--line-strong) transparent; }
.pal-group { font-size:11px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; color:var(--muted);
  padding:12px 12px 4px; }
.pal-row { display:flex; align-items:center; gap:12px; width:100%; min-height:44px; padding:8px 12px;
  border:0; border-radius:8px; background:none; color:var(--txt); font:inherit; font-size:13px; text-align:left; cursor:pointer; }
.pal-row.on { background:var(--card2); }
.pal-ic { flex:0 0 26px; width:26px; height:26px; border-radius:6px; display:grid; place-items:center; font-size:14px;
  background:var(--card2); border:1px solid var(--line); }
.pal-row.on .pal-ic { background:var(--card); border-color:transparent; }
.pal-main { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.pal-main strong { font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pal-main span { font-size:11px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pal-main mark { background:color-mix(in srgb, var(--accent) 28%, transparent); color:inherit; border-radius:2px; padding:0 1px; }
.pal-act { flex:0 0 auto; font-size:10px; font-weight:600; letter-spacing:.04em; text-transform:uppercase;
  padding:4px 8px; border-radius:6px; background:var(--card2); color:var(--muted); }
.pal-act.locked { color:var(--warn); background:var(--warn-soft); }
.pal-row.on .pal-act { background:var(--accent); color:#fff; }
.pal-x { display:none; }
.pal-empty { margin:0; padding:20px 12px 12px; font-size:13px; color:var(--muted); }
.pal-foot { display:flex; justify-content:space-between; gap:12px; padding:8px 16px; border-top:1px solid var(--line);
  background:var(--bg2); font-size:11px; color:var(--muted); }
@media (max-width:560px) {
  .pal { width:100vw; max-width:100vw; max-height:100dvh; height:100dvh; margin:0; border:0; border-radius:0; }
  .pal-search input { font-size:16px; }   /* dưới 16px iOS phóng to khi chạm vào ô */
  .pal-foot #pal-keys { display:none; }   /* điện thoại không có phím mũi tên */
  .pal-search kbd { display:none; }
  .pal-x { display:inline-flex; margin-right:-6px; }
  .pal-search { padding:8px 12px 8px 16px; }
}

/* ── Chia sẻ ──────────────────────────────────────────────────────────────── */
/* Thẻ xem trước: ảnh 1.91:1 + tiêu đề + tên miền, đúng hình thẻ link mà Facebook / Messenger / X / WhatsApp vẽ. */
.share-card { display:flex; flex-direction:column; border:1px solid var(--line); border-radius:var(--r-lg); overflow:hidden;
  background:var(--card2); margin:4px 0 16px; }
.share-card img { width:100%; aspect-ratio:1200/630; object-fit:cover; display:block; background:var(--card); }
.share-card div { display:flex; flex-direction:column; gap:2px; padding:10px 12px; min-width:0; }
.share-card strong { font-size:var(--fs-body); line-height:1.4; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.share-card span { font-size:var(--fs-caption); color:var(--muted); }
.share-grid { display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:8px; }
.share-t { display:flex; flex-direction:column; align-items:center; gap:6px; min-height:72px; padding:10px 4px;
  border:1px solid var(--line); border-radius:var(--r-md); background:none; color:var(--txt); font:inherit;
  font-size:var(--fs-caption); text-decoration:none; cursor:pointer; text-align:center; }
.share-t:hover, .share-t:focus-visible { border-color:var(--line-strong); background:var(--card2); }
.share-ic { width:36px; height:36px; border-radius:50%; display:grid; place-items:center; color:#fff; background:var(--card2); }
.share-ic svg { width:20px; height:20px; }
.s-whatsapp .share-ic { background:#25D366; } .s-messenger .share-ic { background:#0866FF; } .s-wechat .share-ic { background:#07C160; }
.s-telegram .share-ic { background:#26A5E4; } .s-facebook .share-ic { background:#0866FF; }
.s-x .share-ic { background:#000; box-shadow:inset 0 0 0 1px var(--line-strong); }
.s-linkedin .share-ic { background:#0A66C2; } .s-linkedin .share-ic svg { width:22px; height:22px; }
.s-email .share-ic, .s-more .share-ic { background:var(--card2); color:var(--txt); box-shadow:inset 0 0 0 1px var(--line); }
.share-qr { display:flex; flex-direction:column; align-items:center; gap:8px; margin:14px 0 0; }
.share-qr[hidden] { display:none; }
.share-qr svg { width:180px; height:180px; border-radius:var(--r-md); }
.share-qr p { margin:0; color:var(--muted); font-size:var(--fs-caption); text-align:center; }
.share-copy { display:flex; gap:8px; margin:14px 0 0; }
.share-copy input { flex:1 1 auto; min-width:0; min-height:44px; padding:0 12px; border:1px solid var(--line); border-radius:var(--r-md);
  background:var(--bg2); color:var(--txt); font:inherit; font-size:var(--fs-caption); }
.share-copy .btn { min-height:44px; flex:0 0 auto; }
@media (max-width:400px) { .share-grid { grid-template-columns:repeat(3, minmax(0, 1fr)); } }
