/* Light, paper-white, high-contrast. Numbers are the loudest thing on the page;
   chrome stays quiet so a stat row reads at a glance. */
:root {
  --bg: #ffffff;
  --paper: #fcfcfd;
  --ink: #0b1220;
  --ink-2: #35404f;   /* 8.95 → 10.6 : 1 */
  --muted: #5a6575;   /* 4.59 → 6.0 : 1 — 4.5 is a floor, not a target */
  --line: #e6e9ef;
  --line-2: #f1f3f7;
  --accent: #1f5eff;
  --accent-soft: #eef3ff;
  /* Tối hơn một nấc để đạt WCAG AA trên CHÍNH nền -soft của nó.
     Đo trên production: --good trên --good-soft ra 3.94, --warn trên
     --warn-soft ra 3.85 — chuẩn là 4.5. Chín chỗ chữ dưới chuẩn đều quy về
     đúng hai token này. #0e7f57 → 4.53 trên soft, 5.01 trên trắng. */
  --good: #0e7f57;
  --good-soft: #e8f7f0;
  --warn: #9d5c0c;   /* đo trên trang thật: 0 chỗ dưới chuẩn. #a4600d tính ra 4.51 nhưng trình duyệt đo 4.49 — nền thật khác nền tôi giả định */
  --warn-soft: #fdf3e4;
  --bad: #c2334d;
  --bad-soft: #fdeef1;
  /* Token của một khối bê từ hệ thiết kế khác sang (bảng màu đất nung
     #b0392a lộ ra trong các giá trị dự phòng). Phần lớn chỗ dùng có dự phòng
     nên vẫn hiện; .pp và .pp-bar thì KHÔNG, nên viền và nền thanh tỉ lệ rơi
     về trong suốt. Khai báo lại theo đúng bảng màu ở đây. */
  --rule: #e6e9ef;    /* = --line */
  --sunk: #f1f3f7;    /* = --line-2 */
  --card: #ffffff;    /* = --bg */
  --live: #0f8a5f;    /* = --good */
  --err:  #c2334d;    /* = --bad */
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --radius: 14px;
  --shadow: 0 1px 2px rgba(11,18,32,.04), 0 8px 24px rgba(11,18,32,.05);
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; 
/* Lưới an toàn cho chữ dài không ngắt được.
   Ba nguồn trôi ngang trên mobile đo được đều là cùng một hình dạng: một chuỗi
   dài hơn khung mà không có chỗ ngắt — câu tóm tắt do model viết (.why, 562px
   trong khung 327px), thông báo lỗi API (.tk-e), nhãn phân khúc (.chip).
   Liệt kê từng class rồi vá là đuổi theo mãi không hết: nội dung do model và do
   nhà cung cấp dữ liệu sinh ra, hình dạng tiếp theo chưa tồn tại. Đặt sàn ở đây
   một lần. Ô có white-space:nowrap (số trong bảng) không bị ảnh hưởng. */
  overflow-wrap: break-word;
}
body {
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; }

/* ---------- top bar ---------- */
.topbar {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  padding: 14px 28px;
  background: rgba(255,255,255,.88);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.brand {
  display: flex; align-items: center; gap: 9px;
  font-weight: 640; letter-spacing: -.02em; font-size: 16px; text-decoration: none;
}
.brand .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
#runform { display: flex; gap: 8px; flex: 1; max-width: 560px; }
#url {
  flex: 1; padding: 9px 14px; font-size: 14.5px; color: var(--ink);
  border: 1px solid var(--line); border-radius: 10px; background: var(--paper); outline: none;
}
#url:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); background: #fff; }
#go {
  padding: 9px 18px; font-size: 14.5px; font-weight: 560; color: #fff; cursor: pointer;
  background: var(--ink); border: 0; border-radius: 10px;
}
#go:hover { background: var(--accent); }
#go[disabled] { opacity: .45; cursor: default; }

main { max-width: 1180px; margin: 0 auto; padding: 40px 28px 120px; }

/* ---------- empty state ---------- */
.empty:not([hidden]) { display: grid; gap: 34px; align-content: start; }
[hidden] { display: none !important; }
.empty h1 { font-size: 40px; line-height: 1.12; letter-spacing: -.035em; margin: 24px 0 18px; font-weight: 640; }
.empty > p { max-width: 60ch; color: var(--ink-2); font-size: 16px; margin: 0 0 34px; }
.what { list-style: none; padding: 0; margin: 0; display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }
.what li { background: #fff; padding: 18px 20px; display: flex; flex-direction: column; gap: 5px; }
.what b { font-size: 14px; font-weight: 600; }
.what span { color: var(--muted); font-size: 13.5px; line-height: 1.55; }

/* ---------- generic blocks ---------- */
.card { border: 1px solid var(--line); border-radius: var(--radius); background: #fff; box-shadow: var(--shadow); }
.section-title {
  font-size: 12px; font-weight: 640; letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 14px;
}
/* h1 lẫn h2: tên brand giờ là h1 của trang dossier, nhưng .big còn dùng chỗ
   khác. Selector gắn tag như cũ sẽ âm thầm bỏ style khi đổi thẻ. */
h1.big, h2.big { font-size: 26px; letter-spacing: -.025em; margin: 0 0 6px; font-weight: 640; }
.sub { color: var(--muted); font-size: 14px; margin: 0; }
.stack > * + * { margin-top: 34px; }

/* Nhãn chip do model sinh ra, độ dài không đoán trước được — "+ Etsy sellers
   via Printful/print-on-demand" đo được 378px ở khổ 390px. Cho nó xuống dòng
   thay vì đẩy ngang cả trang. */
.chip {
  max-width: 100%; overflow-wrap: anywhere;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 560;
  border: 1px solid var(--line); background: var(--paper); color: var(--ink-2);
  /* KHÔNG nowrap. Nhãn chip phần lớn ngắn và tự nằm gọn một dòng, nhưng nhãn
     phân khúc do model sinh ra thì không đoán được — "+ Etsy sellers via
     Printful/print-on-demand" đo được 367px trong khung 327px ở khổ 390px, và
     nowrap khiến overflow-wrap ở trên vô hiệu. */
  white-space: normal;
}
.chip.live { background: var(--good-soft); border-color: transparent; color: var(--good); }
.chip.warn { background: var(--warn-soft); border-color: transparent; color: var(--warn); }
.chip.off  { background: var(--line-2); border-color: transparent; color: var(--muted); }
.chip.direct { background: var(--accent-soft); border-color: transparent; color: var(--accent); }
.chip.indirect { background: #f6f0ff; border-color: transparent; color: #6a3fc6; }

/* ---------- stat cards (the BrandSearch panel, redrawn) ---------- */
/* Nền container là màu VIỀN để khe 1px thành đường kẻ. Nhưng 10 ô trên lưới 4
   cột để lại 2 chỗ trống ở hàng cuối, và chỗ trống đó hiện ra một mảng xám —
   người đọc thấy hai ô rỗng có nền, hiểu là dữ liệu hỏng chứ không phải "hết ô".
   Đổi lại: container trắng, đường kẻ do chính ô vẽ bằng box-shadow vào khe. */
.stats { display: grid; gap: 1px; background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; grid-template-columns: repeat(4, 1fr); }
.stats > .stat { box-shadow: 1px 0 0 var(--line), 0 1px 0 var(--line); }
@media (max-width: 900px) { .stats { grid-template-columns: repeat(2, 1fr); } }
.stat { background: #fff; padding: 15px 16px 14px; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.stat .k { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); font-weight: 560; }
.stat .v { font-size: 23px; font-weight: 640; letter-spacing: -.03em; font-variant-numeric: tabular-nums; line-height: 1.2; }
.stat .v.sm { font-size: 17px; }
.stat .n { font-size: 11.5px; color: var(--muted); }
.stat .n.measured { color: var(--good); }
.stat .n.modelled { color: var(--warn); }

/* ---------- competitor ---------- */
.rival { scroll-margin-top: 90px; }
.rival > header { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.rival h3 { font-size: 21px; letter-spacing: -.02em; margin: 0; font-weight: 640; }
.rival .dom { color: var(--muted); font-size: 13.5px; text-decoration: none; }
.rival .dom:hover { color: var(--accent); }
.why { color: var(--ink-2); font-size: 15px; line-height: 1.6; margin: 6px 0 16px; max-width: 74ch; }

/* Collapsible section. The header is a real button so keyboard and screen
   readers get the toggle for free. */
.panel { border: 1px solid var(--line); border-radius: var(--radius); background: #fff; overflow: hidden; }
.panel > .head {
  width: 100%; padding: 13px 18px; border: 0; border-bottom: 1px solid transparent;
  display: flex; align-items: center; gap: 11px; background: #fff; cursor: pointer;
  font-family: inherit; text-align: left;
}
.panel > .head:hover { background: var(--paper); }
.panel.open > .head { border-bottom-color: var(--line-2); }
.panel > .head h3, .panel > .head h4 { margin: 0; font-size: 13px; font-weight: 640; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.panel > .head .cnt {
  font-size: 11.5px; font-weight: 640; color: var(--muted); background: var(--line-2);
  border-radius: 999px; padding: 2px 8px; font-variant-numeric: tabular-nums;
}
.panel > .head .chev { margin-left: auto; width: 20px; height: 20px; color: var(--muted); transition: transform .18s ease; }
.panel.open > .head .chev { transform: rotate(180deg); }
.panel > .body { padding: 18px; display: none; }
.panel.open > .body { display: block; }
.grid2 { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
.grid3 { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); }

/* persona */
.persona { border: 1px solid var(--line); border-radius: 12px; padding: 16px; background: var(--paper); }
.persona h5 { margin: 0 0 14px; padding-bottom: 11px; border-bottom: 1px solid var(--line); font-size: 15.5px; font-weight: 660; letter-spacing: -.012em; }
.persona dl { margin: 0; display: grid; gap: 16px; }   /* between pairs */
.persona dt { font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.persona dd { margin: 3px 0 0; font-size: 14px; color: var(--ink); line-height: 1.55; }   /* within pair */
.persona .ev { margin-top: 11px; padding-top: 10px; border-top: 1px dashed var(--line); font-size: 12px; color: var(--muted); }

/* rows */
.rows { display: grid; gap: 10px; }
.row { display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: start; padding: 12px 0; border-top: 1px solid var(--line-2); }
.row:first-child { border-top: 0; padding-top: 0; }
.row .lead { font-weight: 600; font-size: 13.5px; }
.row .txt { font-size: 14px; color: var(--ink-2); line-height: 1.55; }
.row .txt em { color: var(--muted); font-style: normal; font-size: 12.5px; display: block; margin-top: 4px; }

/* landing pages */
.shots { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); }
.shot { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: var(--paper); }
/* The capture is a 1440x900 viewport shot; show it at that ratio so nothing is
   thrown away. A fixed height with object-fit: cover was cropping a third off
   every thumbnail. */
.shot img {
  display: block; width: 100%; aspect-ratio: 1440 / 900; height: auto;
  object-fit: cover; object-position: top center; background: var(--line-2);
  border-bottom: 1px solid var(--line);
}
.shot .meta { padding: 10px 13px; display: flex; flex-direction: column; gap: 4px; }
.shot .meta a { font-size: 12.5px; color: var(--ink-2); text-decoration: none; word-break: break-all; }
.shot .meta a:hover { color: var(--accent); }
.shot .meta .m { font-size: 11.5px; color: var(--muted); }
.noshot { padding: 26px 14px; text-align: center; color: var(--muted); font-size: 12.5px; background: repeating-linear-gradient(45deg, #fafbfc, #fafbfc 10px, #f5f6f8 10px, #f5f6f8 20px); }

/* ad copy swipe */
.swipe { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }
.ad { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: #fff; display: flex; flex-direction: column; }
.ad img { width: 100%; aspect-ratio: 4 / 3; height: auto; object-fit: cover; object-position: center; background: var(--line-2); }
.ad .c { padding: 12px 14px; display: flex; flex-direction: column; gap: 7px; flex: 1; }
.ad .hl { font-size: 13.5px; font-weight: 600; line-height: 1.4; }
.ad .bd { font-size: 12.5px; color: var(--ink-2); line-height: 1.5; max-height: 8.4em; overflow: hidden; }
.ad .ft { margin-top: auto; padding-top: 8px; display: flex; gap: 6px; flex-wrap: wrap; align-items: center; font-size: 11px; color: var(--muted); border-top: 1px solid var(--line-2); }

/* timeline */
.tl { position: relative; padding-left: 20px; }
.tl::before { content: ''; position: absolute; left: 4px; top: 6px; bottom: 6px; width: 2px; background: var(--line); border-radius: 2px; }
.tl .ev { position: relative; padding: 0 0 18px 4px; }
.tl .ev::before { content: ''; position: absolute; left: -20px; top: 6px; width: 10px; height: 10px; border-radius: 50%; background: #fff; border: 2px solid var(--accent); }
.tl .when { font-size: 11.5px; font-weight: 620; letter-spacing: .05em; color: var(--accent); text-transform: uppercase; }
.tl .tl-what { font-size: 14px; font-weight: 560; margin: 2px 0 3px; }
.tl .so { font-size: 13px; color: var(--ink-2); }
.tl .src { font-size: 11.5px; color: var(--muted); margin-top: 3px; }

/* price map */
.band { display: grid; grid-template-columns: 150px 1fr; gap: 14px; padding: 12px 0; border-top: 1px solid var(--line-2); align-items: start; }
.band:first-child { border-top: 0; }
.band .bn { font-weight: 620; font-size: 14px; font-variant-numeric: tabular-nums; }
.band .bb { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 5px; }
.band .note { font-size: 12.5px; color: var(--muted); }

/* log */
.log { font: 12.5px/1.7 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--ink-2); max-height: 260px; overflow: auto; }
.log div { padding: 1px 0; }
.log div::before { content: '· '; color: var(--muted); }
.running { display: inline-flex; align-items: center; gap: 7px; color: var(--accent); font-size: 13px; font-weight: 560; }
.spinner { width: 11px; height: 11px; border: 2px solid var(--accent-soft); border-top-color: var(--accent); border-radius: 50%; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

.assump { margin: 10px 0 0; padding: 11px 13px; background: var(--paper); border: 1px solid var(--line); border-radius: 10px; font-size: 12.5px; color: var(--muted); }
.assump b { color: var(--ink-2); font-weight: 600; }
.assump ul { margin: 6px 0 0; padding-left: 17px; }

.err { padding: 14px 16px; border-radius: 12px; background: var(--bad-soft); color: var(--bad); font-size: 13.5px; }
.divider { display: flex; align-items: center; gap: 14px; margin: 44px 0 22px; }
.divider h2 { margin: 0; font-size: 15px; font-weight: 640; letter-spacing: -.01em; white-space: nowrap; }
.divider .line { flex: 1; height: 1px; background: var(--line); }
.divider .count { font-size: 12.5px; color: var(--muted); }

@media (max-width: 640px) {
  main { padding: 26px 16px 80px; }
  .topbar { padding: 12px 16px; }
  .empty h1 { font-size: 29px; }
  .band { grid-template-columns: 1fr; }
}

/* ---------- illustration marks ---------- */
.ic { width: 100%; height: 100%; display: block; }
.ic-wrap {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; flex: 0 0 30px; border-radius: 9px;
  background: var(--accent-soft); color: var(--accent); padding: 6px;
}
.ic-wrap.big { width: 34px; height: 34px; flex-basis: 34px; padding: 7px; }
.brand .logo { display: inline-flex; width: 22px; height: 22px; color: var(--accent); }
.brand { gap: 8px; }

/* ---------- language switch ---------- */
.lang { display: flex; gap: 2px; padding: 3px; background: var(--line-2); border-radius: 999px; }
.langbtn {
  border: 0; background: transparent; cursor: pointer; border-radius: 999px;
  padding: 5px 12px; font-size: 12.5px; font-weight: 540; color: var(--muted);
  font-family: inherit;
}
.langbtn:hover { color: var(--ink); }
.langbtn.on { background: #fff; color: var(--ink); box-shadow: 0 1px 2px rgba(11,18,32,.08); }
/* Bản dịch chưa viết xong. Không khoá nút — bấm vào vẫn xem được bản gốc và có
   nút yêu cầu viết; chấm chỉ nói trước để khỏi tưởng là lỗi. */
.langbtn.pending { opacity: .62; }
.langdot { color: var(--accent, #b0392a); margin-left: 2px; font-weight: 700; }

/* ---------- hero ---------- */
/* Khối nền trang trí .hero-bg cố ý thò ra ngoài mép 80px (inset auto -80px) cho
   hiệu ứng tràn. Trên desktop container có lề nên không ai thấy; ở khổ 390px nó
   vượt mép và làm TRANG CHỦ cuộn ngang 64px — thường trực, trên chính trang đầu
   tiên ai cũng thấy.
   `clip` thay vì `hidden`: hidden tạo vùng cuộn và sẽ phá position:sticky của
   phần tử con nếu sau này có. Trình duyệt không hiểu `clip` thì rơi về `hidden`. */
.hero { position: relative; padding: 30px 0 10px; overflow-x: hidden; overflow-x: clip; }
.hero-bg { position: absolute; inset: -60px -80px auto auto; width: 640px; max-width: 100%; pointer-events: none; z-index: -1; }
.hero-art { width: 100%; height: auto; display: block; }
.hero h1 { font-size: 42px; line-height: 1.1; letter-spacing: -.038em; margin: 0 0 18px; font-weight: 640; max-width: 17ch; }
.lede { max-width: 62ch; color: var(--ink-2); font-size: 16.5px; margin: 0 0 34px; }
.what li { gap: 9px; }
.what li .ic-wrap { margin-bottom: 3px; }

/* ---------- panel head with icon ---------- */
.panel > .head { gap: 11px; justify-content: flex-start; }

/* ---------- run header ---------- */
.runhead { display: flex; flex-direction: column; gap: 10px; }
.chiprow { display: flex; gap: 6px; flex-wrap: wrap; }
.runacts { display: flex; gap: 8px; }
.ghost {
  border: 1px solid var(--line); background: #fff; color: var(--ink-2); cursor: pointer;
  border-radius: 9px; padding: 6px 13px; font-size: 12.5px; font-weight: 540; font-family: inherit;
}
.ghost:hover { border-color: var(--accent); color: var(--accent); }
.langnote { font-size: 12.5px; color: var(--warn); background: var(--warn-soft); padding: 8px 12px; border-radius: 9px; }
a.plain { text-decoration: none; }
a.plain:hover { color: var(--accent); }

/* ---------- history ---------- */
.hist { display: grid; gap: 1px; background: var(--line-2); margin: -18px; }
.histrow {
  display: grid; grid-template-columns: minmax(120px, 1.2fr) minmax(120px, 1.4fr) auto auto auto auto;
  gap: 12px; align-items: center; padding: 12px 18px; background: #fff;
  text-decoration: none; font-size: 13.5px;
}
.histrow:hover { background: var(--accent-soft); }
.histmore { margin-top: 19px; width: 100%; justify-content: center; }
.histrow .hd { font-weight: 600; }
.histrow .hu, .histrow .hc, .histrow .ht { color: var(--muted); font-size: 12.5px; }
.histrow .ht { text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- misc ---------- */
.divider { gap: 12px; }
.row .txt em.monday { color: var(--accent); }
.shot a { display: block; }

@media (max-width: 760px) {
  .hero h1 { font-size: 30px; }
  .histrow { grid-template-columns: 1fr auto; row-gap: 4px; }
  .histrow .hu, .histrow .hc { grid-column: 1 / -1; }
}

/* ---------- shell: menu button + drawer ---------- */
.menubtn {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: 0 0 34px; padding: 7px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 10px; background: var(--paper); color: var(--ink-2);
}
.menubtn:hover { border-color: var(--accent); color: var(--accent); }
.menucount {
  position: absolute; top: -5px; right: -5px; min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 999px; background: var(--accent); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}
.menucount:empty { display: none; }

.scrim {
  position: fixed; inset: 0; z-index: 60; background: rgba(11,18,32,.28);
  opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
body.drawer-on .scrim { opacity: 1; pointer-events: auto; }

.drawer {
  position: fixed; top: 0; left: 0; bottom: 0; z-index: 70; width: 340px; max-width: 86vw;
  background: #fff; border-right: 1px solid var(--line); overflow-y: auto;
  padding: 18px 18px 40px; display: flex; flex-direction: column; gap: 20px;
  transform: translateX(-102%); transition: transform .22s cubic-bezier(.4,0,.2,1);
  box-shadow: 0 0 0 rgba(11,18,32,0);
}
body.drawer-on .drawer { transform: none; box-shadow: 8px 0 40px rgba(11,18,32,.10); }
.dr-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.dr-new {
  display: flex; align-items: center; gap: 10px; width: 100%; cursor: pointer;
  padding: 11px 13px; border: 1px solid var(--line); border-radius: 12px; background: var(--paper);
  font: inherit; font-size: 14px; font-weight: 560; color: var(--ink); text-align: left;
}
.dr-new:hover { border-color: var(--accent); color: var(--accent); }
.dr-sec { display: flex; flex-direction: column; gap: 8px; }

/* ── doanh thu: mỗi đường một thẻ, lý lẽ nằm ngay dưới con số ── */
.revbox { display: flex; flex-direction: column; gap: 14px; }
.revconf { display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: 12.5px; color: var(--muted); }
.revtotal { padding: 14px 16px; border: 1px solid var(--line); border-radius: 12px; background: var(--paper); }
.revnum { font-size: 20px; font-weight: 640; font-variant-numeric: tabular-nums; }
.revnum.big { font-size: 26px; }
.revper { font-size: 13px; font-weight: 400; color: var(--muted); margin-left: 4px; }
.revpaths { display: grid; gap: 12px; }
@media (min-width: 900px) { .revpaths { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); } }
.revpath { border: 1px solid var(--line); border-radius: 12px; padding: 13px 15px; background: #fff; }
/* Đường không chạy được vẫn PHẢI hiện — nó mang lý do, và một ô trống có lý do
   đáng giá hơn một con số không truy được. Chỉ làm nó lùi lại, không giấu đi. */
.revpath.off { background: var(--paper); border-style: dashed; }
.revpath.k-floor { border-left: 3px solid var(--muted); }
.revpath.k-reported { border-left: 3px solid var(--good); }
.revpath.k-estimate { border-left: 3px solid var(--warn); }
.revhead { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.revin, .revas { margin: 8px 0 0; padding-left: 16px; font-size: 12.5px; line-height: 1.6; }
.revas { color: var(--muted); }
.revlabel { color: var(--muted); }
.revfrom { color: var(--muted); }
.revnote { margin: 9px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--muted); }
.revsrc { margin: 0; }
.dr-filter {
  width: 100%; padding: 8px 12px; font: inherit; font-size: 13.5px; color: var(--ink);
  border: 1px solid var(--line); border-radius: 10px; background: var(--paper); outline: none;
}
.dr-filter:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); background: #fff; }
.dr-list { display: flex; flex-direction: column; gap: 14px; }
.dr-group { display: flex; flex-direction: column; gap: 3px; }
.dr-dom { font-size: 12.5px; font-weight: 620; color: var(--ink-2); padding: 0 2px 3px; }
.dr-run {
  display: flex; align-items: center; gap: 8px; padding: 7px 9px; border-radius: 9px;
  text-decoration: none; font-size: 12.5px; color: var(--muted);
}
.dr-run:hover { background: var(--paper); color: var(--ink); }
.dr-run.on { background: var(--accent-soft); color: var(--accent); }
.dr-when { font-variant-numeric: tabular-nums; }
.dr-split { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 600; }

/* ---------- stage tracker ---------- */
.tracker { border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); padding: 14px 18px; }
.tk-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 10px; }
.tk { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.tk-i {
  /* minmax(150px, …) là SÀN CỨNG: ở khổ 390px, 18 + 150 + gap + cột cuối vượt
     bề ngang và đẩy cả trang (đo được 8px tràn). minmax(0, …) cho cột co lại. */
  display: grid; grid-template-columns: 18px minmax(0, auto) minmax(0, 1fr); gap: 10px;
  align-items: center; padding: 6px 0; font-size: 13px;
  /* .tk-i cũng là grid item của .tk. Không có min-width:0 thì nó nở theo
     min-content của CHÍNH NÓ và rộng hơn cha — đo được li 363px trong ol 320px. */
  min-width: 0;
}
.tk-l, .tk-s { min-width: 0; overflow-wrap: anywhere; }
.tk-dot {
  width: 11px; height: 11px; border-radius: 50%; justify-self: center;
  border: 2px solid var(--line); background: #fff; display: inline-flex;
  align-items: center; justify-content: center;
}
.tk-i.done .tk-dot { background: var(--good); border-color: var(--good); }
.tk-i.failed .tk-dot { background: var(--bad); border-color: var(--bad); }
.tk-i.skipped .tk-dot { border-style: dashed; }
.tk-i.running .tk-dot, .tk-i.retrying .tk-dot { border-color: transparent; background: transparent; }
.tk-l { font-weight: 560; color: var(--ink-2); }
.tk-i.pending .tk-l { color: var(--muted); }
.tk-i.done .tk-l, .tk-i.running .tk-l { color: var(--ink); }
.tk-s { font-size: 12px; color: var(--muted); }
.tk-i.failed .tk-s { color: var(--bad); }
.tk-i.retrying .tk-s { color: var(--warn); }
.tk-e { grid-column: 2 / -1; font-size: 11.5px; color: var(--bad); }

/* ---------- comparison table ---------- */
.tablewrap { overflow-x: auto; margin: -18px; padding: 0; }
table.cmp { border-collapse: collapse; width: 100%; min-width: 640px; font-size: 13.5px; }
table.cmp th {
  text-align: left; font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); font-weight: 600; padding: 11px 14px; border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
table.cmp td { padding: 11px 14px; border-bottom: 1px solid var(--line-2); vertical-align: middle; }
table.cmp tr:last-child td { border-bottom: 0; }
table.cmp td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.cmp td.num.measured { color: var(--good); font-weight: 600; }
table.cmp td.num.modelled { color: var(--warn); }
.crow { cursor: pointer; }
.crow:hover td { background: var(--accent-soft); }
.td-sub { display: block; font-size: 11.5px; color: var(--muted); font-weight: 400; }

/* ---------- competitor card head ---------- */
.rivalhead { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.rh-main { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.rh-main h3 { margin: 0; font-size: 17px; letter-spacing: -.015em; font-weight: 640; text-transform: none; }
.rh-mini { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.panel > .head h3:has(.rivalhead), .panel > .head h4:has(.rivalhead) { text-transform: none; letter-spacing: 0; }
.owns { display: block; margin-top: 6px; color: var(--muted); font-style: normal; }
.lead-why { font-size: 16px; color: var(--ink-2); max-width: 76ch; }
.backlink { display: inline-block; font-size: 13px; color: var(--muted); text-decoration: none; margin-bottom: 4px; }
.backlink:hover { color: var(--accent); }

/* ---------- dynamic ad slots ---------- */
.slot {
  display: inline; padding: 1px 5px; margin: 0 1px; border-radius: 5px;
  background: var(--warn-soft); color: var(--warn); font-size: .92em; font-weight: 560;
  white-space: nowrap;
}
.slot::before { content: '⟨'; opacity: .55; }
.slot::after { content: '⟩'; opacity: .55; }

@media (max-width: 760px) {
  /* 1fr = minmax(auto, 1fr), và `auto` tối thiểu là min-content — một nhãn dài
     vẫn đẩy track rộng ra. minmax(0, 1fr) mới thật sự cho co lại. */
  .tk-i { grid-template-columns: 18px minmax(0, 1fr); }
  .tk-s { grid-column: 2; }
}

/* ---------- charts ---------- */
/* Two validated hues only. Worst-pair CVD ΔE 24.7, normal-vision 33.6, both
   ≥ 3:1 on the white surface — run scripts/validate_palette.js before changing. */
:root {
  --viz-1: #2a78d6;
  --viz-2: #eb6834;
  --viz-grid: #e6e9ef;
  --viz-surface: #ffffff;
}
.vizgrid { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(min(390px, 100%), 1fr)); }
.viz { margin: 0; border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px 12px; background: #fff; min-width: 0; }
.viz figcaption { display: flex; flex-direction: column; gap: 2px; margin-bottom: 10px; }
.viz-t { font-size: 13px; font-weight: 620; letter-spacing: -.01em; }
.viz-s { font-size: 12px; color: var(--muted); line-height: 1.45; }
.viz-svg { width: 100%; height: auto; display: block; overflow: visible; }
.viz-tick { font-size: 10.5px; fill: var(--muted); font-family: inherit; }
.viz-val { font-size: 11px; font-weight: 620; fill: var(--ink-2); font-family: inherit; font-variant-numeric: tabular-nums; }
.viz-lbl { font-size: 11.5px; fill: var(--ink-2); font-family: inherit; }
.viz-lbl.on { font-weight: 660; fill: var(--ink); }
.viz-legend { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; margin-top: 10px; font-size: 11.5px; color: var(--muted); }
.viz-legend span { display: inline-flex; align-items: center; gap: 6px; }
.viz-legend .sw { width: 10px; height: 10px; border-radius: 3px; background: var(--viz-1); display: inline-block; }
.viz-legend .sw.seed { background: var(--viz-2); }
/* Bảng số của biểu đồ phải cuộn TRONG khung của nó. Không có dòng này thì
   một tên brand dài đẩy ngang cả trang — đo được 16px tràn ở khổ 390px. */
.viz-tbl { margin-top: 10px; overflow-x: auto; }
.viz-tbl summary { font-size: 11.5px; color: var(--muted); cursor: pointer; }
.viz-tbl table { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: 12px; }
.viz-tbl th { text-align: left; color: var(--muted); font-weight: 600; padding: 4px 6px; border-bottom: 1px solid var(--line-2); }
.viz-tbl td { padding: 4px 6px; border-bottom: 1px solid var(--line-2); }
.viz-tbl td.num { text-align: right; font-variant-numeric: tabular-nums; }

.viz-tip {
  position: fixed; top: 0; left: 0; z-index: 200; pointer-events: none; opacity: 0;
  background: var(--ink); color: #fff; font-size: 12px; line-height: 1.45;
  padding: 7px 10px; border-radius: 8px; max-width: 300px;
  box-shadow: 0 6px 24px rgba(11,18,32,.22); transition: opacity .12s ease;
}
.viz-tip b { font-weight: 620; }

/* A refusal to state a number is a finding, so it gets a box of its own. */
.assump.warnbox { background: var(--warn-soft); border-color: transparent; color: var(--warn); }
.assump.warnbox b { color: var(--warn); }
.stat .n.off { color: var(--muted); }
table.cmp td.num.off { color: var(--muted); }

/* ---------- quoted buyer voice ---------- */
/* Every quote carries its link: a claim about what buyers want is only worth
   something if the reader can go read the buyer. */
.quote {
  margin: 0 0 12px; padding: 13px 15px; border-left: 3px solid var(--line);
  background: var(--paper); border-radius: 0 10px 10px 0;
  font-size: 14px; color: var(--ink-2); line-height: 1.6;
  display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline;
}
.quote .chip { flex: 0 0 auto; }
.cite { font-size: 11.5px; color: var(--muted); text-decoration: none; border-bottom: 1px dotted var(--line); margin-left: auto; }
.cite:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* ---------- competitor slide-over ---------- */
/* Full height, not full width: the reader is comparing, so the market they are
   comparing against has to stay visible behind the panel. */
.panelscrim {
  position: fixed; inset: 0; z-index: 90; background: rgba(11,18,32,.32);
  opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
body.panel-on .panelscrim { opacity: 1; pointer-events: auto; }
body.panel-on { overflow: hidden; }

.panelover {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 100;
  width: min(80vw, 1120px); background: #fff; border-left: 1px solid var(--line);
  display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform .24s cubic-bezier(.4,0,.2,1);
  box-shadow: -12px 0 44px rgba(11,18,32,.14);
}
.panelover.in { transform: none; }
.pn-head {
  padding: 18px 26px 14px; border-bottom: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 9px; flex: 0 0 auto;
  background: rgba(255,255,255,.94); backdrop-filter: saturate(180%) blur(10px);
}
.pn-head > .pn-title { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.pn-head h2 { margin: 0; font-size: 23px; letter-spacing: -.025em; font-weight: 640; }
.pn-acts { position: absolute; top: 16px; right: 22px; display: flex; gap: 8px; align-items: center; }
.iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 6px; cursor: pointer; color: var(--muted);
  border: 1px solid var(--line); border-radius: 9px; background: #fff;
}
.iconbtn:hover { border-color: var(--ink); color: var(--ink); }
.pn-body { padding: 22px 26px 60px; overflow-y: auto; flex: 1 1 auto; }

@media (max-width: 860px) {
  .panelover { width: 100vw; }
  .pn-body, .pn-head { padding-left: 16px; padding-right: 16px; }
  .pn-acts { right: 14px; }
}

/* ---------- button hierarchy ---------- */
/* The first need on landing is to read the dossier, not to re-run it. So the
   page-level actions are quiet, and only a genuinely primary action is solid. */
.btn-primary {
  padding: 8px 16px; font-size: 13px; font-weight: 560; color: #fff; cursor: pointer;
  background: var(--ink); border: 0; border-radius: 9px; font-family: inherit;
  display: inline-flex; align-items: center; gap: 7px;
}
.btn-primary:hover { background: var(--accent); }
.ghost { display: inline-flex; align-items: center; gap: 7px; transition: border-color .15s, color .15s, background .15s; }
.ghost:active { transform: translateY(1px); }
.ghost.ok { border-color: var(--good); color: var(--good); background: var(--good-soft); }
.ghost .ic { width: 14px; height: 14px; }

/* A copy action that only swaps its own label is easy to miss — say it loudly,
   once, near the pointer. */
.toast {
  position: fixed; left: 50%; bottom: 28px; z-index: 300; transform: translate(-50%, 14px);
  background: var(--ink); color: #fff; font-size: 13px; font-weight: 540;
  padding: 10px 16px; border-radius: 10px; box-shadow: 0 10px 34px rgba(11,18,32,.26);
  opacity: 0; pointer-events: none; transition: opacity .18s ease, transform .18s ease;
  display: inline-flex; align-items: center; gap: 8px;
}
.toast.on { opacity: 1; transform: translate(-50%, 0); }
.ghost.quiet { color: var(--muted); border-color: var(--line-2); }
.ghost.quiet:hover { color: var(--ink-2); border-color: var(--line); }

/* ---------- computed verdict strip ---------- */
.findings { border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); padding: 16px 20px 14px; }
.findings ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--line-2); }
.fd {
  display: grid; grid-template-columns: minmax(64px, auto) 1fr; gap: 14px; align-items: baseline;
  padding: 11px 0 11px 2px; background: var(--paper);
}
.fd-m { font-size: 19px; font-weight: 660; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.fd.warn .fd-m { color: var(--warn); }
.fd.good .fd-m { color: var(--good); }
.fd.neutral .fd-m { color: var(--ink); }
.fd-t { font-size: 14px; color: var(--ink-2); line-height: 1.5; }
@media (max-width: 640px) { .fd { grid-template-columns: 1fr; gap: 2px; } }
.cellink { color: var(--ink-2); text-decoration: none; border-bottom: 1px dotted var(--line); word-break: break-all; }
.cellink:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* ---------- the closing memo ---------- */
/* Set as a long read: one measured column, real hierarchy, generous leading.
   Structured cards only where the content is genuinely structured. */
.panelover.wide { width: min(92vw, 1180px); }
.memo { max-width: 74ch; margin: 0 auto; }
.mm-head { padding-bottom: 26px; margin-bottom: 30px; border-bottom: 2px solid var(--ink); }
.mm-kicker { margin: 0 0 12px; font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--accent); font-weight: 640; }
.mm-head h2 { margin: 0 0 14px; font-size: 33px; line-height: 1.18; letter-spacing: -.032em; font-weight: 660; }
.mm-stand { margin: 0; font-size: 18px; line-height: 1.62; color: var(--ink-2); }

.mm-sec { margin: 0 0 44px; }
.mm-sec h3 {
  margin: 0 0 16px; font-size: 12px; letter-spacing: .11em; text-transform: uppercase;
  color: var(--muted); font-weight: 660; padding-bottom: 9px; border-bottom: 1px solid var(--line);
}
.mm-sec > p { margin: 0 0 18px; font-size: 16.5px; line-height: 1.75; color: var(--ink); max-width: 68ch; }
.mm-sec h4 { margin: 0 0 7px; font-size: 15.5px; font-weight: 620; letter-spacing: -.012em; }

.mm-segs { display: grid; gap: 14px; margin-top: 22px; }
.mm-seg { padding: 16px 18px; border-left: 3px solid var(--accent); background: var(--paper); border-radius: 0 12px 12px 0; }
.mm-seg .bb { margin: 8px 0 10px; }
.mm-seg p { margin: 0; font-size: 15px; line-height: 1.62; color: var(--ink-2); }

.mm-proofs { display: grid; gap: 12px; margin-top: 22px; }
.mm-proof { padding: 15px 18px; border: 1px solid var(--line); border-radius: 12px; }
.mm-mech { margin: 9px 0 6px; font-size: 15px; font-weight: 560; line-height: 1.55; }
.mm-ev { margin: 0; font-size: 13px; color: var(--muted); line-height: 1.55; }

.mm-opens { display: grid; gap: 14px; margin-top: 22px; }
.mm-open { padding: 17px 19px; border: 1px solid var(--line); border-radius: 12px; background: #fff; }
.mm-open.large { border-color: var(--good); background: var(--good-soft); }
.mm-open .chip { margin-bottom: 9px; }
.mm-open p { margin: 0 0 10px; font-size: 15px; line-height: 1.65; color: var(--ink-2); }
.mm-you { color: var(--ink) !important; font-weight: 540; }

.mm-steal { display: grid; gap: 14px; margin-top: 22px; }
.mm-item { padding: 17px 19px; border: 1px solid var(--line); border-radius: 12px; }
.mm-item-h { display: flex; align-items: center; gap: 10px; margin-bottom: 9px; }
.mm-from { font-size: 12.5px; color: var(--muted); }
.mm-item p { margin: 0 0 10px; font-size: 15px; line-height: 1.65; color: var(--ink-2); }
.mm-how { color: var(--accent) !important; font-weight: 540; }

.mm-avoid { margin-top: 26px; padding: 18px 20px; border-radius: 12px; background: var(--bad-soft); }
.mm-avoid h4 { color: var(--bad); margin-bottom: 12px; }
.mm-avoid-i { padding: 10px 0; border-top: 1px solid rgba(194,51,77,.16); }
.mm-avoid-i:first-of-type { border-top: 0; padding-top: 0; }
.mm-avoid-i p { margin: 5px 0 0; font-size: 14px; line-height: 1.6; color: var(--ink-2); }

.mm-plan { display: grid; gap: 14px; margin-top: 22px; }
.mm-horizon { padding: 17px 19px; border: 1px solid var(--line); border-radius: 12px; }
.mm-when { font-size: 11.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--accent); font-weight: 660; margin-bottom: 6px; }
.mm-horizon ul { margin: 10px 0; padding-left: 19px; }
.mm-horizon li { font-size: 15px; line-height: 1.65; color: var(--ink-2); margin-bottom: 9px; }
.mm-measure { margin: 0; font-size: 13.5px; color: var(--good); font-weight: 540; }

.mm-caveats { padding: 17px 20px; border: 1px dashed var(--line); border-radius: 12px; }
.mm-caveats h4 { margin: 0 0 10px; font-size: 12px; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }
.mm-caveats ul { margin: 0; padding-left: 19px; }
.mm-caveats li { font-size: 13.5px; line-height: 1.6; color: var(--muted); margin-bottom: 6px; }

/* the entry point */
.memo-cta {
  display: flex; align-items: center; gap: 14px; width: 100%; cursor: pointer; text-align: left;
  padding: 16px 20px; border: 1px solid var(--accent); border-radius: var(--radius);
  background: var(--accent-soft); font-family: inherit; color: var(--ink);
}
.memo-cta:hover { background: #fff; }
.memo-cta b { display: block; font-size: 15px; font-weight: 620; margin-bottom: 2px; }
.memo-cta .sub { font-size: 13px; }
.memo-arrow { margin-left: auto; width: 20px; height: 20px; color: var(--accent); flex: 0 0 20px; }
.rh-why { font-size: 12.5px; color: var(--muted); line-height: 1.5; margin-top: 2px; }
:root { --viz-3: #1baf7a; }
.viz-legend .sw.alt { background: var(--viz-3); }

/* ---------- brand intelligence ---------- */
.intel { display: grid; gap: 22px; }
.intel-row { display: grid; gap: 8px; }
.bestgrid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(min(140px, 100%), 1fr)); }
.bestcard { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: #fff; }
.bestcard img { display: block; width: 100%; aspect-ratio: 1 / 1; height: auto; object-fit: cover; background: var(--line-2); }
.bc-t { padding: 8px 10px 2px; font-size: 12.5px; line-height: 1.4; font-weight: 540; }
.bc-p { padding: 0 10px 9px; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------- memo: colour and framing ---------- */
/* Each section gets its own accent so the memo reads as chapters. The hues are
   the validated categorical slots; none of them is the orange reserved for
   "your brand" in charts. */
.mm-sec.tone-map   { --tone: #2a78d6; --tone-soft: #eef3ff; }
.mm-sec.tone-works { --tone: #0f8a5f; --tone-soft: #e8f7f0; }
.mm-sec.tone-gap   { --tone: #7c3aed; --tone-soft: #f4efff; }
.mm-sec.tone-copy  { --tone: #b4690e; --tone-soft: #fdf3e4; }
.mm-sec.tone-plan  { --tone: #1baf7a; --tone-soft: #e6f7f1; }

.mm-sec h3 { display: flex; align-items: center; gap: 10px; color: var(--tone, var(--muted)); border-bottom-color: color-mix(in srgb, var(--tone, var(--line)) 24%, transparent); }
.mm-rule { width: 22px; height: 3px; border-radius: 2px; background: var(--tone, var(--line)); flex: 0 0 22px; }

/* A figure inside a paragraph is the checkable part of the claim — let a reader
   skim to it instead of hunting through the sentence. */
.figure {
  background: var(--tone-soft, var(--accent-soft));
  color: color-mix(in srgb, var(--tone, var(--accent)) 82%, #000);
  border-radius: 5px; padding: 0 4px; font-weight: 620;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

.mm-seg { border-left-color: var(--tone); background: var(--tone-soft); }
.mm-proof { border-left: 3px solid var(--tone); }
.mm-open.large { border-color: var(--tone); background: var(--tone-soft); }
.mm-open .chip { background: var(--tone-soft); color: var(--tone); border-color: transparent; font-weight: 620; }

/* advice: numbered, weighted by effort */
.mm-item { display: grid; grid-template-columns: 34px 1fr; gap: 14px; align-items: start; border-left: 3px solid var(--tone); }
.mm-num {
  width: 30px; height: 30px; border-radius: 9px; display: inline-flex;
  align-items: center; justify-content: center; font-size: 14px; font-weight: 700;
  background: var(--tone); color: #fff; font-variant-numeric: tabular-nums;
}
.mm-item.eff-medium .mm-num { opacity: .82; }
.mm-item.eff-high .mm-num { opacity: .62; }
.mm-item-b { min-width: 0; }
.mm-how-k, .mm-measure-k {
  font-size: 11px; letter-spacing: .07em; text-transform: uppercase; font-weight: 700;
  padding: 2px 7px; border-radius: 5px; margin-right: 2px;
}
.mm-how-k { background: var(--accent); color: #fff; }
.mm-measure-k { background: var(--good); color: #fff; }
.mm-how { color: var(--ink) !important; }

.mm-horizon { border-left: 3px solid var(--tone); position: relative; }
.mm-horizon.h1 { background: color-mix(in srgb, var(--tone-soft) 70%, #fff); }
.mm-when { display: flex; align-items: center; gap: 8px; color: var(--tone); }
.mm-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--tone); flex: 0 0 8px; }
.mm-measure { color: var(--ink-2) !important; }

.mm-avoid { border-left: 3px solid var(--bad); }
.mm-avoid .figure { background: rgba(194,51,77,.1); color: var(--bad); }

/* ---------- store hero ---------- */
/* Two columns: the shop as it actually looks, and the facts that frame it. */
.hero-banner { display: grid; grid-template-columns: 1.35fr 1fr; gap: 22px; align-items: stretch; }
.hb-shot { display: block; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--paper); }
.hb-shot img { display: block; width: 100%; aspect-ratio: 1440 / 900; height: auto; object-fit: cover; object-position: top center; }
.hb-side { display: flex; flex-direction: column; gap: 12px; justify-content: center; }
.hb-kicker { font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--accent); font-weight: 700; }
.hb-facts { display: flex; gap: 6px; flex-wrap: wrap; }
.hb-usps { margin: 0; padding-left: 18px; display: grid; gap: 6px; }
.hb-usps li { font-size: 14px; color: var(--ink-2); line-height: 1.5; }
@media (max-width: 860px) { .hero-banner { grid-template-columns: 1fr; } }

/* ---------- memo teaser ---------- */
/* The conclusion, given away before the click. A reader who never opens the memo
   should still leave with the headline and the first three moves. */
.memo-card {
  border: 2px solid var(--ink); border-radius: var(--radius); background: #fff;
  padding: 24px 26px; display: grid; gap: 14px;
  box-shadow: 0 2px 0 var(--ink), 0 14px 40px rgba(11,18,32,.08);
}
.mc-top { display: flex; align-items: center; gap: 10px; }
.mc-badge {
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase; font-weight: 800;
  background: var(--ink); color: #fff; padding: 4px 10px; border-radius: 6px;
}
.mc-len { font-size: 12.5px; color: var(--muted); }
.mc-head { margin: 0; font-size: 24px; line-height: 1.3; letter-spacing: -.026em; font-weight: 680; }
.mc-stand { margin: 0; font-size: 16px; line-height: 1.66; color: var(--ink-2); max-width: 72ch; }

.mc-actions { border-top: 1px solid var(--line); padding-top: 15px; }
.mc-actions-k {
  margin: 0 0 10px; font-size: 11px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted); font-weight: 700;
}
.mc-actions ol { margin: 0; padding-left: 20px; display: grid; gap: 10px; }
.mc-actions li { font-size: 15px; line-height: 1.55; color: var(--ink); }
.mc-actions li em { color: var(--muted); font-style: normal; font-size: 13px; }
.mc-eff {
  display: inline-block; font-size: 10.5px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .06em; padding: 2px 7px; border-radius: 5px; margin-right: 8px; vertical-align: 1px;
}
.mc-eff.low { background: var(--good-soft); color: var(--good); }
.mc-eff.medium { background: var(--warn-soft); color: var(--warn); }
.mc-eff.high { background: var(--bad-soft); color: var(--bad); }

.mc-open {
  justify-self: start; display: inline-flex; align-items: center; gap: 9px; cursor: pointer;
  border: 0; border-radius: 10px; background: var(--ink); color: #fff;
  font: inherit; font-size: 14.5px; font-weight: 600; padding: 11px 20px;
}
.mc-open:hover { background: var(--accent); }
.mc-open .memo-arrow { width: 18px; height: 18px; color: currentColor; margin: 0; }
.err { display: grid; gap: 12px; justify-items: start; }
.resume-btn { background: #fff; border-color: var(--bad); color: var(--bad); font-weight: 600; }
.resume-btn:hover { background: var(--bad); color: #fff; border-color: var(--bad); }
.resume-btn[disabled] { opacity: .6; cursor: default; }

/* ---------- mobile ---------- */
/* The topbar was 166px on a 844px screen — a fifth of the viewport, permanently,
   because brand + search + language stacked into three rows. On small screens
   the language switcher moves into the drawer, where there is room for it, and
   the bar collapses to one row. */
@media (max-width: 720px) {
  .topbar { padding: 10px 16px; gap: 10px; flex-wrap: nowrap; }
  .brand span:last-child { display: none; }          /* the mark alone is enough */
  #runform { flex: 1 1 auto; min-width: 0; }
  #url { min-width: 0; }
  .topbar > .lang { display: none; }                 /* lives in the drawer here */
  .dr-lang { display: block !important; }
}
.dr-lang { display: none; }
.dr-lang .lang { width: 100%; }
.dr-lang .langbtn { flex: 1; text-align: center; }

/* A touch target under ~32px is a miss waiting to happen. Chips are content on a
   mouse and controls on a finger, so they only grow where the pointer is coarse. */
@media (pointer: coarse) {
  .chip { min-height: 30px; padding: 6px 11px; }
  .langbtn { min-height: 38px; padding: 9px 14px; }
  .ghost, .mc-open, .iconbtn, .menubtn { min-height: 40px; }
  .viz-tbl summary { min-height: 32px; display: flex; align-items: center; }
  .histrow, .dr-run { min-height: 44px; }
  .crow td { padding-top: 14px; padding-bottom: 14px; }
}

/* ---------- language banner ---------- */
/* The model-written parts of a dossier belong to the language the run was
   written in. When a reader switches, the chrome and every computed line flips
   instantly while the prose does not — which reads as broken unless the page
   says plainly what is happening and offers the fix in the same breath. */
.langnote {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  font-size: 14px; color: var(--warn); background: var(--warn-soft);
  padding: 14px 18px; border-radius: var(--radius); border: 1px solid transparent;
  line-height: 1.5;
}
.langnote b { color: var(--ink); }
.langnote .ghost {
  margin-left: auto; background: var(--ink); color: #fff; border-color: var(--ink); font-weight: 600;
}
.langnote .ghost:hover { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ---------- funnel, drawn ---------- */
.fn-list { display: grid; gap: 20px; }
.fn { border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px; }
.fn-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 14px; }
.fn-rank {
  width: 24px; height: 24px; border-radius: 7px; background: var(--ink); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; flex: 0 0 24px;
}
.fn-age { font-size: 12.5px; color: var(--muted); margin-left: auto; }

/* ads on the left, the page they land on at the right, an arrow between. */
.fn-flow { display: grid; grid-template-columns: 1fr 28px 1fr; gap: 14px; align-items: start; }
.fn-step { display: grid; gap: 8px; min-width: 0; }
.fn-k { margin: 0; font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.fn-arrow { align-self: center; color: var(--line); }
.fn-arrow svg { width: 26px; height: 26px; display: block; }

.fn-ads { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.fn-ad { border: 1px solid var(--line); border-radius: 9px; overflow: hidden; background: var(--paper); }
.fn-ad img { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover; background: var(--line-2); }
.fn-ad-t {
  display: block; padding: 7px 9px; font-size: 11.5px; line-height: 1.4; color: var(--ink-2);
  max-height: 4.2em; overflow: hidden;
}
.fn-page { display: grid; gap: 6px; text-decoration: none; }
.fn-page img { display: block; width: 100%; aspect-ratio: 1440 / 900; object-fit: cover; object-position: top center; border: 1px solid var(--line); border-radius: 9px; background: var(--line-2); }
.fn-url { font-size: 12px; color: var(--muted); word-break: break-all; }
.fn-page:hover .fn-url { color: var(--accent); }

/* the assessment sits above the chains it is about */
.fn-review { border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px; margin-bottom: 18px; background: var(--paper); }
.fn-verdict { margin: 0 0 14px; font-size: 15.5px; line-height: 1.6; font-weight: 560; color: var(--ink); }
.fn-sw { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.fn-col ul { margin: 6px 0 0; padding-left: 18px; display: grid; gap: 6px; }
.fn-col li { font-size: 14px; line-height: 1.55; color: var(--ink-2); }
.fn-col.good .fn-k { color: var(--good); }
.fn-col.bad .fn-k { color: var(--bad); }
.fn-steal { margin: 14px 0 0; font-size: 14.5px; line-height: 1.6; color: var(--ink); }

@media (max-width: 760px) {
  .fn-flow { grid-template-columns: 1fr; }
  .fn-arrow { justify-self: center; transform: rotate(90deg); }
  .fn-sw { grid-template-columns: 1fr; }
}
.img-gone {
  display: flex; align-items: center; justify-content: center; text-align: center;
  aspect-ratio: 1440 / 900; border: 1px dashed var(--line); border-radius: 9px;
  font-size: 12px; color: var(--muted); padding: 10px;
  background: repeating-linear-gradient(45deg, #fafbfc, #fafbfc 8px, #f4f6f8 8px, #f4f6f8 16px);
}
.fn-ad .img-gone { aspect-ratio: 1 / 1; border: 0; border-radius: 0; }

/* Cửa hàng đã tắt: xám, không dùng màu cảnh báo — nó không nguy hiểm,
   nó chỉ không còn ở đó. */
.chip.dead { background: var(--sunk, #eee); color: var(--ink-2, #666); text-decoration: line-through; }

/* ---------- sản phẩm đang được đẩy ---------- */
/* Thanh tỉ lệ nằm TRONG dòng chứ không thành cột riêng: trên mobile một cột
   thứ ba luôn là cột bị bóp đến mức vô nghĩa. */
.pp { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: 1px;
      background: var(--rule); border: 1px solid var(--rule); border-radius: 3px; }
.pp-row { background: var(--paper); padding: .7rem .85rem;
          display: grid; grid-template-columns: 3.4rem 1fr auto; gap: .55rem .9rem; align-items: center; }
.pp-bar { position: relative; height: 1.55rem; border-radius: 2px; background: var(--sunk);
          display: flex; align-items: center; justify-content: center; overflow: hidden; }
.pp-bar::before { content: ''; position: absolute; inset: 0 auto 0 0; width: var(--w, 0%);
                  background: var(--accent, #b0392a); opacity: .16; }
.pp-n { position: relative; font-family: var(--mono, ui-monospace); font-size: .78rem; font-weight: 700; }
.pp-t { font-size: .93rem; line-height: 1.35; text-decoration: none; overflow-wrap: anywhere; }
.pp-t:hover { text-decoration: underline; }
.pp-meta { display: flex; gap: .4rem; align-items: center; flex-wrap: wrap; justify-content: flex-end;
           font-size: .78rem; color: var(--ink-2, #666); }
.pp-verdict { margin: .9rem 0 0; font-size: 1rem; line-height: 1.5; }
.pp-verdict .chip { margin-left: .4rem; vertical-align: middle; }

@media (max-width: 640px) {
  /* Meta xuống dòng riêng, canh trái, thẳng hàng với tiêu đề — đọc theo cột
     thay vì bị nén vào mép phải. */
  .pp-row { grid-template-columns: 3.4rem 1fr; }
  .pp-meta { grid-column: 2; justify-content: flex-start; }
}

/* Link chữ trong bảng dày đặc: chiều rộng vốn đã đủ (186-356px), chỉ thiếu
   chiều cao. Nới bằng padding dọc thay vì đổi line-height, để dòng chữ không
   giãn ra và bảng không cao thêm. Chỉ áp cho ngón tay, không áp cho chuột. */
@media (pointer: coarse) {
  .pp-t, .cellink { padding-block: .45rem; display: inline-block; }
  .pp-row { padding-block: .5rem; }
}

/* Màn hình vài giây đầu của một run. Cùng khung, cùng lề với thẻ thật, để khi
   dữ liệu tới thì nội dung thế chỗ chứ trang không nhảy. */
.startcard { display: flex; gap: 1rem; align-items: center;
             background: var(--paper); border: 1px solid var(--rule);
             border-radius: 3px; padding: 1.6rem 1.4rem; }
.startcard h2 { margin: 0 0 .3rem; font-size: 1.05rem; }
.startcard .sub { margin: 0; max-width: 40ch; }
@media (max-width: 640px) { .startcard { padding: 1.2rem 1rem; } }

/* ---------- panel: tab + bộ chuyển đối thủ ---------- */
/* Tab dính ở đầu panel, vì lý do tồn tại của nó là "tôi đang ở đâu" — cuộn
   xuống mà mất tab thì lại đúng vấn đề cũ. */
.pn-tabs { display: flex; gap: 2px; margin: .85rem -.15rem -1px; overflow-x: auto;
           scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.pn-tabs::-webkit-scrollbar { display: none; }
.pn-tab { flex: 0 0 auto; background: transparent; border: 0; border-bottom: 2px solid transparent;
          padding: .55rem .7rem; font: inherit; font-size: .86rem; color: var(--ink-2, #666);
          cursor: pointer; white-space: nowrap; min-height: 2.6rem; }
.pn-tab:hover { color: var(--ink, #111); }
.pn-tab.on { color: var(--ink, #111); font-weight: 600; border-bottom-color: var(--accent, #b0392a); }

.pn-nav { display: inline-flex; align-items: center; gap: .1rem; margin-right: .3rem; }
.pn-nav .iconbtn { font-size: 1.25rem; line-height: 1; min-width: 2.2rem; }
.pn-count { font-family: var(--mono, ui-monospace); font-size: .78rem; color: var(--ink-2, #666);
            min-width: 2.6rem; text-align: center; font-variant-numeric: tabular-nums; }

@media (max-width: 640px) {
  /* Trên điện thoại panel chiếm gần hết màn, nên bộ chuyển phải to bằng ngón
     tay chứ không phải bằng con trỏ. */
  .pn-nav .iconbtn { min-width: 2.75rem; min-height: 2.75rem; }
  .pn-tab { padding: .6rem .8rem; }
}

/* ---------- Trustpilot: khách phàn nàn gì ---------- */
.tp-head { display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; margin: 0; }
.tp-head b { font-size: 1.35rem; font-family: var(--mono, ui-monospace); }
.tp-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px;
           background: var(--rule); border: 1px solid var(--rule); border-radius: 3px; }
.tp-list li { background: var(--paper); padding: .75rem .9rem;
              display: grid; grid-template-columns: 2.4rem 1fr; gap: .7rem; align-items: start; }
.tp-star { font-family: var(--mono, ui-monospace); font-size: .8rem; font-weight: 700;
           color: var(--accent, #b0392a); }
.tp-list b { display: block; font-size: .93rem; line-height: 1.35; margin-bottom: .25rem; }
.tp-list .sub { margin: 0 0 .35rem; font-size: .85rem; line-height: 1.45; }
@media (max-width: 640px) { .tp-list li { grid-template-columns: 2rem 1fr; padding: .7rem .75rem; } }

/* ---------- đã đổi gì kể từ lần chạy trước ---------- */
.changes { border: 1px solid var(--rule); border-left: 3px solid var(--accent, #b0392a);
           border-radius: 3px; padding: .95rem 1.1rem; margin: 1rem 0 0; background: var(--card, #fff); }
.chg-head { display: flex; gap: .6rem; align-items: baseline; flex-wrap: wrap; margin-bottom: .6rem; }
.chg-set { display: flex; gap: .35rem; flex-wrap: wrap; margin-bottom: .6rem; }
.chg-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .45rem; }
.chg-list li { display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap;
               padding-bottom: .45rem; border-bottom: 1px solid var(--rule); }
.chg-list li:last-child { border-bottom: 0; padding-bottom: 0; }
.chg-list b { font-size: .93rem; }
/* Con số đổi dùng cùng một màu cho tăng và giảm. Tăng ads của đối thủ không
   phải "tốt", giảm không phải "xấu" — tô xanh/đỏ là gán ý nghĩa mà dữ liệu
   không có. Mũi tên đã nói hướng rồi. */
.chg-n { font-family: var(--mono, ui-monospace); font-size: .8rem; color: var(--ink-2, #666); }
@media (max-width: 640px) { .changes { padding: .8rem .85rem; } }

/* Cụm tab ngoài panel. Đáy trang từng là năm panel gập rời nhau trông ngang
   hàng với thẻ đối thủ; gom lại thành một khối có tab để thứ bậc rõ ra. */
.tabgroup { border: 1px solid var(--rule, #e5e4df); border-radius: 3px; background: var(--card, #fff); }
.tabgroup .pn-tabs { margin: 0 .9rem; border-bottom: 1px solid var(--rule, #e5e4df); }
.tg-body { padding: .9rem; }
.tg-body > .panel:first-child { margin-top: 0; }

/* Ô ảnh hỏng phải trông CỐ Ý, không trông như vỡ. Dòng đầu nói chuyện gì, dòng
   sau nói vì sao — trước đây chỗ này đổ nguyên chuỗi lỗi gemcapture ra màn hình. */
.noshot-t { font-weight: 600; }
.noshot-w { margin-top: .25rem; opacity: .8; }
.noshot.standalone { border: 1px dashed var(--line); border-radius: 12px; }

/* Kênh quảng cáo. Thanh ngang chứ không phải bánh: một ad chạy nhiều kênh cùng
   lúc (98% số ad), nên các con số KHÔNG cộng thành 100% và mọi cách vẽ chia
   phần đều nói dối. */
.chan { list-style: none; margin: .6rem 0 0; padding: 0; display: grid; gap: .35rem; }
.chan li { display: grid; grid-template-columns: 9rem 1fr 3rem; align-items: center; gap: .6rem; }
.chan-n { font-size: .88rem; }
.chan-bar { height: .5rem; border-radius: 999px; background: var(--sunk, #f2f1ed); overflow: hidden; }
.chan-bar i { display: block; height: 100%; background: var(--ink, #16181d); opacity: .55; }
.chan-p { font-family: var(--mono, ui-monospace); font-size: .8rem; text-align: right;
          font-variant-numeric: tabular-nums; color: var(--ink-2, #6b6f76); }
@media (max-width: 560px) { .chan li { grid-template-columns: 7rem 1fr 2.6rem; } }

/* Google đứng riêng dòng dưới dãy Meta: nó là ĐẾM ad, không phải % số ad, nên
   xếp chung một thanh tỉ lệ là so hai đơn vị khác nhau. */
.chan-g { margin: .6rem 0 0; font-size: .84rem; color: var(--ink-2, #6b6f76);
          padding-top: .5rem; border-top: 1px solid var(--rule, #e5e4df); }

/* Câu dẫn của cả dossier. To hơn thân bài nhưng KHÔNG to bằng tiêu đề brand —
   nó là một câu, không phải một mục. */
.headline { font-size: 1.14rem; line-height: 1.5; font-weight: 600; margin: .9rem 0 0;
            max-width: 46rem; }

/* Mạnh / yếu đứng cạnh nhau. Trước đây cả ba ý nằm trong một đoạn 734 ký tự và
   người đọc phải tự trích ra. */
.posgrid { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; margin-top: 1rem; }
.pos { border: 1px solid var(--rule, #e5e4df); border-radius: 4px; padding: .7rem .85rem;
       background: var(--card, #fff); }
.pos-k { display: block; font-size: .7rem; letter-spacing: .09em; text-transform: uppercase;
         color: var(--ink-2, #6b6f76); margin-bottom: .3rem; }
.pos p { margin: 0; font-size: .92rem; }
.pos.ok    { box-shadow: inset 3px 0 0 var(--live, #1f6f43); }
.pos.risk  { box-shadow: inset 3px 0 0 var(--err, #b0392a); }
@media (max-width: 620px) { .posgrid { grid-template-columns: 1fr; } }

/* ── ba lỗi tìm ra khi rà giao diện bằng máy ─────────────────────────────────

   1. Bảng so sánh làm CẢ TRANG trôi ngang trên mobile.

   .tablewrap đã có overflow-x:auto, nhưng `margin:-18px` khiến chính nó rộng
   hơn khung cha 36px. Trên màn 390px thì nó vượt màn hình, và trình duyệt cho
   TRANG cuộn ngang thay vì cho bảng cuộn bên trong — người dùng vuốt ngang thì
   cả tiêu đề và nội dung trôi theo.

   Âm lề là để bảng chạm mép thẻ trên desktop. Trên mobile bỏ nó đi: chạm mép
   đẹp không đáng để đánh đổi một trang trôi ngang. */
@media (max-width: 720px) {
  .tablewrap { margin: 0; -webkit-overflow-scrolling: touch; }
}

/* 2. Vùng bấm dưới 32px.

   Đo được 8 chỗ: nút ngôn ngữ 25px, logo 22px, nút phụ 29px. Ngón tay không
   trúng, và người dùng nghĩ nút hỏng chứ không nghĩ nút nhỏ. */
.langbtn { min-height: 32px; display: inline-flex; align-items: center; }
@media (max-width: 720px) {
  .langbtn { min-height: 40px; padding-left: 14px; padding-right: 14px; }
  .ghost, .iconbtn { min-height: 40px; }
}

/* 3. Chữ 10px.

   Nhỏ hơn ngưỡng đọc thoải mái trên mọi màn hình, và đây là các con số — thứ
   người ta đến đây để đọc. */
.viz-tick, .td-sub, .chip.small { font-size: 11px; }

/* 4. Tiêu đề mục và biểu đồ đẩy trang trôi ngang trên mobile.

   Đo trên màn 390px: `span.count` trong tiêu đề mục chạm tới 492px — đúng bằng
   scrollWidth của cả trang. Hàng tiêu đề là flex một dòng, không co được, nên
   khi tên mục dài thì số đếm bị đẩy ra ngoài mép và kéo cả trang theo.

   Flex item mặc định min-width:auto — nó KHÔNG chịu co nhỏ hơn nội dung. Phải
   nói rõ min-width:0 thì tiêu đề mới cắt bớt được thay vì đẩy hàng xóm ra ngoài. */
/* Chỗ tràn thật là `.divider`, không phải `.head` — tôi nhắm nhầm class ở lần
   sửa đầu và bài rà tự động cho thấy con số không đổi.

   .divider là hàng flex với h2 { white-space: nowrap } và .count đứng cạnh. Từ
   khi nhóm đối thủ theo mô hình kinh doanh, .count mang CẢ CÂU giải thích cách
   kiếm tiền — dài hơn hẳn con số nó được thiết kế để chứa. Trên màn 390px, tiêu
   đề không xuống dòng được cộng câu dài đẩy `.line` ra tới 504px và kéo cả
   trang trôi ngang.

   Chính tính năng tôi thêm làm lộ giới hạn này. */
/* Tiêu đề nhóm KHÔNG được nowrap khi hộp đã cho phép co.
   min-width:0 ở trên (thêm để chặn trôi ngang trên mobile) cho h2 co nhỏ hơn nội
   dung; nhưng white-space:nowrap ở .divider h2 vẫn còn, nên chữ VẼ RA NGOÀI hộp
   và đè lên câu mô tả bên cạnh. Đo trên desktop 1440px: 5/5 tiêu đề nhóm tràn
   26–170px. Mobile không dính vì media query dưới đã đặt normal — tức bản vá
   đúng đã có sẵn, chỉ là chưa áp cho desktop. */
.divider h2 { min-width: 0; white-space: normal; flex: 0 0 auto; }
.divider .count { min-width: 0; overflow-wrap: anywhere; flex: 1 1 340px; }
/* .divider được thiết kế cho `.count` là một CON SỐ ("40"), nên nó là hàng flex
   một dòng: tiêu đề · đường kẻ · số. Từ khi nhóm đối thủ theo mô hình kinh
   doanh, `.count` mang CẢ CÂU giải thích cách kiếm tiền.
   Ép câu đó nằm cùng một dòng thì tiêu đề — thứ quan trọng hơn — bị bóp xuống
   ~140px và gãy làm 3 dòng, còn câu mô tả chiếm ~900px. Thứ bậc ngược.
   flex-wrap + basis 340px: câu ngắn vẫn nằm cùng dòng như cũ, câu dài tự rơi
   xuống hàng riêng chiếm hết bề ngang, và tiêu đề giữ bề ngang tự nhiên. */
.divider { flex-wrap: wrap; row-gap: 6px; }
@media (max-width: 720px) {
  .divider { flex-wrap: wrap; gap: 8px 10px; }
  .divider h2 { white-space: normal; flex: 1 1 auto; }
  .divider .count { flex: 1 1 100%; order: 3; }
  /* Đường kẻ trang trí: trên màn hẹp nó chỉ tốn chỗ và là thứ đẩy trang trôi. */
  .divider .line { display: none; }
}

.panel > .head { flex-wrap: wrap; }
.panel > .head h3, .panel > .head h4 { min-width: 0; overflow-wrap: anywhere; }
.panel > .head .cnt { flex: 0 0 auto; }

/* Biểu đồ vẽ ở khổ cố định 560px. Trong khung 390px nó tràn ra.
   SVG co được nếu nói rõ; không nói thì nó giữ nguyên khổ gốc. */
.viz { max-width: 100%; }
.viz svg { max-width: 100%; height: auto; display: block; }

/* Vì sao mọi lưới trên dùng minmax(min(Npx, 100%), 1fr):

   minmax(390px, 1fr) buộc cột rộng ÍT NHẤT 390px, kể cả khi khung chứa chỉ có
   358px — lưới không co xuống dưới ngưỡng đó, nó tràn ra ngoài và kéo cả trang
   trôi ngang. Đo thật trên màn 390px: figure.viz rộng 390 trong khung 358.

   min(390px, 100%) đọc là "390px, nhưng đừng bao giờ vượt khung". Ngưỡng vẫn
   giữ nguyên trên màn rộng; chỉ khi hẹp hơn ngưỡng nó mới nhường. */

/* Bảng số liệu dưới mỗi biểu đồ (bản đọc được cho người dùng trình đọc màn hình
   và cho ai muốn con số thật) tràn khung mà KHÔNG cuộn: đo được 401px trong
   khung 293px với overflow-x:visible.

   Bảng rộng phải cuộn trong khung của chính nó, không đẩy trang. */
.viz-tbl { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.viz-tbl table { min-width: 0; }

/* Nút mở bảng số liệu dưới biểu đồ cao 18px — ngón tay không trúng, và người
   dùng kết luận nút hỏng chứ không kết luận nút nhỏ. Nó là đường DUY NHẤT tới
   con số thật của biểu đồ, nên càng không được khó bấm. */
.viz-tbl summary {
  min-height: 32px; display: flex; align-items: center;
  padding: 4px 2px; -webkit-tap-highlight-color: transparent;
}
@media (max-width: 720px) { .viz-tbl summary { min-height: 40px; } }

/* Huy hiệu đếm số run: 10px là dưới ngưỡng đọc thoải mái, mà đây là một con số
   — thứ người ta nhìn để biết đã soi bao nhiêu cửa hàng. */
.menucount { min-width: 18px; height: 18px; line-height: 18px; font-size: 11px; }

/* Thẻ đối thủ là TÓM TẮT, bấm vào mở panel.

   Trước đây thẻ mở ra tại chỗ hiện 11 mục, rồi nút "Chi tiết" mở panel chứa
   đúng 11 mục đó cộng hai cái nữa. Cùng nội dung ở hai nơi, và người đọc phải
   đoán nơi nào là nơi thật. Giờ chi tiết chỉ ở panel. */
.rivalcard {
  display: block; width: 100%; text-align: left; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--radius, 12px);
  background: #fff; padding: 14px 18px; margin: 0;
  transition: border-color .12s, box-shadow .12s;
}
.rivalcard:hover, .rivalcard:focus-visible { border-color: var(--accent); box-shadow: 0 1px 3px rgba(11,18,32,.07); }
.rivalcard:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.rivalcard .rh-line { margin: 8px 0 0; font-size: 13.5px; color: var(--muted); line-height: 1.5; }
.rivalcard .rh-go { display: inline-block; margin-top: 10px; font-size: 12.5px; color: var(--accent); font-weight: 600; }
.rivalcard .rh-go::after { content: ' →'; }

/* Vì sao brand này chạy ads mà không có trang đích nào. */
.lp-note {
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
  background: var(--paper);
  border-left: 2px solid var(--line);
  padding: 6px 10px;
  border-radius: 0 4px 4px 0;
  margin-bottom: 10px;
}

/* Khu đối thủ: MỘT danh sách, hai cách xem. Thanh này là chỗ duy nhất
   người đọc chọn cách nhìn — không còn hai danh sách hiện song song. */
.compregion { margin: 28px 0 8px; }
.compbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  padding-bottom: 10px; margin-bottom: 14px;
  border-bottom: 1px solid var(--line);
}
.cb-t { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.cb-t h2 { margin: 0; font-size: 20px; letter-spacing: -0.01em; }
.cb-n {
  font-size: 12px; font-variant-numeric: tabular-nums;
  color: var(--muted); background: var(--paper);
  padding: 2px 8px; border-radius: 999px;
}
.vswitch {
  display: inline-flex; gap: 2px; padding: 2px;
  background: var(--paper); border: 1px solid var(--line); border-radius: 8px;
}
.vbtn {
  display: inline-flex; align-items: center; gap: 6px;
  font: inherit; font-size: 13px; line-height: 1;
  padding: 7px 12px; border: 0; border-radius: 6px;
  background: transparent; color: var(--muted); cursor: pointer;
  /* Ngón tay cần ít nhất 44px chiều cao để bấm trúng trên điện thoại. */
  min-height: 34px;
}
.vbtn:hover { color: var(--ink); }
.vbtn.on { background: var(--bg); color: var(--ink); box-shadow: 0 1px 2px rgb(0 0 0 / 0.06); }
.vbtn .ic-wrap { display: inline-flex; }
.vbtn .ic { width: 15px; height: 15px; }
.vbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
@media (max-width: 560px) {
  .compbar { align-items: flex-start; }
  .vswitch { width: 100%; }
  .vbtn { flex: 1; justify-content: center; }
}

/* Mục lục dính. Trang dossier dài ~8 màn hình; trước đây không có neo nào để
   quay lại phần kết luận ngoài cuộn tay. */
.pagenav {
  position: sticky;
  /* Xếp NGAY DƯỚI topbar. top phải là chiều cao thật của topbar, nếu không hai
     thanh dính chồng lên nhau. */
  top: 57px;
  z-index: 40;
  display: flex; align-items: center; gap: 2px;
  padding: 8px 28px;
  background: rgba(255,255,255,.92);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
  /* Không cuộn ngang nữa: nội dung là MỘT nút, danh sách nằm trong panel cuộn
     DỌC. `position: sticky` ở trên vừa giữ thanh dính vừa làm mốc neo cho panel;
     `overflow: visible` để panel tràn ra ngoài thanh được. */
  overflow: visible;
}
/* Mục lục trang: MỘT NÚT, không phải một dải cuộn ngang.
   Dải cũ giấu 76% nội dung trên mobile và cắt nhãn thành vô nghĩa — xem ghi chú
   trong rebuildPageNav. */
.pn-btn {
  display: inline-flex; align-items: center; gap: 8px;
  max-width: 100%; min-height: 38px; padding: 7px 12px;
  font: inherit; font-size: 13px; color: var(--ink); cursor: pointer;
  /* Viền và nền để nó ĐỌC RA là một cái bấm được. Dải cũ là chữ xám trên nền
     xám, không có gì nói rằng nó tương tác được. */
  background: var(--paper); border: 1px solid var(--line); border-radius: 999px;
}
.pn-btn:hover { border-color: var(--accent); }
.pn-btn[aria-expanded="true"] { border-color: var(--accent); background: var(--accent-soft); }
.pn-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pn-kicker { color: var(--muted); font-size: 11.5px; letter-spacing: .04em; text-transform: uppercase; }
/* Tên mục đang đọc. Cắt bằng ellipsis CSS chứ không cắt chuỗi trong JS: trình
   duyệt cắt đúng chỗ vừa khít, còn cắt cứng 26 ký tự thì lúc thừa lúc thiếu. */
.pn-cur { font-weight: 560; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-caret { color: var(--muted); font-size: 11px; flex: 0 0 auto; }

.pn-panel {
  position: absolute; z-index: 40; top: calc(100% - 4px); left: 28px;
  min-width: 260px; max-width: min(420px, calc(100vw - 28px));
  /* Nhiều mục thì cuộn DỌC trong panel — cuộn dọc có thanh cuộn thật và ai cũng
     hiểu, khác hẳn cuộn ngang bị ẩn. */
  max-height: min(60vh, 420px); overflow-y: auto;
  display: flex; flex-direction: column; padding: 6px;
  background: #fff; border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 12px 32px rgba(11, 18, 32, .13);
}
.pn-item {
  display: flex; align-items: flex-start; gap: 9px; width: 100%;
  padding: 9px 10px; border: 0; border-radius: 9px; background: transparent;
  font: inherit; font-size: 13.5px; line-height: 1.45; color: var(--ink);
  text-align: left; cursor: pointer;
  /* Nhãn ĐẦY ĐỦ, xuống dòng được. Đây là cả lý do đổi sang panel. */
  white-space: normal; overflow-wrap: anywhere;
}
.pn-item:hover { background: var(--paper); }
.pn-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.pn-item.on { background: var(--accent-soft); font-weight: 560; }
.pn-dot { flex: 0 0 auto; width: 6px; height: 6px; margin-top: 7px; border-radius: 50%; background: var(--line-2); }
/* Người tắt hiệu ứng chuyển động vẫn phải được giấu thanh — chỉ là không trượt. */
@media (prefers-reduced-motion: reduce) { .pagenav { transition: none; } }
.pn-item.on .pn-dot { background: var(--accent); }

/* Neo phải dừng DƯỚI hai thanh dính, nếu không mốc vừa nhảy tới đã bị che. */
#run .memo-card, #run .divider, #run .compbar { scroll-margin-top: 108px; }
@media (max-width: 760px) {
  .pagenav { top: 53px; padding: 6px 16px; }
  /* Panel canh theo padding của thanh, nếu không nó lệch khỏi cái nút. */
  .pn-panel { left: 16px; right: 16px; min-width: 0; max-width: none; }
  /* 44px là sàn chạm của Apple/Android. Nút cũ cao 34px và là chữ trần. */
  .pn-btn { min-height: 44px; width: 100%; justify-content: flex-start; }
  /* Trên màn hẹp, chữ "TRONG TRANG NÀY" xuống hai dòng và ép tên mục còn một
     mẩu. Biểu tượng đã mang đủ nghĩa ở đó — bỏ chữ, trả chỗ cho thứ người đọc
     thật sự cần: họ đang ở mục nào. */
  .pn-kicker { display: none; }
  /* Button mặc định canh GIỮA chữ, nên nhãn trôi ra khỏi biểu tượng. */
  .pn-cur { flex: 1 1 auto; text-align: left; }

  /* Ẩn khi cuộn xuống, hiện khi cuộn lên — xem ghi chú trong rebuildPageNav.
     Dịch lên đúng chiều cao của chính nó cộng 1px viền, để không để lại một
     vệt mờ dưới topbar. */
  .pagenav { transition: transform .18s ease, opacity .18s ease; will-change: transform; }
  .pagenav.pn-tucked { transform: translateY(calc(-100% - 1px)); opacity: 0; pointer-events: none; }
  .pn-item { padding: 12px 10px; min-height: 44px; align-items: center; }
  #run .memo-card, #run .divider, #run .compbar { scroll-margin-top: 100px; }
}

/* Ảnh trang đối thủ ở đầu panel. Cắt thấp: để nhận ra cửa hàng trong một cái
   liếc, không phải đọc nó — panel còn 4 tab nội dung phía dưới. */
.pn-hero {
  display: block; position: relative;
  margin: 0 0 16px; border-radius: 10px; overflow: hidden;
  border: 1px solid var(--line); background: var(--paper);
  line-height: 0;
}
.pn-hero img {
  width: 100%; height: auto; max-height: 190px;
  object-fit: cover; object-position: top center;
  display: block;
}
.pn-hero-cap {
  position: absolute; left: 10px; bottom: 10px;
  font-size: 11.5px; line-height: 1; font-weight: 560;
  color: #fff; background: rgba(11,18,32,.72);
  padding: 6px 10px; border-radius: 999px;
  backdrop-filter: blur(6px);
}
.pn-hero:hover { border-color: var(--accent); }
.pn-hero:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 760px) { .pn-hero img { max-height: 140px; } }

/* Bản dịch chạy dở khác hẳn bản dịch chưa có: nửa trang ở ngôn ngữ khác là một
   trục trặc, không phải một lựa chọn chưa dùng. */
.langnote.warn { background: var(--warn-soft); border-color: var(--warn); color: var(--warn); }

/* Băng báo dịch vụ — hết credit model, khoá chết.
   Nằm ngoài #run nên nó sống qua mọi lần vẽ lại dossier, và đứng đầu <main> vì
   nó trả lời câu hỏi "bấm Chạy có ra gì không" — thứ cần biết TRƯỚC khi gõ URL. */
.notice {
  display: grid; gap: 6px; margin: 0 0 22px;
  padding: 14px 16px; border-radius: 12px;
  background: var(--bad-soft); color: var(--bad); font-size: 13.5px;
  border: 1px solid color-mix(in srgb, var(--bad) 22%, transparent);
}
.notice[hidden] { display: none; }
.notice strong { font-weight: 640; }
.notice .muted { color: color-mix(in srgb, var(--bad) 72%, transparent); }

/* Cùng lời giải thích, nhưng đặt trong dossier: nó nói vì sao các ô đỏ bên dưới
   hỏng, nên phải đọc trước chúng. */
.llmdown { display: grid; gap: 6px; justify-items: stretch; }
.llmdown .muted { color: color-mix(in srgb, var(--bad) 72%, transparent); font-size: 12.5px; }

/* Ghế dự bị — ai đã được cân nhắc mà không vào dossier.
   Đóng mặc định: nó là câu trả lời cho một câu hỏi cụ thể ("sao không thấy X?"),
   không phải thứ cần đọc mỗi lần mở trang. */
.bench { margin: 18px 0; border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; }
.bench summary { cursor: pointer; font-size: 13.5px; font-weight: 600; }
.bench p { margin: 10px 0 8px; font-size: 12.5px; line-height: 1.6; }
.bench ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 5px; }
.bench li { font-size: 12.5px; display: flex; gap: 8px; flex-wrap: wrap; }
.bench .bd { font-variant-numeric: tabular-nums; }
.bench .bs { color: var(--muted); }
