:root{
  /* Bốn bộ chữ chọn được ở /settings, khai báo ĐÚNG MỘT LẦN ở đây. Trang cài
     đặt mượn lại chính mấy biến này để in chữ mẫu, nên ô "Roboto" bên đó không
     bao giờ lệch với Roboto thật trên trang. */
  --font-plex-sans:'IBM Plex Sans','Noto Sans KR',system-ui,sans-serif;
  --font-plex-serif:'IBM Plex Serif','Noto Serif KR',serif;
  --font-plex-mono:'IBM Plex Mono','Noto Sans KR',monospace;

  /* Bộ hệ thống không tải gì cả — trang hiện ngay từ khung hình đầu tiên, đổi
     lại là mỗi máy một dáng chữ. Chữ Hàn nhờ font sẵn có của máy (Malgun Gothic
     trên Windows, Apple SD Gothic Neo trên macOS). */
  --font-system-sans:system-ui,-apple-system,'Segoe UI',Roboto,'Malgun Gothic','Apple SD Gothic Neo','Noto Sans KR',sans-serif;
  --font-system-serif:Georgia,'Times New Roman','Batang','Apple SD Gothic Neo','Noto Serif KR',serif;
  --font-system-mono:ui-monospace,SFMono-Regular,Consolas,'Malgun Gothic','Noto Sans KR',monospace;

  --font-noto-sans:'Noto Sans','Noto Sans KR',system-ui,sans-serif;
  --font-noto-serif:'Noto Serif','Noto Serif KR',serif;
  --font-noto-mono:'Noto Sans Mono','Noto Sans KR',monospace;

  --font-roboto-sans:'Roboto','Noto Sans KR',system-ui,sans-serif;
  --font-roboto-serif:'Roboto Slab','Noto Serif KR',serif;
  --font-roboto-mono:'Roboto Mono','Noto Sans KR',monospace;

  /* Bộ đang dùng. Máy chủ gắn html[data-font=…] theo cv.json (settings.font) và
     <link> Google Fonts ở lib/render.js chỉ nạp đúng bộ đó — chọn Roboto thì
     trình duyệt không tải một byte IBM Plex nào. Mặc định IBM Plex: đúng bộ chữ
     trang được thiết kế từ đầu. */
  --f-sans:var(--font-plex-sans);
  --f-serif:var(--font-plex-serif);
  --f-mono:var(--font-plex-mono);

  --paper:#FAFBFC;
  --ink:#16232E;
  --slate:#54626F;
  --accent:#17677F;
  --accent-soft:#EAF2F5;
  --line:#E2E8EC;
  --maxw:960px;
}
html[data-font="system"]{
  --f-sans:var(--font-system-sans);
  --f-serif:var(--font-system-serif);
  --f-mono:var(--font-system-mono);
}
html[data-font="noto"]{
  --f-sans:var(--font-noto-sans);
  --f-serif:var(--font-noto-serif);
  --f-mono:var(--font-noto-mono);
}
html[data-font="roboto"]{
  --f-sans:var(--font-roboto-sans);
  --f-serif:var(--font-roboto-serif);
  --f-mono:var(--font-roboto-mono);
}

*{margin:0;padding:0;box-sizing:border-box}
body{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--f-sans);
  font-size:16px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
a{color:var(--accent);text-decoration:none;border-bottom:1px solid transparent;transition:border-color .15s}
a:hover{border-bottom-color:var(--accent)}
a:focus-visible,button:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}

.wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px}

/* ---------- language switching ---------- */
html[data-lang="en"] .vi,html[data-lang="en"] .ko{display:none!important}
html[data-lang="vi"] .en,html[data-lang="vi"] .ko{display:none!important}
html[data-lang="ko"] .en,html[data-lang="ko"] .vi{display:none!important}
html[data-lang="ko"]{word-break:keep-all}
.lang-switch{
  position:absolute;top:22px;right:24px;z-index:3;
  display:flex;border:1px solid var(--line);border-radius:999px;
  overflow:hidden;background:rgba(255,255,255,.7);
  font-family:var(--f-mono);font-size:12.5px;
}
.lang-switch button{
  appearance:none;border:none;background:none;cursor:pointer;
  padding:5px 13px;color:var(--slate);
  font-family:inherit;font-size:inherit;
  transition:background .15s,color .15s;
}
.lang-switch button[aria-pressed="true"]{background:var(--accent);color:#fff}

/* ---------- letterhead rule ---------- */
.rule-top{height:3px;background:var(--accent)}

/* ---------- header ---------- */
header{position:relative;background:#fff;padding:76px 0 60px}
.hero{display:flex;align-items:center;gap:40px;position:relative;z-index:1}
.hero img{
  width:124px;height:124px;border-radius:50%;
  object-fit:cover;border:1px solid var(--line);
  background:var(--accent-soft);flex-shrink:0;
}
.kicker{
  font-family:var(--f-mono);
  font-size:12.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent);margin-bottom:10px;
}
h1{
  font-family:var(--f-serif);
  font-weight:600;font-size:clamp(32px,5vw,46px);
  line-height:1.1;letter-spacing:-.01em;
}
.lede{margin-top:14px;color:var(--slate);max-width:60ch}
.lede strong{color:var(--ink);font-weight:600}
.contact-row{margin-top:16px;display:flex;flex-wrap:wrap;gap:8px 22px;
  font-family:var(--f-mono);font-size:13.5px}

/* ---------- tab bar (desktop: underline) ---------- */
.tabbar-outer{
  position:sticky;top:0;z-index:10;
  background:color-mix(in srgb,var(--paper) 88%,transparent);
  backdrop-filter:blur(8px);
  -webkit-backdrop-filter:blur(8px);
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
}
.tabbar{display:flex;gap:2px}
.tab{
  appearance:none;background:none;border:none;cursor:pointer;
  font-family:var(--f-sans);font-size:14.5px;font-weight:500;
  color:var(--slate);
  padding:15px 14px 13px;
  border-bottom:2px solid transparent;
  white-space:nowrap;
  transition:color .15s,border-color .15s,background .15s;
}
.tab:hover{color:var(--ink)}
.tab[aria-selected="true"]{color:var(--accent);border-bottom-color:var(--accent)}

/* ---------- panels ---------- */
/* <main> mang luôn class .wrap — phải viết main.wrap, nếu không padding dọc bị .wrap{padding:0 24px} ghi đè */
main.wrap{padding:60px 24px 96px;min-height:60vh}
.panel{display:none}
.panel.active{display:block;animation:fadein .25s ease-out}
@keyframes fadein{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .panel.active{animation:none}
}

h2{
  font-family:var(--f-serif);font-weight:600;
  font-size:23px;margin-bottom:26px;
  display:flex;align-items:baseline;gap:14px;
}
h2::after{content:"";flex:1;height:1px;background:var(--line)}
/* Thanh tab dính (sticky) luôn hiển thị tên mục đang xem, nên tiêu đề trong panel
   chỉ lặp lại — ẩn trên màn hình, vẫn giữ trong DOM cho SEO / bản in */
.panel > h2{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;
}
@media print{
  .panel > h2{position:static;width:auto;height:auto;margin:0 0 26px;
    overflow:visible;clip:auto;clip-path:none;white-space:normal}
}
.group{font-family:var(--f-mono);font-size:12.5px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--slate);
  margin:34px 0 18px}
.group:first-of-type{margin-top:0}

/* entries */
.entry{display:grid;grid-template-columns:140px 1fr;gap:24px;margin-bottom:34px}
.entry:last-child{margin-bottom:0}
.when{
  font-family:var(--f-mono);font-size:13px;
  color:var(--slate);padding-top:5px;white-space:nowrap;
}
.entry h3{font-family:var(--f-serif);font-size:17px;font-weight:600;line-height:1.4}
.entry .sub{color:var(--slate);font-size:15px;margin-top:2px}
.entry .thesis{color:var(--slate);font-size:14.5px;font-style:italic;margin-top:6px}
.entry ul{margin-top:10px;padding-left:18px;color:var(--slate);font-size:15px}
.entry ul li{margin-bottom:6px}
.entry ul li::marker{color:var(--accent)}

/* publications */
.pub{margin-bottom:24px;padding-left:20px;border-left:2px solid var(--line)}
.pub:last-child{margin-bottom:0}
.pub .cite{font-size:15.5px}
.pub .authors{color:var(--slate);font-size:14.5px;margin-top:2px}
.pub .authors .me{color:var(--ink);font-weight:600}
.pub .meta{
  margin-top:6px;font-family:var(--f-mono);font-size:12.5px;
  display:flex;flex-wrap:wrap;gap:12px;color:var(--slate);align-items:center;
}
.tag{
  display:inline-block;background:var(--accent-soft);color:var(--accent);
  border-radius:3px;padding:1px 8px;font-family:var(--f-mono);
  font-size:12px;
}

/* skills */
.skills{display:grid;grid-template-columns:1fr 1fr;gap:22px 40px}
.skill h3{font-size:13.5px;font-family:var(--f-mono);
  letter-spacing:.08em;text-transform:uppercase;color:var(--accent);
  font-weight:500;margin-bottom:8px}
.skill p{color:var(--slate);font-size:15px}

/* referees */
.refs{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:24px}
.ref{border:1px solid var(--line);border-radius:6px;padding:20px}
.ref h3{font-family:var(--f-serif);font-size:16.5px;font-weight:600}
.ref p{color:var(--slate);font-size:14.5px;margin-top:4px}
.ref .meta{margin-top:10px;font-family:var(--f-mono);font-size:12.5px}

footer{border-top:1px solid var(--line);padding:24px 0;
  font-family:var(--f-mono);font-size:12.5px;color:var(--slate)}
footer .wrap{display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px}

/* ---------- mobile: pill grid, no horizontal scroll ---------- */
@media (max-width:680px){
  header{padding:60px 0 34px}
  .lang-switch{top:14px;right:16px}
  .hero{flex-direction:column;align-items:flex-start;gap:22px}
  .hero img{width:96px;height:96px}

  .tabbar-outer{
    position:static;
    background:none;
    backdrop-filter:none;
    -webkit-backdrop-filter:none;
    border-top:1px solid var(--line);
    border-bottom:none;
  }
  .tabbar{flex-wrap:wrap;gap:8px;padding:18px 0 2px}
  .tab{
    border:1px solid var(--line);
    border-radius:999px;
    padding:7px 14px;
    font-size:13.5px;
    background:#fff;
  }
  .tab[aria-selected="true"]{
    background:var(--accent-soft);
    border-color:var(--accent);
    color:var(--accent);
  }

  main.wrap{padding:38px 24px 72px}
  .entry{grid-template-columns:1fr;gap:4px;margin-bottom:26px}
  .skills{grid-template-columns:1fr}
  .pub{padding-left:14px}
}

/* ---------- lối vào khu sửa (chân trang) ---------- */
.signin{margin-left:14px;opacity:.55}
.signin a{color:var(--slate)}
.signin a:hover{color:var(--accent)}
