@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@600;700&display=swap");

/* =====================================================================
   KATTY — HỆ THIẾT KẾ DÙNG CHUNG (design system) cho katty.io.vn
   Dùng chung cho toàn bộ 10 trang: /, /tinh-nang, /bang-gia, /huong-dan,
   /dang-ky, /dieu-khoan, /chinh-sach-*, /huong-dan-thanh-toan.

   Khung bố cục học theo preny.ai; màu và chữ lấy từ bộ nhận diện Katty
   (brand/logo): gradient Violet #8B5CF6 → Blue #4F6BFF → Cyan #22D3EE,
   nền chữ Ink #0B1020.

   ĐỔI MÀU TOÀN WEB = sửa 6 biến trong khối [01], hoặc gắn
   <html data-palette="b|c"> để xem 2 bộ màu dự phòng.
   ĐỔI SÁNG/TỐI = <html data-theme="light|dark">, bỏ trống = theo máy.
   ===================================================================== */

/* ============ [01] TOKEN — MÀU ============ */
:root{
  /* --- 3 chặng gradient thương hiệu (lấy thẳng từ file logo) --- */
  --b1:#8B5CF6;                    /* violet */
  --b2:#4F6BFF;                    /* blue   */
  --b3:#22D3EE;                    /* cyan   */
  --brand:#7C3AED;                 /* màu đặc: nút, link, số liệu */
  --brand-strong:#6D28D9;          /* trạng thái hover */
  --brand-weak:#F3F0FF;            /* nền nhạt: chip, ô icon */
  --on-brand:#ffffff;              /* chữ nằm trên nền thương hiệu */
  --on-solid:#ffffff;              /* chữ trên nút đặc --brand (nền tối sẽ đảo lại) */
  --ink-fixed:#0B1020;             /* luôn tối, kể cả ở chế độ tối: nút trên nền gradient */

  --grad:linear-gradient(135deg,var(--b1) 0%,var(--b2) 52%,var(--b3) 100%);
  --grad-soft:linear-gradient(135deg,
      color-mix(in srgb,var(--b1) 12%,transparent),
      color-mix(in srgb,var(--b3) 12%,transparent));

  /* --- nền & chữ (chế độ sáng) --- */
  --bg:#ffffff;
  --card:#ffffff;
  --soft:#F7F8FC;                  /* nền section xen kẽ */
  --sunken:#EEF1F8;                /* nền lõm: ảnh giả lập, khung chat */
  --line:#E5E8F0;
  --line-soft:#EFF1F7;
  --ink:#0B1020;                   /* tiêu đề */
  --ink-2:#333B4D;                 /* thân bài */
  --muted:#646E82;                 /* chú thích */
  --faint:#98A2B8;                 /* mờ nhất */

  /* --- màu chức năng --- */
  --ok:#16A34A; --ok-weak:#ECFDF3;
  --warn:#D97706; --warn-weak:#FFFBEB;
  --err:#DC2626; --err-weak:#FEF2F2;

  /* ============ TOKEN — HÌNH KHỐI ============ */
  --r-xs:8px; --r-sm:10px; --r:14px; --r-md:18px; --r-lg:24px; --r-xl:32px; --r-full:999px;

  --sh-xs:0 1px 2px rgba(11,16,32,.05);
  --sh-sm:0 1px 2px rgba(11,16,32,.04), 0 4px 12px rgba(11,16,32,.05);
  --sh:0 1px 2px rgba(11,16,32,.04), 0 12px 32px rgba(11,16,32,.07);
  --sh-lg:0 4px 12px rgba(11,16,32,.06), 0 28px 64px rgba(11,16,32,.11);
  --sh-brand:0 12px 34px color-mix(in srgb,var(--b2) 26%,transparent);
  --ring:0 0 0 4px color-mix(in srgb,var(--brand) 16%,transparent);

  /* ============ TOKEN — KHOẢNG CÁCH & KÍCH THƯỚC ============ */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:22px;
  --s6:30px; --s7:40px; --s8:56px; --s9:76px; --s10:104px;
  --maxw:1160px;                   /* bề ngang khung nội dung */
  --maxw-narrow:820px;             /* trang văn bản dài */
  --gutter:20px;

  /* ============ TOKEN — CHỮ ============ */
  --font:"Inter","Be Vietnam Pro",-apple-system,BlinkMacSystemFont,"Segoe UI",
         Roboto,"Helvetica Neue",Arial,sans-serif;

  /* ============ TOKEN — CHUYỂN ĐỘNG & LỚP ============ */
  --t-fast:.14s cubic-bezier(.4,0,.2,1);
  --t:.22s cubic-bezier(.4,0,.2,1);
  --z-header:80; --z-menu:90; --z-modal:100;
}

/* --- Bộ màu dự phòng: gắn data-palette lên <html> để xem thử --- */
:root[data-palette="b"]{           /* B · Indigo → Coral: ấm, hiếu khách */
  --b1:#4F46E5; --b2:#A855F7; --b3:#FB7185;
  --brand:#4F46E5; --brand-strong:#4338CA; --brand-weak:#EEF0FF;
}
:root[data-palette="c"]{           /* C · Midnight → Emerald: điềm đạm, tin cậy */
  --b1:#1E3A8A; --b2:#0EA5E9; --b3:#34D399;
  --brand:#0369A1; --brand-strong:#075985; --brand-weak:#EFF8FF;
}

/* ============ [02] CHẾ ĐỘ TỐI ============ */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#0B1020; --card:#131A2E; --soft:#0F1526; --sunken:#0A0F1D;
    --line:#242D45; --line-soft:#1B2337;
    --ink:#EEF1F8; --ink-2:#CBD3E3; --muted:#98A2B8; --faint:#6B7590;
    --brand:#A78BFA; --brand-strong:#C4B5FD; --brand-weak:#1C1B3A; --on-solid:#0B1020;
    --ok-weak:#0C2118; --warn-weak:#241B08; --err-weak:#2A1315;
    --sh-xs:0 1px 2px rgba(0,0,0,.4);
    --sh-sm:0 1px 2px rgba(0,0,0,.35), 0 4px 12px rgba(0,0,0,.35);
    --sh:0 1px 2px rgba(0,0,0,.35), 0 12px 32px rgba(0,0,0,.42);
    --sh-lg:0 4px 12px rgba(0,0,0,.4), 0 28px 64px rgba(0,0,0,.55);
  }
}
:root[data-theme="dark"]{
  --bg:#0B1020; --card:#131A2E; --soft:#0F1526; --sunken:#0A0F1D;
  --line:#242D45; --line-soft:#1B2337;
  --ink:#EEF1F8; --ink-2:#CBD3E3; --muted:#98A2B8; --faint:#6B7590;
  --brand:#A78BFA; --brand-strong:#C4B5FD; --brand-weak:#1C1B3A; --on-solid:#0B1020;
  --ok-weak:#0C2118; --warn-weak:#241B08; --err-weak:#2A1315;
  --sh-xs:0 1px 2px rgba(0,0,0,.4);
  --sh-sm:0 1px 2px rgba(0,0,0,.35), 0 4px 12px rgba(0,0,0,.35);
  --sh:0 1px 2px rgba(0,0,0,.35), 0 12px 32px rgba(0,0,0,.42);
  --sh-lg:0 4px 12px rgba(0,0,0,.4), 0 28px 64px rgba(0,0,0,.55);
}

/* ============ [03] RESET & NỀN CHUNG ============ */
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth; -webkit-text-size-adjust:100%; scroll-padding-top:88px}
body{
  margin:0; background:var(--bg); color:var(--ink-2);
  font-family:var(--font); font-size:16px; line-height:1.65;
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}
img,svg,video{max-width:100%; height:auto; display:block}
button,input,select,textarea{font:inherit; color:inherit}
h1,h2,h3,h4,h5{
  color:var(--ink); line-height:1.2; margin:0 0 .5em;
  letter-spacing:-.022em; font-weight:760; text-wrap:balance;
}
h1{font-size:clamp(32px,5.2vw,54px); letter-spacing:-.032em}
h2{font-size:clamp(25px,3.6vw,38px); letter-spacing:-.028em}
h3{font-size:clamp(18px,2vw,21px)}
h4{font-size:16.5px}
p{margin:0 0 1em}
p:last-child{margin-bottom:0}
a{color:var(--brand); text-decoration:none; transition:color var(--t-fast)}
a:hover{color:var(--brand-strong); text-decoration:underline}
:focus-visible{outline:2px solid var(--brand); outline-offset:3px; border-radius:4px}
hr{border:0; border-top:1px solid var(--line); margin:var(--s7) 0}
::selection{background:color-mix(in srgb,var(--b2) 24%,transparent)}
strong,b{color:var(--ink); font-weight:700}
small{font-size:13.5px}

/* ============ [04] BỐ CỤC ============ */
.wrap{max-width:var(--maxw); margin-inline:auto; padding-inline:var(--gutter)}
.wrap.narrow{max-width:var(--maxw-narrow)}
section{padding:var(--s9) 0}
section.tight{padding:var(--s8) 0}
section.line{border-top:1px solid var(--line)}
section.soft{background:var(--soft)}
section.ink{background:var(--ink); color:#CBD3E3}
section.ink h2,section.ink h3{color:#fff}

/* đầu mục của mỗi khối */
.head{max-width:64ch; margin:0 auto var(--s7); text-align:center}
.head.left{margin-inline:0; text-align:left}
.head h2{margin-bottom:14px}
.head p{color:var(--muted); font-size:17px; margin:0}
.eyebrow{
  display:inline-block; font-size:12.5px; font-weight:750; letter-spacing:.11em;
  text-transform:uppercase; margin-bottom:12px;
  background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent;
}
.center{text-align:center}
.nav .menu .only-sm{display:none}   /* 2 nút chỉ dành cho điện thoại */
.grid{display:grid; gap:var(--s5)}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
.grid.tight{gap:var(--s4)}

/* ============ [05] THANH ĐIỀU HƯỚNG ============ */
header{
  position:sticky; top:0; z-index:var(--z-header);
  background:color-mix(in srgb,var(--bg) 82%,transparent);
  backdrop-filter:saturate(180%) blur(16px);
  -webkit-backdrop-filter:saturate(180%) blur(16px);
  border-bottom:1px solid transparent;
  transition:border-color var(--t),box-shadow var(--t);
}
header.stuck{border-bottom-color:var(--line); box-shadow:var(--sh-xs)}
.nav{display:flex; align-items:center; gap:var(--s2); height:68px}
.brand{display:flex; align-items:center; gap:9px; flex:none; color:var(--ink); font-weight:800; font-size:19px}
.brand:hover{text-decoration:none; color:var(--ink)}
.brand img,.brand>svg{height:30px; width:auto}
.brand .mark,.brand .paw{                 /* ô biểu tượng khi không dùng file logo */
  width:32px; height:32px; border-radius:10px; display:grid; place-items:center;
  background:var(--grad); color:#fff; font-size:17px; font-weight:800;
}
.nav .menu{display:flex; gap:2px; margin-left:var(--s5)}
.nav .menu a{
  color:var(--muted); font-size:15px; font-weight:560;
  padding:9px 13px; border-radius:var(--r-sm); transition:var(--t-fast);
}
.nav .menu a:hover{color:var(--ink); background:var(--soft); text-decoration:none}
.nav .menu a.on{color:var(--brand); background:var(--brand-weak)}
.nav .sp{flex:1}
.nav .acts{display:flex; align-items:center; gap:9px; flex:none}
.burger{
  display:none; background:none; border:1px solid var(--line); border-radius:var(--r-xs);
  width:38px; height:38px; padding:0; cursor:pointer; color:var(--ink); font-size:19px;
}
.theme-btn{                                /* nút chuyển sáng/tối */
  width:38px; height:38px; border-radius:var(--r-xs); border:1px solid var(--line);
  background:transparent; cursor:pointer; display:grid; place-items:center;
  font-size:16px; color:var(--muted); transition:var(--t-fast);
}
.theme-btn:hover{border-color:var(--brand); color:var(--brand)}

/* ============ [06] NÚT ============ */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:11px 20px; border-radius:var(--r-sm); border:1px solid transparent;
  font-weight:650; font-size:15px; line-height:1.35; cursor:pointer;
  font-family:inherit; text-align:center; white-space:nowrap;
  transition:transform var(--t-fast),background var(--t-fast),box-shadow var(--t-fast),border-color var(--t-fast),filter var(--t-fast);
}
.btn:hover{text-decoration:none}
.btn:active{transform:translateY(1px)}
.btn-p{background:var(--grad); color:#fff; box-shadow:var(--sh-brand)}
.btn-p:hover{color:#fff; filter:brightness(1.07); box-shadow:0 16px 40px color-mix(in srgb,var(--b2) 34%,transparent)}
.btn-s{background:var(--brand); color:var(--on-solid)}  /* nút đặc, không gradient */
.btn-s:hover{background:var(--brand-strong); color:var(--on-solid)}
.btn-g{background:var(--card); color:var(--ink); border-color:var(--line); box-shadow:var(--sh-xs)}
.btn-g:hover{border-color:var(--brand); color:var(--brand)}
.btn-ghost{background:transparent; color:var(--muted)}
.btn-ghost:hover{background:var(--soft); color:var(--ink)}
.btn-w{background:#fff; color:var(--b1)}             /* dùng trên nền gradient */
.btn-w:hover{background:#F3F0FF; color:var(--b1)}
.btn-lg{padding:15px 30px; font-size:16.5px; border-radius:var(--r)}
.btn-sm{padding:8px 14px; font-size:14px}
.btn-block{display:flex; width:100%}
.btn[disabled],.btn:disabled{opacity:.55; cursor:not-allowed; transform:none}

/* ============ [07] CHIP · THẺ NHÃN ============ */
.pill{
  display:inline-flex; align-items:center; gap:8px; padding:6px 15px 6px 8px;
  border-radius:var(--r-full); background:var(--brand-weak); color:var(--brand-strong);
  font-size:13.5px; font-weight:650; margin-bottom:var(--s5);
  border:1px solid color-mix(in srgb,var(--brand) 18%,transparent);
}
.pill b{
  background:var(--grad); color:#fff; padding:2px 9px; border-radius:var(--r-full);
  font-size:11.5px; font-weight:750; letter-spacing:.02em;
}
.tag{
  display:inline-block; padding:4px 10px; border-radius:var(--r-xs);
  background:var(--brand-weak); color:var(--brand-strong);
  font-size:12px; font-weight:700;
}
.tag.ok{background:var(--ok-weak); color:var(--ok)}
.tag.warn{background:var(--warn-weak); color:var(--warn)}
.tag.gray{background:var(--soft); color:var(--muted)}
.note{margin-top:var(--s4); font-size:13.5px; color:var(--muted)}

/* ============ [08] HERO ============ */
.hero{position:relative; padding:var(--s9) 0 var(--s8); text-align:center; overflow:hidden}
.hero::before{                      /* quầng sáng gradient sau tiêu đề */
  content:""; position:absolute; top:-320px; left:50%; transform:translateX(-50%);
  width:1000px; height:700px; pointer-events:none; opacity:.5; filter:blur(18px);
  background:
    radial-gradient(closest-side,color-mix(in srgb,var(--b1) 42%,transparent),transparent),
    radial-gradient(closest-side,color-mix(in srgb,var(--b3) 30%,transparent),transparent) 60% 40%/70% 70% no-repeat;
}
.hero::after{                       /* lưới mờ tạo chiều sâu */
  content:""; position:absolute; inset:0; pointer-events:none; opacity:.5;
  background-image:linear-gradient(var(--line) 1px,transparent 1px),
                   linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:64px 64px;
  -webkit-mask-image:radial-gradient(ellipse 80% 60% at 50% 0%,#000,transparent 75%);
  mask-image:radial-gradient(ellipse 80% 60% at 50% 0%,#000,transparent 75%);
}
.hero>*{position:relative; z-index:1}
.hero h1{max-width:19ch; margin-inline:auto}
.hero h1 em,.grad-text{
  font-style:normal; background:var(--grad);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
.lede{font-size:clamp(16.5px,1.9vw,20px); color:var(--muted); max-width:62ch; margin:0 auto var(--s6)}
.cta-row{display:flex; gap:var(--s3); justify-content:center; flex-wrap:wrap}
.hero .shot{margin-top:var(--s8); text-align:left}

/* ============ [09] DẢI SỐ LIỆU ============ */
.stats{
  display:grid; grid-template-columns:repeat(4,1fr); gap:1px; margin-top:var(--s8);
  background:var(--line); border:1px solid var(--line);
  border-radius:var(--r-md); overflow:hidden; box-shadow:var(--sh-sm);
}
.stat{background:var(--card); padding:var(--s6) var(--s4); text-align:center}
.stat b{
  display:block; font-size:clamp(28px,3.8vw,40px); font-weight:800; letter-spacing:-.04em;
  font-variant-numeric:tabular-nums;
  background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent;
}
.stat span{display:block; margin-top:4px; font-size:13.5px; color:var(--muted)}

/* ============ [10] THẺ ============ */
.card{
  position:relative; background:var(--card); border:1px solid var(--line);
  border-radius:var(--r-md); padding:28px 26px; box-shadow:var(--sh-sm);
  transition:transform var(--t),box-shadow var(--t),border-color var(--t);
}
.card:hover{transform:translateY(-3px); box-shadow:var(--sh-lg); border-color:color-mix(in srgb,var(--brand) 30%,var(--line))}
.card.flat{box-shadow:none}
.card.flat:hover{transform:none; box-shadow:var(--sh-sm)}
.card h3{margin-bottom:8px}
.card p{color:var(--muted); font-size:15.2px}
.card .ico{
  width:48px; height:48px; border-radius:var(--r); display:grid; place-items:center;
  background:var(--brand-weak); font-size:22px; margin-bottom:var(--s4);
}
.card .ico.grad{background:var(--grad); color:#fff}
.card .tag{margin-top:var(--s4)}
.card.glow{                                /* thẻ viền gradient */
  border:1px solid transparent;
  background:linear-gradient(var(--card),var(--card)) padding-box, var(--grad) border-box;
}

/* danh sách có dấu tích */
.card ul,.list{margin:var(--s3) 0 0; padding:0; list-style:none; font-size:14.8px}
.card ul li,.list li{position:relative; padding:6px 0 6px 25px; color:var(--muted)}
.card ul li::before,.list li::before{content:"✓"; position:absolute; left:3px; color:var(--brand); font-weight:900}

/* ============ [11] KHỐI XEN KẼ ẢNH – CHỮ ============ */
.split{display:grid; grid-template-columns:1fr 1fr; gap:var(--s8); align-items:center; margin-bottom:var(--s9)}
.split:last-child{margin-bottom:0}
.split.flip .txt{order:2}
.split h3{font-size:clamp(22px,2.7vw,29px); letter-spacing:-.026em; margin-bottom:12px}
.split p{color:var(--muted); font-size:16.5px}
.split .num{
  display:inline-grid; place-items:center; width:36px; height:36px; border-radius:var(--r-sm);
  background:var(--grad); color:#fff; font-weight:800; font-size:15px; margin-bottom:var(--s4);
}

/* ảnh giả lập giao diện app */
.shot{
  background:var(--card); border:1px solid var(--line); border-radius:var(--r-lg);
  box-shadow:var(--sh-lg); padding:18px; overflow:hidden;
}
.shot.window{padding:0}
.shot .bar{
  display:flex; align-items:center; gap:6px; padding:11px 14px;
  border-bottom:1px solid var(--line); background:var(--soft);
}
.shot .bar i{display:block; width:10px; height:10px; border-radius:50%; background:var(--line)}
.shot .bar .url{
  flex:1; margin-left:8px; height:23px; padding:0 10px; border-radius:var(--r-full);
  background:var(--card); border:1px solid var(--line);
  display:flex; align-items:center; font-size:11.5px; color:var(--faint);
}
.shot .pad{padding:18px}

/* ============ [12] KHUNG CHAT GIẢ LẬP ============ */
.chat{display:flex; flex-direction:column; gap:9px; font-size:14.4px}
.chat .who{font-size:11.5px; color:var(--faint); font-weight:600; margin-bottom:-4px}
.chat .who.r{align-self:flex-end}
.chat .b{max-width:84%; padding:10px 15px; border-radius:16px; line-height:1.5}
.chat .b.k{background:var(--sunken); color:var(--ink-2); align-self:flex-start; border-bottom-left-radius:5px}
.chat .b.a{background:var(--grad); color:#fff; align-self:flex-end; border-bottom-right-radius:5px}
.chat .typing{display:flex; gap:4px; align-self:flex-start; padding:13px 15px; background:var(--sunken); border-radius:16px}
.chat .typing i{width:6px; height:6px; border-radius:50%; background:var(--faint); animation:bl 1.2s infinite}
.chat .typing i:nth-child(2){animation-delay:.2s}
.chat .typing i:nth-child(3){animation-delay:.4s}
@keyframes bl{0%,60%,100%{opacity:.25} 30%{opacity:1}}

/* ============ [13] TAB NGÀNH NGHỀ ============ */
.tabs{display:flex; gap:8px; justify-content:center; flex-wrap:wrap; margin-bottom:var(--s6)}
.tabs button{
  padding:9px 18px; border-radius:var(--r-full); border:1px solid var(--line);
  background:var(--card); color:var(--muted); font-size:14px; font-weight:650;
  letter-spacing:.02em; cursor:pointer; transition:var(--t-fast);
}
.tabs button:hover{color:var(--ink); border-color:var(--brand)}
.tabs button[aria-selected="true"]{background:var(--grad); color:#fff; border-color:transparent; box-shadow:var(--sh-brand)}
.panel[hidden]{display:none}

/* ============ [14] CÁC BƯỚC ============ */
.steps{display:grid; grid-template-columns:repeat(3,1fr); gap:var(--s6); counter-reset:s}
.step{position:relative; padding-top:var(--s8)}
.step::before{
  counter-increment:s; content:counter(s);
  position:absolute; top:0; left:0; width:42px; height:42px; border-radius:var(--r);
  background:var(--grad); color:#fff; display:grid; place-items:center;
  font-weight:800; font-size:17px; box-shadow:var(--sh-brand);
}
.step h3{margin-bottom:6px}
.step p{color:var(--muted); font-size:15.2px; margin:0}

/* ============ [15] BẢNG GIÁ ============ */
.prices{display:grid; grid-template-columns:repeat(4,1fr); gap:var(--s4); align-items:stretch}
.price{
  display:flex; flex-direction:column; background:var(--card);
  border:1px solid var(--line); border-radius:var(--r-md);
  padding:30px 24px; box-shadow:var(--sh-sm);
}
.price.best{
  position:relative; border:1px solid transparent; box-shadow:var(--sh-lg);
  background:linear-gradient(var(--card),var(--card)) padding-box, var(--grad) border-box;
}
.price.best::after{
  content:"Phổ biến nhất"; position:absolute; top:-13px; left:50%; transform:translateX(-50%);
  background:var(--grad); color:#fff; font-size:11.5px; font-weight:750;
  padding:5px 14px; border-radius:var(--r-full); white-space:nowrap; box-shadow:var(--sh-brand);
}
.price h3{font-size:18.5px; margin-bottom:4px}
.price .for{min-height:2.7em; margin-bottom:var(--s4); font-size:13.6px; color:var(--muted)}
.price .old:empty{text-decoration:none}
.price .old{min-height:1.4em; margin-bottom:2px; font-size:14px; color:var(--faint); text-decoration:line-through}
.price .amt{font-size:33px; font-weight:800; letter-spacing:-.04em; color:var(--ink); font-variant-numeric:tabular-nums}
.price .amt small{font-size:14.5px; font-weight:600; color:var(--muted); letter-spacing:0}
.price ul{flex:1; list-style:none; padding:0; margin:var(--s5) 0 var(--s6); font-size:14.6px}
.price li{position:relative; padding:7px 0 7px 25px; color:var(--muted)}
.price li::before{content:"✓"; position:absolute; left:2px; color:var(--brand); font-weight:900}
.price li.no{opacity:.5}
.price li.no::before{content:"—"; color:var(--faint)}

/* bảng so sánh gói */
.cmp-scroll{overflow-x:auto; border:1px solid var(--line); border-radius:var(--r-md); background:var(--card)}
table.cmp{width:100%; min-width:660px; border-collapse:collapse; font-size:14.8px}
table.cmp th,table.cmp td{padding:14px 16px; border-bottom:1px solid var(--line-soft); text-align:center}
table.cmp th:first-child,table.cmp td:first-child{text-align:left; color:var(--ink-2); font-weight:600}
table.cmp thead th{background:var(--soft); font-weight:750; font-size:14px; color:var(--ink)}
table.cmp tbody tr:last-child td{border-bottom:0}
table.cmp tbody tr:hover td{background:color-mix(in srgb,var(--brand) 4%,transparent)}
table.cmp .y{color:var(--ok); font-weight:800}
table.cmp .n{color:var(--faint)}

/* ============ [16] CÂU HỎI THƯỜNG GẶP ============ */
.faq{max-width:820px; margin-inline:auto}
details{
  background:var(--card); border:1px solid var(--line); border-radius:var(--r);
  margin-bottom:11px; overflow:hidden; transition:border-color var(--t-fast);
}
details[open]{border-color:color-mix(in srgb,var(--brand) 34%,var(--line)); box-shadow:var(--sh-sm)}
summary{
  display:flex; justify-content:space-between; align-items:center; gap:18px;
  padding:18px 22px; cursor:pointer; list-style:none;
  font-weight:650; font-size:16px; color:var(--ink);
}
summary::-webkit-details-marker{display:none}
summary::after{content:"+"; flex:none; font-size:23px; line-height:1; font-weight:400; color:var(--brand)}
details[open] summary::after{content:"−"}
details .body{padding:0 22px 20px; color:var(--muted); font-size:15.2px}

/* ============ [17] KHỐI KÊU GỌI & BIỂU MẪU ============ */
.cta-box{
  position:relative; overflow:hidden;
  display:grid; grid-template-columns:1fr 1fr; gap:var(--s7); align-items:center;
  padding:52px 46px; border-radius:var(--r-xl); color:#fff;
  background:var(--grad); box-shadow:var(--sh-lg);
}
.cta-box::before{
  content:""; position:absolute; inset:0; pointer-events:none; opacity:.35;
  background:radial-gradient(closest-side,rgba(255,255,255,.35),transparent) 88% -30%/60% 130% no-repeat;
}
.cta-box>*{position:relative}
.cta-box h2{color:#fff; margin-bottom:12px}
.cta-box p{color:rgba(255,255,255,.92); font-size:16.5px; margin:0}
.cta-box .list li{color:rgba(255,255,255,.92)}
.cta-box .list li::before{color:#fff}

.form{display:grid; gap:11px}
.form label{margin-bottom:-5px; font-size:13.5px; font-weight:600; color:rgba(255,255,255,.9)}
.form input,.form select,.form textarea{
  width:100%; padding:13px 15px; border-radius:var(--r-sm); border:0;
  font-size:15px; background:rgba(255,255,255,.97); color:#111827;
}
.form input:focus,.form select:focus,.form textarea:focus{outline:0; box-shadow:0 0 0 3px rgba(255,255,255,.55)}
.form textarea{min-height:86px; resize:vertical}
.form button{
  padding:14px; border-radius:var(--r-sm); border:0; background:var(--ink-fixed); color:#fff;
  font-weight:700; font-size:15.5px; cursor:pointer; transition:var(--t-fast);
}
.form button:hover{filter:brightness(1.25)}
.form button:disabled{opacity:.6; cursor:default}
.form .msg{padding:12px 15px; border-radius:var(--r-sm); background:rgba(255,255,255,.2); font-size:14.6px}
.form .hint{font-size:12.8px; color:rgba(255,255,255,.8); margin:0}

/* biểu mẫu trên nền trắng (trang Đăng ký) */
.form-plain label{color:var(--ink-2)}
.form-plain input,.form-plain select,.form-plain textarea{
  background:var(--card); border:1px solid var(--line); color:var(--ink);
}
.form-plain input:focus,.form-plain select:focus,.form-plain textarea:focus{
  border-color:var(--brand); box-shadow:var(--ring);
}
.form-plain button{background:var(--grad)}
.form-plain .msg{background:var(--brand-weak); color:var(--brand-strong)}
.form-plain .hint{color:var(--muted)}

/* ============ [18] TRANG VĂN BẢN DÀI (điều khoản, chính sách) ============ */
.doc{max-width:var(--maxw-narrow); margin-inline:auto}
.doc h2{margin-top:var(--s7); font-size:clamp(21px,2.4vw,26px)}
.doc h2:first-of-type{margin-top:0}
.doc h3{margin-top:var(--s6); font-size:18px}
.doc p,.doc li{color:var(--ink-2); font-size:15.8px}
.doc ul,.doc ol{padding-left:22px}
.doc li{margin-bottom:7px}
.doc .upd{
  padding:13px 16px; border:1px solid var(--line); border-radius:var(--r);
  background:var(--soft); color:var(--muted); font-size:14px;
}
.doc .toc{
  padding:20px 24px; margin-bottom:var(--s7);
  border:1px solid var(--line); border-radius:var(--r); background:var(--soft);
}
.doc .toc ol{margin:0; font-size:15px}

/* ============ [19] CHÂN TRANG ============ */
footer{
  border-top:1px solid var(--line); background:var(--soft);
  padding:var(--s8) 0 var(--s6); color:var(--muted); font-size:14.6px;
}
.fgrid{display:grid; grid-template-columns:2fr 1fr 1fr 1fr; gap:var(--s6); margin-bottom:var(--s7)}
footer h4{margin:0 0 14px; font-size:14px; font-weight:750; color:var(--ink)}
footer ul{list-style:none; margin:0; padding:0}
footer li{margin-bottom:9px}
footer a{color:var(--muted)}
footer a:hover{color:var(--brand)}
.fbot{
  display:flex; justify-content:space-between; flex-wrap:wrap; gap:var(--s4);
  padding-top:var(--s5); border-top:1px solid var(--line); font-size:13.4px;
}

/* ============ [20] TIỆN ÍCH ============ */
.mono-num{font-variant-numeric:tabular-nums}
.muted{color:var(--muted)}
.mt0{margin-top:0}.mb0{margin-bottom:0}
.mt4{margin-top:var(--s4)}.mt6{margin-top:var(--s6)}.mt8{margin-top:var(--s8)}
.sr-only{position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0}

/* hiện dần khi cuộn tới (JS gắn .in) */
.reveal{opacity:0; transform:translateY(16px); transition:opacity .5s ease,transform .5s ease}
.reveal.in{opacity:1; transform:none}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important; transition-duration:.001ms !important}
  .reveal{opacity:1; transform:none}
  html{scroll-behavior:auto}
}

/* ============ [21] MÀN HÌNH NHỎ ============ */
@media (max-width:1020px){
  .g4,.prices{grid-template-columns:repeat(2,1fr)}
  .fgrid{grid-template-columns:1fr 1fr}
  .split{gap:var(--s6)}
}
@media (max-width:880px){
  .g3,.steps{grid-template-columns:repeat(2,1fr)}
  .split{grid-template-columns:1fr; gap:var(--s6); margin-bottom:var(--s8)}
  .split.flip .txt{order:0}
  .cta-box{grid-template-columns:1fr; padding:38px 26px}
}
/* Thanh trên chuyển sang menu burger SỚM hơn phần còn lại của trang.
   Đo thật: logo 90 + menu ngang 480 + cụm nút 353 = 923px, cộng 2 lề 20px
   ⇒ cần 963px mới xếp vừa một hàng. Trước đây burger chỉ bật ở ≤640px nên
   mọi khổ 641–962px (máy tính bảng, laptop nhỏ, cửa sổ thu hẹp) bị TRÀN NGANG
   — cụm .acts đội ra ngoài mép phải. Để mốc 1024px cho dư khoảng an toàn,
   phòng khi font Việt về muộn làm chữ trong menu rộng thêm vài px. */
@media (max-width:1024px){
  .nav .menu{
    display:none; position:absolute; top:68px; left:0; right:0; z-index:var(--z-menu);
    flex-direction:column; gap:2px; margin:0; padding:12px var(--gutter) 18px;
    background:var(--bg); border-bottom:1px solid var(--line); box-shadow:var(--sh);
  }
  .nav .menu.open{display:flex}
  .nav .menu a{padding:12px 13px; font-size:16px}
  .nav .acts .btn{display:none}          /* đẩy 2 nút xuống trong menu */
  .nav .menu .only-sm{display:flex}
  .nav .menu .btn{margin-top:8px}
  .burger{display:grid; place-items:center}
}

@media (max-width:640px){
  :root{--gutter:16px}
  .brand img,.brand>svg{height:26px}
  .g2,.g3,.g4,.steps,.prices{grid-template-columns:1fr}
  .stats{grid-template-columns:repeat(2,1fr)}
  section{padding:var(--s8) 0}
  .hero{padding:var(--s7) 0}
  .fgrid{grid-template-columns:1fr}
  .fbot{flex-direction:column; gap:8px}
}

/* ============ [22] IN GIẤY ============ */
@media print{
  header,footer,.cta-box,.burger,.theme-btn{display:none !important}
  body{background:#fff; color:#000}
  section{padding:16px 0}
}

/* =====================================================================
   [23] KHỐI RIÊNG CỦA TRANG CHỦ & TRANG TÍNH NĂNG
   (khung học theo preny.ai: khối tối bo tròn, lưới bento, dải kênh,
    tab ngành nghề, huy hiệu bay quanh ảnh app)
   ===================================================================== */

/* --- khối nền tối bo tròn lớn --- */
.dark-block{
  position:relative; overflow:hidden; border-radius:var(--r-xl);
  padding:66px 56px; background:#080D1B; color:#B9C2D6;
}
.dark-block::before{
  content:""; position:absolute; inset:0; pointer-events:none; opacity:.5;
  background:
    radial-gradient(closest-side,color-mix(in srgb,var(--b1) 55%,transparent),transparent) 12% 0/58% 70% no-repeat,
    radial-gradient(closest-side,color-mix(in srgb,var(--b3) 32%,transparent),transparent) 96% 88%/50% 60% no-repeat;
  filter:blur(30px);
}
.dark-block>*{position:relative}
.dark-block h2,.dark-block h3,.dark-block h4{color:#fff}
.dark-block p,.dark-block .split p{color:#8E9AB4}
.dark-block .list li{color:#8E9AB4}
.dark-block .shot{background:#0F1526; border-color:#222C45}
.dark-block .shot .bar{background:#131A2E; border-color:#222C45}
.dark-block .chat .b.k{background:#151D33; color:#C7D0E2}
.dark-block .shot .bar .url{background:#0B1120; border-color:#222C45; color:#5D6883}
.dark-block .shot .bar i{background:#2A3450}
.dark-block table.cmp{color:#B9C2D6}
.dark-block table.cmp thead th{background:#151D33; color:#fff}
.dark-block table.cmp th,.dark-block table.cmp td{border-color:#222C45}
.dark-block table.cmp td:first-child{color:#DDE3EF}
.dark-block table.cmp tbody tr:hover td{background:rgba(255,255,255,.03)}
.dark-block .inbox .side .ln{background:#2A3450}

/* --- lưới bento 5 ô (2 hàng: 2+1 rồi 1+1+1) --- */
.bento{display:grid; grid-template-columns:repeat(3,1fr); gap:18px}
.bento .b-wide{grid-column:span 2}
.bento .card{display:flex; flex-direction:column; overflow:hidden}
.bento .card h4{margin-bottom:8px; font-size:17px}
.bento .card p{font-size:15px}
.bento .card .fill{margin-top:auto; padding-top:var(--s5)}

/* --- dải kênh: ô nghiêng như hạt xúc xắc --- */
.hexrow{display:flex; flex-wrap:wrap; gap:16px; justify-content:center; margin-top:var(--s5)}
.hex{
  width:72px; height:72px; border-radius:20px; display:grid; place-items:center;
  background:var(--card); border:1px solid var(--line); box-shadow:var(--sh-sm);
  transform:rotate(45deg); transition:transform var(--t),box-shadow var(--t);
}
.hex>*{transform:rotate(-45deg)}
.hex:hover{transform:rotate(45deg) translateY(-4px); box-shadow:var(--sh-lg)}
.hex svg{width:30px; height:30px}
.chanrow{display:flex; flex-wrap:wrap; gap:10px; justify-content:center}
.chan{
  display:inline-flex; align-items:center; gap:9px; padding:9px 16px 9px 11px;
  border:1px solid var(--line); border-radius:var(--r-full); background:var(--card);
  font-size:14.5px; font-weight:600; color:var(--ink-2); box-shadow:var(--sh-xs);
}
.chan svg{width:20px; height:20px; flex:none}

/* --- tab ngành nghề (thanh có viền, tab đang chọn có gạch gradient) --- */
.indtabs{
  display:grid; grid-template-columns:repeat(5,1fr);
  border:1px solid var(--line); border-radius:var(--r-md) var(--r-md) 0 0;
  background:var(--card); overflow:hidden;
}
.indtabs button{
  display:flex; align-items:center; justify-content:center; gap:9px;
  padding:18px 10px; border:0; border-right:1px solid var(--line); background:transparent;
  font-size:14px; font-weight:750; letter-spacing:.05em; color:var(--muted);
  cursor:pointer; position:relative; transition:var(--t-fast);
}
.indtabs button:last-child{border-right:0}
.indtabs button svg{width:20px; height:20px; flex:none}
.indtabs button:hover{color:var(--ink); background:var(--soft)}
.indtabs button[aria-selected="true"]{color:var(--brand); background:var(--brand-weak)}
.indtabs button[aria-selected="true"]::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:3px; background:var(--grad);
}
.indbody{
  border:1px solid var(--line); border-top:0; border-radius:0 0 var(--r-md) var(--r-md);
  background:var(--card); padding:46px 44px;
}
.indbody .split{margin-bottom:0; gap:var(--s7)}
.indbody .kind{font-style:italic; color:var(--muted); font-size:16px; margin-bottom:2px}
.indbody h3{
  font-size:clamp(26px,3.4vw,36px); letter-spacing:.02em; margin-bottom:16px;
  background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent;
}
.linkmore{display:inline-flex; align-items:center; gap:6px; font-weight:650; font-size:15px}
.linkmore::after{content:"›"; font-size:19px; line-height:1}

/* --- ảnh app + huy hiệu bay quanh --- */
.showcase{position:relative; margin-top:var(--s8)}
.showcase .shot{position:relative; z-index:2; max-width:86%; margin-inline:auto}
.badge-float{
  position:absolute; z-index:3; display:inline-flex; align-items:center; gap:8px;
  padding:9px 14px; border-radius:var(--r-full); background:var(--card);
  border:1px solid var(--line); box-shadow:var(--sh-lg);
  font-size:13.5px; font-weight:650; color:var(--ink); white-space:nowrap;
  animation:fl 5s ease-in-out infinite;
}
.badge-float .dot{width:8px; height:8px; border-radius:50%; background:var(--grad); flex:none}
.badge-float.a{top:6%;   left:0}
.badge-float.b{top:30%;  right:0;  animation-delay:-1.6s}
.badge-float.c{bottom:18%; left:1%; animation-delay:-3.2s}
.badge-float.d{bottom:4%;  right:1%; animation-delay:-2.4s}
@keyframes fl{0%,100%{transform:translateY(0)} 50%{transform:translateY(-9px)}}

/* --- ảnh giả lập hộp thư 2 cột --- */
.inbox{display:grid; grid-template-columns:210px 1fr; min-height:330px}
.inbox .side{border-right:1px solid var(--line); padding:14px 12px; background:var(--soft)}
.dark-block .inbox .side{background:#0C1220; border-color:#222C45}
.inbox .side .row{display:flex; gap:9px; align-items:center; padding:9px 8px; border-radius:10px}
.inbox .side .row.on{background:var(--brand-weak)}
.dark-block .inbox .side .row.on{background:#1B1B3C}
.inbox .side .av{width:28px; height:28px; border-radius:50%; background:var(--grad); flex:none}
.inbox .side .ln{height:7px; border-radius:4px; background:var(--line); flex:1}
.inbox .side .ln.s{width:60%; flex:none; margin-top:5px}
.inbox .main{padding:16px 18px}

@media (max-width:980px){
  .bento{grid-template-columns:repeat(2,1fr)}
  .bento .b-wide{grid-column:span 2}
  .indtabs{grid-template-columns:repeat(3,1fr)}
  .indtabs button{border-bottom:1px solid var(--line)}
}
@media (max-width:880px){
  .dark-block{padding:44px 26px}
  .indbody{padding:30px 22px}
  .inbox{grid-template-columns:1fr}
  .inbox .side{display:none}
}
@media (max-width:640px){
  .bento{grid-template-columns:1fr}
  .bento .b-wide{grid-column:span 1}
  .indtabs{grid-template-columns:repeat(2,1fr)}
  .indtabs button{padding:14px 8px; font-size:13px}
  .badge-float{display:none}
}

/* =====================================================================
   [24] SƠ ĐỒ CHÒM SAO Ở HERO
   Thẻ trung tâm (danh sách khách) nối dây sang các thẻ vệ tinh.
   Dây vẽ bằng viền bo góc của thẻ rỗng -> khúc cua mềm, co giãn theo
   màn hình, không cần SVG. Cột dùng hàng cao bằng nhau để tính được
   tâm mỗi thẻ bằng calc().
   ===================================================================== */
.constel{
  --gap:76px;                       /* khe giữa 3 cột = chỗ chạy dây */
  --cg:20px;                        /* khe dọc giữa các thẻ trong cột */
  --wire:color-mix(in srgb,var(--b1) 55%,transparent);
  --elbow:18px;                     /* độ bo của khúc cua */
  --nhip:3.4s;                      /* chu kỳ vệt sáng chạy trên dây */
  --chay:calc(var(--gap) / 2 - 7px);/* quãng chấm sáng đi hết một nhánh */
  position:relative; margin-top:var(--s8); text-align:left;
  display:grid; grid-template-columns:1fr 1.12fr 1fr; gap:var(--gap);
  align-items:center; padding:var(--s7) var(--s6);
}
/* nền loang màu phía sau cho cả cụm */
.constel::before{
  content:""; position:absolute; inset:0; z-index:0; border-radius:var(--r-xl);
  background:
    radial-gradient(60% 60% at 22% 18%, color-mix(in srgb,var(--b1) 14%,transparent), transparent 70%),
    radial-gradient(55% 55% at 82% 82%, color-mix(in srgb,var(--b3) 13%,transparent), transparent 70%),
    linear-gradient(160deg, color-mix(in srgb,var(--b2) 5%,transparent), transparent 60%);
}
.constel>*{position:relative; z-index:1}
/* Trước đây cột dùng grid-auto-rows:1fr để tâm mỗi thẻ tính được bằng calc().
   Cái giá là thẻ ngắn bị kéo cao bằng thẻ dài nhất: thẻ bảo mật cần 337px thì
   hai thẻ 129px cũng phải 337px -> mỗi thẻ thừa hơn 200px ruột rỗng.
   Giờ để thẻ cao theo đúng nội dung, còn tâm thẻ do JS đo và đổ vào --y1/--y3
   (xem app.js, mục "dây nối cụm constellation"). calc() cũ giữ làm giá trị dự
   phòng cho trường hợp JS không chạy. */
.constel .col{position:relative; display:grid; grid-auto-rows:auto; align-items:center; gap:var(--cg)}
/* Hàng trên và hàng dưới bằng nhau -> thẻ giữa luôn nằm đúng tâm cột, khớp với
   .w.mid và với đoạn nối vào thẻ trung tâm. */
.col.n3{grid-template-rows:1fr auto 1fr}

/* ---- thẻ vệ tinh ---- */
.cnode{
  position:relative; display:flex; flex-direction:column; justify-content:center;
  background:var(--card);
  border:1px solid color-mix(in srgb,var(--b1) 12%,var(--line));
  border-radius:var(--r-md); padding:17px 19px;
  box-shadow:0 1px 2px rgba(11,16,32,.04), 0 10px 26px color-mix(in srgb,var(--b2) 8%,transparent);
  transition:transform var(--t),box-shadow var(--t);
}
.cnode:hover{
  transform:translateY(-3px);
  box-shadow:0 4px 10px rgba(11,16,32,.05), 0 22px 46px color-mix(in srgb,var(--b2) 16%,transparent);
}
.cnode h4{margin:0 0 11px; font-size:14.6px; display:flex; align-items:center; gap:9px}
.cnode h4 .ic{
  width:25px; height:25px; border-radius:8px; display:grid; place-items:center;
  background:var(--grad); color:#fff; font-size:12.5px; flex:none;
}
.cnode .sub{font-size:12.3px; color:var(--faint); font-weight:500; margin:-6px 0 11px}
/* danh sách trong thẻ vệ tinh: chữ nhỏ và dòng sát hơn danh sách thường,
   vì thẻ chỉ rộng 291px, mỗi gạch đầu dòng đã tự xuống 2 hàng rồi */
.cnode .list{margin:0; font-size:12.4px; line-height:1.45}
.cnode .list li{padding:3px 0 3px 21px}
.cnode .list li::before{font-size:11px; top:3px}

/* ---- thẻ trung tâm ---- */
.chub{
  position:relative; border:1px solid transparent; border-radius:var(--r-lg);
  background:linear-gradient(var(--card),var(--card)) padding-box, var(--grad) border-box;
  box-shadow:0 6px 16px rgba(11,16,32,.06), 0 30px 66px color-mix(in srgb,var(--b2) 20%,transparent);
  padding:20px 18px;
}
.chub>h4{margin:0 0 var(--s4); font-size:15.5px; text-align:center}
.crow{
  border:1px solid var(--line-soft); border-radius:var(--r);
  padding:12px 13px; margin-bottom:10px; background:var(--card);
}
.crow:last-child{margin-bottom:0}
.crow .top{display:flex; align-items:center; gap:10px}
.crow .av{width:32px; height:32px; border-radius:50%; background:var(--grad); flex:none}
.crow .nm{font-weight:700; font-size:14px; color:var(--ink); line-height:1.3}
.crow .ph{font-size:12.4px; color:var(--muted); font-variant-numeric:tabular-nums}
.crow .chips{display:flex; flex-wrap:wrap; gap:6px; margin-top:9px}
.crow .li{display:flex; align-items:center; gap:8px; margin-top:8px; font-size:12.4px; color:var(--muted)}
.crow .li .d{width:5px; height:5px; border-radius:50%; background:var(--brand); flex:none}

/* nhãn viền rỗng (giống chip của Preny) */
.chip{
  display:inline-block; padding:2px 9px; border-radius:var(--r-full);
  font-size:11px; font-weight:650; line-height:1.6;
  border:1px solid currentColor; background:transparent;
}
.chip.v{color:var(--brand)}
.chip.g{color:var(--ok)}
.chip.o{color:var(--warn)}
.chip.m{color:var(--faint)}

/* ---- thanh đo ---- */
.bar{display:flex; align-items:center; gap:9px; margin-top:8px; font-size:12.4px; color:var(--muted)}
.bar .lb{min-width:66px}
.bar .track{display:block; flex:1; height:6px; border-radius:99px; background:var(--sunken); overflow:hidden}
.bar .fillv{display:block; height:100%; border-radius:99px; background:var(--grad)}
.bar .v{font-weight:750; color:var(--ink); font-variant-numeric:tabular-nums; min-width:42px; text-align:right}

/* ---- ô kênh ---- */
.minichan{display:grid; grid-template-columns:1fr 1fr; gap:8px}
.minichan span{display:flex; align-items:center; gap:8px; font-size:12.6px; color:var(--ink-2)}
.minichan svg{width:17px; height:17px; flex:none}

/* =============== DÂY NỐI =============== */
/* Mỗi dây là một hộp rỗng chỉ bật 2 cạnh viền + bo một góc -> khúc cua mềm.
   Hộp chạy từ mép thẻ ra giữa khe; đoạn từ giữa khe vào thẻ trung tâm do
   .chub::before / ::after lo.                                              */
.constel .w{
  position:absolute; width:calc(var(--gap) / 2);
  border:0 solid var(--wire); pointer-events:none; z-index:0;
}
.col-l .w{right:calc(var(--gap) / -2)}
.col-r .w{left:calc(var(--gap) / -2)}
.col-l .w.up{border-top-width:1px; border-right-width:1px; border-top-right-radius:var(--elbow)}
.col-l .w.dn{border-bottom-width:1px; border-right-width:1px; border-bottom-right-radius:var(--elbow)}
.col-r .w.up{border-top-width:1px; border-left-width:1px; border-top-left-radius:var(--elbow)}
.col-r .w.dn{border-bottom-width:1px; border-left-width:1px; border-bottom-left-radius:var(--elbow)}
.constel .w.mid{top:50%; height:0; border-top-width:1px}

/* --y1: tâm thẻ đầu tính từ đỉnh cột. --y3: tâm thẻ cuối tính từ đáy cột.
   JS đổ vào; calc() phía sau là giá trị dự phòng theo công thức thẻ đều nhau. */
.col.n2 .w.up{top:var(--y1,calc((100% - var(--cg)) / 4)); bottom:50%}
.col.n2 .w.dn{top:50%; bottom:var(--y3,calc((100% - var(--cg)) / 4))}
.col.n3 .w.up{top:var(--y1,calc((100% - 2 * var(--cg)) / 6)); bottom:50%}
.col.n3 .w.dn{top:50%; bottom:var(--y3,calc((100% - 2 * var(--cg)) / 6))}

/* chấm tròn ở chỗ dây chạm thẻ */
.cnode::after{
  content:""; position:absolute; top:50%; margin-top:-3px;
  width:6px; height:6px; border-radius:50%; background:var(--wire); z-index:1;
}
.col-l .cnode::after{right:-3px}
.col-r .cnode::after{left:-3px}

/* đoạn nối từ giữa khe vào thẻ trung tâm */
.chub::before,.chub::after{
  content:""; position:absolute; top:50%; width:calc(var(--gap) / 2); height:1px;
  background-color:var(--wire); z-index:0;
  /* vệt sáng chạy dọc đoạn này, xuất phát từ thẻ trung tâm */
  background-image:linear-gradient(90deg,transparent,var(--b2),transparent);
  background-size:40% 100%; background-repeat:no-repeat;
}
.chub::before{left:calc(var(--gap) / -2)}
.chub::after{right:calc(var(--gap) / -2)}

/* =============== HIỆU ỨNG =============== */
/* 1. Tín hiệu chạy dọc dây, hướng từ thẻ vệ tinh vào thẻ trung tâm */
.constel .w::after{
  content:""; position:absolute; width:7px; height:7px; border-radius:50%;
  background:var(--b2); box-shadow:0 0 10px 2px color-mix(in srgb,var(--b2) 55%,transparent);
}
.col-l .w.up::after,.col-r .w.up::after{top:-3.5px}
.col-l .w.dn::after,.col-r .w.dn::after{bottom:-3.5px}
.constel .w.mid::after{top:-3.5px}
/* Hướng chạy: THẺ TRUNG TÂM -> ra hai bên -> tới từng thẻ vệ tinh.
   Vệt sáng đi đoạn .chub::before/::after trước, tới nửa khe thì chấm sáng
   trên .w nhận tiếp và chạy nốt vào thẻ. Hai chặng dùng cùng chu kỳ, chặng
   sau trễ đúng nửa nhịp nên mắt đọc thành một đường liền. */
.chub::before{animation:tia-ra-trai var(--nhip) cubic-bezier(.5,0,.5,1) infinite}
.chub::after{animation:tia-ra-phai var(--nhip) cubic-bezier(.5,0,.5,1) infinite}
/* ⚠ Không đụng vào opacity ở đây: nền của chính ::before/::after là sợi dây.
   Cho opacity chạy 0->1 là cả sợi dây nhấp nháy tắt/bật. Chỉ trượt vệt sáng;
   trượt hết ra ngoài khung là nó tự khuất, dây vẫn nguyên. */
@keyframes tia-ra-phai{
  0%{background-position-x:-70%}
  45%,100%{background-position-x:170%}
}
@keyframes tia-ra-trai{
  0%{background-position-x:170%}
  45%,100%{background-position-x:-70%}
}

/* chấm sáng trên nhánh: cột trái chạy từ giữa khe vào thẻ (sang trái),
   cột phải chạy từ giữa khe ra thẻ (sang phải) */
.col-l .w::after{right:0; animation:chay-trai var(--nhip) cubic-bezier(.5,0,.5,1) infinite}
.col-r .w::after{left:0; animation:chay-phai var(--nhip) cubic-bezier(.5,0,.5,1) infinite}
.constel .w::after{animation-delay:calc(var(--nhip) * .34)}
.col-l .w:nth-of-type(2)::after,.col-r .w:nth-of-type(2)::after{animation-delay:calc(var(--nhip) * .34 + .5s)}
.col-r .w:nth-of-type(3)::after{animation-delay:calc(var(--nhip) * .34 + 1s)}
/* ⚠ translateX(%) trong pseudo tính theo bề rộng của CHÍNH chấm sáng (7px),
   không phải bề rộng sợi dây. calc(100% - 18px) ra -11px: chấm nhích 11px
   và nhích ngược chiều — nên trước giờ nhìn như dây đứng im. Phải ghi thẳng
   quãng đường theo --gap. */
@keyframes chay-phai{
  0%{transform:translateX(0); opacity:0}
  12%{opacity:1}
  60%,100%{transform:translateX(var(--chay)); opacity:0}
}
@keyframes chay-trai{
  0%{transform:translateX(0); opacity:0}
  12%{opacity:1}
  60%,100%{transform:translateX(calc(var(--chay) * -1)); opacity:0}
}

/* 2. Vòng sóng lan ra ở chỗ dây chạm thẻ */
.cnode::before{
  content:""; position:absolute; top:50%; margin-top:-3px;
  width:6px; height:6px; border-radius:50%;
  border:1px solid var(--b2); z-index:1; pointer-events:none;
  animation:song 2.6s ease-out infinite;
}
.col-l .cnode::before{right:-3px}
.col-r .cnode::before{left:-3px}
/* vòng sóng nổ đúng lúc chấm sáng chạm mép thẻ */
.constel .cnode::before{animation-duration:var(--nhip); animation-delay:calc(var(--nhip) * .9)}
.col-l .cnode:nth-of-type(2)::before,.col-r .cnode:nth-of-type(2)::before{animation-delay:calc(var(--nhip) * .9 + .5s)}
.col-r .cnode:nth-of-type(3)::before{animation-delay:calc(var(--nhip) * .9 + 1s)}
@keyframes song{
  0%{transform:scale(1); opacity:.6}
  70%,100%{transform:scale(3.2); opacity:0}
}

/* 3. Thanh đo tự chạy lên khi trang mở */
.bar .fillv{animation:len 1.1s cubic-bezier(.2,.7,.3,1) both}
@keyframes len{from{width:0}}

/* 4. Các thẻ hiện dần lần lượt */
.constel .cnode,.constel .chub{animation:noi-len .6s cubic-bezier(.2,.7,.3,1) both}
.constel .chub{animation-delay:.05s}
.col-l .cnode:nth-of-type(1){animation-delay:.18s}
.col-l .cnode:nth-of-type(2){animation-delay:.28s}
.col-r .cnode:nth-of-type(1){animation-delay:.24s}
.col-r .cnode:nth-of-type(2){animation-delay:.34s}
.col-r .cnode:nth-of-type(3){animation-delay:.44s}
@keyframes noi-len{from{opacity:0; transform:translateY(14px)}}

/* 5. Nền loang thở nhẹ */
.constel::before{animation:tho 14s ease-in-out infinite}
@keyframes tho{0%,100%{opacity:1} 50%{opacity:.72}}

/* 6. Cả cụm bồng bềnh như nổi trên mặt nước.
   Chạy trên .constel chứ không chạy trên từng thẻ: dây nối là viền của các
   hộp con, thẻ mà trôi lệch nhau vài px là dây đứt khỏi thẻ ngay. Nâng cả
   cụm thì dây đi theo, không bao giờ rời. Biên độ ±13px (~7mm mỗi chiều),
   nhịp lệch pha nhẹ cho đỡ máy móc. */
.constel{
  animation:bong-benh 7.5s ease-in-out infinite;
  will-change:transform;
}
@keyframes bong-benh{
  0%  {transform:translateY(-13px)}
  28% {transform:translateY(3px)}
  50% {transform:translateY(13px)}
  76% {transform:translateY(-4px)}
  100%{transform:translateY(-13px)}
}
/* bóng đổ dày lên khi cụm chìm xuống, mỏng đi khi nổi lên — cho ra cảm giác
   thật sự đang bập bềnh chứ không phải chỉ trượt lên trượt xuống */
.constel .chub{
  animation:noi-len .6s cubic-bezier(.2,.7,.3,1) .05s both,
            bong-benh-bong 7.5s ease-in-out infinite;
}
@keyframes bong-benh-bong{
  0%,100%{box-shadow:0 14px 30px rgba(11,16,32,.07), 0 44px 88px color-mix(in srgb,var(--b2) 22%,transparent)}
  50%    {box-shadow:0 4px 12px rgba(11,16,32,.05), 0 20px 48px color-mix(in srgb,var(--b2) 14%,transparent)}
}

@media (max-width:1040px){
  .constel{--gap:48px; --elbow:14px; grid-template-columns:1fr 1.1fr; padding:var(--s6) var(--s4)}
  /* ⚠ align-items PHẢI là start, ĐỪNG đổi lại thành stretch.
     Ba thẻ này xếp thành một hàng ngang, nội dung dài ngắn rất khác nhau:
     "Bảo mật dữ liệu" cần 282px, hai thẻ kia chỉ cần 129px. Với stretch thì cả
     ba bị kéo cao bằng thẻ cao nhất, mà .cnode có justify-content:center nên
     chữ dồn vào giữa ⇒ hai thẻ ngắn đội đệm trên/dưới lên 94px thay vì 17px,
     thừa 152px ruột rỗng mỗi thẻ. start = thẻ cao đúng bằng nội dung.
     (Cùng một cái bẫy với grid-auto-rows:1fr đã bỏ ở khối .constel .col trên.) */
  .constel .col-r{grid-column:1 / -1; grid-auto-rows:auto; grid-template-columns:repeat(3,1fr); grid-template-rows:none; align-items:start}
  .col-r .w,.chub::after{display:none}
  .col-r .cnode::after{display:none}
}
/* --- ĐIỆN THOẠI: cụm thẻ thành băng chuyền vuốt ngang, có chấm chỉ trang --- */
@media (max-width:760px){
  .constel{
    display:flex; grid-template-columns:none; gap:12px;
    overflow-x:auto; overflow-y:hidden; scroll-snap-type:x mandatory;
    padding:var(--s5) var(--s4); margin-inline:calc(var(--gutter) * -1);
    scroll-padding-inline:var(--s4); -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    animation:none;                               /* băng chuyền thì không bồng bềnh */
  }
  .constel::-webkit-scrollbar{display:none}
  .constel::before{border-radius:0; inset:0}
  .constel .col{display:contents}                 /* thẻ con thành ô của băng chuyền */
  .constel .cnode,.constel .chub{
    flex:0 0 82%; scroll-snap-align:center; margin:0;
    animation:none;                               /* băng chuyền rồi thì thôi hiệu ứng nổi lên */
  }
  .constel .chub{order:-1}                        /* danh sách khách hàng đứng đầu */
  .constel .w,.cnode::after,.cnode::before,.chub::before,.chub::after{display:none}
  .cnode:hover,.chub:hover{transform:none}
}

/* chấm chỉ trang của băng chuyền */
.dots{display:none; justify-content:center; gap:7px; margin-top:var(--s4)}
.dots button{
  width:7px; height:7px; padding:0; border:0; border-radius:99px; cursor:pointer;
  background:color-mix(in srgb,var(--brand) 26%,transparent); transition:var(--t);
}
.dots button[aria-current="true"]{width:22px; background:var(--grad)}
@media (max-width:760px){ .dots{display:flex} }

/* --- Ô cần bạn điền trước khi đăng (tên đơn vị, MST, số tài khoản…) --- */
.tbd{
  background:#FEF3C7; color:#92400E; padding:1px 7px; border-radius:6px;
  font-weight:650; font-size:.94em; border:1px dashed #D97706;
}
:root[data-theme="dark"] .tbd{background:#3A2A08; color:#FCD34D; border-color:#B45309}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .tbd{background:#3A2A08; color:#FCD34D; border-color:#B45309}
}

/* =====================================================================
   [25] HIỆU ỨNG CAO CẤP — kính mờ · viền gradient chạy · quầng sáng
   -------------------------------------------------------------------
   Học KỸ THUẬT từ preny.ai (đo bằng cách đọc CSS thật của họ), nhưng:
   • KHÔNG lấy một file ảnh/SVG nào của họ — mọi hình nền ở đây tự vẽ
     bằng gradient CSS, nên nhẹ (0 KB ảnh) và tự đổi theo bộ màu Katty.
   • Đổi bảng màu tím–hồng–cam của họ sang violet→blue→cyan của mình,
     tức là dùng thẳng --b1/--b2/--b3 nên gắn data-palette="b|c" là đổi hết.
   Dùng cho khối "Khám phá các module cốt lõi" và lưới bento ở trang chủ.
   ===================================================================== */

/* --- [25.1] Nền cực quang cho khối tối --------------------------------
   Cũ: 2 vệt loang mờ. Mới: 4 vệt lệch nhau + lưới mảnh bị che dần ở mép
   + đường sáng mảnh chạy dọc cạnh trên (giả phản chiếu ánh sáng). ------ */
.dark-block{
  border:1px solid rgba(139,92,246,.20);
  box-shadow:0 40px 90px rgba(0,0,0,.45);
  background:#080D1B;
}
.dark-block::before{
  opacity:.85; filter:blur(46px);
  background:
    radial-gradient(closest-side,color-mix(in srgb,var(--b1) 62%,transparent),transparent) 8% -6%/62% 74% no-repeat,
    radial-gradient(closest-side,color-mix(in srgb,var(--b2) 40%,transparent),transparent) 78% 8%/46% 52% no-repeat,
    radial-gradient(closest-side,color-mix(in srgb,var(--b3) 34%,transparent),transparent) 98% 92%/52% 62% no-repeat,
    radial-gradient(closest-side,color-mix(in srgb,var(--b1) 26%,transparent),transparent) 4% 104%/56% 56% no-repeat;
}
.dark-block::after{                      /* lưới mảnh + gờ sáng cạnh trên */
  content:""; position:absolute; inset:0; pointer-events:none; z-index:0; opacity:.5;
  background-image:
    linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);
  background-size:72px 72px;
  -webkit-mask-image:radial-gradient(ellipse 76% 58% at 50% 0%,#000,transparent 72%);
          mask-image:radial-gradient(ellipse 76% 58% at 50% 0%,#000,transparent 72%);
}
.dark-block>*{z-index:1}

/* --- [25.2] Huy hiệu phát sáng (thay chip .tag nhỏ trong khối tối) ----
   Chip gradient cao 46px, có vòng sáng trắng 1px bao ngoài + đổ bóng màu
   → nổi hẳn khỏi nền tối, đây là thứ tạo cảm giác "đắt" nhất. --------- */
.glow-pill{
  display:inline-flex; align-items:center; gap:9px;
  min-height:46px; padding:9px 20px; border-radius:14px; margin-bottom:18px;
  font-size:17px; font-weight:800; letter-spacing:-.01em; line-height:1.25; color:#fff;
  background:linear-gradient(88deg,
    color-mix(in srgb,var(--b1) 86%,transparent) 4%,
    color-mix(in srgb,var(--b2) 86%,transparent) 62%,
    color-mix(in srgb,var(--b3) 80%,transparent) 96%);
  -webkit-backdrop-filter:blur(50px); backdrop-filter:blur(50px);
  box-shadow:0 0 0 1px rgba(255,255,255,.30),
             0 6px 26px color-mix(in srgb,var(--b2) 45%,transparent);
}
.glow-pill .dot{
  width:9px; height:9px; border-radius:50%; flex:none; background:#fff;
  box-shadow:0 0 0 4px rgba(255,255,255,.22); animation:pulse 2.4s ease-in-out infinite;
}
@keyframes pulse{0%,100%{box-shadow:0 0 0 4px rgba(255,255,255,.22)} 50%{box-shadow:0 0 0 8px rgba(255,255,255,.06)}}

/* --- [25.3] Chữ gradient cho tiêu đề phụ -----------------------------
   Trong khối tối, h4 chuyển từ trắng phẳng sang gradient sáng. Chặng đầu
   dùng violet SÁNG (#A78BFA) chứ không phải #8B5CF6 để còn đọc được. -- */
.gtext,
.dark-block .txt h4{
  background:linear-gradient(88deg,#A78BFA -2%,#6E8BFF 46%,#22D3EE 96%);
  -webkit-background-clip:text; background-clip:text;
  color:transparent; -webkit-text-fill-color:transparent;
}
.dark-block .txt h4{font-size:17.5px; font-weight:800; margin-bottom:6px; letter-spacing:-.012em}

/* --- [25.4] Kính mờ (glassmorphism) ----------------------------------
   3 lớp: nền trắng rất nhạt + làm mờ hậu cảnh + 2 gờ sáng nội (trên và
   trái) giả cạnh vát của tấm kính. Có bản cho nền sáng và nền tối. --- */
/* ⚠ Tấm kính PHẢI đổi theo nền sáng/tối. Bản đầu ghi cứng rgba(255,255,255,.55)
   nên ở chế độ tối tấm kính vẫn sáng trong khi chữ đã chuyển sang màu sáng
   → chữ sáng trên nền sáng, đọc không nổi (bắt được bằng ảnh chụp nền tối).
   Cách chữa: để 5 biến, đổi biến theo chủ đề — khối tối tự đặt biến của
   riêng nó nên vẫn đúng ngay cả khi cả trang đang ở nền sáng. */
:root{
  --glass-bg:rgba(255,255,255,.55);
  --glass-line:rgba(255,255,255,.65);
  --glass-sh:0 8px 32px rgba(11,16,32,.08), inset 0 1px 0 rgba(255,255,255,.9);
  --glass-top:linear-gradient(90deg,transparent,rgba(255,255,255,.85),transparent);
  --glass-left:linear-gradient(180deg,rgba(255,255,255,.8),transparent,rgba(255,255,255,.3));
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --glass-bg:rgba(255,255,255,.055);
    --glass-line:rgba(255,255,255,.11);
    --glass-sh:0 10px 38px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.16);
    --glass-top:linear-gradient(90deg,transparent,rgba(255,255,255,.35),transparent);
    --glass-left:linear-gradient(180deg,rgba(255,255,255,.28),transparent,rgba(255,255,255,.1));
  }
}
:root[data-theme="dark"]{
  --glass-bg:rgba(255,255,255,.055);
  --glass-line:rgba(255,255,255,.11);
  --glass-sh:0 10px 38px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.16);
  --glass-top:linear-gradient(90deg,transparent,rgba(255,255,255,.35),transparent);
  --glass-left:linear-gradient(180deg,rgba(255,255,255,.28),transparent,rgba(255,255,255,.1));
}
.dark-block,.glass.on-dark{               /* luôn dùng bản nền tối */
  --glass-bg:rgba(255,255,255,.055);
  --glass-line:rgba(255,255,255,.11);
  --glass-sh:0 10px 38px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.16);
  --glass-top:linear-gradient(90deg,transparent,rgba(255,255,255,.35),transparent);
  --glass-left:linear-gradient(180deg,rgba(255,255,255,.28),transparent,rgba(255,255,255,.1));
}
.glass{
  position:relative; overflow:hidden; border-radius:var(--r-md);
  background:var(--glass-bg);
  -webkit-backdrop-filter:blur(20px); backdrop-filter:blur(20px);
  border:1px solid var(--glass-line);
  box-shadow:var(--glass-sh);
}
.glass::before{                          /* gờ sáng cạnh trên */
  content:""; position:absolute; top:0; left:0; right:0; height:1px;
  background:var(--glass-top);
}
.glass::after{                           /* gờ sáng cạnh trái */
  content:""; position:absolute; top:0; left:0; width:1px; height:100%;
  background:var(--glass-left);
}

/* --- [25.5] Ảnh giả lập trong khối tối = tấm kính --------------------- */
.dark-block .shot{
  background:rgba(255,255,255,.05);
  -webkit-backdrop-filter:blur(18px); backdrop-filter:blur(18px);
  border-color:rgba(255,255,255,.11);
  box-shadow:0 24px 64px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.14);
}
.dark-block .shot .bar{background:rgba(255,255,255,.045); border-color:rgba(255,255,255,.09)}
.dark-block .shot .bar .url{background:rgba(0,0,0,.28); border-color:rgba(255,255,255,.09); color:#8E9AB4}
.dark-block .shot .bar i{background:rgba(255,255,255,.18)}

/* --- [25.6] Thẻ sang: viền gradient chạy khi rê chuột -----------------
   Hai lớp ::before/::after nằm sẵn ngoài khung (một trên, một dưới), rê
   chuột thì trượt vào giữa và hiện dần → cảm giác ánh sáng quét qua thẻ.
   Viền đổi thành gradient bằng mẹo 2 nền padding-box + border-box. ---- */
.card.lux{overflow:hidden; border:1px solid var(--line); transition:transform .5s cubic-bezier(.4,0,.2,1),box-shadow .5s,border-color .5s,background .5s}
.card.lux::before,.card.lux::after{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  border-radius:inherit; opacity:0;
  transition:opacity .7s ease-in-out,transform .7s ease-in-out;
  /* ⚠ phải ghi rõ bán kính (circle 260px). Để "circle at 0 0" trống thì
     mặc định là farthest-corner → vệt loang phủ kín thẻ, chữ xám nằm trên
     nền tím bão hoà là mất tương phản. Đã đo bằng ảnh chụp rồi mới sửa. */
  background:
    radial-gradient(circle 260px at 0 0,
      color-mix(in srgb,var(--b1) 19%,transparent) 0,
      color-mix(in srgb,var(--b2) 9%,transparent) 42%, transparent 78%),
    radial-gradient(circle 260px at 100% 100%,
      color-mix(in srgb,var(--b3) 18%,transparent) 0,
      color-mix(in srgb,var(--b2) 8%,transparent) 42%, transparent 78%);
}
/* Vệt loang làm nền sáng lên → chữ phụ phải đậm lại cho đủ tương phản.
   Đo thật: để nguyên màu --muted thì chỉ còn 3,7:1 (dưới chuẩn 4,5:1). */
.card.lux:hover p,.card.lux:hover .list li,.card.lux:hover ul li{color:var(--ink-2)}
.card.lux::before{transform:translateY(-100%)}
.card.lux::after{transform:translateY(100%)}
.card.lux:hover::before,.card.lux:hover::after{opacity:1; transform:translateY(0)}
.card.lux>*:not(.lop-nen){position:relative; z-index:1}
.card.lux:hover{
  transform:translateY(-4px); box-shadow:var(--sh-lg); border-color:transparent;
  background:linear-gradient(var(--card),var(--card)) padding-box, var(--grad) border-box;
}
/* quầng sáng ở góc thẻ, nở to và đậm lên khi rê chuột */
.lux-glow{
  position:absolute; left:-40px; bottom:-40px; width:220px; height:220px;
  z-index:0; pointer-events:none; filter:blur(60px); transition:all .9s ease-in-out;
  background:radial-gradient(circle,
    color-mix(in srgb,var(--b1) 25%,transparent),
    color-mix(in srgb,var(--b2) 15%,transparent), transparent 70%);
}
.card.lux:hover .lux-glow{
  filter:blur(80px);
  background:radial-gradient(circle,
    color-mix(in srgb,var(--b1) 50%,transparent),
    color-mix(in srgb,var(--b2) 38%,transparent),
    color-mix(in srgb,var(--b3) 28%,transparent), transparent 70%);
}

/* --- [25.7] Ô icon: mặc định là kính, rê vào thẻ thì đổ đầy gradient -- */
.iconbadge{
  position:relative; width:48px; height:48px; border-radius:16px; overflow:hidden;
  display:grid; place-items:center; color:var(--brand);
  background:rgba(255,255,255,.15); -webkit-backdrop-filter:blur(20px); backdrop-filter:blur(20px);
  border:1px solid var(--line);
  box-shadow:0 8px 32px rgba(11,16,32,.06), inset 0 1px 0 rgba(255,255,255,.8);
  transition:background .5s,border-color .5s,box-shadow .5s,color .5s;
}
.iconbadge svg{width:24px; height:24px; position:relative; z-index:1}
.iconbadge::before{
  content:""; position:absolute; inset:0; border-radius:inherit; z-index:0;
  background:var(--grad); opacity:0; transition:opacity .5s ease-in-out;
}
.card.lux:hover .iconbadge{border-color:transparent; box-shadow:var(--sh-brand); color:#fff}
.card.lux:hover .iconbadge::before{opacity:1; transition-delay:.35s}

/* --- [25.8] Khung điện thoại giả lập ---------------------------------
   Viền máy là gradient thương hiệu, bên trong là màn hình kính. Không
   dùng ảnh — nên đổi bộ màu là đổi luôn màu viền máy. ----------------- */
.phone{
  position:relative; width:100%; max-width:335px; margin-inline:auto;
  padding:11px 11px 13px; border-radius:42px;
  background:linear-gradient(155deg,
    color-mix(in srgb,var(--b1) 62%,#0B1020),
    color-mix(in srgb,var(--b2) 40%,#0B1020) 55%,
    color-mix(in srgb,var(--b3) 34%,#0B1020));
  box-shadow:0 34px 80px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.32);
}
.phone::before{                          /* loa thoại ở đỉnh máy */
  content:""; position:absolute; top:20px; left:50%; transform:translateX(-50%);
  width:78px; height:6px; border-radius:99px; background:#05080F; z-index:3;
  box-shadow:inset 0 1px 2px rgba(0,0,0,.9);
}
.phone .screen{
  border-radius:32px; overflow:hidden; background:#0C1220;
  border:1px solid rgba(255,255,255,.09);
}
.phone .top{                             /* thanh tên người đang chat */
  display:flex; align-items:center; gap:11px; padding:26px 15px 13px;
  border-bottom:1px solid rgba(255,255,255,.08); background:rgba(255,255,255,.04);
}
.phone .top .av{width:26px; height:26px; border-radius:50%; background:var(--grad); flex:none}
.phone .top .ln{display:block; height:8px; border-radius:99px; background:rgba(255,255,255,.16)}
.phone .top .ln+.ln{margin-top:6px; width:64%; background:rgba(255,255,255,.09)}

/* --- [25.9] Hội thoại thật hơn: có tên người gửi + giờ + hiện dần ---- */
.feed{
  height:470px; overflow-y:auto; padding:14px 13px 18px;
  display:flex; flex-direction:column; gap:11px;
  /* ⚠ PHẢI là auto, không được smooth: app.js tự nhích scrollTop 40ms một
     lần, nếu để smooth thì mỗi lần gán lại khởi động một cú cuộn mượt mới
     → giật cục và bị trình duyệt nuốt mất. Việc trôi mượt do app.js lo. */
  scroll-behavior:auto;
  /* mờ dần ở mép trên/dưới để tin nhắn không bị cắt cụt ngang phè */
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 20px,#000 calc(100% - 26px),transparent 100%);
          mask-image:linear-gradient(180deg,transparent 0,#000 20px,#000 calc(100% - 26px),transparent 100%);
}
.feed .msg{max-width:88%; padding:11px 15px; font-size:13.6px; line-height:1.55; animation:slideIn .5s both}
.feed .msg .nm{display:block; font-size:11px; font-weight:750; margin-bottom:5px}
.feed .msg .tm{display:block; margin-top:6px; font-size:10px; text-align:right}
.feed .me{                               /* khách: thẻ trắng, gạch màu bên trái */
  align-self:flex-end; background:#fff; color:#1B2130;
  border-radius:22px 22px 6px 22px; border-left:4px solid var(--b1);
}
.feed .me .nm{color:var(--b1)}
.feed .me .tm{color:#9AA3B5}
.feed .bot{                              /* Katty: nền gradient, chữ trắng */
  align-self:flex-start; color:#fff; border-radius:22px 22px 22px 6px;
  background:linear-gradient(135deg,
    color-mix(in srgb,var(--b1) 92%,#0B1020),
    color-mix(in srgb,var(--b2) 82%,#0B1020));
  box-shadow:0 10px 26px color-mix(in srgb,var(--b1) 30%,transparent);
}
.feed .bot .nm{color:rgba(255,255,255,.72)}
.feed .bot .tm{color:rgba(255,255,255,.6)}
.feed .msg:nth-child(2){animation-delay:.1s}
.feed .msg:nth-child(3){animation-delay:.2s}
.feed .msg:nth-child(4){animation-delay:.3s}
.feed .msg:nth-child(5){animation-delay:.4s}
.feed .msg:nth-child(6){animation-delay:.5s}
.feed .msg:nth-child(7){animation-delay:.6s}
.feed .msg:nth-child(8){animation-delay:.7s}
@keyframes slideIn{from{opacity:0; transform:translateY(10px)} to{opacity:1; transform:translateY(0)}}
/* thẻ nhỏ "Katty vừa làm gì" chèn giữa hội thoại */
.feed .act{
  align-self:flex-start; display:inline-flex; align-items:center; gap:7px;
  padding:7px 13px; border-radius:99px; font-size:11.5px; font-weight:700; color:#CBD3E3;
  background:rgba(255,255,255,.07); border:1px solid rgba(255,255,255,.12);
  animation:slideIn .5s both;
}
.feed .act::before{content:""; width:6px; height:6px; border-radius:50%; background:var(--grad)}

/* --- [25.10] Thanh cuộn gradient (thay thanh cuộn xám của hệ điều hành) */
.kscroll{scrollbar-width:thin; scrollbar-color:color-mix(in srgb,var(--b2) 70%,transparent) transparent}
.kscroll::-webkit-scrollbar{width:6px}
.kscroll::-webkit-scrollbar-track{background:transparent}
.kscroll::-webkit-scrollbar-thumb{
  border-radius:99px; opacity:.85;
  background:linear-gradient(180deg,var(--b1),var(--b3));
  box-shadow:0 6px 18px color-mix(in srgb,var(--b2) 35%,transparent), inset 0 0 0 1px rgba(255,255,255,.4);
}
.kscroll::-webkit-scrollbar-thumb:hover{background:linear-gradient(180deg,var(--b2),var(--b3))}

/* --- [25.11] Màn hình nhỏ & người tắt hiệu ứng ------------------------ */
@media (max-width:640px){
  .glow-pill{font-size:15px; min-height:40px; padding:8px 15px}
  .phone{max-width:290px}
  .feed{height:400px}
}
@media (prefers-reduced-motion:reduce){
  .feed .msg,.feed .act{animation:none}
  .glow-pill .dot{animation:none}
  .constel,.constel .chub{animation:none}
  .constel .w::after,.constel .cnode::before,.chub::before,.chub::after{animation:none}
  .card.lux,.card.lux::before,.card.lux::after,.lux-glow,.iconbadge{transition:none}
}
/* ⚠ Quầng sáng phải nằm NGOÀI dòng chảy và nằm DƯỚI chữ. Luật
   `.card.lux>*{position:relative}` ở trên có độ ưu tiên cao hơn
   `.lux-glow{position:absolute}` nên đã biến quầng sáng thành một khối
   cao 220px chen vào giữa thẻ, đẩy nội dung tụt xuống 157px. Đo bằng
   getBoundingClientRect mới thấy. Phải ghi đè cả position lẫn z-index. */
.card.lux>.lux-glow{position:absolute; z-index:0}

/* =====================================================================
   [26] Ô BENTO 3 LỚP — dựng theo đúng cách preny.ai xếp lớp
   -------------------------------------------------------------------
   Bản cũ chỉ có 1 lớp phẳng (tiêu đề + đoạn văn) nên nhìn trống.
   Preny lồng 3 lớp, đó là thứ làm ô nhìn "đầy" mà không cần thêm chữ:
       [1] khung ngoài  : nền gradient nhạt, bo 20px          -> .card.bx
       [2] tấm lót      : trắng mờ 70% + làm mờ hậu cảnh, bo 18px -> .bx-in
       [3] tấm kính     : chứa tiêu đề + đoạn văn, bo 14px    -> .bx-txt
   rồi huy hiệu icon nằm lệch góc dưới phải                   -> .bx-foot
   ===================================================================== */

.bento .card.bx{
  padding:10px;                        /* khung ngoài chỉ là một viền dày */
  border:0; border-radius:20px; box-shadow:var(--sh-sm);
  background:linear-gradient(to top right,
    color-mix(in srgb,var(--b1) 26%,var(--card)) 0%,
    var(--card) 52%,
    color-mix(in srgb,var(--b3) 20%,var(--card)) 100%);
}
.bento .card.bx:hover{
  /* đè lại luật .card.lux:hover — ở đây khung ngoài ĐÃ là gradient rồi,
     không cần mẹo viền gradient nữa, chỉ cần đậm màu lên và nhấc thẻ */
  background:linear-gradient(to top right,
    color-mix(in srgb,var(--b1) 44%,var(--card)) 0%,
    var(--card) 50%,
    color-mix(in srgb,var(--b3) 34%,var(--card)) 100%);
}
.bx-in{
  position:relative; z-index:1; height:100%;
  display:flex; flex-direction:column;
  border-radius:14px; padding:10px;
  background:color-mix(in srgb,var(--card) 74%,transparent);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
}
.bx-txt{padding:17px 16px 18px; border-radius:11px}
.bx-txt h4{margin:0 0 9px; font-size:17px; letter-spacing:-.015em}
.bx-txt p{margin:0; font-size:14.8px; color:var(--muted)}
.bx-foot{display:flex; justify-content:flex-end; align-items:flex-end; margin-top:auto; padding-top:16px}
.bento .card.bx .bx-body{margin-top:14px}   /* vùng minh hoạ giữa chữ và icon */

/* --- Cụm chữ tô gradient để nhấn ý chính (Preny tô rất nhiều) --------
   ⚠ KHÔNG dùng thẳng var(--grad): chặng cyan #22D3EE nằm trên nền trắng
   chỉ đạt 1,9:1 — chữ thân bài coi như không đọc được. Nên phải pha tối
   3 chặng lại cho nền sáng, và pha sáng lên cho nền tối. Đo lại sau khi
   pha: thấp nhất 5,0:1 (nền sáng) và 8,1:1 (nền tối), đều đạt.
   Vẫn suy ra từ --b1/--b2/--b3 nên đổi data-palette là đổi theo.        */
:root{
  --grad-hl:linear-gradient(92deg,
    color-mix(in srgb,var(--b1) 82%,#000) 0%,
    color-mix(in srgb,var(--b2) 88%,#000) 46%,
    color-mix(in srgb,var(--b3) 58%,#000) 100%);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --grad-hl:linear-gradient(92deg,
      color-mix(in srgb,var(--b1) 76%,#fff) 0%,
      color-mix(in srgb,var(--b2) 68%,#fff) 46%,
      var(--b3) 100%);
  }
}
:root[data-theme="dark"]{
  --grad-hl:linear-gradient(92deg,
    color-mix(in srgb,var(--b1) 76%,#fff) 0%,
    color-mix(in srgb,var(--b2) 68%,#fff) 46%,
    var(--b3) 100%);
}
.hl{
  font-weight:680; background:var(--grad-hl);
  -webkit-background-clip:text; background-clip:text;
  color:transparent; -webkit-text-fill-color:transparent;
}
/* trong khối tối thì luôn dùng bản sáng, kể cả khi cả trang đang nền sáng */
.dark-block .hl{
  background:linear-gradient(92deg,
    color-mix(in srgb,var(--b1) 76%,#fff) 0%,
    color-mix(in srgb,var(--b2) 68%,#fff) 46%,
    var(--b3) 100%);
  -webkit-background-clip:text; background-clip:text;
}

/* --- Tổ ong icon kênh: các ô thoi xếp so le, ô trống làm nền -------- */
.honey{display:flex; flex-direction:column; align-items:center; gap:9px; padding:8px 0 4px}
.honey .r{display:flex; gap:11px}
.honey .r.so-le{margin-left:41px}          /* lệch nửa ô để khớp thành tổ ong */
.honey .d{
  width:70px; height:70px; border-radius:19px; flex:none;
  display:grid; place-items:center; transform:rotate(45deg);
  background:color-mix(in srgb,var(--card) 82%,transparent);
  border:1px solid color-mix(in srgb,var(--line) 70%,transparent);
  box-shadow:var(--sh-xs); transition:transform var(--t),box-shadow var(--t);
}
.honey .d>*{transform:rotate(-45deg)}      /* xoay ngược cho icon đứng thẳng */
.honey .d svg{width:29px; height:29px; display:block}
.honey .d.trong{background:color-mix(in srgb,var(--card) 42%,transparent); border-style:dashed; box-shadow:none}
.honey .d:not(.trong):hover{transform:rotate(45deg) translateY(-4px); box-shadow:var(--sh)}

@media (max-width:980px){
  .honey .d{width:60px; height:60px; border-radius:16px}
  .honey .r.so-le{margin-left:35px}
  .honey .d svg{width:25px; height:25px}
}
@media (max-width:640px){
  .honey .d{width:54px; height:54px; border-radius:14px}
  .honey .r.so-le{margin-left:32px}
  .honey .d svg{width:22px; height:22px}
  .bx-txt{padding:14px 13px 15px}
}

/* lưới bento 4 cột dùng ở trang Tính năng (mặc định .bento là 3 cột) */
.bento.bento-4{grid-template-columns:repeat(4,1fr)}
.bento.bento-4 .card{text-decoration:none; color:inherit}
@media (max-width:1080px){ .bento.bento-4{grid-template-columns:repeat(2,1fr)} }
@media (max-width:600px){ .bento.bento-4{grid-template-columns:1fr} }

/* =====================================================================
   [27] CHUYỂN ĐỘNG "CÔNG NGHỆ" — viền sáng quét · vệt chạy vòng · quầng lướt
   -------------------------------------------------------------------
   Dựng lại 3 hiệu ứng của preny.ai (đọc từ CSS thật của họ):
     glowBorderSweep  -> .edge-sweep  : dải gradient quét ngang TRÊN VIỀN
     borderLineTrace  -> .edge-trace  : vệt sáng chạy vòng quanh viền
     cardPulse        -> .seq-glow    : quầng màu lướt qua trong thẻ
   Mỗi thẻ đặt --seq-delay/--edge-delay khác nhau ⇒ các mục sáng LẦN LƯỢT,
   đó chính là cảm giác "chạy" khi nhìn cả lưới.

   ⚠ Mẹo cắt viền: vẽ nền rồi dùng 2 lớp mask (padding-box và toàn phần)
   với mask-composite:exclude → chỉ còn lại đúng cái vành 1,4px.
   ⚠ KHÔNG dùng ::before/::after của .card.lux hay .glass — hai pseudo đó
   đã dùng hết rồi. Nên các hiệu ứng này là THẺ SPAN riêng.
   ===================================================================== */

/* góc quay của conic-gradient: phải khai báo @property thì mới animate được
   (không có nó, trình duyệt coi góc là chuỗi và nhảy cóc thay vì quay mượt) */
@property --ang{syntax:'<angle>'; inherits:false; initial-value:0deg}

/* --- [27.1] Viền sáng quét ngang ------------------------------------- */
.edge-sweep{
  position:absolute; inset:0; border-radius:inherit; pointer-events:none; z-index:3;
  border:1.4px solid transparent;
  background:var(--grad) border-box;
  background-size:240% 100%; background-repeat:no-repeat; background-position:120% 50%;
  -webkit-mask:linear-gradient(#fff 0 0) padding-box,linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;
          mask:linear-gradient(#fff 0 0) padding-box,linear-gradient(#fff 0 0);
          mask-composite:exclude;
  filter:drop-shadow(0 0 22px color-mix(in srgb,var(--b1) 50%,transparent));
  animation:edgeSweep var(--edge-dur,9s) linear infinite;
  animation-delay:var(--edge-delay,0s);
}
@keyframes edgeSweep{from{background-position:120% 50%} to{background-position:-120% 50%}}

/* --- [27.2] Vệt sáng chạy vòng quanh viền ---------------------------- */
.edge-trace{
  position:absolute; inset:0; border-radius:inherit; pointer-events:none; z-index:3;
  padding:1.6px;
  background:conic-gradient(from var(--ang),
    transparent 0deg, transparent 74deg,
    color-mix(in srgb,var(--b1) 92%,transparent) 94deg,
    color-mix(in srgb,var(--b2) 96%,transparent) 116deg,
    color-mix(in srgb,var(--b3) 90%,transparent) 134deg,
    transparent 156deg, transparent 360deg);
  -webkit-mask:linear-gradient(#000 0 0) padding-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
          mask:linear-gradient(#000 0 0) padding-box,linear-gradient(#000 0 0);
          mask-composite:exclude;
  filter:drop-shadow(0 0 18px color-mix(in srgb,var(--b2) 45%,transparent));
  animation:edgeTrace var(--trace-dur,7s) linear infinite;
  animation-delay:var(--trace-delay,0s);
}
@keyframes edgeTrace{to{--ang:360deg}}

/* --- [27.3] Quầng màu lướt qua trong thẻ ----------------------------- */
.seq-glow{
  position:absolute; inset:-35%; pointer-events:none; z-index:0;
  background:
    radial-gradient(circle at 22% 45%, color-mix(in srgb,var(--b2) 62%,transparent), transparent 44%),
    radial-gradient(circle at 70% 55%, color-mix(in srgb,var(--b3) 46%,transparent), transparent 46%),
    linear-gradient(110deg, color-mix(in srgb,var(--b1) 60%,transparent), color-mix(in srgb,var(--b3) 38%,transparent));
  filter:blur(24px); opacity:0;
  /* ⚠ screen chồng lên nền TRẮNG thì ra trắng → ở chế độ sáng coi như mất
     hiệu ứng (đo bằng ảnh chụp mới thấy). Nên phải đổi cách hoà trộn và
     hạ độ đậm theo chủ đề: sáng = trộn thường + nhạt, tối = screen + đậm. */
  mix-blend-mode:var(--seq-blend,normal);
  transform:translateX(-26%) scale(.92);
  animation:seqPulse var(--seq-dur,8.4s) ease-in-out infinite;
  animation-delay:var(--seq-delay,0s);
}
:root{--seq-blend:normal; --seq-peak:.42; --seq-tail:.26}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){--seq-blend:screen; --seq-peak:.85; --seq-tail:.55}
}
:root[data-theme="dark"]{--seq-blend:screen; --seq-peak:.85; --seq-tail:.55}
.dark-block{--seq-blend:screen; --seq-peak:.85; --seq-tail:.55}
@keyframes seqPulse{
  0%  {opacity:0;                 transform:translateX(-32%) scale(.94)}
  14% {opacity:var(--seq-peak);   transform:translateX(-8%)  scale(1.03)}
  24% {opacity:var(--seq-peak);   transform:translateX(18%)  scale(1.08)}
  34% {opacity:var(--seq-tail);   transform:translateX(32%)  scale(1.10)}
  50%,100%{opacity:0;             transform:translateX(45%) scale(1.12)}
}

/* thẻ chứa hiệu ứng phải cắt phần thừa và tạo lớp riêng */
.co-hieu-ung{position:relative; isolation:isolate; overflow:hidden}
.co-hieu-ung>*:not(.lop-nen){position:relative; z-index:1}
/* đẩy GPU, tránh giật khi nhiều thẻ cùng chạy */
.edge-sweep,.edge-trace,.seq-glow{transform:translateZ(0); backface-visibility:hidden}

/* --- [27.4] Tôn trọng người tắt hiệu ứng chuyển động ------------------ */
@media (prefers-reduced-motion:reduce){
  .edge-sweep{animation:none; background-position:50% 50%}
  .edge-trace{animation:none}
  .seq-glow{animation:none; opacity:.16; transform:none}
}

/* [27.5] Quầng lướt nằm TRONG tấm lót .bx-in (không phải sau nó) — nếu để
   sau, tấm lót phủ 74% màu nền lên trên nên ở chế độ sáng gần như mất hẳn. */
.bx-in{position:relative; overflow:hidden; isolation:isolate}
.bx-in>*:not(.lop-nen){position:relative; z-index:1}
.bx-in>.seq-glow{z-index:0}

/* [27.6] ⚠ TẤM KÍNH CHỨA CHỮ PHẢI ĐỦ ĐỤC KHI CÓ QUẦNG SÁNG CHẠY PHÍA SAU.
   Đo thật lúc quầng sáng đạt đỉnh ở nền tối: nền tấm kính bị đẩy lên
   rgb(88,99,175), chữ thân bài chỉ còn 2,15:1 (chuẩn 4,5:1) vì ở chế độ tối
   .glass chỉ đục 5,5%. Preny né được nhờ box-shadow inset trắng toả 10px làm
   tấm kính gần như đặc ở giữa — mình bổ sung đúng thứ đó bằng màu nền thẻ. */
.bento .bx-txt{
  background:color-mix(in srgb,var(--card) 92%,transparent);
  box-shadow:var(--glass-sh), inset 0 0 24px 14px color-mix(in srgb,var(--card) 88%,transparent);
}

/* [27.7] Thẻ bảng giá: chữ phải nằm trên quầng sáng, và cắt phần thừa */
.price.co-hieu-ung{position:relative; isolation:isolate; overflow:hidden}
.price.co-hieu-ung>*:not(.lop-nen){position:relative; z-index:1}
.price.co-hieu-ung>.seq-glow{z-index:0}

/* ⚠ Thẻ giá KHÔNG có tấm kính che chữ như ô bento, nên quầng sáng phải yếu
   hơn nhiều. Tính ngược từ chuẩn 4,5:1: nền thẻ tối có độ chói 0,011; chữ
   --muted có 0,360 ⇒ nền chỉ được phép sáng tới 0,041. Ở độ đậm 0,85 nó vọt
   lên 0,144 (chữ còn 2,14:1). Tỉ lệ ⇒ độ đậm tối đa ≈ 0,19. Lấy 0,18. */
.price.co-hieu-ung{--seq-peak:.18; --seq-tail:.11}

/* =====================================================================
   [28] MẠCH NỐI GIỮA CÁC KHU — dây dẫn có xung sáng chạy dọc
   -------------------------------------------------------------------
   Vấn đề của khối [27]: hiệu ứng chỉ chạy BÊN TRONG từng thẻ nên không
   nói lên được điều gì — mắt thấy đẹp nhưng đầu không hiểu ý.
   Khối này làm phần ngược lại: một sợi dây thật sự NỐI khu trên xuống
   khu dưới, có xung sáng chạy theo đúng chiều đọc, và có NHÃN ghi rõ
   thứ đang chạy qua dây ("Khách nhắn từ 5 kênh", "Katty đọc và trả lời"...).
   Nhờ vậy chuyển động mang nghĩa: đây là một dòng chảy, không phải trang trí.

   Mẹo: đặt pathLength="100" cho mọi đường ⇒ mọi nét dài bằng nhau về mặt
   đơn vị, nên chỉ cần MỘT bộ keyframes cho mọi hình dạng đường, không phải
   đo chiều dài từng đường.
   ===================================================================== */
.mach{position:relative; width:100%; height:150px; margin:0; pointer-events:none}
.mach svg{display:block; width:100%; height:100%; overflow:visible}
.mach .day{                              /* sợi dây nền, luôn hiện mờ */
  fill:none; stroke:var(--line); stroke-width:1.5; vector-effect:non-scaling-stroke;
}
.mach .xung{                             /* xung sáng chạy trên dây */
  fill:none; stroke:url(#machGrad); stroke-width:2.4; stroke-linecap:round;
  vector-effect:non-scaling-stroke;
  stroke-dasharray:13 87;
  animation:machChay var(--mach-dur,3.4s) linear infinite;
  animation-delay:var(--mach-delay,0s);
  filter:drop-shadow(0 0 6px color-mix(in srgb,var(--b2) 85%,transparent));
}
@keyframes machChay{from{stroke-dashoffset:100} to{stroke-dashoffset:0}}

.mach .nut{                              /* đầu mối ở ngã rẽ */
  fill:var(--bg); stroke:var(--brand); stroke-width:1.6; vector-effect:non-scaling-stroke;
}
.mach .nut-sang{fill:var(--brand); animation:nutTho 3.4s ease-in-out infinite}
@keyframes nutTho{0%,100%{opacity:.45} 50%{opacity:1}}

/* nhãn nói rõ cái gì đang chạy qua dây — đây là chỗ tạo ra "ý nghĩa" */
.mach .nhan{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  display:inline-flex; align-items:center; gap:9px; white-space:nowrap;
  padding:8px 17px; border-radius:var(--r-full);
  background:var(--card); border:1px solid var(--line); box-shadow:var(--sh-sm);
  font-size:13.5px; font-weight:680; color:var(--ink-2);
}
.mach .nhan .cham{
  width:7px; height:7px; border-radius:50%; background:var(--grad); flex:none;
  box-shadow:0 0 0 4px color-mix(in srgb,var(--b2) 22%,transparent);
  animation:nutTho 2.2s ease-in-out infinite;
}
.mach .nhan .mui{color:var(--brand); font-weight:800}

/* trong khối tối thì dây và nhãn phải sáng lên mới thấy */
.dark-block .mach .day{stroke:rgba(255,255,255,.14)}
.dark-block .mach .nut{fill:#080D1B; stroke:#A78BFA}
.dark-block .mach .nhan{background:rgba(255,255,255,.06); border-color:rgba(255,255,255,.13); color:#CBD3E3}

@media (max-width:760px){
  .mach{height:104px}
  .mach .nhan{font-size:12.4px; padding:7px 13px}
}
@media (prefers-reduced-motion:reduce){
  .mach .xung{animation:none; stroke-dasharray:none; opacity:.5}
  .mach .nut-sang,.mach .nhan .cham{animation:none}
}

/* =====================================================================
   [29] LỚP NỀN TRANG TRÍ — .lop-nen
   BA LẦN liên tiếp dính cùng một lỗi: các luật quét chung dạng
   `.X > * { position:relative }` đè mất `position:absolute` của lớp trang
   trí (.lux-glow, .seq-glow, .edge-*), biến nó thành khối nằm trong dòng
   chảy cao 150–220px, đẩy nội dung tụt xuống và thổi phồng chiều cao thẻ.
   Chữa tận gốc: MỌI lớp trang trí mang chung class .lop-nen, và mọi luật
   quét chung đều loại trừ đúng một class đó. Thêm lớp mới thì chỉ cần gắn
   .lop-nen là xong, không phải đi sửa lại các luật quét.
   ===================================================================== */
.lop-nen{position:absolute; z-index:0; pointer-events:none}

/* =====================================================================
   [30] SƠ ĐỒ HỘI TỤ — 5 kênh chạy vào một hộp thư
   -------------------------------------------------------------------
   Thay cho lưới tổ ong trang trí (học của Preny): tổ ong đẹp nhưng KHÔNG
   nói lên điều gì, và để lại một mảng trống lớn giữa ô. Sơ đồ này nói
   đúng câu đang viết ở tiêu đề — "hợp nhất đa kênh vào MỘT hệ thống" —
   và xung sáng chạy trên dây cho thấy tin nhắn đang đổ về.
   ===================================================================== */
.hoi-tu{
  display:grid; grid-template-columns:auto minmax(70px,1fr) auto;
  align-items:center; gap:0; margin-top:16px;
}
.hoi-tu .kenh{display:flex; flex-direction:column; gap:12px}
.hoi-tu .kenh span{
  display:inline-flex; align-items:center; gap:9px; height:34px; padding:0 13px 0 9px;
  border-radius:var(--r-full); background:var(--card); border:1px solid var(--line);
  font-size:13.4px; font-weight:640; color:var(--ink-2); white-space:nowrap;
  box-shadow:var(--sh-xs); transition:transform var(--t),box-shadow var(--t);
}
.hoi-tu .kenh span:hover{transform:translateX(3px); box-shadow:var(--sh-sm)}
.hoi-tu .kenh svg{width:19px; height:19px; flex:none}

.hoi-tu .day-noi{width:100%; height:218px; display:block; overflow:visible}
.hoi-tu .day-noi .d{fill:none; stroke:var(--line); stroke-width:1.4; vector-effect:non-scaling-stroke}
.hoi-tu .day-noi .x{
  fill:none; stroke:url(#htGrad); stroke-width:2.2; stroke-linecap:round;
  vector-effect:non-scaling-stroke; stroke-dasharray:16 84;
  animation:machChay 2.8s linear infinite; animation-delay:var(--dl,0s);
  filter:drop-shadow(0 0 5px color-mix(in srgb,var(--b2) 85%,transparent));
}

.hoi-tu .hop{
  display:flex; flex-direction:column; align-items:center; gap:5px; text-align:center;
  padding:16px 18px; border-radius:var(--r-md); min-width:124px;
  background:var(--card); border:1px solid transparent;
  background:linear-gradient(var(--card),var(--card)) padding-box, var(--grad) border-box;
  box-shadow:var(--sh);
}
.hoi-tu .hop .ic{
  width:38px; height:38px; border-radius:12px; display:grid; place-items:center;
  background:var(--grad); color:#fff; margin-bottom:3px;
}
.hoi-tu .hop .ic svg{width:21px; height:21px}
.hoi-tu .hop b{font-size:14.2px; letter-spacing:-.01em}
.hoi-tu .hop small{font-size:11.8px; color:var(--muted)}
.hoi-tu .hop .dem{
  margin-top:5px; padding:3px 10px; border-radius:var(--r-full);
  background:var(--brand-weak); color:var(--brand-strong);
  font-size:11.5px; font-weight:750; font-variant-numeric:tabular-nums;
}

/* trong khối tối */
.dark-block .hoi-tu .kenh span{background:rgba(255,255,255,.05); border-color:rgba(255,255,255,.12); color:#CBD3E3}
.dark-block .hoi-tu .day-noi .d{stroke:rgba(255,255,255,.14)}

@media (max-width:860px){
  .hoi-tu{grid-template-columns:1fr; justify-items:center; gap:14px}
  .hoi-tu .kenh{flex-direction:row; flex-wrap:wrap; justify-content:center}
  .hoi-tu .day-noi{display:none}          /* dây dọc vô nghĩa khi đã xếp chồng */
  .hoi-tu .hop{width:100%; max-width:230px}
}
@media (prefers-reduced-motion:reduce){
  .hoi-tu .day-noi .x{animation:none; stroke-dasharray:none; opacity:.55}
}

/* =====================================================================
   [31] LOGO KATTY — bộ "1a · Wordmark"
   Dựng bằng chữ thật (phông Outfit 700) chứ KHÔNG dùng <img src="*.svg">:
   trong <img>, SVG là một tài liệu riêng nên không lấy được màu chữ của
   trang → ở nền tối logo vẫn đen thui, mất hút. Dựng bằng chữ thì phần
   "KATT" ăn theo var(--ink), tự đảo sáng/tối, còn chấm tròn và chữ "Y"
   giữ nguyên gradient tím → xanh của bộ nhận diện.
   Mọi kích thước của chấm tròn tính bằng `em` để logo phóng to thu nhỏ
   theo font-size mà không lệch (tỉ lệ lấy từ bản gốc 68px).
   ===================================================================== */
:root{
  --logo-g1:#9B61EA;               /* tím  — oklch(.62 .2 300) trong bản gốc */
  --logo-g2:#009CEC;               /* xanh — oklch(.65 .18 235) */
}
.katty-logo{
  position:relative; display:inline-block; white-space:nowrap;
  font-family:"Outfit",var(--font); font-weight:700; font-size:26px;
  letter-spacing:.01em; line-height:1; color:var(--ink);
  margin-left:.19em;                        /* chừa chỗ cho chấm tròn thò ra trái */
}
.katty-logo .kl-dot{                        /* chấm tròn nằm trên chữ K */
  position:absolute; top:-.147em; left:-.184em; width:.235em; height:.235em;
  border-radius:50%;
  background:linear-gradient(135deg,var(--logo-g1),var(--logo-g2));
}
.katty-logo .kl-y{                          /* chữ Y tô gradient */
  background:linear-gradient(90deg,var(--logo-g1),var(--logo-g2));
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
.brand{display:inline-flex; align-items:center; color:var(--ink); text-decoration:none}
.brand:hover{opacity:.85}
footer .katty-logo{font-size:24px}
@media (max-width:640px){ .katty-logo{font-size:22px} }

/* dải số liệu dưới sơ đồ hội tụ — lấp chỗ trống bằng thông tin thật,
   không phải bằng hoạ tiết trang trí */
.hop-so{
  display:grid; grid-template-columns:repeat(4,1fr); gap:1px; margin-top:18px;
  background:var(--line); border:1px solid var(--line); border-radius:var(--r);
  overflow:hidden;
}
.hop-so>div{background:var(--card); padding:12px 8px; text-align:center}
.hop-so b{
  display:block; font-size:19px; font-weight:800; letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;
  background:var(--grad-hl); -webkit-background-clip:text; background-clip:text;
  color:transparent; -webkit-text-fill-color:transparent;
}
.hop-so span{display:block; margin-top:2px; font-size:11.6px; color:var(--muted); line-height:1.35}
.dark-block .hop-so{background:rgba(255,255,255,.10); border-color:rgba(255,255,255,.12)}
.dark-block .hop-so>div{background:rgba(255,255,255,.04)}
@media (max-width:640px){ .hop-so{grid-template-columns:repeat(2,1fr)} }
