/* ============================================================
   pulse.css — PULSE v7, chất "app trả phí": dark có chiều sâu
   (gradient nhẹ + hairline, KHÔNG đen trơn), icon chip màu kiểu iOS,
   ring 5h, thẻ số liệu, biểu đồ SVG. Font hệ thống (trên iPhone =
   SF Pro thật — đúng chất app native), số dùng mono tabular.
============================================================ */
:root{
  --bg:#0a0c12; --bg2:#0d1019;
  --card:#121623; --card2:#171c2c; --cardHi:#1c2235;
  --line:rgba(148,163,199,.13); --line2:rgba(148,163,199,.22);
  /* --tx3 CŨ #5d6880 chỉ đạt 3.50:1 trên nền màn / 3.23:1 trên card — dưới chuẩn AA 4.5
     (đo 12/08). Nay 5.53:1 trên card · 6.23:1 trên nền màn. ĐỪNG hạ tối hơn #7d8aa2.
     --tx-hero: chữ phụ TRONG .hero — nền gradient #232a55 sáng hơn nên --tx3 ở đó chỉ
     được 4.36:1, phải có token riêng (6.67:1). */
  --tx:#eef1f8; --tx2:#b6c0d6; --tx3:#8592aa; --tx-hero:#aab4d8;
  --pri:#6d8dff; --pri2:#8fa8ff; --vio:#9d7bff; --cy:#38c8dd;
  --ok:#3ddc97; --warn:#f0b13d; --err:#f26d7a; --pink:#ef7fae;
  --grad:linear-gradient(135deg,#5b7cfe 0%,#7c62f5 55%,#9d55e8 100%);
  --sans:-apple-system,BlinkMacSystemFont,'SF Pro Text','Segoe UI',Roboto,sans-serif;
  --mono:'SF Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  --sat:env(safe-area-inset-top,0px); --sab:env(safe-area-inset-bottom,0px);
  /* ĐO CDP 12/08 (--sab=34px): #tabbar cao THẬT 53.0px khi sab=0 và 68.3px khi sab=34
     (đúng 53 + 34*.45). Số cũ 58px cao hơn thân tab 5px ⇒ vùng cuộn chừa 81.3px trong khi
     tab chỉ chiếm 68.3px = lộ 13px trống dưới đáy (ý đồ chỉ 8px). Nay 53px = khớp thân tab. */
  /* 12/08 (bản Instagram): viên tab cao 48px (4+4 đệm + 8+8 đệm nút + icon 24) và nổi cách
     đáy 6px + 60% vùng vạch home. Vùng cuộn phải chừa đúng bằng đó — đổi viên thì đổi cả đây. */
  --tabH:calc(62px + var(--sab) * .55); /* viên cao 56 (4+4 đệm + 8+8 nút + icon 30 + viền) + 6 cách đáy */
}
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
/* html cũng khoá cuộn (09/08): body đã fixed nhưng PWA iOS vẫn cuộn được tài liệu gốc khi
   bàn phím mở → nóc trang trôi khỏi mép. Khoá cả hai tầng cho chắc. */
html,body{background:var(--bg);color:var(--tx);height:100%;overflow:hidden}
body{font:15px/1.5 var(--sans);-webkit-font-smoothing:antialiased;overflow:hidden;position:fixed;inset:0;width:100%}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
input,textarea{font:inherit;color:var(--tx)}
a{color:inherit;text-decoration:none}
svg{display:block;flex:none}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums}
::-webkit-scrollbar{display:none}

#phone{height:100%;position:relative;max-width:560px;margin:0 auto;background:var(--bg);overflow:hidden} /* overflow:hidden — kẻo sheet đóng (translateX 103%) lòi mép phải trên màn rộng Mac */

/* ---------------- màn hình ---------------- */
.scr{position:absolute;inset:0;overflow-y:auto;-webkit-overflow-scrolling:touch;
  /* Khang 12/08: "vẫn còn extra space ở dưới cùng". Vùng cuộn chừa dư 22px NGOÀI chiều
     cao thanh tab — cuộn hết trang là lộ ra một dải trống. Còn 8px là vừa đủ thoáng. */
  padding:calc(14px + var(--sat)) 16px calc(var(--tabH) + 8px);display:none;background:
  radial-gradient(1200px 500px at 50% -220px, rgba(93,124,254,.10), transparent 60%), var(--bg)}
.scr.on{display:block}
/* transition nằm ở base để CẢ CHIỀU RA cũng trượt — để trong .push thì lúc bỏ class là
   transition mất theo, list nhảy cụp 8% một phát ngay lúc sheet đóng xong (giật 09/08 tối) */
.scr.host{transition:transform .28s}
.scr.host.push{transform:translateX(-8%);pointer-events:none}
/* SWIPE-BACK viết lại 09/08 khuya theo chuẩn senior (Missive 60fps + Ionic gesture):
   dải mép riêng bắt gesture — touch-action:none nên trình duyệt không giành cuộn dọc;
   z-index DƯỚI .dhead (z5) nên nút back trong header không bị che. */
#swEdge{position:absolute;left:0;top:0;bottom:0;width:24px;z-index:4;background:transparent;touch-action:none}
/* đang kéo theo ngón: chỉ tắt transition — KHÔNG thêm việc gì khác lúc gesture bắt đầu */
.scr.det.drag{transition:none!important}

/* sheet chi tiết trượt đè */
/* sheet = GPU layer CỐ ĐỊNH (luôn có transform + will-change) — promote layer giữa gesture
   là re-rasterize cả sheet ngay khung hình đầu = hitch (bài học 09/08 khuya) */
.scr.det{display:block;transform:translateX(103%);transition:transform .3s cubic-bezier(.2,.9,.25,1);
  will-change:transform;z-index:40;background:var(--bg2);padding:0 0 calc(var(--sab) + 16px)}
.scr.det.on{transform:translateX(0)}/* giữ transform (đừng `none` — mất layer) */
/* .dhead: BỎ blur (09/08 khuya) — sheet là flex column nên KHÔNG có gì cuộn dưới header,
   blur chỉ tốn re-blur mỗi khung hình lúc sheet trượt; nền đặc lên .97 là y hệt */
.dhead{position:sticky;top:0;z-index:5;display:flex;align-items:center;gap:8px;
  padding:calc(10px + var(--sat)) 12px 10px;background:rgba(15,18,27,.97);
  border-bottom:1px solid var(--line)}
.dback{display:flex;align-items:center;gap:3px;color:var(--pri2);font:500 14.5px var(--sans);padding:4px 6px 4px 0;flex:none;max-width:34%}
.dback span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* back CHỈ dấu < kiểu Messenger (Khang 09/08 — tab VSCode): chevron to hơn, vùng bấm giữ nguyên */
.dback span:empty{display:none}
.dback.solo{padding:4px 12px 4px 2px}
.dback.solo svg{width:23px;height:23px}
.dtitle{flex:1;min-width:0;text-align:center;font:600 16px var(--sans);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dact{flex:none;min-width:56px;display:flex;justify-content:flex-end}
.dbody{padding:14px 16px 30px}

/* ---------------- header màn ---------------- */
.mhead{display:flex;align-items:flex-end;gap:12px;margin:4px 2px 14px}
.mhead .big{font:700 27px/1.15 var(--sans);letter-spacing:.2px}
.mhead .sub{font:400 12.5px var(--sans);color:var(--tx3);margin-top:3px}
.mhead .ava{margin-left:auto;width:38px;height:38px;border-radius:50%;background:var(--grad);
  display:flex;align-items:center;justify-content:center;font:700 16px var(--sans);color:#fff;
  box-shadow:0 4px 14px rgba(108,98,245,.35)}

/* ---------------- thẻ & mục ---------------- */
.card{background:linear-gradient(180deg,var(--card2),var(--card));border:1px solid var(--line);
  border-radius:16px;padding:14px 15px;margin-bottom:12px;box-shadow:0 1px 2px rgba(0,0,0,.25)}
.card.flat{padding:6px 15px}
.sh{display:flex;align-items:baseline;gap:8px;margin:20px 2px 9px;font:700 11px var(--sans);
  letter-spacing:1.6px;color:var(--tx3);text-transform:uppercase}
.sh .act{margin-left:auto;font:500 12.5px var(--sans);color:var(--pri2);letter-spacing:0;text-transform:none}
.empty{color:var(--tx3);font:400 12.5px var(--sans);text-align:center;padding:12px 6px}
.foot{color:var(--tx3);font:400 11.5px var(--sans);text-align:center;padding:10px 0 0}

/* icon chip màu kiểu iOS Settings */
.ichip{width:30px;height:30px;border-radius:9px;display:flex;align-items:center;justify-content:center;flex:none}
.ichip svg{width:16px;height:16px}
.ic-pri{background:rgba(109,141,255,.16);color:var(--pri2)}
.ic-vio{background:rgba(157,123,255,.16);color:#b9a4ff}
.ic-cy{background:rgba(56,200,221,.14);color:#6ad9ea}
.ic-ok{background:rgba(61,220,151,.13);color:#66e5ae}
.ic-warn{background:rgba(240,177,61,.14);color:#f6c56b}
.ic-err{background:rgba(242,109,122,.14);color:#f68f99}
.ic-pink{background:rgba(239,127,174,.14);color:#f5a3c3}

/* ---------------- HERO hôm nay ---------------- */
.hero{position:relative;border-radius:20px;padding:18px 18px 16px;margin-bottom:14px;overflow:hidden;
  background:linear-gradient(140deg,#1c2340 0%,#232a55 45%,#2c2357 100%);border:1px solid rgba(140,158,255,.22)}
.hero:before{content:"";position:absolute;inset:0;background:
  radial-gradient(420px 200px at 88% -30%, rgba(125,98,245,.4), transparent 65%),
  radial-gradient(300px 170px at -8% 110%, rgba(56,200,221,.16), transparent 60%);pointer-events:none}
.hero>*{position:relative}
.hgreet{font:600 17px var(--sans)}
.hdate{font:400 12px var(--sans);color:#aab4d8;margin-top:2px}
.hrow{display:flex;align-items:center;gap:16px;margin-top:14px}
.ringWrap{position:relative;width:92px;height:92px;flex:none}
.ringWrap svg{width:92px;height:92px}
.ringTx{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.ringTx b{font:700 20px var(--mono)}
.ringTx i{font:600 8.5px var(--sans);font-style:normal;color:#aab4d8;letter-spacing:1.2px;margin-top:1px}
.hstats{flex:1;display:flex;flex-direction:column;gap:9px;min-width:0}
.hst{display:flex;align-items:baseline;gap:8px}
.hst .v{font:700 19px var(--mono)}
.hst .l{font:400 11.5px var(--sans);color:#aab4d8;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hst .delta{font:600 10.5px var(--mono);padding:2px 6px;border-radius:6px}
.delta.up{color:#6ff0b9;background:rgba(61,220,151,.14)}
.delta.down{color:#f89aa5;background:rgba(242,109,122,.15)}
.hfoot{display:flex;gap:8px;margin-top:13px}
.hchip{flex:1;text-align:center;background:rgba(10,13,22,.4);border:1px solid rgba(140,158,255,.16);
  border-radius:11px;padding:7px 4px}
.hchip b{display:block;font:700 14.5px var(--mono)}
.hchip i{font:500 9.5px var(--sans);font-style:normal;color:#aab4d8;letter-spacing:.6px;text-transform:uppercase}

/* ---------------- KPI lưới ---------------- */
.g2{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:2px}
.kx{background:linear-gradient(180deg,var(--card2),var(--card));border:1px solid var(--line);
  border-radius:14px;padding:12px 13px}
.kx .kt{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.kx em{font:500 11px var(--sans);font-style:normal;color:var(--tx2)}
.kx b{font:700 21px var(--mono);display:block}
.kx .sub{font:400 10.5px var(--sans);color:var(--tx3);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---------------- hàng list chung ---------------- */
.row{display:flex;align-items:center;gap:11px;padding:11px 2px;border-bottom:1px solid var(--line);min-width:0}
.card .row:last-child{border-bottom:none}
.row.tap:active{opacity:.6}
.row .rc{flex:1;min-width:0}
.row .rt{font:600 14px var(--sans);display:flex;align-items:center;gap:7px;min-width:0}
.row .rt .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.row .rs{font:400 12px var(--sans);color:var(--tx2);margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.row .rr{flex:none;text-align:right}
.row .rr b{font:600 12.5px var(--mono);display:block}
.row .rr i{font:400 10.5px var(--sans);font-style:normal;color:var(--tx3)}
.chev{color:var(--tx3);flex:none}
.dot{width:8px;height:8px;border-radius:50%;background:var(--tx3);flex:none}
.dot.ok{background:var(--ok)} .dot.warn{background:var(--warn)} .dot.off{background:#2c3346}
.dot.pulse{animation:pu 2.2s ease-in-out infinite}
@keyframes pu{0%,100%{opacity:1}50%{opacity:.3}}
.tag{display:inline-flex;align-items:center;gap:5px;font:600 10px var(--mono);color:var(--tx2);
  background:rgba(148,163,199,.09);border:1px solid var(--line);border-radius:6px;padding:2px 6px;white-space:nowrap}
.tag.grn{color:#66e5ae;border-color:rgba(61,220,151,.3)}
.tag.amb{color:#f6c56b;border-color:rgba(240,177,61,.3)}
.tag.live{color:#66e5ae;border-color:rgba(61,220,151,.35);background:rgba(61,220,151,.08)}
.pill{display:inline-block;width:9px;height:9px;border-radius:3px;margin-right:6px;vertical-align:-1px}

/* nút */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;border-radius:11px;
  padding:9px 14px;font:600 13.5px var(--sans)}
.btnPri{background:var(--grad);color:#fff;box-shadow:0 4px 14px rgba(108,98,245,.3)}
.btnPri:active{opacity:.8}
.btnGhost{border:1px solid var(--line2);color:var(--tx2)}
.btnSm{border:1px solid var(--line2);border-radius:9px;padding:5px 11px;font:600 12px var(--sans);color:var(--tx2)}
.btnSm.pri{color:var(--pri2);border-color:rgba(109,141,255,.4)}
.btnSm.danger{color:var(--err);border-color:rgba(242,109,122,.35)}
.btnSm:active,.btnGhost:active{opacity:.6}
.seg{display:inline-flex;background:rgba(10,13,22,.5);border:1px solid var(--line);border-radius:9px;padding:2px}
.seg button{padding:4px 11px;border-radius:7px;font:600 11px var(--mono);color:var(--tx3)}
.seg button.on{background:var(--card2);color:var(--tx);border:1px solid var(--line)}

/* ---------------- biểu đồ ---------------- */
.chart{position:relative;min-width:0}
.chart svg{width:100%;height:auto;display:block}
.legend{display:flex;flex-wrap:wrap;gap:10px 14px;margin-top:9px}
.legend .li{display:inline-flex;align-items:center;font:500 11px var(--sans);color:var(--tx2)}
.tip{position:fixed;z-index:90;background:#1d2436;border:1px solid var(--line2);border-radius:10px;
  padding:8px 11px;font:400 11.5px var(--sans);color:var(--tx);pointer-events:none;opacity:0;
  transition:opacity .12s;max-width:240px;box-shadow:0 10px 30px rgba(0,0,0,.5)}
.tip.on{opacity:1}
.tip .tt{font:600 10.5px var(--mono);color:var(--tx3);margin-bottom:4px}
.tip .tr{display:flex;justify-content:space-between;gap:14px}
.tip .tr b{font:600 11px var(--mono)}
.hm{overflow-x:auto;padding-bottom:2px}
.hmRowLb{font:500 9px var(--mono);fill:#5d6880}

/* ---------------- NÃO PHIÊN (cơ chế LITE) ---------------- */
.st{display:flex;align-items:baseline;gap:8px;margin:18px 2px 8px;font:700 11px var(--sans);
  letter-spacing:1.6px;color:var(--tx3);text-transform:uppercase}
.st .sthin{font:400 10.5px var(--sans);letter-spacing:.2px;text-transform:none;color:var(--tx3)}
.st .stlive{font:700 9.5px var(--mono);color:#66e5ae;letter-spacing:1px}
.think{background:linear-gradient(180deg,rgba(157,123,255,.09),rgba(157,123,255,.04));
  border:1px solid rgba(157,123,255,.25);border-radius:13px;padding:11px 13px;
  font:400 13px/1.6 var(--sans);color:#cfc4f4}
.think.tnil{color:var(--tx3);font-style:italic;background:var(--card);border-color:var(--line)}
/* hàng lượt prompt (turnRow) */
.ptr{display:flex;align-items:center;gap:8px;padding:10px 10px;border:1px solid var(--line);
  border-radius:12px;background:var(--card);margin-bottom:7px;min-width:0}
.ptr:active{opacity:.75}
.ptr.live{border-color:rgba(61,220,151,.35);background:linear-gradient(180deg,rgba(61,220,151,.07),var(--card))}
.ptr.tt-on{border-color:rgba(56,200,221,.45)}
.p-t{font:600 11px var(--mono);color:var(--tx3);flex:none}
.p-d{font:500 10.5px var(--mono);color:var(--tx3);flex:none}
.p-k{font:600 10.5px var(--mono);color:var(--cy);flex:none}
.p-k i{font-style:normal;color:var(--tx3);font-size:9px}
.p-x{flex:1;min-width:0;font:400 12.5px var(--sans);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.p-live{font:700 9px var(--mono);color:#66e5ae;letter-spacing:1px;flex:none}
.pfull{flex:none;font:600 10.5px var(--sans);color:var(--pri2);padding:3px 6px}
/* box câu trả lời (ttx — tông cyan y LITE) + box nguyên văn (pfx — vàng đồng) */
.ttx{border:1px solid rgba(56,200,221,.3);border-radius:13px;background:rgba(56,200,221,.05);
  margin:-1px 0 9px;overflow:hidden}
.tt-hd{display:flex;justify-content:space-between;gap:10px;padding:8px 12px;font:600 11px var(--mono);
  color:#6ad9ea;border-bottom:1px solid rgba(56,200,221,.16);min-width:0}
.tt-pv{font:400 10.5px var(--sans);color:var(--tx3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;text-align:right}
.tt-bd{padding:11px 13px;font:400 13px/1.65 var(--sans);color:#d9dfec;white-space:pre-wrap;
  word-break:break-word;max-height:46vh;overflow-y:auto}
.pfx{border:1px solid rgba(240,177,61,.3);border-radius:13px;background:rgba(240,177,61,.05);margin:-1px 0 9px}
.pf-hd{padding:8px 12px;font:600 11px var(--mono);color:#f6c56b;border-bottom:1px solid rgba(240,177,61,.16)}
.pf-bd{padding:11px 13px;font:400 13px/1.6 var(--sans);color:#e6dcc8;white-space:pre-wrap;word-break:break-word;max-height:38vh;overflow-y:auto}
/* code live changes.diff */
.stog{cursor:pointer}
.stcar{color:var(--tx3);font-family:var(--mono)}
.dwrap{background:#0b0e15;border:1px solid var(--line);border-radius:12px;padding:10px 12px;margin-bottom:6px;
  font:400 11px/1.55 var(--mono);color:#9fb0c9;white-space:pre-wrap;word-break:break-all;max-height:300px;overflow-y:auto}
/* nhắn phiên */
.msgIn{display:flex;gap:8px}
.msgIn input{flex:1;background:rgba(10,13,22,.6);border:1px solid var(--line2);border-radius:11px;
  padding:10px 13px;font:400 13.5px var(--sans)}
.msgIn input:focus{outline:none;border-color:var(--pri)}
.msgNote{font:400 11px var(--sans);color:var(--tx3);margin-top:7px}
/* thợ phụ pill */
.spill{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line2);border-radius:20px;
  padding:6px 12px;margin:0 6px 6px 0;font:500 12.5px var(--sans);background:var(--card)}
.spill:active{opacity:.6}

/* ---------------- feed hoạt động ---------------- */
.fi{display:flex;gap:10px;padding:9px 2px;border-bottom:1px solid var(--line);min-width:0}
.card .fi:last-child{border-bottom:none}
.fBody{min-width:0;flex:1}
.fMsg{font:400 13px var(--sans);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fMeta{font:500 10.5px var(--mono);color:var(--tx3);margin-top:2px;display:flex;gap:8px;min-width:0}
.fMeta .fp{color:var(--pri2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---------------- tin tức ---------------- */
.nItem{padding:10px 2px;border-bottom:1px solid var(--line)}
.card .nItem:last-child{border-bottom:none}
.nItem a{font:500 15px/1.45 var(--sans);display:block}
.nItem .mt{font:500 10.5px var(--mono);color:var(--tx3);margin-top:3px}
.nTech .w{color:var(--tx2);font-size:13.5px;display:block;margin-top:3px;line-height:1.5}
.nTech .hh{color:#66e5ae;font-size:13.5px;display:block;margin-top:2px;line-height:1.5}
.briefBox{background:linear-gradient(180deg,rgba(109,141,255,.1),rgba(109,141,255,.04));
  border:1px solid rgba(109,141,255,.28);border-radius:13px;padding:12px 14px;margin-bottom:12px}
.briefBox pre{white-space:pre-wrap;font:400 13px/1.7 var(--sans)}
.briefBox .mt{font:500 10px var(--mono);color:var(--tx3);margin-top:8px}
.newsTabs{display:flex;gap:6px;overflow-x:auto;margin-bottom:11px;padding:2px}
.nt{flex:none;border:1px solid var(--line);border-radius:18px;padding:6px 13px;font:600 12px var(--sans);color:var(--tx2);background:var(--card)}
.nt.on{background:rgba(109,141,255,.15);border-color:rgba(109,141,255,.45);color:var(--pri2)}

/* ---------------- doanh nghiệp ---------------- */
.bizCard{position:relative;overflow:hidden;border-radius:16px;border:1px solid var(--line);
  background:linear-gradient(180deg,var(--card2),var(--card));padding:14px 15px;margin-bottom:12px}
.bizCard:active{opacity:.75}
.bizTop{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.bizName{font:700 15.5px var(--sans)}
.bizSub{font:400 11px var(--sans);color:var(--tx3)}
.bnum .lb{font:500 10.5px var(--sans);color:var(--tx2);letter-spacing:.4px}
.bnum .big{font:700 24px var(--mono);margin:2px 0 6px}
.bfoot{display:flex;justify-content:space-between;font:400 12px var(--sans);color:var(--tx2);
  border-top:1px solid var(--line);margin-top:10px;padding-top:9px}
.bfoot b{font:600 13px var(--mono);color:var(--tx)}
.gitr{display:flex;align-items:center;gap:8px;padding:8px 2px;border-bottom:1px solid var(--line);font:400 12.5px var(--sans)}
.card .gitr:last-child{border-bottom:none}
.gitr .nm{font-weight:600;flex:1}
.gitr .br{color:var(--tx3);font:500 11px var(--mono)}
.kv{display:flex;justify-content:space-between;gap:10px;padding:8px 2px;border-bottom:1px solid var(--line);font:400 13px var(--sans)}
.card .kv:last-child{border-bottom:none}
.kv em{font-style:normal;color:var(--tx2)}
.kv b{font-weight:600;text-align:right;min-width:0;overflow:hidden;text-overflow:ellipsis}
.bul{list-style:none}
.bul li{padding:6px 0 6px 16px;position:relative;font:400 13px/1.55 var(--sans);color:#d5dae6}
.bul li:before{content:"";position:absolute;left:2px;top:12px;width:5px;height:5px;border-radius:50%;background:var(--pri)}
.reply{font:400 13px/1.65 var(--sans);color:#d9dfec;white-space:pre-wrap}

/* ---------------- glog (git chi tiết) ---------------- */
.glog{list-style:none}
.glog li{display:flex;gap:9px;padding:8px 2px;border-bottom:1px solid var(--line);font:400 12.5px var(--sans);min-width:0}
.glog li:last-child{border-bottom:none}
.glog .h{font:600 10.5px var(--mono);color:var(--pri2);flex:none;padding-top:2px}
.glog .m{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.glog .w{color:var(--tx3);font:500 10px var(--mono);flex:none}
.dirty{font:400 11px var(--mono);color:var(--warn);padding:2px 0}

/* ---------------- skeleton shimmer ---------------- */
.skl{border-radius:12px;background:linear-gradient(90deg,var(--card) 25%,var(--card2) 45%,var(--card) 65%);
  background-size:220% 100%;animation:shm 1.3s linear infinite;border:1px solid var(--line)}
@keyframes shm{0%{background-position:180% 0}100%{background-position:-40% 0}}

/* ---------------- tabbar ---------------- */
/* ===== THANH TAB KIỂU INSTAGRAM / iOS 26 (12/08) =========================
   Khang chốt: đổi sang "viên thuốc nổi" như Instagram. Số lấy từ hướng dẫn iOS 26
   (Apple: tab bar nổi, thụt 21pt trái/phải/dưới) + đo lại trên ảnh Khang gửi:
   viên cao ~48px, bo tròn hết cỡ, nền kính mờ, KHÔNG nhãn chữ — chỉ icon, tab đang
   mở có ô sáng bo tròn phía sau. Khoảng trống dưới viên là CỐ Ý (vạch home nằm trong
   đó), khác hẳn vụ "dải trống" hôm nay — đây là ý đồ thiết kế của Apple/Instagram.
   ⚠ Đổi chiều cao viên thì PHẢI sửa --tabH ở :root cho khớp, kẻo vùng cuộn hụt/dư. */
/* ===== KÍNH LỎNG (12/08 lượt 2) — mượn đúng công thức "Liquid glass v2 (iOS)" Khang đã
   dùng bên utxi-web (`web/src/index.css`): kính mờ + RIM LIGHT (viền TRÊN sáng hơn viền
   dưới) + vệt sáng trong (`inset 0 1px 0`) + bóng đổ sâu. Đó là thứ làm nó ra "kính"
   chứ không phải "hộp xám mờ". Kèm fallback khi máy không hỗ trợ backdrop-filter. */
/* ===== TỐI + BỚT ÁM MÀU (12/08 lượt 3 — Khang: "Instagram tối màu hơn") ==========
   ĐO CDP bản trước: thân viên trên nền tối = rgb(36,41,55) NHƯNG đoạn nằm dưới ảnh tin
   màu cam = rgb(80,55,58) — lệch 44 ở kênh đỏ, tức viên tab ĐỔI MÀU theo nội dung trôi
   phía sau. Gốc: saturate(1.7) khuếch đại màu hút lên + nền alpha .72 cho lọt quá nhiều.
   iOS/Instagram không bị vậy vì material có lớp nền tối ĐẶC hơn và vibrancy thấp.
   Nay: nền .82 tối hơn + saturate 1.25 + blur 28 ⇒ tông trung tính, trôi qua ảnh không đổi màu. */
#tabbar{--ti:0;position:absolute;left:16px;right:16px;bottom:calc(6px + var(--sab) * .55);z-index:30;
  display:flex;gap:0;padding:4px 5px;border-radius:29px;contain:paint;
  background:rgba(18,21,30,.82);backdrop-filter:blur(28px) saturate(1.25);
  -webkit-backdrop-filter:blur(28px) saturate(1.25);
  /* rim light ĐÚNG công thức "Liquid glass v2 (iOS)" bên utxi-web: viền trên/trái sáng
     hơn hẳn + vệt sáng trong. Nền tối hơn nên rim mới nổi ra thành "kính", không phải
     "hộp xám mờ" — số cũ (.26/.16/.20) là bản đã hạ xuống cho nền sáng. */
  border:1px solid rgba(255,255,255,.10);
  border-top-color:rgba(255,255,255,.32);border-left-color:rgba(255,255,255,.22);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.35), 0 12px 36px rgba(0,0,0,.60)}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  #tabbar{background:rgba(16,19,27,.97)}
}
.tb{position:relative;flex:1;display:flex;align-items:center;justify-content:center;
  padding:8px 0;border-radius:24px;color:var(--tx3);
  /* CẢM GIÁC BẤM kiểu iOS (12/08 lượt 3): lún xuống PHẢI tức thì, bung lên mới mềm.
     Bản cũ để transform .1s cho CẢ hai chiều ⇒ ngón chạm rồi icon mới từ từ lún =
     cảm giác trễ. Nay: nhả ra .24s có đà, còn lúc :active ghi đè xuống .04s. */
  transition:color .12s, transform .24s cubic-bezier(.2,.9,.3,1)}
.tb svg{width:30px;height:30px}
.tb span{display:none}                    /* Instagram không có nhãn chữ */
.tb.on{color:var(--tx)}
.tb:active{transform:scale(.9);transition-duration:.12s,.04s}   /* lún NGAY khi chạm */
/* Ô SÁNG TRƯỢT: một khối duy nhất chạy sang tab mới thay vì tắt chỗ này bật chỗ kia.
   5 tab đều nhau nên rộng = (100% - đệm 10px)/5, dịch đúng 1 ô mỗi bậc (--ti do app.js đặt).
   Chỉ animate transform ⇒ chạy trên GPU, không reflow. */
#tabbar::before{content:'';position:absolute;top:4px;bottom:4px;left:5px;
  width:calc((100% - 10px) / 5);border-radius:24px;pointer-events:none;
  /* viên kính nhỏ chạy bên trong viên kính lớn: sáng ở nóc, mờ dần xuống đáy */
  background:linear-gradient(180deg,rgba(255,255,255,.19),rgba(255,255,255,.09));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.30);
  transform:translate3d(calc(var(--ti) * 100%),0,0);
  /* nảy nhẹ như iOS: vượt qua đích một chút rồi lùi về, thay vì trượt thẳng đơ */
  transition:transform .30s cubic-bezier(.32,1.24,.38,1)}
@media(prefers-reduced-motion:reduce){ #tabbar::before{transition:none} }
#tabbar.hid{display:none}
.tb .bdg{position:absolute;top:4px;left:calc(50% + 5px);margin:0;min-width:15px;height:15px;border-radius:8px;
  background:var(--ok);color:#06281a;font:700 9px var(--mono);display:flex;align-items:center;justify-content:center;padding:0 4px}

@media(min-width:561px){ #phone{border-left:1px solid var(--line);border-right:1px solid var(--line)} }

/* ============ v8 (07/08): chat não phiên + lịch sử + plan + offline ============ */
/* banner ngoại tuyến */
#offBar{position:absolute;top:calc(var(--sat) + 6px);left:50%;transform:translateX(-50%);z-index:60;
  display:none;align-items:center;gap:7px;background:rgba(240,177,61,.14);border:1px solid rgba(240,177,61,.4);
  color:#f6c56b;border-radius:20px;padding:5px 13px;font:600 11.5px var(--sans);backdrop-filter:blur(10px);white-space:nowrap}
#offBar.on{display:inline-flex}

/* segmented to đầu màn (Đang mở / Lịch sử) */
.segBig{display:flex;background:var(--card);border:1px solid var(--line);border-radius:13px;padding:3px;margin-bottom:13px}
.segBig button{flex:1;padding:8px 4px;border-radius:10px;font:600 13px var(--sans);color:var(--tx3);display:flex;align-items:center;justify-content:center;gap:6px}
.segBig button.on{background:var(--card2);color:var(--tx);border:1px solid var(--line)}
.segBig .cnt{font:600 10px var(--mono);color:var(--tx3);background:rgba(148,163,199,.1);border-radius:8px;padding:1px 6px}

/* sheet dạng cột (não chat cần ô soạn ghim đáy) */
.scr.det{display:flex;flex-direction:column;padding:0}
.scr.det .dbody{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:14px 16px 20px}
.dfoot{flex:none;display:flex;gap:8px;padding:10px 12px calc(10px + var(--sab));
  background:rgba(15,18,27,.97);border-top:1px solid var(--line)}/* bỏ blur — không có gì cuộn dưới (09/08 khuya) */
.dfoot input{flex:1;background:rgba(10,13,22,.6);border:1px solid var(--line2);border-radius:20px;
  padding:10px 15px;font:400 13.5px var(--sans)}
.dfoot input:focus{outline:none;border-color:var(--pri)}
.dfoot .sendB{width:40px;height:40px;border-radius:50%;background:var(--grad);color:#fff;
  display:flex;align-items:center;justify-content:center;flex:none}
.dfoot .sendB:active{opacity:.75}
.dfootNote{font:400 10px var(--sans);color:var(--tx3);text-align:center;padding:0 14px 6px;background:rgba(13,16,25,.92)}

/* kế hoạch việc (TodoWrite) */
.plan{background:linear-gradient(180deg,var(--card2),var(--card));border:1px solid var(--line);border-radius:14px;margin-bottom:12px;overflow:hidden}
.planH{display:flex;align-items:center;gap:9px;padding:11px 14px;font:600 12.5px var(--sans);cursor:pointer}
.planH .bar{flex:1;height:4px;border-radius:2px;background:rgba(148,163,199,.12);overflow:hidden}
.planH .bar i{display:block;height:100%;background:var(--grad);border-radius:2px;transition:width .4s}
.planH .pn{font:600 10.5px var(--mono);color:var(--tx3)}
.planB{padding:2px 14px 11px;display:none}
.plan.open .planB{display:block}
.pi{display:flex;gap:10px;padding:5.5px 0;font:400 13px/1.5 var(--sans);align-items:flex-start}
.pi .pbox{width:16px;height:16px;border-radius:5.5px;border:1.5px solid var(--line2);flex:none;margin-top:1.5px;
  display:flex;align-items:center;justify-content:center;color:#fff}
.pi.done .pbox{background:var(--ok);border-color:var(--ok)}
.pi.done span{color:var(--tx3);text-decoration:line-through}
.pi.run .pbox{border-color:var(--pri);box-shadow:0 0 0 3px rgba(109,141,255,.18)}
.pi.run span{color:#dbe6ff;font-weight:600}
.pi span{min-width:0}

/* dải suy nghĩ (chỉ khi live) */
.thStrip{display:flex;gap:10px;align-items:flex-start;background:rgba(157,123,255,.08);
  border:1px solid rgba(157,123,255,.24);border-radius:13px;padding:10px 13px;margin-bottom:12px;
  font:italic 400 12.5px/1.6 var(--sans);color:#cfc4f4}
.thStrip .ichip{width:26px;height:26px;border-radius:8px;margin-top:1px}

/* chat thread */
.chatT{display:flex;flex-direction:column;padding-bottom:6px}
.cbDay{align-self:center;font:600 10px var(--mono);color:var(--tx3);background:var(--card);
  border:1px solid var(--line);border-radius:12px;padding:3px 11px;margin:12px 0 6px}
.cbRow{display:flex;flex-direction:column;margin:4px 0;min-width:0}
.cbRow.u{align-items:flex-end}
.cbRow.a{align-items:flex-start}
.cb{max-width:88%;border-radius:17px;padding:9px 13px;font:400 13.5px/1.62 var(--sans);
  white-space:pre-wrap;word-break:break-word;position:relative;min-width:0}
.cbRow.u .cb{background:linear-gradient(135deg,#4e6ee3,#6a55d8);color:#fff;border-bottom-right-radius:6px}
.cbRow.a .cb{background:var(--card2);border:1px solid var(--line);color:#dde3ef;border-bottom-left-radius:6px}
.cbRow.a .cb.wait{color:var(--tx3)}
.cbMeta{font:500 9.5px var(--mono);color:var(--tx3);margin:3px 6px 0;display:flex;gap:8px;align-items:center}
.cbMeta .lv{color:#66e5ae;font-weight:700;letter-spacing:.8px}
.cbBtn{border:1px dashed var(--line2);border-radius:14px;padding:8px 14px;font:600 12px var(--sans);color:var(--pri2)}
.cbBtn:active{opacity:.6}
.cbSys{align-self:center;font:500 11px var(--sans);color:var(--tx3);background:var(--card);
  border:1px solid var(--line);border-radius:12px;padding:4px 12px;margin:8px 0;text-align:center}
.typing{display:inline-flex;gap:4px;align-items:center;padding:3px 2px}
.typing i{width:6px;height:6px;border-radius:50%;background:#8b93ad;animation:ty 1.2s ease-in-out infinite}
.typing i:nth-child(2){animation-delay:.15s}
.typing i:nth-child(3){animation-delay:.3s}
@keyframes ty{0%,60%,100%{opacity:.25;transform:translateY(0)}30%{opacity:1;transform:translateY(-3.5px)}}
.cb .xmore{display:block;margin-top:6px;font:600 12px var(--sans);color:var(--pri2);cursor:pointer}
.cbRow.u .cb .xmore{color:#cdd9ff}

/* hàng lịch sử phiên */
.hrow{display:flex;gap:11px;padding:11px 2px;border-bottom:1px solid var(--line);min-width:0;align-items:flex-start}
.card .hrow:last-child{border-bottom:none}
.hrow:active{opacity:.6}
.hrow .hic{width:34px;height:34px;border-radius:11px;flex:none;display:flex;align-items:center;justify-content:center;
  font:700 13px var(--sans);color:#fff}
.hrow .hc{flex:1;min-width:0}
.hrow .ht{font:600 13.5px var(--sans);display:flex;gap:8px;align-items:baseline}
.hrow .ht .tm{margin-left:auto;font:500 10px var(--mono);color:var(--tx3);flex:none}
.hrow .hs{font:400 12px/1.5 var(--sans);color:var(--tx2);margin-top:1px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.hrow .hn{font:500 10px var(--mono);color:var(--tx3);margin-top:2px}

/* thẻ block 5h + tuần (Phân tích) */
.qGrid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.qCell{padding:7px 0}
.qCell em{font:500 10.5px var(--sans);font-style:normal;color:var(--tx3);display:block}
.qCell b{font:600 15px var(--mono)}
.wbar{height:6px;border-radius:3px;background:rgba(148,163,199,.12);overflow:hidden;margin:8px 0 4px}
.wbar i{display:block;height:100%;border-radius:3px;background:var(--grad)}
.dayRow{display:flex;align-items:center;gap:9px;padding:4px 0;font:400 12px var(--sans);color:var(--tx2)}
.dayRow .dl{width:34px;font:500 10.5px var(--mono);color:var(--tx3)}
.dayRow .db{flex:1;height:7px;border-radius:3.5px;background:rgba(148,163,199,.1);overflow:hidden}
.dayRow .db i{display:block;height:100%;border-radius:3.5px;background:var(--pri);opacity:.85}
.dayRow.today .db i{background:var(--grad);opacity:1}
.dayRow .dv{width:52px;text-align:right;font:600 11px var(--mono);color:var(--tx)}

/* ============ v9 (07/08): chip hạn mức + timeline reply + tin bot + gauge ============ */
.uchip{display:inline-flex;align-items:center;gap:5px;font:600 10.5px var(--mono);color:#aab4d8;
  background:rgba(10,13,22,.45);border:1px solid rgba(140,158,255,.22);border-radius:7px;padding:3px 8px}
.uchip b{color:#fff;font-weight:700}
.beat{display:inline-flex;opacity:.9}
.nwWhy{font:400 12.5px/1.55 var(--sans);color:#c9b9f5;margin-top:3px}
.nwAgo{font:400 11.5px var(--sans);color:var(--tx3);margin-top:4px}

/* TIMELINE reply (concept mới 07/08 — thay bubble messenger): mỗi lượt = 1 khối dọc */
.trn{margin:0 0 18px;min-width:0}
.trnP{border-left:3px solid var(--pri);background:rgba(109,141,255,.09);border-radius:0 13px 13px 0;
  padding:10px 13px;font:600 14px/1.6 var(--sans);color:#dbe4ff;white-space:pre-wrap;word-break:break-word}
.trnMeta{display:flex;gap:10px;align-items:center;font:500 10.5px var(--mono);color:var(--tx3);margin:6px 2px}
.trnMeta .lv{color:#66e5ae;font-weight:700;letter-spacing:.8px}
.trnR{font:400 15px/1.75 var(--sans);color:#e6ebf5;white-space:pre-wrap;word-break:break-word;padding:2px 2px 0}
.trnR.wait{color:var(--tx3)}
.trnHr{border-top:1px solid var(--line);margin:16px 0}
.trnDay{text-align:center;font:600 10px var(--mono);color:var(--tx3);margin:14px 0 10px}
.trnDay span{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:3px 11px}

/* gauge tròn nhỏ (Phân tích — 5H/Tuần/Fable kiểu Coding Space) */
.gaugeRow{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.gg{background:linear-gradient(180deg,var(--card2),var(--card));border:1px solid var(--line);
  border-radius:14px;padding:12px 8px;display:flex;flex-direction:column;align-items:center;gap:6px}
.gg .gr{position:relative;width:74px;height:74px}
.gg .gr svg{width:74px;height:74px}
.gg .gt{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font:700 16px var(--mono)}
.gg em{font:600 10px var(--sans);font-style:normal;letter-spacing:1.2px;color:var(--tx3);text-transform:uppercase}
.gg .gs{font:500 10px var(--mono);color:var(--tx3)}

/* chat hỏi bot doanh nghiệp + sổ sách */
.askBox{display:flex;gap:8px;margin-top:10px}
.askBox input{flex:1;background:rgba(10,13,22,.6);border:1px solid var(--line2);border-radius:11px;padding:9px 12px;font:400 13px var(--sans)}
.askBox input:focus{outline:none;border-color:var(--pri)}
.askAns{background:var(--card2);border:1px solid var(--line);border-radius:12px;padding:11px 13px;
  font:400 13.5px/1.65 var(--sans);color:#dde3ef;white-space:pre-wrap;margin-top:9px}
.sheetSec{margin-top:10px}
.sheetSec .shd{display:flex;align-items:center;gap:8px;padding:9px 2px;font:600 13px var(--sans);cursor:pointer;border-top:1px solid var(--line)}
.sheetSec pre{background:#0b0e15;border:1px solid var(--line);border-radius:10px;padding:10px;overflow-x:auto;
  font:400 10.5px/1.6 var(--mono);color:#b9c4d8;white-space:pre;max-height:320px;overflow-y:auto}
.kvHours{display:flex;align-items:flex-end;gap:3px;height:84px;margin-top:10px} /* mục 9 (07/08 đêm): cột lùn quá — nâng cao */
.kvHours i{flex:1;background:var(--ok);opacity:.75;border-radius:2px 2px 0 0;min-height:2px}
.kvHours i.now{background:var(--warn);opacity:1}

/* ============ v10 (07/08): thanh fill hạn mức + máy Mac + Kinh doanh dashboard ============ */
.ubars{display:flex;flex-direction:column;gap:8px;margin-top:12px}
.ubar{display:flex;align-items:center;gap:9px;min-width:0}
.ubar .ul{width:46px;flex:none;font:700 9.5px var(--mono);letter-spacing:1px;color:#aab4d8}
.ubar .ub{flex:1;height:7px;border-radius:4px;background:rgba(10,13,22,.55);overflow:hidden;border:1px solid rgba(140,158,255,.14)}
.ubar .ub i{display:block;height:100%;border-radius:4px;transition:width .5s}
.ubar .uv{width:40px;flex:none;text-align:right;font:700 11.5px var(--mono)}
.ubar .us{flex:none;font:500 9.5px var(--mono);color:#8b93ad;width:78px;text-align:right;overflow:hidden;white-space:nowrap}
.ubar.big .ub{height:10px}
.ubar.big .ul{width:56px;font-size:10.5px}
.ubar.big .uv{font-size:13px;width:46px}
.macGrid{display:grid;grid-template-columns:1fr 1fr;gap:12px 16px}
.mcell{min-width:0}
.mcell .mcT{display:flex;align-items:center;gap:8px;margin-bottom:5px}
.mcell .mcT em{font:500 10.5px var(--sans);font-style:normal;color:var(--tx3)}
.mcell b{font:600 14.5px var(--mono)}
.mcBar{height:5px;border-radius:3px;background:rgba(148,163,199,.12);overflow:hidden;margin-top:5px}
.mcBar i{display:block;height:100%;border-radius:3px}
/* ring to cho dashboard Kinh doanh */
.ringBig{position:relative;width:104px;height:104px;flex:none}
.ringBig svg{width:104px;height:104px}
.ringBig .rt{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.ringBig .rt b{font:700 19px var(--mono)}
.ringBig .rt i{font:600 8.5px var(--sans);font-style:normal;color:var(--tx3);letter-spacing:.8px;text-transform:uppercase;margin-top:2px;text-align:center}
/* hàng mở chat messenger */
.chatRow{display:flex;align-items:center;gap:11px;padding:12px 2px;cursor:pointer}
.chatRow:active{opacity:.6}
.chatRow .cc{flex:1;min-width:0}
.chatRow .ct{font:600 13.5px var(--sans)}
.chatRow .cs{font:400 11.5px var(--sans);color:var(--tx3);margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ============ v11 (07/08): tin có ảnh + biz 2 DN trong Phân tích ============ */
.nRow{display:flex;gap:12px;align-items:flex-start;min-width:0}
.nBody{flex:1;min-width:0}
/* ---- LỊCH SỬ: gom theo project, bấm tên là xổ ra / thu lại (Khang 10/08) ---- */
.hsHead{cursor:pointer;-webkit-tap-highlight-color:transparent}
.hsHead:active{opacity:.72}
.hsChev{margin-left:auto;color:var(--tx3);display:flex;transition:transform .18s}
.hsChev.on{transform:rotate(180deg);color:var(--pri2)}
.hsRows.off{display:none}
/* thanh dưới sheet lịch sử: 2 lối đi tiếp cho phiên đã đóng */
.hsFoot{display:flex;gap:8px;padding:10px 14px calc(10px + var(--sab));
  background:rgba(15,18,27,.97);border-top:1px solid var(--line)}
.hsBtn{flex:1;height:42px;border-radius:12px;background:var(--card2);border:1px solid var(--line2);
  color:var(--tx);font:600 14px var(--sans);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0 12px}
.hsBtn.pri{background:var(--pri);border-color:transparent;color:#fff}
.hsBtn:active{opacity:.75}

/* ---- THẺ TIN KIỂU VNEXPRESS (Khang 10/08: "cho giống VnExpress bố trí, card to hơn")
   Ảnh full-width 16:9 nằm TRÊN, tiêu đề to đậm, tóm tắt, rồi dòng nguồn/giờ.
   Cỡ chữ đo theo app VnExpress: tít 18.5px/1.3 · tóm tắt 14.5px/1.5 · meta 11.5px. ---- */
.nvWrap{display:flex;flex-direction:column;gap:12px}
.nvx{background:linear-gradient(180deg,var(--card2),var(--card));border:1px solid var(--line);
  border-radius:16px;padding:0 0 13px;overflow:hidden}
.nvImg{display:block;margin-bottom:11px}
.nvx .nThumb{width:100%;aspect-ratio:16/9;height:auto;border:none;border-radius:0;display:block;
  object-fit:cover;background:var(--card2)}
.nvTt{display:block;padding:0 14px;font:700 18.5px/1.3 var(--sans);color:var(--tx);letter-spacing:-.2px}
.nvDesc{padding:0 14px;margin-top:7px;font:400 14.5px/1.5 var(--sans);color:var(--tx2);
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.nvWhy{padding:0 14px;margin-top:7px;font:400 14.5px/1.5 var(--sans);color:#c9b9f5}
.nvMeta{padding:0 14px;margin-top:10px;font:500 11.5px var(--mono);color:var(--tx3)}
/* thẻ không có ảnh: chừa đệm trên cho cân */
.nvx > .nvTt:first-child{padding-top:14px}

.nThumb{width:76px;height:76px;border-radius:11px;object-fit:cover;flex:none;background:var(--card2);border:1px solid var(--line)}
.nDesc{font:400 12px/1.55 var(--sans);color:var(--tx2);margin-top:3px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* ============ v12 (07/08): messenger avatar + swipe back + tin chữ to ============ */
.mRow{display:flex;gap:8px;margin:5px 0;min-width:0;align-items:flex-end}
.mRow.u{justify-content:flex-end}
.mAva{width:28px;height:28px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line2);background:var(--card2)}
.mAva.mK{background:var(--grad);color:#fff;font:700 12px var(--sans)}
.mAva.mCli{background:#1b1d21;border-color:#33363d}
.mBub{max-width:82%;border-radius:16px;padding:9px 13px;font:400 15px/1.7 var(--sans);
  white-space:pre-wrap;word-break:break-word;min-width:0}
.mBub.u{background:linear-gradient(135deg,#4e6ee3,#6a55d8);color:#fff;border-bottom-right-radius:5px;font-weight:500}
.mBub.a{background:var(--card2);border:1px solid var(--line);color:#eef2f8;border-bottom-left-radius:5px}
.mBub.a.wait{color:var(--tx3)}
/* tin tức chữ to (mục 4 — CHỈ tab Tin tức) */
.nRow .nBody a{font:600 15.5px/1.5 var(--sans)}
.nRow .nDesc{font-size:13px}
.nRow .nwWhy{font-size:13.5px}

/* ============ v13: BẢN WEB (Vercel) — cổng PIN + băng bản chụp ============ */
#pinGate{position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;
  background:radial-gradient(120% 90% at 50% 0%,#141a2b,#080a10 70%);padding:24px}
.pgBox{width:100%;max-width:320px;text-align:center}
.pgTitle{font:800 30px var(--sans);letter-spacing:-.5px;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.pgSub{font:400 13px var(--sans);color:var(--tx2);margin:6px 0 20px}
#pgIn{width:100%;box-sizing:border-box;padding:14px 16px;border-radius:14px;border:1px solid var(--line2);
  background:var(--card);color:var(--tx);font:600 18px var(--mono);text-align:center;letter-spacing:6px;outline:none}
#pgIn:focus{border-color:var(--pri)}
#pgGo{width:100%;margin-top:11px;padding:13px;border:none;border-radius:14px;background:var(--grad);
  color:#fff;font:700 14px var(--sans);cursor:pointer}
#pgGo:active{opacity:.8}
.pgErr{min-height:18px;margin-top:10px;font:500 12px var(--sans);color:var(--warn)}

/* ============ v13 (07/08 tối): NÃO PHIÊN kiểu iMessage/Messenger ============ */
/* đầu não dính nóc: trạng thái mịn + đồng hồ lượt + token đang đốt + token project */
/* ⚠ ĐỪNG ĐỘNG VÀO top/padding của khối này (09/08 khuya trả về đúng nguyên bản): đổi
   `top` hay đệm là dải rời khỏi mép, hở khe cho chat chạy phía sau ("lọt hố" — Khang bắt).
   Muốn cân trên/dưới thì chỉnh đệm của dải CON `.bh3`, không đụng khung ngoài này. */
#bHead{position:sticky;top:-14px;z-index:6;margin:-14px -16px 12px;padding:10px 16px 9px;
  background:rgba(10,12,18,.97);/* bỏ blur 09/08 khuya — #bHead trượt cùng sheet, re-blur mỗi khung hình là tụt FPS */
  border-bottom:1px solid var(--line)}
.bHead{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.stChip{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;
  font:700 10px var(--mono);letter-spacing:.9px;color:var(--c);background:color-mix(in srgb,var(--c) 15%,transparent);
  border:1px solid color-mix(in srgb,var(--c) 34%,transparent)}
.stChip i{width:6px;height:6px;border-radius:50%;background:var(--c);flex:none;animation:stp 1.8s ease-in-out infinite}
@keyframes stp{0%,100%{opacity:1}50%{opacity:.32}}
.bkv{display:flex;flex-direction:column;gap:1px;padding:2px 9px;border-radius:9px;background:var(--card);border:1px solid var(--line);min-width:0}
.bkv em{font:600 8.5px var(--sans);font-style:normal;letter-spacing:.7px;text-transform:uppercase;color:var(--tx3);white-space:nowrap}
.bkv b{font:700 12.5px var(--mono);color:var(--tx)}
.bkv.hot b{color:#ffbe3d}
/* dòng "N agent đang chạy" (07/08 đêm — thay pill thợ phụ bấm được) */
.subLine{display:flex;flex-wrap:wrap;gap:5px;align-items:center;margin:0 0 10px;
  font:400 12px var(--sans);color:var(--tx2)}
.subLine svg{color:var(--pri2);flex:none}
.subLine b{font-weight:600;color:var(--tx2)}
.subLine i{font-style:normal;color:var(--tx3)}
/* nhiều bong bóng 1 lượt: tin giữa = vừa-nói-vừa-làm (dịu), tin cuối = trả lời chốt */
.mAva.mGap{background:none;border:none;visibility:hidden}
/* SÁNG HƠN (Khang 10/08: "chữ bubble reply hơi tối") — vẫn giữ khoảng cách nhìn
   thấy giữa 2 loại: tin giữa lượt #d5dceb · câu chốt #f4f7fc. Đừng kéo nar về sát fin. */
.mBub.a.nar{background:rgba(148,163,199,.07);border-color:rgba(148,163,199,.16);color:#d5dceb;font-size:16px}
.mBub.a.fin{background:var(--card2);border-color:var(--line2);color:#f4f7fc}
.mTag{display:block;font:700 8.5px var(--sans);letter-spacing:1px;text-transform:uppercase;color:var(--tx3);margin-bottom:4px}
/* bong bóng PLAN trong dòng chat (Khang 08/08: "plans phải hiện ngay trong reply, đọc được hết") */
.mBub.a.plnB{background:rgba(109,141,255,.09);border-color:rgba(109,141,255,.26);max-width:88%;color:#dfe5f2}
.plnH{display:flex;gap:7px;align-items:center;font:700 11px var(--sans);color:#9db4ff;margin-bottom:7px}
.plnH .pn{margin-left:auto;font:600 10.5px var(--mono);color:var(--tx3)}
.plnH .ichip{width:22px;height:22px;border-radius:7px}
.plnI{display:flex;gap:9px;align-items:flex-start;padding:3.5px 0;font:400 13.5px/1.55 var(--sans)}
.plnI.done{color:var(--tx3)}
.plnI.done span:last-child{text-decoration:line-through}
.plnI.run{color:#ffd98a;font-weight:500}
.plnI .pbx{width:15px;height:15px;border-radius:5px;border:1.5px solid var(--line2);flex:none;margin-top:2.5px;display:flex;align-items:center;justify-content:center;color:#7ee2b8}
.plnI.done .pbx{background:rgba(61,220,151,.14);border-color:rgba(61,220,151,.4)}
.plnI.run .pbx{border-color:#ffd98a}
/* bong bóng THOUGHT — hiện tức thì trên dấu đang gõ */
.mBub.a.thB{background:rgba(157,123,255,.10);border-color:rgba(157,123,255,.26);color:#cfc3f2;font-size:15px;font-style:italic}
/* THOUGHTS = LỆNH đang chạy, bấm để xổ full lệnh của lượt đó (Khang 11/08).
   Tên tool là mã máy nên để MONO, phần mô tả để sans cho dễ đọc. */
.mBub.a.thB{cursor:pointer;-webkit-tap-highlight-color:transparent}
/* ⛔ THOUGHTS PHẢI CAO CỐ ĐỊNH 1 DÒNG — đây là GỐC vụ "reply giật lên giật xuống khi đang
   type" (Khang 11/08). Bong bóng này nằm TRƯỚC các reply trong cùng lượt và nội dung đổi
   mỗi nhịp poll; câu dài thì wrap 3 dòng, câu ngắn 1 dòng ⇒ chiều cao nhảy ⇒ đẩy toàn bộ
   reply bên dưới lên/xuống, cộng thêm autoscroll ép về đáy là thành giật.
   Khoá 1 dòng + ellipsis: nội dung đổi bao nhiêu lần thì chiều cao vẫn y nguyên.
   Chỉ khi Khang CHỦ ĐỘNG bấm xổ (.op) mới cho xuống dòng. */
.mBub.a.thB .thNow{font-style:normal;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mBub.a.thB.op .thNow{white-space:normal;overflow:visible}
/* ~~chip đếm số lệnh .thCnt~~ — Khang bỏ 11/08 ("click vào đã có thời gian làm việc rồi") */
.mBub.a.thB.op{background:rgba(157,123,255,.14)}
/* Xổ full: KHÔNG giới hạn chiều cao, KHÔNG cắt chữ — bong bóng dài ra thoải mái
   (Khang 11/08: "nó không hiển thị được full text của 1 thought, ép nó hiển thị full,
   cần thì làm bubble dài ra"). ~~max-height 46vh + overflow-y~~ đã bỏ. */
.thList{margin-top:8px;padding-top:8px;border-top:1px solid rgba(157,123,255,.2);
  display:flex;flex-direction:column;gap:9px}
/* ⛔ MỘT DÒNG LỆNH PHẢI BIẾT XUỐNG HÀNG (Khang 11/08: "thoughts chèn layout").
   Gốc bệnh: `b` (tên lệnh) để `flex:none` nên KHÔNG BAO GIỜ co — gặp tên dài
   `mcp__mcp-gsheets__sheets_batch_get_values` là nó ăn hết bề ngang, cột mô tả `span`
   (flex:1 + min-width:0) bị ép còn ~10px, mà `overflow-wrap:anywhere` thì chữ rơi
   xuống MỖI DÒNG 1 KÝ TỰ ⇒ dải chữ dựng đứng cao 400px giữa bong bóng (đo thật).
   Chữa: cho cả hàng `flex-wrap`, mô tả có bề rộng tối thiểu 130px — không đủ chỗ thì
   nó tự tụt xuống dòng dưới và ăn trọn bề ngang, KHÔNG cắt chữ nào. */
.thIt{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 7px;font-style:normal;font-size:12.5px;line-height:1.45}
.thIt b{flex:0 1 auto;min-width:0;font:600 11.5px var(--mono);color:#c9b6ff;overflow-wrap:anywhere}
.thIt span{flex:1 1 130px;min-width:0;color:var(--tx2);overflow-wrap:anywhere;white-space:pre-wrap}
.thIt i{flex:none;margin-left:auto;font:500 10.5px var(--mono);font-style:normal;color:var(--tx3)}
.mBub{transition:background .18s ease}

/* ============ v14 (07/08 đêm) — 10 góp ý Khang ============ */
/* CARD WORK PULSE remake (mục 7): phẳng, hairline, thẳng hàng, label rõ nghĩa */
.hb2Top{display:flex;align-items:baseline;justify-content:space-between}
.hb2Tt{font:600 12px var(--sans);letter-spacing:.4px;color:var(--tx2);text-transform:uppercase}
.hb2Clk{font:500 12px var(--sans);color:var(--tx-hero)}
.hb2Num{margin:10px 0 2px}
.hb2Num b{font:700 30px/1.1 var(--sans);letter-spacing:-.4px;color:#f2f5fb}
.hb2Meta{display:flex;flex-wrap:wrap;gap:2px 10px;margin-top:3px;font:400 12px var(--sans);color:var(--tx2)}
.hb2Meta .mut{color:var(--tx-hero)}
.hb2Bars{margin-top:12px;padding-top:11px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:8px}
.hb2{display:grid;grid-template-columns:44px 1fr 40px auto;gap:9px;align-items:center;min-width:0}
.hb2l{font:600 11px var(--sans);color:var(--tx2);white-space:nowrap}
.hb2t{height:5px;border-radius:3px;background:rgba(148,163,199,.13);overflow:hidden;min-width:0}
.hb2t i{display:block;height:100%;border-radius:3px;transition:width .5s}
.hb2v{font:600 11.5px var(--sans);font-variant-numeric:tabular-nums;text-align:right;color:#e8edf6}
.hb2s{font:400 10.5px var(--sans);color:var(--tx-hero);white-space:nowrap;text-align:right;min-width:82px}
/* mục 7 (09/08): thanh token THEO PROJECT hôm nay — project đang chạy có chấm xanh nhấp */
.hb2Pj{margin-top:12px;padding-top:11px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:7px}
.pjB{display:grid;grid-template-columns:100px 1fr 48px;gap:9px;align-items:center;min-width:0}
.pjB em{font:600 11px var(--sans);font-style:normal;color:var(--tx2);display:flex;align-items:center;gap:5px;
  white-space:nowrap;overflow:hidden;min-width:0}
.pjB em span{min-width:0;overflow:hidden;text-overflow:ellipsis}/* tên dài cắt bằng … thay vì cụt lủn */
.pjB em .pjLive{flex:none;width:6px;height:6px;border-radius:50%;background:#3ddc97;text-decoration:none;
  animation:pjPulse 1.4s ease-in-out infinite}
.pjTr{height:5px;border-radius:3px;background:rgba(148,163,199,.13);overflow:hidden;min-width:0}
.pjTr i{display:block;height:100%;border-radius:3px;transition:width .5s}
.pjB b{font:600 11.5px var(--sans);font-variant-numeric:tabular-nums;text-align:right;color:#e8edf6}
@keyframes pjPulse{0%,100%{opacity:1}50%{opacity:.3}}
.hb2Chips{display:grid;grid-template-columns:repeat(4,1fr);margin-top:12px;padding-top:11px;border-top:1px solid var(--line)}
.hcp{background:none;border:none;padding:2px 0;text-align:center;cursor:pointer;border-radius:8px}
.hcp:active{background:rgba(148,163,199,.09)}
.hcp b{display:block;font:700 17px var(--sans);font-variant-numeric:tabular-nums;color:#eef2f8}
.hcp i{display:block;margin-top:2px;font:400 10px var(--sans);font-style:normal;color:var(--tx-hero)}
/* nút tải lại Tin tức (mục 1) */
.reloadB{background:var(--card);border:1px solid var(--line);border-radius:50%;width:34px;height:34px;
  display:flex;align-items:center;justify-content:center;color:var(--tx2);margin-right:9px;cursor:pointer;flex:none;align-self:center}
.reloadB:active{opacity:.6}
.reloadB.spin svg{animation:rl 1s linear infinite}
@keyframes rl{to{transform:rotate(360deg)}}
/* lịch sử phiên làm lại (mục 9) */
.hDay{font:600 10.5px var(--sans);letter-spacing:1px;text-transform:uppercase;color:var(--tx3);margin:14px 2px 7px}
.h2r{display:flex;gap:10px;align-items:flex-start;padding:10px 2px;border-bottom:1px solid var(--line);cursor:pointer;min-width:0}
.card .h2r:last-child{border-bottom:none}
.h2r:active{opacity:.6}
.h2d{width:8px;height:8px;border-radius:50%;flex:none;margin-top:5px}
.h2c{flex:1;min-width:0}
.h2t{display:flex;align-items:baseline;gap:7px;min-width:0}
.h2t b{font:600 13px var(--sans);color:var(--tx)}
.h2tm{margin-left:auto;font:500 11px var(--mono);color:var(--tx3);flex:none}
.h2s{font:400 12px/1.5 var(--sans);color:var(--tx2);margin-top:2px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.h2n{font:500 10px var(--mono);color:var(--tx3);flex:none;margin-top:4px}
/* số tiền kinh doanh = font thường, không đ (mục 6) */
#scr-biz .num,.bizFont .num,#qBiz .num{font-family:var(--sans);letter-spacing:.2px}
#scr-biz .dv,.bizFont .dv{font-family:var(--sans);color:#dde5f2}
.bnum .big{font-family:var(--sans);letter-spacing:.2px;color:#f2f5fb}

/* ============ v16 (08/08) — đợt góp ý 4 ============ */
/* mục 2: khoá zoom — pan được 2 chiều nhưng cấm pinch-zoom; chữ không tự phóng */
html{touch-action:pan-x pan-y;-webkit-text-size-adjust:100%}
/* mục 1: ô KPI bấm được */
.kx.tap{cursor:pointer}
.kx.tap:active{opacity:.6}
/* mục 3: avatar SVG theo Ý NGHĨA project (thay 2 chữ cái) */
.mlAva svg{width:21px;height:21px;filter:drop-shadow(0 1.5px 2px rgba(0,0,0,.4))}
/* (mục 4 sửa THẲNG vào định nghĩa gốc .phSt/.mlSt bên dưới — override đặt ở đây
   bị khối sau đè ngược, đó là lý do Khang kêu 2 lần mà chip không đổi) */

/* ============ v15 (07/08 đêm) — đợt góp ý 3 ============ */
/* mục 1: title sheet căn giữa TUYỆT ĐỐI (trước lệch vì nút trái/phải không bằng nhau).
   dtitle rời khỏi flow → dact PHẢI tự neo phải, không là trôi sang cạnh nút back. */
.dhead{position:relative}
.dtitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);max-width:50%;text-align:center;pointer-events:none}
.dact{margin-left:auto;position:relative;z-index:2}
/* mục 4: đầu não CSS RIÊNG của Pulse — pill mềm, không mono terminal */
.phRow{display:flex;align-items:stretch;gap:7px;flex-wrap:wrap;min-width:0}
/* chip trạng thái concept PULSE (Khang 08/08, kêu lần 3 mới ăn — trước bị override
   sai chỗ đè ngược): pill tròn hẳn, chữ thường sentence-case, không giãn chữ kiểu LITE */
.phSt{display:inline-flex;align-items:center;gap:7px;padding:6px 13px;border-radius:999px;
  font:600 12px var(--sans);letter-spacing:0;text-transform:none;color:var(--c);
  background:color-mix(in srgb,var(--c) 12%,transparent);border:1px solid color-mix(in srgb,var(--c) 26%,transparent)}
.phSt i{width:6px;height:6px;border-radius:50%;background:var(--c);animation:stp 1.8s ease-in-out infinite}
.phC{display:flex;flex-direction:column;justify-content:center;gap:1px;padding:4px 12px;border-radius:12px;
  background:rgba(148,163,199,.08);min-width:0}
.phC em{font:500 9.5px var(--sans);font-style:normal;color:var(--tx3);white-space:nowrap}
.phC b{font:700 13px var(--sans);font-variant-numeric:tabular-nums;color:#eef2f8}
.phC.hot b{color:#ffca6a}
.phThink{display:flex;gap:8px;align-items:flex-start;margin-top:8px;padding:8px 11px;border-radius:12px;
  background:rgba(157,123,255,.09);border:1px solid rgba(157,123,255,.2)}
.phThink span{font:400 12.5px/1.55 var(--sans);color:#cfc3f2;min-width:0;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.phThink.dim span{color:var(--tx3)}
.phThink .ichip{width:24px;height:24px;border-radius:8px;flex:none}
/* mục 4a+7: tab Phiên = danh sách hội thoại kiểu Messenger */
.mlRow{display:flex;gap:11px;padding:12px 2px;border-bottom:1px solid var(--line);cursor:pointer;min-width:0;align-items:flex-start}
.card .mlRow:last-child{border-bottom:none}
.mlRow:active{opacity:.6}
.mlAva{position:relative;width:46px;height:46px;border-radius:14px;flex:none;display:flex;align-items:center;justify-content:center;color:#fff;
  background:
    radial-gradient(130% 100% at 18% 12%, color-mix(in srgb,var(--pc) 62%, #fff 16%), transparent 52%),
    linear-gradient(155deg, color-mix(in srgb,var(--pc) 96%, #fff 3%) 0%, color-mix(in srgb,var(--pc) 58%, #0a0c12 34%) 100%);
  box-shadow: inset 0 1px 1px rgba(255,255,255,.3), inset 0 -8px 14px rgba(0,0,0,.24),
    0 4px 10px color-mix(in srgb, var(--pc) 26%, transparent);
  border:1px solid color-mix(in srgb, var(--pc) 45%, rgba(255,255,255,.14))}
.mlDot{position:absolute;right:-3px;bottom:-3px;width:13px;height:13px;border-radius:50%;border:2.5px solid var(--bg);box-shadow:0 1px 3px rgba(0,0,0,.4)}
.mlC{flex:1;min-width:0}
.mlT{display:flex;align-items:baseline;gap:8px;min-width:0}
.mlT>b{font:600 14.5px var(--sans);color:var(--tx);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mlTime{margin-left:auto;flex:none;font:500 11.5px var(--sans);font-variant-numeric:tabular-nums;color:var(--tx3)}
.mlTime b{font:600 11.5px var(--sans);color:#7ee2b8}
.mlPrev{font:400 12.5px/1.5 var(--sans);color:var(--tx2);margin-top:2px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.mlTok{display:flex;align-items:baseline;gap:5px;margin-top:4px;font-variant-numeric:tabular-nums;min-width:0}
.mlTok b{font:700 11.5px var(--sans)}
.mlTok i{font:400 10px var(--sans);font-style:normal;color:var(--tx3)}
.mlTok>span{color:var(--tx3);font-size:10px}
.tkNow{color:#ffca6a}
.tkAll{color:#8fb2ff}
.mlSt{margin-left:auto;flex:none;font:600 10.5px var(--sans);letter-spacing:0;text-transform:none}
/* nhánh sub-agent mọc dưới phiên cha */
.mlBranch{display:flex;align-items:center;gap:7px;padding:7px 2px 7px 24px;border-bottom:1px solid var(--line);min-width:0;
  font:400 12px var(--sans);color:var(--tx2)}
.card .mlBranch:last-child{border-bottom:none}
.mlElbow{width:14px;height:14px;flex:none;border-left:1.5px solid var(--line2);border-bottom:1.5px solid var(--line2);
  border-bottom-left-radius:7px;margin-top:-10px}
.mlBDot{width:7px;height:7px;border-radius:50%;flex:none}
.mlBranch b{font-weight:600;color:var(--tx)}
.mlBSt{font:500 10.5px var(--sans)}
.mlBTok{margin-left:auto;font:600 10.5px var(--sans);font-variant-numeric:tabular-nums;color:var(--tx3)}
/* mục 5: nút tải lại NHỎ cuối hàng chip tin tức */
.ntRe{flex:none;width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:var(--card);border:1px solid var(--line);color:var(--tx3);cursor:pointer;margin-left:auto;align-self:center}
.ntRe:active{opacity:.6}
.ntRe.spin svg{animation:rl 1s linear infinite}
/* mục 5b: X — chữ to hơn, cả khối bấm được */
.xItem{display:block;padding:12px 2px;border-bottom:1px solid var(--line);min-width:0}
.card .xItem:last-child{border-bottom:none}
.xItem:active{opacity:.6}
.xTag{display:block;font:700 16px/1.4 var(--sans);color:var(--tx)}
.xRg{display:inline-block;vertical-align:2px;margin-right:8px;padding:2px 8px;border-radius:7px;font:700 10px var(--sans);letter-spacing:.4px}
.xRgVN{background:rgba(61,220,151,.14);color:#5fe0a8;border:1px solid rgba(61,220,151,.3)}
.xRgKR{background:rgba(157,123,255,.14);color:#b79bff;border:1px solid rgba(157,123,255,.3)}
.xRgUS{background:rgba(109,141,255,.14);color:#93aeff;border:1px solid rgba(109,141,255,.3)}
.xSum{display:block;margin-top:3px;font:400 14px/1.65 var(--sans);color:#cfd6e4}
.xGo{display:inline-flex;align-items:center;gap:5px;margin-top:7px;font:600 11.5px var(--sans);color:var(--pri2)}
/* mục 6: tab Dự án — 1 tông màu, sạch */
.pjR{display:flex;gap:10px;padding:11px 2px;border-bottom:1px solid var(--line);cursor:pointer;min-width:0;align-items:flex-start}
.card .pjR:last-child{border-bottom:none}
.pjR:active{opacity:.6}
.pjR>.dot{margin-top:5px}
.pjC{flex:1;min-width:0}
.pjT{display:flex;align-items:baseline;gap:8px;min-width:0}
.pjT>b{font:600 13.5px var(--sans);color:var(--tx)}
.pjTm{margin-left:auto;flex:none;font:400 11px var(--sans);color:var(--tx3)}
.pjS{font:400 12px/1.5 var(--sans);color:var(--tx2);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pjM{font:400 10.5px var(--sans);color:var(--tx3);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pjTok{flex:none;text-align:right;align-self:center}
.pjTok b{display:block;font:700 13px var(--sans);font-variant-numeric:tabular-nums;color:#8fb2ff}
.pjTok i{font:400 9.5px var(--sans);font-style:normal;color:var(--tx3)}

/* ============ v13 (07/08 tối): mail công ty đọc được ============ */
.mailRow{display:flex;gap:10px;align-items:center;cursor:pointer}
.mailRow:active{opacity:.6}
.mailRow .nBody a{font:600 13.5px/1.45 var(--sans)}
.mailHd{font:600 16px/1.45 var(--sans);color:var(--tx)}
.mailMeta{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap;margin-top:5px;font:500 11px var(--mono);color:var(--tx3)}
.mailMeta .mfrom{color:var(--pri2);font:600 12px var(--sans)}
.mailTo{margin-top:4px;font:400 11.5px/1.5 var(--sans);color:var(--tx3);word-break:break-word}
.mailBody{white-space:pre-wrap;word-break:break-word;font:400 14.5px/1.75 var(--sans);color:#e6ebf5;margin:0}

/* ============ 08/08 — THỜI TIẾT + VOICE JARVIS (khối MỚI cuối file — luật: sửa style cũ
   thì sửa thẳng định nghĩa gốc, khối mới thì nằm CUỐI cho thắng specificity) ============ */
.wxCard{display:flex;align-items:center;gap:11px;background:var(--card);border:1px solid var(--line);
  border-radius:16px;padding:11px 13px;margin:0 0 14px;cursor:pointer}
.wxCard .wxIc{color:var(--cy);flex:none}
.wxC{flex:1;min-width:0}
.wxT{font:600 14px var(--sans);display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.wxT b{font-size:17px}
.wxS{font:400 12px var(--sans);color:var(--tx2);margin-top:1px}
.wxStale{font:500 10px var(--sans);color:var(--warn);border:1px solid rgba(240,177,61,.4);
  border-radius:8px;padding:1px 6px}
.wxAdv{flex:none;max-width:34%;font:500 11px var(--sans);color:var(--tx2);text-align:right;line-height:1.35}
.wxBig{display:flex;align-items:center;gap:14px}
.wxBig .wxIc{color:var(--cy)}
.wxAdvBig{margin-top:10px;font:500 13px var(--sans);color:var(--tx);background:rgba(56,200,221,.08);
  border:1px solid rgba(56,200,221,.25);border-radius:10px;padding:8px 10px}
.wxHours{display:flex;gap:4px;overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:2px}
.wxH{flex:none;width:46px;display:flex;flex-direction:column;align-items:center;gap:4px;color:var(--tx2)}
.wxH em{font:500 10.5px var(--sans);font-style:normal}
.wxH b{font:600 12.5px var(--mono);color:var(--tx)}
.wxH i{font:500 10px var(--sans);font-style:normal;color:var(--cy);min-height:12px}

/* ---- sheet JARVIS ---- */
.vHead{text-align:center;padding:6px 0 14px;border-bottom:1px solid var(--line);margin-bottom:12px}
.vOrb{display:block;width:52px;height:52px;border-radius:50%;margin:4px auto 10px;
  background:radial-gradient(circle at 35% 30%, #8fa8ff, #5b7cfe 55%, #2a3a8f);
  box-shadow:0 0 22px rgba(109,141,255,.45);transition:box-shadow .3s}
.vOrb.listen{animation:vPulse 1.1s ease-in-out infinite;box-shadow:0 0 30px rgba(61,220,151,.65);
  background:radial-gradient(circle at 35% 30%, #7fe8bc, #3ddc97 55%, #167a52)}
.vOrb.think{animation:vSpin 1.6s linear infinite;box-shadow:0 0 26px rgba(157,123,255,.6);
  background:conic-gradient(from 0deg, #9d7bff, #6d8dff, #38c8dd, #9d7bff)}
.vOrb.speak{animation:vPulse .55s ease-in-out infinite;box-shadow:0 0 30px rgba(56,200,221,.65);
  background:radial-gradient(circle at 35% 30%, #7fdcec, #38c8dd 55%, #146675)}
@keyframes vPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.12)}}
@keyframes vSpin{to{transform:rotate(360deg)}}
.vHT{font:700 15px var(--sans)}
.vHS{font:400 12px var(--sans);color:var(--tx2);margin-top:3px;padding:0 14px}
.vSpk{margin-top:8px;font:500 11.5px var(--sans);color:var(--tx2);border:1px solid var(--line2);
  border-radius:12px;padding:3px 10px}
.vFoot{flex:none;display:flex;gap:8px;align-items:center;padding:10px 12px calc(10px + var(--sab));
  border-top:1px solid var(--line);background:var(--bg2)}
.vFoot input{flex:1;background:rgba(10,13,22,.6);border:1px solid var(--line2);border-radius:20px;
  padding:9px 14px;font-size:14px;outline:none;min-width:0}
.vMic{flex:none;width:46px;height:46px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:var(--grad);color:#fff;box-shadow:0 3px 12px rgba(109,141,255,.35)}
.vMic.on{background:linear-gradient(135deg,#f26d7a,#c2385a);animation:vPulse 1.1s ease-in-out infinite;
  box-shadow:0 0 18px rgba(242,109,122,.55)}

/* ---- 08/08 tối: REMAKE màn talking Jarvis + nhắn VS Code kèm ảnh ---- */
.vBody{display:flex;flex-direction:column}
.vStage{flex:none;display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:34px 16px 20px;text-align:center}
.vOrb2{position:relative;display:block;width:116px;height:116px;border-radius:50%;margin-bottom:16px;
  background:radial-gradient(circle at 35% 30%, #9db1ff, #5b7cfe 52%, #1d2b6e);
  box-shadow:0 0 34px rgba(109,141,255,.4), inset 0 -8px 22px rgba(10,13,25,.5);
  transition:box-shadow .4s, background .4s}
.vOrb2 i{content:'';position:absolute;inset:-10px;border-radius:50%;border:1.5px solid rgba(141,168,255,.35);
  animation:vRing 2.6s ease-out infinite}
.vOrb2 i:nth-child(2){inset:-22px;border-color:rgba(141,168,255,.16);animation-delay:1.3s}
.vOrb2 b{position:absolute;inset:26%;border-radius:50%;background:radial-gradient(circle at 40% 35%, rgba(255,255,255,.75), rgba(255,255,255,.06) 60%);
  filter:blur(1px)}
@keyframes vRing{0%{transform:scale(.92);opacity:.9}100%{transform:scale(1.22);opacity:0}}
.vOrb2.listen{background:radial-gradient(circle at 35% 30%, #8ff0c6, #3ddc97 52%, #0f5c3d);
  box-shadow:0 0 40px rgba(61,220,151,.55), inset 0 -8px 22px rgba(8,20,14,.5)}
.vOrb2.listen i{border-color:rgba(61,220,151,.45);animation-duration:1.1s}
.vOrb2.listen i:nth-child(2){animation-delay:.55s}
.vOrb2.think{background:conic-gradient(from 0deg, #9d7bff, #6d8dff, #38c8dd, #9d7bff);
  animation:vSpin 1.5s linear infinite;box-shadow:0 0 34px rgba(157,123,255,.5)}
.vOrb2.think b{display:none}
.vOrb2.speak{background:radial-gradient(circle at 35% 30%, #8fe2f2, #38c8dd 52%, #0d4a57);
  box-shadow:0 0 40px rgba(56,200,221,.6), inset 0 -8px 22px rgba(8,18,22,.5)}
.vOrb2.speak i{border-color:rgba(56,200,221,.5);animation-duration:.9s}
.vOrb2.speak i:nth-child(2){animation-delay:.45s}
.vState{font:500 13px var(--sans);color:var(--tx2);min-height:18px;padding:0 18px}
#vChat{padding:0 2px 12px}
.mBub.a.vErr{background:rgba(242,109,122,.12);border:1px solid rgba(242,109,122,.4);color:var(--tx)}
.vFoot2{flex:none;display:flex;align-items:center;justify-content:center;gap:26px;
  padding:10px 12px calc(12px + var(--sab));border-top:1px solid var(--line);background:var(--bg2)}
.vSide{width:44px;height:44px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  color:var(--tx2);border:1px solid var(--line2);background:var(--card)}
.vSide.off{opacity:.45}
.vMic2{width:66px;height:66px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:var(--grad);color:#fff;box-shadow:0 4px 18px rgba(109,141,255,.4)}
.vMic2.on{background:linear-gradient(135deg,#f26d7a,#c2385a);animation:vPulse 1.1s ease-in-out infinite;
  box-shadow:0 0 22px rgba(242,109,122,.55)}
.vTypeRow{flex:none;display:flex;gap:8px;padding:10px 12px 4px;background:var(--bg2);border-top:1px solid var(--line)}
.vTypeRow input{flex:1;background:rgba(10,13,22,.6);border:1px solid var(--line2);border-radius:20px;
  padding:9px 14px;font-size:14px;outline:none;min-width:0}
.attB{flex:none;width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  color:var(--tx2);border:1px solid var(--line2)}
.attRow{display:flex;gap:8px;padding:8px 12px 0;background:var(--bg2)}
.attChip{position:relative;width:46px;height:46px;border-radius:10px;overflow:hidden;border:1px solid var(--line2)}
.attChip img{width:100%;height:100%;object-fit:cover;display:block}
/* ĐỒNG HỒ vs GIỜ — 2 màu tách bạch (Khang 10/08: "đọc còn không hiểu và rối") */
/* MỌI SỐ Ở CARD DÙNG CHUNG MỘT HỆ (Khang 11/08: "size token không đều gì cả, nhìn rối
   lắm, font số không đẹp"). ĐO ra 3 cỡ + 2 font lẫn lộn: 11px mono, 11.5px mono, 13px sans.
   Chốt: sans hết, số 13px, nhãn phụ 11.5px, tabular-nums để số không nhảy bề rộng. */
.tRecv{color:var(--tx3);font:500 11.5px var(--sans)}
/* ~~.subChip "N subagents"~~ — Khang BỎ HẲN 11/08 (card subagent bên dưới đã nói đủ).
   Đã gỡ cả markup lẫn CSS; đừng dựng lại. */
/* (10/08 tối Khang: bỏ dot tròn; khuya: BỎ CAM — timer màu accent dịu --pri2) */
.tRun{color:var(--pri2)!important;font-weight:600}
/* timer cạnh tên hội thoại: CÙNG font + cỡ với tên, không nhô lên tụt xuống (Khang) */
.cvT .tRun{font-family:var(--sans);font-size:14px;font-weight:600}
.tDone{color:#9fb3c8;font:600 12.5px var(--sans);font-variant-numeric:tabular-nums}
.cvTime{display:inline-flex;align-items:center;gap:7px;flex-wrap:wrap}
/* hội thoại ĐANG CHẠY sáng hơn card done (Khang chốt: CHỈ nền sáng, KHÔNG vạch màu trái;
   10/08 khuya hạ từ --cardHi xuống --card2 — "sáng quá, lấn cả title project").
   Nền phải ĐỤC — nền trong là nút Archive đỏ sau lưng lộ xuyên qua (bẫy opacity 09/08). */
.convRow.live{background:var(--card2)}
/* chi tiết món của 1 hoá đơn (bấm hàng là xổ) + nút Xem thêm đơn — Khang 10/08 */
.ivDet{margin-top:7px;padding-top:7px;border-top:1px dashed var(--line2);display:flex;flex-direction:column;gap:4px}
.ivDl{display:flex;gap:10px;align-items:baseline;font:400 13px var(--sans);color:var(--tx2)}
.ivDl span{flex:1;min-width:0}
.ivDl b{font-size:12.5px;color:var(--tx)}
.ivMore{display:block;width:100%;margin-top:8px;padding:10px;border-radius:12px;
  background:rgba(148,163,199,.08);border:1px solid var(--line);color:var(--pri2);
  font:600 13.5px var(--sans)}
.ivMore:active{opacity:.7}
/* ô CHỜ trong lúc nén ảnh (ảnh iPhone 12-48MP mất 1-3s/tấm) */
.attChip.attWait{display:flex;align-items:center;justify-content:center;background:rgba(148,163,199,.10)}
.attSpin{width:16px;height:16px;border-radius:50%;border:2px solid rgba(148,163,199,.30);
  border-top-color:var(--pri2);animation:attsp .7s linear infinite}
/* 12/08 — thumbnail hiện NGAY từ file gốc (objectURL), nén xong mới thay: chip ĐÃ đứng
   sẵn đúng chỗ, chỉ mờ đi + vòng xoay đè lên nên hàng ảnh không nhảy. `b.attSpin` (không
   phải `i`) để khỏi dính luật `.attChip i` của nút x. */
.attChip.attBusy img{opacity:.42}
.attChip b.attSpin{position:absolute;left:50%;top:50%;margin:-8px 0 0 -8px;display:block}
@keyframes attsp{to{transform:rotate(360deg)}}
.attChip i{position:absolute;top:1px;right:1px;width:16px;height:16px;border-radius:50%;background:rgba(10,12,18,.85);
  color:#fff;font:700 10px/16px var(--sans);font-style:normal;text-align:center}

/* 08/08 khuya — Jarvis TEXT-ONLY: stage thu nhỏ (voice đã gỡ theo lệnh Khang) */
.vStage.vMini{padding:20px 16px 12px}
.vStage.vMini .vOrb2{width:64px;height:64px;margin-bottom:10px}
.vTypeRow{padding:10px 12px calc(12px + var(--sab))}

/* ============ 08/08 đêm — ĐẠI TU TAB PHIÊN (card RỜI theo project) + composer iMessage
   + header não thoáng. Khối MỚI cuối file cho thắng specificity. ============ */
.sjCard{background:var(--card);border:1px solid var(--line);border-radius:18px;margin-bottom:14px;overflow:hidden}
.sjHead{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--line)}
.sjAva{width:30px;height:30px;border-radius:9px;display:flex;align-items:center;justify-content:center;
  background:var(--pc,#333);color:#fff;flex:none}
.sjT{flex:1;min-width:0;display:flex;flex-direction:column}
/* 09/08 khuya Khang: title + tên hội thoại = BẰNG cỡ chữ trong chat (17px) */
/* tên PROJECT phải SÁNG NHẤT thứ bậc (Khang 10/08 tối: "title tối hơn mục phụ thì kì") */
.sjT b{display:block;font:700 17px var(--sans);color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sjT span{font:400 11.5px var(--sans);color:var(--tx2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sjT .sjOn{font-style:normal;color:var(--ok);font-weight:600}
.sjT .sjTok{display:inline;font:600 12.5px var(--sans);font-variant-numeric:tabular-nums;color:#c3b0f5}
/* ^ display:inline vì .sjT b{display:block} ăn lây. Màu: ~~--tx trắng~~ -> tím nhạt như
   token session (Khang 11/08: "màu text của title chính project token vẫn là màu trắng"). */
/* 10/08 khuya Khang: nút New chat nhỏ lại cho cân với header */
.sjNew{flex:none;display:flex;align-items:center;gap:4px;font:600 10.5px var(--sans);color:var(--pri2);
  border:1px solid rgba(109,141,255,.3);border-radius:10px;padding:3px 8px;background:rgba(109,141,255,.07)}
.convWrap{position:relative;overflow:hidden;border-bottom:1px solid var(--line)}
.convWrap:last-child{border-bottom:none}
/* nền đỏ rộng 160px nhưng chữ nằm gọn trong 96px bên phải (padding-left bù) — kéo lố
   một chút vẫn thấy màu đỏ liền mạch như iOS, không hở mảng trống phía sau hàng */
.convDel{position:absolute;top:0;right:0;bottom:0;width:160px;padding-left:64px;background:linear-gradient(135deg,#f26d7a,#c2385a);
  color:#fff;font:600 12.5px var(--sans);display:flex;align-items:center;justify-content:center}
.convRow{position:relative;display:flex;align-items:flex-start;gap:10px;padding:11px 12px 11px 14px;
  background:var(--card);transition:transform .26s cubic-bezier(.22,.61,.36,1);touch-action:pan-y}
/* đang kéo = KHÔNG transition (có transition là mỗi nhịp ngón tay bị animate trễ -> cảm giác lag) */
.convRow.drag{transition:none;will-change:transform}
/* (09/08 tối — Khang bỏ chấm màu .cvDot trước hàng; trạng thái chuyển vào chip .cvState to hơn) */
.cvC{flex:1;min-width:0}
.cvT{display:flex;align-items:center;gap:6px}
.cvT b{font:600 13.5px var(--sans);color:#dde3f0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.cvEdit{flex:none;width:24px;height:24px;display:flex;align-items:center;justify-content:center;
  color:var(--tx3);border-radius:7px;opacity:.55}
.cvEdit:active,.cvEdit:hover{opacity:1;color:var(--tx2)}
.cvTime{margin-left:auto;flex:none;font:500 11px var(--mono);color:var(--tx3)}
.cvP{font:400 13px var(--sans);color:var(--tx2);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* wrap khi chật (chip "6 subagents" + 2 số token từng cắt cụt chữ "session") */
.cvTok{display:flex;flex-wrap:wrap;row-gap:3px;align-items:center;gap:5px;margin-top:4px;font:500 10.5px var(--sans);color:var(--tx3)}
.cvTok b{font:600 12.5px var(--mono);color:var(--tx2)}
.cvTok i{font-style:normal;white-space:nowrap}
/* STATE to ngay hàng token (mục 8 Khang 09/08 — thay chấm đen): chip màu theo trạng thái,
   đang chạy thì chấm THỞ nhè nhẹ (Khang 09/08 khuya chê vòng lan cvRing — đổi kiểu
   breathing như đèn ghi âm iOS; chỉ opacity+scale nên compositor lo trọn, 0 tốn) */
/* 10/08 khuya Khang: chip state SÁNG QUÁ — pha 45% về --tx2 (đo: 62% vẫn còn rực),
   chấm nhỏ + mờ bớt, nhịp thở 2.4s (bản cũ 1.1s nhấp nháy như báo động) */
.cvState{display:inline-flex;align-items:center;gap:6px;font:600 11px var(--sans);color:color-mix(in srgb,var(--c) 45%,var(--tx2))}
.cvState i{flex:none;width:6px;height:6px;border-radius:50%;background:var(--c);opacity:.6}
.cvState.run i{animation:cvBreath 2.4s ease-in-out infinite alternate}
/* MỘT định nghĩa DUY NHẤT (10/08 khuya: từng có 2 bản, bản rực nằm sau nên đè bản dịu —
   chấm chip state + chấm subCard dùng chung nhịp này) */
@keyframes cvBreath{from{opacity:.3;transform:scale(.85)}to{opacity:.75;transform:scale(1)}}
.cvTokR{margin-left:auto;display:inline-flex;align-items:center;gap:5px}
/* SUBAGENT = CARD NHỎ RIÊNG nằm DƯỚI card hội thoại (Khang 10/08 khuya: "không nằm chung
   card"), line nối kiểu cây. THEME PHẢI LÀ HỆ PULSE (card lớp + border --line + sans +
   accent --pri) — bản đầu cyan/mono bị Khang bắt "nhìn như LITE app". Nền subTree phải
   ĐỤC var(--card) — trong suốt là nút Archive đỏ sau lưng lộ xuyên (bẫy opacity). */
.subTree{position:relative;background:var(--card);padding:2px 14px 12px 34px}
/* ĐƯỜNG NỐI = chữ L BO GÓC, mỗi card tự vẽ nhánh của nó (Khang 11/08: "line 90 độ nhìn
   không ngay ngắn, làm đẹp hơn professional hơn").
   ~~Bản cũ: 1 trục dọc chung (.subTree::before) + nhánh ngang vuông góc~~ — trục đó kết thúc
   lơ lửng ở một con số bottom đoán chừng, không khớp tâm card cuối, nên nhìn gãy và lệch.
   Nay bỏ trục chung: mỗi nhánh là một đường cong liền từ trên bẻ vào tâm card. Card đầu nối
   lên card hội thoại; card sau nối lên TÂM card trước (top -22px) nên các nhánh nối tiếp
   thành một trục liên tục mà không cần đo chiều cao bằng JS. */
.subCard{position:relative;display:flex;align-items:center;gap:8px;width:fit-content;max-width:100%;
  margin-top:8px;padding:6px 12px 6px 10px;background:linear-gradient(180deg,var(--card2),var(--card));
  border:1px solid var(--line);border-radius:10px;font:500 12px var(--sans);color:var(--tx3);
  box-shadow:0 1px 4px rgba(0,0,0,.22)}
.subCard::before{content:'';position:absolute;left:-12px;top:-22px;bottom:50%;width:11px;
  border-left:1.5px solid var(--line2);border-bottom:1.5px solid var(--line2);
  border-bottom-left-radius:9px}
.subCard:first-child::before{top:-10px}
.subCard b{font:600 12.5px var(--sans);color:var(--tx2);white-space:nowrap}
.subCard span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.subCard .scDot{flex:none;width:7px;height:7px;border-radius:50%;background:var(--ok);animation:cvBreath 1.1s ease-in-out infinite alternate}
/* HỆ MÀU NGỮ NGHĨA của hàng hội thoại — 3 vai, 3 màu, KHÔNG trùng nhau, KHÔNG CAM:
     · timer      = --pri2 xanh      (việc đang chạy, số nhảy real-time)
     · this turn  = --vio  tím đậm   (token đang đốt cho lượt này)
     · session    = #c3b0f5 tím NHẠT (tổng tích luỹ)
   ~~session dùng --tx2 xám~~ — Khang 11/08: "đừng dùng màu trắng, dùng màu cùng theme nhưng
   không giống token burn, có thể dùng loại tím khác". Nay cùng họ tím với burn nhưng nhạt
   hơn hẳn: liếc là phân biệt được đâu là số đang đốt, đâu là tổng. */
.cvTokR .tkBurn{color:var(--vio)}
.cvTokR .tkSes{color:#c3b0f5}
/* VAI THỨ 4 — context (12/08). CỐ Ý KHÔNG lấy màu tím họ token: đây không phải tiền mà là
   ĐỘ ĐẦY trí nhớ phiên. Bình thường xám như nhãn (không tranh mắt với 2 số tiền), chỉ đổi
   màu khi tới ngưỡng: 70% = sắp phải dọn · 90% = Claude sắp tự nén và bắt đầu quên đầu đuôi.
   Vàng/đỏ ở đây là BÁO ĐỘNG chứ không phải màu vai, nên không phạm luật "KHÔNG CAM" ở trên. */
.cvTokR .tkCtx{color:var(--tx2)}
.cvTokR .tkCtx.warm{color:var(--warn)}
.cvTokR .tkCtx.hot{color:var(--err)}

/* ---- header não thoáng (thay hàng pill cũ) ---- */
.bh2{display:flex;align-items:center;gap:12px;padding:10px 2px 12px;border-bottom:1px solid var(--line);margin-bottom:10px}
.bhSt{flex:none;display:inline-flex;align-items:center;gap:7px;font:600 10.5px var(--sans);color:var(--c,#8b93ad);
  background:color-mix(in srgb, var(--c,#8b93ad) 12%, transparent);border:1px solid color-mix(in srgb, var(--c,#8b93ad) 30%, transparent);
  border-radius:14px;padding:6px 12px}
.bhSt i{width:7px;height:7px;border-radius:50%;background:var(--c,#8b93ad);box-shadow:0 0 8px var(--c,#8b93ad)}
.bhStats{flex:1;display:flex;justify-content:flex-end}
.bhCell{padding:0 14px;border-left:1px solid var(--line);text-align:right}
.bhCell:first-child{border-left:none}
.bhCell:last-child{padding-right:2px}
.bhCell em{display:block;font:600 7.5px var(--sans);font-style:normal;letter-spacing:1.1px;text-transform:uppercase;color:var(--tx3);margin-bottom:2px}
.bhCell b{font:600 12px var(--mono);color:var(--tx)}
.bhCell.hot b{color:var(--warn)}

/* ---- composer iMessage: hàng ảnh riêng bên trên, textarea tự giãn, nút dính đáy ---- */
.cmpWrap{flex:none;display:flex;flex-direction:column;background:var(--bg2);border-top:1px solid var(--line)}
.cmpWrap .attRow{padding:10px 12px 0;background:none}
.cmpRow{display:flex;align-items:flex-end;gap:8px;padding:10px 12px calc(10px + var(--sab))}
.cmpRow .attB{margin-bottom:2px}
.cmpRow textarea{flex:1;min-width:0;background:rgba(10,13,22,.6);border:1px solid var(--line2);border-radius:18px;
  padding:9px 14px;font:15px/1.4 var(--sans);outline:none;resize:none;max-height:132px;overflow-y:auto;
  -webkit-overflow-scrolling:touch}
.cmpRow .sendB{margin-bottom:2px}

/* 08/08 khuya v2 — Khang chê thanh token TO + text bừa: thu nhỏ dải đầu não, chỉnh nhịp chữ chat */
.bh2{padding:5px 2px 8px;gap:10px;margin-bottom:8px}
.bhSt{font:600 10.5px var(--sans);padding:4px 10px;border-radius:11px;gap:5px}
.bhSt i{width:5.5px;height:5.5px}
.bhCell{padding:0 10px}
.bhCell:last-child{padding-right:0}
.bhCell em{font-size:7.5px;letter-spacing:.9px;margin-bottom:1px}
.bhCell b{font:600 12px var(--mono)}
/* 09/08 — Khang: "cỡ text chat bằng Messenger và iMessage, hiện đang nhỏ hơn tí".
   17px là cỡ chữ thân bài chuẩn iOS (iMessage/Messenger cùng dùng), nhịp dòng 1.35 ≈ 23px. */
.mBub{font-size:17px;line-height:1.35}
.mBub .mTx{white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere;display:block}
/* BẢNG trong câu trả lời — vẽ ra bảng thật như chat VS Code (09/08). Bọc ngoài cho cuộn
   ngang khi bảng rộng hơn bong bóng; white-space:normal vì .mTx đang pre-wrap. */
.mBub .mdTW{display:block;white-space:normal;overflow-x:auto;-webkit-overflow-scrolling:touch;margin:7px 0}
.mBub .mdT{border-collapse:collapse;font-size:14px;line-height:1.4;min-width:100%}
.mBub .mdT th,.mBub .mdT td{border:1px solid var(--line2);padding:5px 9px;text-align:left;vertical-align:top;word-break:normal}
.mBub .mdT th{background:rgba(148,163,199,.12);font-weight:600;color:var(--tx);white-space:nowrap}
.mRow{margin:7px 0}
.mBub.a .mTag{margin-bottom:3px}
.plnB .plnI{padding:2.5px 0;line-height:1.42}
.trnMeta{opacity:.85}

/* 08/08 khuya v3 — dải đầu não = MỘT DÒNG MỎNG (Khang chửi bản 2 tầng): tổng cao ~24px */
.bh3{display:flex;align-items:center;gap:6px;padding:1px 2px 7px;margin-bottom:6px;border-bottom:1px solid var(--line)}
.bh3St{display:inline-flex;align-items:center;gap:5px;font:600 11px var(--sans);color:var(--c,#8b93ad)}
.bh3St i{flex:none;width:6px;height:6px;border-radius:50%;background:var(--c,#8b93ad);box-shadow:0 0 6px var(--c,#8b93ad)}
/* SỐ ĐẾM KHÔNG ĐƯỢC NHẢY (Khang 09/08 khuya: "số ở chỗ đếm nhảy real time xấu quá"):
   chữ số cùng bề rộng (tabular-nums) + KHOÁ bề rộng từng ô theo mốc lớn nhất, canh phải —
   1:09 lên 12:09 hay 9k lên 21k thì cả dải vẫn đứng im, chỉ chữ số đổi tại chỗ. */
.bh3R{margin-left:auto;display:inline-flex;align-items:center;gap:4px;font:500 10.5px var(--mono);
  color:var(--tx2);white-space:nowrap;font-variant-numeric:tabular-nums}
.bh3R b{display:inline-block;text-align:right}
.bh3R b[data-tst]{min-width:38px}       /* 0:09 → 12:09 */
.bh3R b.tok{min-width:52px}             /* 900 tok → 128k tok */
.bh3R b.day{min-width:60px}             /* 9k today → 1,2M today */
.bh3R s{text-decoration:none;color:var(--tx3)}
.bh3R b{font-weight:600}
/* MÀU TOKEN (Khang 11/08 "đổi màu token lại"): ~~cam --warn~~ -> TÍM --vio, khớp đúng
   màu token "this turn" ở card ngoài danh sách. Cam giờ chỉ còn dành cho cảnh báo. */
.bh3R b.tok{color:var(--vio)}
.bh3R b.hot{color:var(--vio)}

/* 08/08 khuya v4 — nút SEND teo vì style gốc nằm scope .dfoot (tôi dời markup quên mang
   theo): định nghĩa ĐẦY ĐỦ cho khung mới; + bh3 bỏ line thừa, ôm sát */
.cmpRow .sendB,.vTypeRow .sendB{flex:none;width:42px;height:42px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;background:var(--grad);color:#fff;
  box-shadow:0 2px 10px rgba(109,141,255,.35);margin-bottom:0}
.cmpRow .sendB:active,.vTypeRow .sendB:active{opacity:.75}
.cmpRow .attB{width:42px;height:42px;margin-bottom:0}
.bh3{border-bottom:none;padding:0 2px;margin-bottom:0}/* đệm trên/dưới do #bHead lo (9px cân) */

/* 08/08 khuya v5 — ô soạn contenteditable (thoát thanh mũi tên iOS của textarea) */
.cmpEdit{flex:1;min-width:0;min-height:40px;max-height:132px;overflow-y:auto;-webkit-overflow-scrolling:touch;
  background:rgba(10,13,22,.6);border:1px solid var(--line2);border-radius:18px;
  padding:9px 14px;font:15px/1.4 var(--sans);color:var(--tx);outline:none;
  word-break:break-word;overflow-wrap:anywhere;-webkit-user-modify:read-write-plaintext-only}
.cmpEdit:empty::before{content:attr(data-ph);color:var(--tx3);pointer-events:none}

/* 09/08 sáng — Khang: hàng hội thoại TO lại (lỡ giảm nhỏ) + row offline mờ CHỮ thôi
   (mờ cả row = nút Lưu trữ đỏ phía sau lộ xuyên qua) */
.convRow{padding:13px 14px}
/* THỨ BẬC: tên project (.sjT b 17px) PHẢI TO HƠN tên hội thoại — hội thoại là mục CON
   (Khang 09/08 khuya). Đừng cho 2 cái bằng nhau. */
/* THANG CỠ CHỮ CỦA CARD (đo + chốt 10/08 khuya — đừng phá lẻ tẻ, sửa là sửa cả thang):
   17px tên project > 14px tên hội thoại = timer > 13px dòng việc > 11.5px dòng meta
   > 11px "Received" > 10.5px nhãn token. Khối này nằm CUỐI file nên nó THẮNG — chỉnh cỡ
   chữ card phải chỉnh Ở ĐÂY, sửa khối gốc phía trên là vô hiệu (bẫy override 20). */
.cvT b{font:600 14px var(--sans)} /* Khang hạ 15→14: "tên hội thoại to quá" */
/* TIMER và TOKEN phải CÙNG FONT CÙNG CỠ (Khang 11/08 — đo được trước khi sửa: timer 14px
   sans, token 11.5px MONO, lệch cả hai thứ). Chốt 13px sans cho cả hai: vẫn nhỏ hơn tên
   hội thoại 14px nên thứ bậc còn nguyên, mà hai con số cùng một hệ. tabular-nums để số
   nhảy real-time không làm dải co giãn. */
/* THANG SỐ — CHỈ CÒN 2 BẬC (Khang 11/08 chiều: "font số token hơi to, hơi xấu, nhìn chưa
   đồng đều size"). Đo trước khi sửa ra BA bậc chen nhau trong cùng một hàng:
   số 13px · "Received" 11.5px · nhãn this-turn/session 10.5px ⇒ con số 13px nằm cạnh nhãn
   10.5px trông phồng hẳn lên, mà mỗi hàng lại lệch nhau một kiểu.
   Chốt: MỌI CON SỐ 12.5px/600 · MỌI CHỮ NHÃN 11.5px/500 — cách nhau đúng 1px nên đọc ra
   là "cố ý", số vẫn nổi nhờ ĐẬM + MÀU chứ không nhờ to. Tên hội thoại 14px vẫn trên cùng.
   Sửa thang là sửa CẢ CỤM ở đây (khối cuối file mới thắng — bẫy override 20). */
.cvT .tRun{font:600 12.5px var(--sans);font-variant-numeric:tabular-nums;flex:none}
.cvT .cvTime{font-size:11.5px}
.cvP{font-size:13px;margin-top:3px}
.cvTok{font-size:11.5px;margin-top:5px}
.cvTok b{font:600 12.5px var(--sans);font-variant-numeric:tabular-nums} /* = ĐÚNG timer (11/08) */
.cvTok i,.tRecv{font-size:11.5px;font-weight:500}
.tDone{font:600 12.5px var(--sans);font-variant-numeric:tabular-nums}
.sjT .sjTok{font:600 12.5px var(--sans);font-variant-numeric:tabular-nums}
.cvState{font-size:11.5px}
.cvEdit{width:26px;height:26px}
.convRow.off .cvC{opacity:.55}
/* hàng LỊCH SỬ trong card project (09/08 tối — mục 5): giống hàng Active, không vuốt */
.hsRow{border-bottom:1px solid var(--line)}
.sjCard .hsRow:last-child{border-bottom:none}
.hsRow .cvT .tag{flex:none}

/* ============ 09/08 chiều — composer não: NÚT ẢNH trở lại + hết dải trống khi bật phím ============ */
/* khung ngoài giữ nền + viền, .dfoot bên trong lo phần hàng ngang (style gốc nguyên vẹn) */
.dfootW{flex:none;display:flex;flex-direction:column;background:rgba(15,18,27,.97);
  border-top:1px solid var(--line)}/* bỏ blur — không có gì cuộn dưới, đỡ re-blur lúc sheet trượt (09/08 khuya) */
.dfootW .dfoot{background:none;backdrop-filter:none;border-top:none}
/* hàng ảnh đính kèm: nằm HẲN trên một hàng riêng, tự xuống dòng, không bao giờ bóp ô soạn
   (Khang 09/08: "đính kèm hình ảnh thì không bị bug chèn ép cột or bug layout") */
.dfootW .attRow{background:none;padding:9px 12px 0;flex-wrap:wrap;row-gap:8px}
.dfootW .attChip{flex:none}
.dfoot .attB{width:42px;height:42px;flex:none;border-radius:50%}
/* BÀN PHÍM ĐANG BẬT: bỏ đệm safe-area dưới ô soạn — vạch home bị bàn phím che nên đệm đó
   chỉ còn là dải trống thừa (Khang 09/08: "dưới box text có thêm 1 dòng thụt xuống") */
body.kbOn .dfoot{padding-bottom:8px}
/* COMPOSER — BỐ CỤC CŨ trả về 09/08 khuya (Khang: "để nút gửi cũ đi"): nút ảnh · ô soạn ·
   nút gửi trên MỘT hàng, hai nút tròn 40px BẰNG NHAU nên cân; bám đáy (align-items:flex-end)
   nên ô soạn giãn cao thì hai nút vẫn ngang dòng cuối. Hàng ảnh đính kèm nằm hàng RIÊNG bên
   trên (.dfootW .attRow) — không bao giờ đè chữ. Bản "nút gửi trong pill" đã BỎ. */
.dfoot{gap:8px;padding:8px 10px calc(8px + var(--sab));align-items:flex-end}
.dfoot .attB,.dfoot .sendB{width:40px;height:40px;flex:none;border-radius:50%;
  display:flex;align-items:center;justify-content:center;margin-bottom:0}
.dfoot .attB{background:rgba(118,128,160,.14);color:var(--tx2)}
.dfoot .sendB{background:var(--grad);color:#fff;box-shadow:0 2px 10px rgba(109,141,255,.35)}
.dfoot .attB:active,.dfoot .sendB:active{opacity:.7}
/* max-height 300 = TRẦN CỨNG cuối cùng thôi. Trần THẬT do JS tính theo phần màn còn nhìn
   thấy (visualViewport × 0.38) nên bàn phím bật là tự nhỏ lại. Để 132px ở đây thì dù JS
   tính bao nhiêu, CSS vẫn chặn ở 5 dòng — đó là gốc "gõ dài mà box không expand như iMess"
   (đo 10/08: JS cho 300 nhưng ô vẫn đứng đúng 132). */
.dfoot textarea{flex:1;min-width:0;min-height:40px;max-height:320px;overflow-y:auto;
  -webkit-overflow-scrolling:touch;resize:none;outline:none;display:block;
  background:rgba(118,128,160,.12);border:1px solid rgba(148,163,199,.25);border-radius:20px;
  padding:8px 14px;font:400 17px/1.3 var(--sans);color:var(--tx)}
.dfoot textarea::placeholder{color:var(--tx3)}
.dfoot textarea:focus{border-color:rgba(148,163,199,.5)}
/* bong bóng tin GỬI NGAY (optimistic) — mờ nhẹ cho biết đang bay */
.tmpSend .mBub.u{opacity:.72}
.sndImgs{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:6px}
.sndImgs img{width:76px;height:76px;object-fit:cover;border-radius:10px;display:block}

/* ẢNH ĐÃ GỬI nằm TRONG bong bóng tin của Khang (11/08) — kiểu iMessage: ảnh trên, chữ dưới.
   Ô chờ `.uImgWait` giữ sẵn chỗ đúng số ảnh nên lúc ảnh về KHÔNG làm khung chat giãn giật. */
.uImgs{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:7px}
.uImgs:empty{display:none}
.uImg,.uImgWait{width:86px;height:86px;border-radius:11px;display:block;flex:none}
.uImg{object-fit:cover;cursor:pointer;-webkit-tap-highlight-color:transparent;
  background:rgba(0,0,0,.18);border:1px solid rgba(255,255,255,.14)}
.uImg:active{opacity:.75}
.uImgWait{background:rgba(255,255,255,.10);animation:cvBreath 2.4s ease-in-out infinite alternate}
/* XEM TO: phủ kín màn, bấm đâu cũng đóng. z-index trên cả sheet (.det z50) lẫn ô soạn. */
#imgView{position:fixed;inset:0;z-index:90;display:none;align-items:center;justify-content:center;
  background:rgba(0,0,0,.94);padding:14px}
#imgView.on{display:flex}
#imgView img{max-width:100%;max-height:100%;object-fit:contain;border-radius:8px}

/* Đơn vừa bán: tên MÓN là chính, giờ ở dưới, tiền bên phải (Khang 09/08) */
.ivR{display:flex;align-items:flex-start;gap:10px;padding:9px 2px;border-bottom:1px solid var(--line)}
.ivR:last-child{border-bottom:none}
.ivC{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.ivC b{font:600 13.5px var(--sans);color:var(--tx);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ivC span{font:500 11px var(--mono);color:var(--tx3)}
.ivR .ivM{flex:none;font:600 13.5px var(--mono);color:var(--tx)}

/* ---- bảng lệnh /model · /effort ngay trên ô soạn (09/08) ---- */
.cmdP{padding:10px 12px 2px;border-bottom:1px solid var(--line)}
.cmdH{font:500 11.5px var(--sans);color:var(--tx3);margin-bottom:8px}
.cmdH b{color:var(--tx2);font-weight:600}
.cmdP .nsR{margin-bottom:8px}
/* model + độ sâu đang dùng, ngay trên dải đầu não */
/* MODEL = CHỮ TRƠN đứng ngay sau state, CÙNG font CÙNG cỡ (Khang 11/08: "chữ Opus 5 không
   cần box card, để chữ bình thường"). ~~box viền bo + nền xanh~~ đã bỏ. Vẫn bấm được để
   mở sẵn lệnh /model nên giữ cursor:pointer làm gợi ý. */
.bh3M{flex:none;font:600 11px var(--sans);color:var(--tx3);white-space:nowrap;
  background:none;border:0;padding:0;cursor:pointer}
/* giữ ĐÚNG MỘT DÒNG (luật cũ của Khang): không xuống hàng, chật thì cuộn ngang */
.bh3{flex-wrap:nowrap;overflow-x:auto}
.bh3St{flex:none;white-space:nowrap}

/* ---- bảng "Phiên mới": tên + model + độ sâu (09/08) ---- */
.nsIn{width:100%;background:rgba(118,128,160,.13);border:1px solid rgba(148,163,199,.22);
  border-radius:14px;padding:11px 15px;font:400 16px var(--sans);color:var(--tx);outline:none}
.nsIn:focus{border-color:var(--pri)}
.nsR{display:flex;flex-wrap:wrap;gap:8px}
.nsC{border:1px solid var(--line2);background:var(--card);color:var(--tx2);border-radius:13px;
  padding:8px 13px;font:600 13px var(--sans)}
.nsC.on{background:rgba(109,141,255,.16);border-color:rgba(109,141,255,.55);color:#dbe6ff}
.nsNote{font:400 11.5px/1.5 var(--sans);color:var(--tx3);margin:12px 2px 0}
.nsGo{width:100%;margin-top:16px;background:var(--grad);color:#fff;border-radius:15px;
  padding:14px;font:600 15px var(--sans);box-shadow:0 4px 16px rgba(109,141,255,.32)}
.nsGo:disabled{opacity:.6}

/* dòng ghi chú dưới đầu mục (bot xếp lúc mấy giờ) — tách hàng riêng cho đầu mục khỏi chật */
.shNote{font:400 11px var(--sans);color:var(--tx3);margin:-5px 2px 9px}
.sh .act + .act{margin-left:12px}

/* Nhãn trục biểu đồ do charts.js (module dùng chung) ghi cứng fill="#5c6577" = 3.34:1.
   Không sửa file đó — đè từ đây, đúng cách bản desk đã làm. */
svg text{fill:var(--tx3)}   /* phủ cả biểu đồ trong sheet chi tiết, không chỉ trong .scr */

/* Hàng nhãn — giá trị: thiếu min-width:0 nên nhãn dài đẩy cả hai bên vỡ 2 dòng, chữ cuối
   ("app") lơ lửng canh phải (Khang thấy ở khối Phân tích doanh nghiệp 12/08). */
.kv{align-items:flex-start}
.kv>em{min-width:0;flex:1 1 auto}
.kv>b{flex:0 0 auto;text-align:right;max-width:58%}
/* câu ngắn báo trạng thái trong card (thay biểu đồ rỗng) */
.msgNote{font:400 13px var(--sans);color:var(--tx3);padding:14px 2px}

/* Dòng phụ trong tiêu đề mục: KHÔNG in hoa giãn chữ như tiêu đề, nếu không hai cụm dính
   thành một câu khó đọc ("CHỜ KHANG DUYỆT PHIÊN ĐANG ĐỨNG CHỜ" — Khang thấy 12/08). */
.sh .sthin{text-transform:none;letter-spacing:0;color:var(--tx3);font-weight:400;margin-left:6px}
/* giờ của mục "Có gì mới" — đọc cái là biết tin lúc nào, giống bên tin tức */
.nTech .mt{font:400 11px var(--sans);color:var(--tx3);display:block;margin-top:4px}

/* ═══════════ 12/08 — ANIMATION KHUNG CHAT (kiểu iMessage / Messenger) ═══════════
   ⛔ LUẬT 1 — CHỈ `transform` + `opacity`. Cấm animate height/top/left/margin: khung chat
   này DÁN ĐÁY ngay trong cùng frame sau mỗi lần vẽ (xem `paintBrain`), một cú reflow giữa
   chừng là scrollTop lệch = đúng cú giật Khang bắt 11/08.
   ⛔ LUẬT 2 — KHÔNG viết animation thẳng vào `.mBub`. Khung chat bị DỰNG LẠI mỗi nhịp SSE
   (`refreshTurn` viết lại nguyên khối lượt sống), animation sẽ chạy lại với mọi bong bóng
   vừa sinh ⇒ cả khung nhấp nháy 3 giây/lần. Hiệu ứng vào chỉ được treo ở class `.bIn`, do
   `stampBubbles()` trong `pulse/js/tabs/sessions.js` gắn cho ĐÚNG bong bóng vừa xuất hiện.
   ⛔ LUẬT 3 (12/08 chiều) — `.tmpSend` (bong bóng gửi tạm) NAY BỊ DỰNG LẠI: `paintBrain`
   viết lại cả `#bChat` mỗi lần danh sách lượt đổi, nên `keepEcho()` phải chèn lại nó. Vì
   vậy hiệu ứng bay-vào KHÔNG được treo ở `.tmpSend` nữa mà ở `.tmpSend.eIn` — class `eIn`
   chỉ đeo ở LẦN CHÈN ĐẦU (lúc bấm gửi); các lần chèn lại đứng im, không nhấp nháy.
   Hai hướng vào KHÁC NHAU như Messenger: tin Claude từ mép TRÁI, tin Khang từ mép PHẢI. */
@keyframes bubInA{from{opacity:0;transform:translate3d(-10px,8px,0) scale(.96)}
  to{opacity:1;transform:translate3d(0,0,0) scale(1)}}
@keyframes bubInU{from{opacity:0;transform:translate3d(10px,8px,0) scale(.96)}
  to{opacity:.72;transform:translate3d(0,0,0) scale(1)}}
@keyframes bubSettle{from{opacity:.72}to{opacity:1}}
@keyframes sndRing{to{transform:rotate(360deg)}}

/* tin Claude (và plan/thought) — bật lên từ góc dưới-trái, phía avatar CLI */
.mBub.bIn{animation:bubInA .2s cubic-bezier(.2,.8,.2,1) both;transform-origin:0 100%}
/* TIN CỦA KHANG khi lượt THẬT về: KHÔNG cho trượt/scale lại. Chỗ đó vừa có bong bóng tạm
   mờ .72 đứng sẵn; cho nó bật lại từ đầu là NHẤP NHÁY + nhảy chỗ ngay dưới mắt Khang.
   Chỉ SÁNG DẦN .72 → 1 nên nhìn ra "tin vừa được chốt", liền mạch với bong bóng tạm.
   (Tin Khang gõ thẳng bên VS Code cũng vào bằng kiểu này — mềm, không giật.) */
[data-tk] .mBub.u.bIn{animation:bubSettle .18s ease-out both;transform-origin:100% 100%}

/* ĐANG GỬI — bong bóng tạm bay vào từ mép PHẢI rồi dừng ở opacity .72 (mờ = chưa chốt),
   kèm VÒNG XOAY nhỏ quanh avatar Khang. Vòng này là `::after` tuyệt đối NẰM TRONG avatar
   ⇒ không chiếm chỗ, không đẩy chữ, không reflow. Gửi xong bong bóng tạm biến mất và bong
   bóng thật sáng lên — không có bước nào nhấp nháy. */
.tmpSend.eIn .mBub.u{animation:bubInU .2s cubic-bezier(.2,.8,.2,1) both;transform-origin:100% 100%}
.tmpSend .mRow.u .mAva{position:relative}
.tmpSend .mRow.u .mAva::after{content:'';position:absolute;inset:-3px;border-radius:50%;
  border:1.5px solid rgba(157,180,255,.85);border-top-color:transparent;
  animation:sndRing .9s linear infinite}

/* Máy đặt "giảm chuyển động": bỏ hết hiệu ứng vào, chỉ giữ dấu hiệu tĩnh cho tin đang gửi
   (opacity .72 của `.tmpSend .mBub.u` + vòng đứng yên) — không mất thông tin nào. */
@media (prefers-reduced-motion:reduce){
  .mBub.bIn,[data-tk] .mBub.u.bIn,.tmpSend.eIn .mBub.u{animation:none}
  .tmpSend .mRow.u .mAva::after{animation:none;opacity:.55}
}

/* ghi chú "N ảnh đang gửi" trong bong bóng tạm khi app vừa mở lại (ảnh không cất xuống đĩa) */
.sndNote{display:block;margin-top:4px;font:500 11.5px var(--sans);opacity:.7}
