/* =========================================================
   Jeonghun Lee — scroll CV
   Glass + gradient · anime.js v4
   ========================================================= */

@import url('https://fonts.googleapis.com/css2?family=Inter+Tight:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');

:root{
  --bg:#06060c;
  --bg2:#0a0a14;
  --ink:#f3f3f8;
  --muted:rgba(243,243,248,.60);
  --faint:rgba(243,243,248,.34);
  --line:rgba(255,255,255,.09);
  --line2:rgba(255,255,255,.16);
  --glass:rgba(255,255,255,.045);
  --glass2:rgba(255,255,255,.075);
  --v:#8b5cf6;
  --c:#22d3ee;
  --p:#f472b6;
  --a:#a78bfa;
  --grad:linear-gradient(100deg,var(--a) 0%,var(--c) 45%,var(--p) 100%);
  --r:22px;
  --ease:cubic-bezier(.22,1,.36,1);
  --pad:clamp(20px,5vw,80px);
  --sans:'Inter Tight','Pretendard','Apple SD Gothic Neo',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:auto;-webkit-text-size-adjust:100%;overflow-x:clip}
/* `clip` not `hidden`: hidden would make <html> a scroll container and
   break the sticky project cards and the pinned experience stage. */
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--sans);font-size:16px;line-height:1.6;
  -webkit-font-smoothing:antialiased;
  /* no overflow-x here: <html> already clips. Setting hidden on body once
     <html> is non-visible makes BODY a scroll container, which silently
     breaks every position:sticky pin on the page. */
}
body.is-locked{overflow:hidden;height:100vh}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
::selection{background:var(--a);color:#08080f}

/* ---------- ambient layers ---------- */
#aurora{position:fixed;inset:0;width:100%;height:100%;z-index:0;pointer-events:none;opacity:.72}
.grain{
  position:fixed;inset:-200%;z-index:2;pointer-events:none;opacity:.16;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  animation:grain 7s steps(6) infinite;mix-blend-mode:overlay;
}
@keyframes grain{
  0%{transform:translate(0,0)}20%{transform:translate(-4%,-3%)}40%{transform:translate(3%,-5%)}
  60%{transform:translate(-2%,4%)}80%{transform:translate(4%,2%)}100%{transform:translate(0,0)}
}
.vignette{position:fixed;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(120% 90% at 50% 40%,transparent 45%,rgba(3,3,8,.72) 100%)}

/* ---------- cursor ---------- */
.cur,.cur-ring{position:fixed;top:0;left:0;z-index:9999;pointer-events:none;border-radius:50%;
  will-change:transform;mix-blend-mode:difference;opacity:0;transition:opacity .3s}
body.has-cursor .cur,body.has-cursor .cur-ring{opacity:1}
.cur{width:7px;height:7px;background:#fff;margin:-3.5px 0 0 -3.5px}
.cur-ring{width:38px;height:38px;border:1px solid rgba(255,255,255,.55);margin:-19px 0 0 -19px}
@media (hover:none),(pointer:coarse){.cur,.cur-ring{display:none}}

/* ---------- loader ---------- */
.loader{position:fixed;inset:0;z-index:9000;background:var(--bg);
  display:flex;align-items:center;justify-content:center;flex-direction:column;gap:26px}
.loader__name{font-size:clamp(24px,6vw,64px);font-weight:700;letter-spacing:-.03em;display:flex;overflow:hidden}
.loader__name span{display:inline-block;white-space:pre}
.loader__bar{width:min(420px,60vw);height:2px;background:rgba(255,255,255,.12);overflow:hidden;border-radius:2px}
.loader__bar i{display:block;height:100%;width:0%;background:var(--grad)}
.loader__num{font-family:var(--mono);font-size:13px;color:var(--faint);letter-spacing:.1em}
.loader__curtain{position:fixed;inset:0;z-index:8999;display:grid;grid-template-columns:repeat(6,1fr);pointer-events:none}
.loader__curtain i{background:var(--bg2);transform-origin:bottom}

/* ---------- progress + nav ---------- */
.progress{position:fixed;top:0;left:0;right:0;height:2px;z-index:800;background:rgba(255,255,255,.06)}
.progress i{display:block;height:100%;width:0%;background:var(--grad);box-shadow:0 0 18px rgba(139,92,246,.8)}

.nav{position:fixed;top:0;left:0;right:0;z-index:700;display:flex;align-items:center;justify-content:space-between;
  gap:20px;padding:16px var(--pad);transition:background .4s,backdrop-filter .4s}
.nav.stuck{background:rgba(8,8,16,.55);backdrop-filter:blur(18px) saturate(150%);
  -webkit-backdrop-filter:blur(18px) saturate(150%);border-bottom:1px solid var(--line)}
.nav__brand{font-weight:800;letter-spacing:-.04em;font-size:19px;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.nav__links{display:flex;gap:4px;padding:5px;border-radius:999px;
  background:var(--glass);border:1px solid var(--line);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.nav__links a{font-size:12.5px;letter-spacing:.02em;color:var(--muted);padding:7px 14px;border-radius:999px;
  transition:color .3s,background .3s;white-space:nowrap}
.nav__links a:hover{color:var(--ink)}
.nav__links a.on{color:#08080f;background:#fff}
@media(max-width:860px){.nav__links{display:none}}
.lang{display:flex;align-items:center;gap:2px;font-family:var(--mono);font-size:11px;letter-spacing:.08em;
  padding:8px 13px;border-radius:999px;background:var(--glass);border:1px solid var(--line);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);color:var(--faint)}
.lang b{color:var(--ink);font-weight:500}
.lang:hover{border-color:var(--line2)}

/* ---------- layout ---------- */
main{position:relative;z-index:3}
/* reveal start-states translate sideways (slide-l/slide-r), which would
   otherwise let the page scroll horizontally. `clip` contains that without
   creating a scroll container, so the sticky pins keep working. */
main{overflow-x:clip}
section{position:relative;padding:clamp(90px,13vh,170px) var(--pad);scroll-margin-top:80px}
.wrap{max-width:1180px;margin:0 auto;width:100%}
.eyebrow{display:inline-flex;align-items:center;gap:9px;font-family:var(--mono);font-size:11px;
  letter-spacing:.22em;text-transform:uppercase;color:var(--faint);margin-bottom:22px}
.eyebrow::before{content:'';width:26px;height:1px;background:var(--grad)}
h2.title{font-size:clamp(32px,6vw,66px);font-weight:600;letter-spacing:-.035em;line-height:1.03;margin:0 0 18px}
.title em{font-style:normal;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.lede{max-width:62ch;color:var(--muted);font-size:clamp(15px,1.5vw,18px)}

.glass{background:var(--glass);border:1px solid var(--line);border-radius:var(--r);
  backdrop-filter:blur(22px) saturate(150%);-webkit-backdrop-filter:blur(22px) saturate(150%);
  box-shadow:0 1px 0 rgba(255,255,255,.06) inset,0 30px 70px -40px rgba(0,0,0,.9)}
.glass:hover{border-color:var(--line2)}

/* ---------- hero ---------- */
.hero{min-height:100svh;display:flex;align-items:center;padding-top:120px;overflow:hidden}
.hero__grid{display:grid;grid-template-columns:1.35fr .65fr;gap:clamp(24px,4vw,60px);align-items:end;width:100%}
@media(max-width:900px){.hero__grid{grid-template-columns:1fr}}
.hero__name{font-size:clamp(46px,11.5vw,168px);font-weight:700;letter-spacing:-.055em;line-height:.88;margin:0}
.hero__line{display:block;overflow:hidden;padding-bottom:.06em}
.hero__name .ch{display:inline-block}
html[data-lang="ko"] .hero__name{line-height:1.02;letter-spacing:-.03em}
html[data-lang="ko"] .hero__line{padding-bottom:.02em}
.hero__name .g,.hero__name .g .ch{color:transparent}
.hero__name .g{background:var(--grad);background-size:100% 100%;
  -webkit-background-clip:text;background-clip:text}
.hero__name .g .ch{background:inherit;background-clip:text;-webkit-background-clip:text;
  background-attachment:fixed}
.hero__head{margin:26px 0 0;font-size:clamp(15px,1.9vw,22px);color:var(--muted);max-width:34ch;font-weight:300}
.hero__roles{display:flex;flex-wrap:wrap;gap:8px;margin-top:26px}
.chip{font-family:var(--mono);font-size:11px;letter-spacing:.06em;padding:8px 14px;border-radius:999px;
  background:var(--glass);border:1px solid var(--line);color:var(--muted);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.chip.hot{color:var(--ink);border-color:rgba(167,139,250,.45);
  background:linear-gradient(120deg,rgba(139,92,246,.18),rgba(34,211,238,.13))}
.hero__card{padding:22px;display:flex;flex-direction:column;gap:16px}
.hero__ph{width:100%;aspect-ratio:1/1.12;border-radius:16px;overflow:hidden;position:relative;background:var(--bg2)}
.hero__ph img{width:100%;height:100%;object-fit:cover;filter:grayscale(.35) contrast(1.06)}
.hero__ph::after{content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,transparent 45%,rgba(6,6,12,.75));mix-blend-mode:multiply}
.meta{display:grid;gap:9px}
.meta div{display:flex;justify-content:space-between;gap:12px;font-size:12.5px;
  padding-bottom:9px;border-bottom:1px solid var(--line)}
.meta div:last-child{border:0;padding-bottom:0}
.meta span{color:var(--faint);font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase}
.meta b{font-weight:500;text-align:right}
.scrollcue{position:absolute;left:var(--pad);bottom:34px;display:flex;align-items:center;gap:12px;
  font-family:var(--mono);font-size:10px;letter-spacing:.24em;color:var(--faint);text-transform:uppercase}
.scrollcue i{display:block;width:1px;height:44px;background:linear-gradient(var(--a),transparent);
  animation:cue 1.8s var(--ease) infinite}
@keyframes cue{0%{transform:scaleY(0);transform-origin:top}50%{transform:scaleY(1);transform-origin:top}
  51%{transform:scaleY(1);transform-origin:bottom}100%{transform:scaleY(0);transform-origin:bottom}}

/* ---------- about: word scrub ---------- */
.about__stage{min-height:260vh;position:relative}
.about__sticky{position:sticky;top:0;height:100svh;display:flex;align-items:center;
  overflow:hidden;padding:88px 0 40px}
.about__sticky .wrap{max-height:100%}
.scrub{font-size:clamp(15px,1.95vw,29px);font-weight:400;line-height:1.5;letter-spacing:-.015em;max-width:44ch;margin:0}
.scrub .w{display:inline-block;color:rgba(243,243,248,.14);transition:none;will-change:color,opacity}
.focus-row{display:flex;flex-wrap:wrap;gap:10px;margin-top:26px}

/* ---------- marquee ---------- */
.marq{padding:0;border-block:1px solid var(--line);overflow:hidden;
  background:linear-gradient(90deg,rgba(139,92,246,.06),rgba(34,211,238,.05))}
.marq__track{display:flex;gap:44px;padding:20px 0;white-space:nowrap;will-change:transform}
.marq__track span{font-size:clamp(18px,3vw,38px);font-weight:600;letter-spacing:-.03em;color:rgba(243,243,248,.2);
  display:flex;align-items:center;gap:44px}
.marq__track span::after{content:'';width:7px;height:7px;border-radius:50%;background:var(--a);opacity:.55}

/* ---------- experience: horizontal pin ---------- */
.hstage{height:400vh;position:relative;padding:0}
.hpin{position:sticky;top:0;height:100svh;display:flex;flex-direction:column;justify-content:center;
  overflow:hidden;padding:0 0 0 var(--pad)}
.hpin__head{margin-bottom:34px;padding-right:var(--pad)}
.htrack{display:flex;gap:26px;will-change:transform}
.xcard{flex:0 0 clamp(290px,38vw,470px);padding:30px;display:flex;flex-direction:column;gap:14px;min-height:52vh}
.xcard__yr{font-family:var(--mono);font-size:11px;letter-spacing:.14em;color:var(--a)}
.xcard h3{margin:0;font-size:clamp(19px,2.1vw,26px);font-weight:600;letter-spacing:-.025em;line-height:1.2}
.xcard .org{font-size:14px;color:var(--ink);opacity:.86}
.xcard p{margin:0;font-size:14px;color:var(--muted);line-height:1.62}
.xcard .loc{margin-top:auto;font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint)}
.xcard__num{position:absolute;right:22px;top:16px;font-size:60px;font-weight:700;letter-spacing:-.05em;
  color:rgba(255,255,255,.045);line-height:1}
.xcard{position:relative;overflow:hidden}
.xcard::before{content:'';position:absolute;inset:0;opacity:0;transition:opacity .5s;
  background:radial-gradient(60% 60% at 20% 0%,rgba(139,92,246,.22),transparent 70%)}
.xcard:hover::before{opacity:1}

/* ---------- education timeline ---------- */
/* minmax(0,1fr): a plain 1fr floors at the content's min-content width, which
   pushed the cards past the viewport on narrow screens. */
.edu__grid{display:grid;grid-template-columns:52px minmax(0,1fr);gap:0 clamp(18px,3vw,44px)}
@media(max-width:820px){
  .edu__grid{grid-template-columns:minmax(0,1fr)}
  .edu__rail{display:none}
}
.edu__rail{position:relative}
.edu__rail svg{position:sticky;top:18vh;width:52px;height:64vh;overflow:visible}
.edu__items{display:grid;gap:22px}
.edu__item{padding:28px;display:grid;gap:9px;position:relative}
.edu__item .yr{font-family:var(--mono);font-size:11px;letter-spacing:.14em;color:var(--c)}
.edu__item h3{margin:0;font-size:clamp(20px,2.3vw,29px);font-weight:600;letter-spacing:-.03em}
.edu__item .dept{color:var(--muted);font-size:14.5px}
.edu__item p{margin:0;color:var(--muted);font-size:14px}
.gpa{display:inline-flex;align-items:baseline;gap:7px;margin-top:6px;font-family:var(--mono);font-size:12px;
  color:var(--faint);letter-spacing:.08em}
.gpa b{font-family:var(--sans);font-size:26px;font-weight:600;letter-spacing:-.03em;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}

/* ---------- projects: stacked sticky cards ---------- */
.pcard{position:sticky;top:calc(12vh + var(--i,0) * 16px);margin-bottom:26px;
  padding:0;overflow:hidden;will-change:transform}
.pcard__in{display:grid;grid-template-columns:1.05fr .95fr;min-height:min(560px,72vh)}
@media(max-width:880px){.pcard__in{grid-template-columns:1fr}}
.pcard__txt{padding:clamp(24px,3.2vw,46px);display:flex;flex-direction:column;gap:15px}
.pcard__cat{display:flex;align-items:center;gap:12px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--faint)}
.pcard__cat b{color:var(--a);font-weight:500}
.pcard h3{margin:0;font-size:clamp(21px,2.5vw,34px);font-weight:600;line-height:1.15;letter-spacing:-.03em}
.pcard p{margin:0;color:var(--muted);font-size:14.5px;line-height:1.66}
.hl{display:grid;gap:9px;margin:2px 0 0;padding:0;list-style:none}
.hl li{position:relative;padding-left:20px;font-size:13.5px;color:var(--muted)}
.hl li::before{content:'';position:absolute;left:0;top:9px;width:8px;height:1px;background:var(--grad)}
.tags{display:flex;flex-wrap:wrap;gap:7px;margin-top:auto;padding-top:8px}
.tag{font-family:var(--mono);font-size:10px;letter-spacing:.08em;padding:6px 11px;border-radius:8px;
  background:rgba(255,255,255,.05);border:1px solid var(--line);color:var(--muted)}
.pcard__img{position:relative;overflow:hidden;background:#0b0b15;border-left:1px solid var(--line)}
@media(max-width:880px){.pcard__img{border-left:0;border-top:1px solid var(--line);min-height:280px;order:-1}}
.pcard__img img{position:absolute;inset:0;width:100%;height:100%;will-change:transform}
.pcard__img.fit img{object-fit:contain;padding:26px;filter:brightness(.96) saturate(1.04)}
.pcard__img.cover img{object-fit:cover}
.pcard__img::after{content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(160deg,rgba(139,92,246,.14),transparent 55%,rgba(34,211,238,.11))}

/* ---------- skills ---------- */
.sk__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(258px,1fr));gap:18px}
.sk{padding:26px;display:grid;gap:15px;align-content:start}
.sk h3{margin:0;font-size:16px;font-weight:600;letter-spacing:-.01em;display:flex;align-items:center;gap:10px}
.sk h3::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--grad)}
.sk ul{margin:0;padding:0;list-style:none;display:flex;flex-wrap:wrap;gap:7px}
.sk li{font-size:12.5px;padding:7px 12px;border-radius:9px;background:rgba(255,255,255,.045);
  border:1px solid var(--line);color:var(--muted);will-change:transform,opacity}
.sk li:hover{color:var(--ink);border-color:var(--line2)}

/* ---------- research / awards ---------- */
.two{display:grid;grid-template-columns:1.25fr .75fr;gap:clamp(22px,4vw,56px);align-items:start}
@media(max-width:900px){.two{grid-template-columns:1fr}}
.pub{padding:22px 0;border-bottom:1px solid var(--line);display:grid;
  grid-template-columns:64px 1fr;gap:18px;align-items:start}
.pub .y{font-family:var(--mono);font-size:12px;color:var(--a);letter-spacing:.08em;padding-top:3px}
.pub h4{margin:0 0 5px;font-size:16.5px;font-weight:500;letter-spacing:-.015em;line-height:1.35}
.pub .au{font-size:13px;color:var(--muted)}
.pub .vn{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--faint);margin-top:5px}
.award{padding:26px;display:grid;gap:9px}
.award .y{font-family:var(--mono);font-size:11px;letter-spacing:.14em;color:var(--p)}
.award h4{margin:0;font-size:19px;font-weight:600;letter-spacing:-.02em}
.award .org{font-size:13.5px;color:var(--ink);opacity:.85}
.award p{margin:0;font-size:13.5px;color:var(--muted)}

/* ---------- contact ---------- */
.contact{text-align:center;padding-bottom:clamp(60px,9vh,110px)}
.contact h2{font-size:clamp(38px,9vw,124px);font-weight:700;letter-spacing:-.05em;line-height:.95;margin:0 0 30px}
.contact h2 .ch{display:inline-block;will-change:transform}
.cta{display:inline-flex;align-items:center;gap:12px;padding:16px 30px;border-radius:999px;
  background:var(--grad);color:#08080f;font-weight:600;font-size:15px;letter-spacing:-.01em;
  position:relative;overflow:hidden;will-change:transform}
.cta:hover{filter:brightness(1.08)}
.links{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;margin-top:26px}
.links a{font-family:var(--mono);font-size:11.5px;letter-spacing:.08em;padding:11px 18px;border-radius:999px;
  background:var(--glass);border:1px solid var(--line);color:var(--muted);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);transition:color .3s,border-color .3s}
.links a:hover{color:var(--ink);border-color:var(--line2)}
footer{padding:26px var(--pad);border-top:1px solid var(--line);display:flex;flex-wrap:wrap;gap:12px;
  justify-content:space-between;font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--faint);position:relative;z-index:3}

/* ---------- reveal defaults ---------- */
[data-reveal]{opacity:0}
.no-motion [data-reveal]{opacity:1!important;transform:none!important;filter:none!important}
@media (prefers-reduced-motion:reduce){
  [data-reveal]{opacity:1!important}
  .grain{animation:none}
}

/* =========================================================
   v2 — richer motion surfaces
   ========================================================= */

/* ---------- sliding nav pill ---------- */
.nav__links{position:relative}
.nav__links a{position:relative;z-index:1}
.nav__links a.on{color:#08080f;background:transparent}
.nav__pill{position:absolute;top:5px;left:0;height:calc(100% - 10px);width:0;
  background:#fff;border-radius:999px;z-index:0;opacity:0;pointer-events:none;
  will-change:transform,width}

/* ---------- cursor label ---------- */
.cur-ring b{position:absolute;inset:0;display:grid;place-items:center;
  font-family:var(--mono);font-size:8.5px;letter-spacing:.14em;font-weight:500;
  color:#08080f;opacity:0;text-transform:uppercase}
.cur-ring.labelled{mix-blend-mode:normal;background:#fff;border-color:transparent}
.cur-ring.labelled b{opacity:1}

/* ---------- stat band ---------- */
.statband{padding:clamp(40px,7vw,86px) 0;position:relative;z-index:3}
.stat__row{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(12px,2.5vw,34px)}
@media(max-width:760px){.stat__row{grid-template-columns:repeat(2,1fr)}}
.stat{display:grid;gap:6px;padding:22px 4px;border-top:1px solid var(--line);position:relative}
.stat::after{content:'';position:absolute;top:-1px;left:0;height:1px;width:0;background:var(--grad)}
.stat__n{font-size:clamp(34px,5.5vw,62px);font-weight:700;letter-spacing:-.05em;line-height:1;
  font-variant-numeric:tabular-nums;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.stat span{font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--faint)}

/* ---------- marquee: two counter-running rows + velocity skew ---------- */
.marq__skew{will-change:transform}
.marq__track--b{opacity:.55}
.marq__track--b span{font-size:clamp(14px,2.1vw,26px)}
.marq__track--b span::after{background:var(--c)}

/* ---------- experience progress rail ---------- */
.hrail{margin-top:26px;height:2px;background:var(--line);border-radius:2px;overflow:hidden}
.hrail i{display:block;height:100%;width:0;background:var(--grad);border-radius:2px}

/* ---------- education node dots ---------- */
.edu__item{position:relative}
.edu__node{position:absolute;left:-38px;top:30px;width:11px;height:11px;border-radius:50%;
  background:var(--a);box-shadow:0 0 0 4px rgba(167,139,250,.16);opacity:0}
@media(max-width:820px){.edu__node{display:none}}

/* ---------- project accent + index numeral ---------- */
/* NB: no `position` here — .pcard is sticky (stacked-card effect) and
   sticky already anchors the absolutely-positioned index numeral. */
.pcard{--acc:hsl(var(--h,268) 85% 68%)}
.pcard__idx{position:absolute;top:18px;right:24px;z-index:2;
  font-family:var(--mono);font-size:clamp(40px,6vw,74px);font-weight:500;line-height:1;
  color:transparent;-webkit-text-stroke:1.5px hsl(var(--h,268) 90% 74% / .62);
  filter:drop-shadow(0 2px 12px rgba(0,0,0,.6));
  pointer-events:none;will-change:transform}
.pcard .tag{border-color:hsl(var(--h,268) 85% 68% / .28)}
.pcard .hl li::marker{color:var(--acc)}
.pcard__cat b{color:var(--acc)}

/* ---------- publication award badge ---------- */
.pub__medal{font-style:normal;margin-left:8px;color:#fbbf24;font-size:13px;
  display:inline-block;will-change:transform}
.pub__aw{margin-top:7px;display:inline-flex;align-items:center;gap:7px;
  font-family:var(--mono);font-size:10px;letter-spacing:.11em;text-transform:uppercase;
  padding:5px 11px;border-radius:999px;color:#fcd34d;
  background:linear-gradient(100deg,rgba(251,191,36,.16),rgba(251,191,36,.05));
  border:1px solid rgba(251,191,36,.32)}

/* ---------- award spotlight card ---------- */
.award{position:relative;overflow:hidden;padding:28px;gap:11px;
  border-color:rgba(251,191,36,.24)}
.award__sheen{position:absolute;top:0;bottom:0;width:38%;pointer-events:none;left:-40%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.16),transparent);
  will-change:transform}
.award__top{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
.award__y{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;color:#fcd34d;
  text-transform:uppercase}
.award h4{margin:4px 0 0;font-size:22px;font-weight:700;letter-spacing:-.025em}
.award__seal{flex:none;width:58px;height:58px;border-radius:50%;display:grid;place-items:center;
  background:radial-gradient(circle at 34% 30%,#f9d976,#c2410c);
  box-shadow:0 6px 22px rgba(194,65,12,.42),inset 0 0 0 2px rgba(255,255,255,.30);
  will-change:transform}
.award__seal span{font-size:23px;font-weight:700;color:#fff7ed;line-height:1}
.award__venue{font-size:14px;font-weight:500;color:var(--ink)}
.award__row{display:grid;grid-template-columns:70px 1fr;gap:12px;align-items:baseline;
  padding-top:9px;border-top:1px solid var(--line)}
.award__row span{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint)}
.award__row b{font-size:13px;font-weight:500;line-height:1.45;color:var(--ink)}
.award p{margin:2px 0 0;font-size:13px;color:var(--muted)}
.award__org{font-family:var(--mono);font-size:10px;letter-spacing:.09em;color:var(--faint);
  padding-top:9px;border-top:1px solid var(--line)}

/* ---------- reveal rest-states (JS animates from these) ---------- */
[data-reveal]{will-change:transform,opacity}
.no-motion [data-reveal]{opacity:1!important;transform:none!important;filter:none!important;clip-path:none!important}

/* ---------- registered accent so section changes ease, not snap ---------- */
@property --a { syntax:'<color>'; inherits:true; initial-value:#a78bfa }
:root{transition:--a .9s var(--ease)}

/* ---------- split section headings ---------- */
/* horizontal padding + matching negative margin: the overflow:hidden that
   masks the vertical rise would otherwise clip glyph side-bearings
   (narrow letters like "I" lost most of their width). */
.tline{display:inline-block;overflow:hidden;vertical-align:bottom;
  padding:.02em .1em .1em;margin:0 -.1em}
/* font-style:normal — the word wrapper is an <i>, which the UA stylesheet
   renders italic; every non-gradient heading word was coming out oblique. */
.tw{display:inline-block;will-change:transform;font-style:normal}
.tw.em{font-style:normal;background:var(--grad);
  -webkit-background-clip:text;background-clip:text;color:transparent}

/* the stat rule is drawn by animating --w */
.stat::after{width:var(--w,0%)}

/* =========================================================
   mobile
   ========================================================= */
.navbtn{display:none;width:40px;height:40px;border-radius:999px;position:relative;
  border:1px solid var(--line2);background:var(--glass);flex:none}
.navbtn i{position:absolute;left:11px;width:18px;height:1.5px;background:var(--ink);border-radius:2px;
  transition:transform .34s var(--ease),opacity .2s}
.navbtn i:nth-child(1){top:15px}
.navbtn i:nth-child(2){top:23px}
body.menu-open .navbtn i:nth-child(1){transform:translateY(4px) rotate(45deg)}
body.menu-open .navbtn i:nth-child(2){transform:translateY(-4px) rotate(-45deg)}

.menu{position:fixed;inset:0;z-index:690;display:none;flex-direction:column;
  justify-content:center;gap:6px;padding:0 var(--pad);overflow-y:auto;
  background:rgba(6,6,12,.88);backdrop-filter:blur(26px) saturate(150%)}
.menu.on{display:flex}
/* #menuLinks is the actual flex item (.menu's only direct child); the <a>s
   inside it are plain inline elements by default, so without display:block
   here they inline-flow onto one shared text line and can overflow the
   viewport entirely — "Home About Experience Educ…" running off the right
   edge, with every link past it unreachable. */
#menuLinks{display:flex;flex-direction:column;gap:6px}
.menu a{display:block;font-size:clamp(24px,8vw,44px);font-weight:600;letter-spacing:-.035em;
  padding:8px 0;opacity:0;border-bottom:1px solid var(--line)}
.menu a.on{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}

@media(max-width:860px){
  .navbtn{display:block}
  .nav{padding-inline:20px}
  .hero{padding-top:96px}
  .statband{padding:34px 0}
  .stat{padding:16px 4px}
  .award__row{grid-template-columns:60px minmax(0,1fr)}
  .award{padding:22px}
  .xcard{min-height:46vh;padding:24px}
  .hpin__head{margin-bottom:22px}
  .pcard__in{min-height:0}
  .marq__track--b{display:none}
}
body.menu-open{overflow:hidden}

/* ---------- lightbox ("View" on a project card) ---------- */
/* display:none by default, NOT on the [hidden] attribute: [hidden] and a
   plain .lb{display:grid} rule are equal specificity, and our stylesheet
   loads after the UA stylesheet, so display:grid was winning outright —
   a full-viewport, invisible, z-index:900 layer sat on top of the entire
   site from page load and silently ate every real click and tap (missed
   in testing because it only ever used element.click(), which bypasses
   hit-testing). pointer-events:none is a second line of defense against
   the same mistake ever happening again. */
.lb{position:fixed;inset:0;z-index:900;display:none;place-items:center;padding:clamp(16px,4vw,52px);
  background:rgba(4,4,10,.9);backdrop-filter:blur(20px);opacity:0;cursor:zoom-out;pointer-events:none}
.lb:not([hidden]){display:grid;pointer-events:auto}
.lb__in{max-width:min(1100px,92vw);width:100%;display:grid;gap:14px;justify-items:center}
.lb__in img{max-height:78vh;width:auto;border-radius:14px;border:1px solid var(--line2);
  box-shadow:0 30px 90px rgba(0,0,0,.6)}
.lb__cap{font-size:14px;color:var(--muted);text-align:center;max-width:60ch}
.lb__x{position:absolute;top:18px;right:22px;width:42px;height:42px;border-radius:999px;
  border:1px solid var(--line2);background:var(--glass);font-size:22px;line-height:1}
.pcard{cursor:zoom-in}

/* ---------- award certificate ---------- */
/* This is a document that needs to stay legible, not a decorative photo —
   a fixed max-height + overflow:hidden crop was showing only the vertically
   centered ~17-48% of the certificate (worse on wide cards, since the crop
   height stayed fixed while width kept growing). Capped by max-width
   instead: the whole document renders at its own aspect ratio, uncropped,
   at roughly real certificate size regardless of how wide the card is. */
.award__cert{margin:4px 0 0;padding:0;position:relative;overflow:hidden;border-radius:12px;
  border:1px solid rgba(251,191,36,.26);background:#fff;cursor:zoom-in;
  max-width:300px}
.award__cert img{width:100%;height:auto;display:block;
  transition:transform .7s var(--ease)}
.award__cert:hover img{transform:scale(1.035)}
@media(max-width:420px){.award__cert{max-width:100%}}

.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}

/* =========================================================
   3D world integration (myhub_01_static only — these
   selectors simply match nothing in the standalone copy)
   ========================================================= */
.worldbtn{font-family:var(--mono);font-size:11px;letter-spacing:.1em;font-weight:500;
  padding:8px 13px;border-radius:999px;border:1px solid var(--line);
  background:var(--glass);color:var(--muted);line-height:1}
.worldbtn:hover{border-color:var(--line2);color:var(--ink)}
.worldbtn[aria-pressed="true"]{background:var(--grad);border-color:transparent;color:#08080f}

/* the original site header is gone, so the world fills the viewport */
.metaverse-stage{top:0!important;z-index:600}
#cv-shell[hidden]{display:none}

/* Exit control for the 3D world. #worldBtn (the toggle in the CV nav) lives
   inside #cv-shell, which gets hidden while the world is active — so once a
   visitor entered 3D, the ONLY way back was Escape, which does not exist on
   a touchscreen. This sits in .world-ui instead (never hidden by cv-shell)
   and is always reachable, mouse or touch. */
.world-exit{position:absolute;top:14px;right:20px;z-index:5;pointer-events:auto;
  display:flex;align-items:center;gap:6px;padding:9px 14px;border-radius:999px;
  border:1px solid rgba(48,45,40,.22);background:rgba(255,255,255,.86);
  color:#302d28;font-family:var(--mono);font-size:11px;font-weight:600;letter-spacing:.08em;
  box-shadow:0 8px 22px rgba(0,0,0,.18)}
.world-exit span:last-child{font-size:15px;font-weight:700;line-height:1}
[data-theme="dark"] .world-exit,html:not([data-theme="light"]) .world-exit{
  background:rgba(20,20,26,.72);color:#f3f3f8;border-color:rgba(255,255,255,.16)}

/* The previous design scrolled two inner panels, so its stylesheet pinned the
   document with html/body { height:100%; overflow:hidden }. The scroll CV needs
   the page itself to scroll, or nothing below the fold is reachable at all. */
html{height:auto}
body{height:auto;min-height:0;overflow:visible}

/* Hidden curtains must not cover the CV when reduced motion skips the intro. */
.loader__curtain[hidden]{display:none}
.nav__right a.worldbtn{display:inline-flex;align-items:center;text-decoration:none;white-space:nowrap}

/* Exhibits are documents, not scroll-triggered sections. */
.world-detail-content .world-detail-section { padding:12px 0!important; height:auto!important; min-height:0!important; color:var(--ink); }
.world-detail-content [data-reveal], .world-detail-content .sk, .world-detail-content .pub { opacity:1!important; }
.world-detail-content .about__stage, .world-detail-content .about__sticky,
.world-detail-content .hpin { position:static!important; height:auto!important; min-height:0!important; }
.world-detail-content .htrack { display:grid; width:100%!important; transform:none!important; padding:12px 0; gap:18px; }
.world-detail-content .xcard { width:100%; min-width:0; }
.world-detail-content .wrap { width:100%; padding:0; }
.world-detail-content .pcard { position:static!important; opacity:1!important; transform:none!important; }
.world-detail-content .sk__fill { transform:scaleX(1)!important; }
