@font-face{font-family:"Obel Mono";src:url(../fonts/ObelMono-VF.woff2) format("woff2");font-weight:100 900;font-display:swap}
:root{
  --bg:#080507;--bg2:#120a0e;--line:#2a1219;--fg:#f3e4ea;--dim:#a08791;
  --g:#ff2d95;--c:#ff3b4a;--p:#ff8cc6;--r:#ff1744;
  --mono:"Obel Mono",ui-monospace,"JetBrains Mono",Consolas,monospace;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{background:var(--bg);color:var(--fg);font-family:var(--mono);font-size:15px;line-height:1.65;overflow-x:hidden}
::selection{background:var(--g);color:#000}
a{color:inherit;text-decoration:none}
#bg{position:fixed;inset:0;z-index:-2;opacity:.42;mix-blend-mode:screen}
.wrap{max-width:1100px;margin:0 auto;padding:0 24px}
/* boot */
#boot{position:fixed;inset:0;z-index:100;background:#000;display:flex;align-items:center;justify-content:center;transition:opacity .6s,visibility .6s}
#boot pre{color:var(--g);font:13px/1.7 var(--mono);width:min(560px,90vw);white-space:pre-wrap}
#boot.done{opacity:0;visibility:hidden}
/* nav */
nav{position:sticky;top:0;z-index:40;backdrop-filter:blur(12px);background:rgba(8,5,7,.5);border-bottom:1px solid var(--line)}
nav .wrap{display:flex;justify-content:space-between;align-items:center;height:56px}
.logo{display:inline-block;color:var(--g);font-weight:700}
.logo i{color:var(--dim);font-style:normal}
nav ul{display:flex;gap:22px;list-style:none;font-size:13px}
nav li a{display:inline-block;color:var(--dim);transition:color .2s}
nav li a:hover,nav li a.on{color:var(--g)}
@media(max-width:700px){nav ul{display:none}}
/* hero */
.hero{position:relative;min-height:calc(100vh - 56px);display:grid;grid-template-columns:1.25fr .75fr;gap:48px;align-items:center;padding:48px 0}
@media(max-width:860px){.stage{margin:0 -20px}.hero{grid-template-columns:1fr}.photo{order:-1;max-width:340px}}
.tag{display:inline-flex;gap:8px;align-items:center;border:1px solid var(--line);background:rgba(20,8,14,.6);backdrop-filter:blur(8px);padding:4px 12px;border-radius:99px;font-size:12px;color:var(--dim)}
.dot{width:8px;height:8px;border-radius:50%;background:var(--g);box-shadow:0 0 10px var(--g);animation:pulse 1.6s infinite}
@keyframes pulse{50%{opacity:.35}}
h1{font-size:clamp(38px,7vw,76px);line-height:1.05;margin:20px 0 12px;font-weight:800;letter-spacing:-.03em}
.glitch{position:relative;display:inline-block}
.glitch::before,.glitch::after{content:attr(data-t);position:absolute;inset:0;opacity:0}
.glitch:hover::before{opacity:.8;color:var(--c);transform:translate(-3px,1px);clip-path:inset(0 0 55% 0)}
.glitch:hover::after{opacity:.8;color:var(--r);transform:translate(3px,-1px);clip-path:inset(50% 0 0 0)}
.role{font-size:clamp(16px,2.4vw,22px);color:var(--c);min-height:1.6em}
.role b{color:var(--fg)}
.cur{display:inline-block;width:.6ch;background:var(--g);animation:blink 1s steps(1) infinite;margin-left:2px}
@keyframes blink{50%{opacity:0}}
.lead{color:var(--dim);max-width:56ch;margin:20px 0 28px}
.btns{display:flex;gap:12px;flex-wrap:wrap}
.btn{display:inline-flex;align-items:center;padding:11px 20px;border:1px solid var(--g);color:var(--g);border-radius:6px;font-size:13px;font-weight:600;transition:.2s;position:relative;overflow:hidden}
.btn:hover{background:linear-gradient(120deg,var(--g),var(--c));color:#0a0306;border-color:transparent;box-shadow:0 0 30px rgba(255,45,149,.55),0 0 90px rgba(255,23,68,.3)}
.btn::after{content:"";position:absolute;top:0;left:-130%;width:60%;height:100%;background:linear-gradient(100deg,transparent,rgba(255,255,255,.55),transparent);transform:skewX(-20deg);transition:left .7s;pointer-events:none}
.btn:hover::after{left:150%}
.btn.alt{border-color:var(--line);color:var(--fg)}
.btn.alt:hover{background:linear-gradient(120deg,#fff,var(--p));color:#0a0306;box-shadow:0 0 30px rgba(255,140,198,.45)}
.stats{display:flex;gap:32px;margin-top:40px;flex-wrap:wrap}
.stats div b{display:block;font-size:28px;color:var(--fg)}
.stats div span{font-size:12px;color:var(--dim)}
/* photo / lanyard */
.photo{justify-self:center;width:100%;max-width:430px}
.stage{position:relative;margin:0 -70px;height:min(440px,60vh);min-height:360px;cursor:grab;touch-action:pan-y;user-select:none}
.stage:active{cursor:grabbing}
/* component 3D vốn dùng class Tailwind — khai báo tay để canvas khớp đúng khung */
#lanyard>div{position:relative;width:100%;height:100%;overflow:hidden}
#lanyard canvas{display:block;width:100%!important;height:100%!important}
.boot3d{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:11px;color:var(--dim);animation:pulse 1.4s infinite}
.hint{display:flex;justify-content:space-between;align-items:center;font-size:10px;letter-spacing:.08em;color:var(--dim);text-transform:uppercase;padding:0 4px;margin-top:6px}
.hint span{display:flex;align-items:center;gap:6px}
.hint .dot{width:6px;height:6px}
/* sections */
section{padding:84px 0}
.h{display:flex;align-items:baseline;gap:14px;margin-bottom:36px}
.h span{color:var(--g)}
.h h2{font-size:clamp(24px,4vw,36px);letter-spacing:-.02em;background:linear-gradient(90deg,#fff,var(--p) 55%,var(--g));-webkit-background-clip:text;background-clip:text;color:transparent}
.h::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--line),transparent)}
.reveal{opacity:0;transform:translateY(40px) scale(.98);filter:blur(10px);transition:opacity .9s,transform .9s cubic-bezier(.2,.8,.2,1),filter .9s}
.reveal.in{opacity:1;transform:none;filter:none}
/* terminal */
.term{border:1px solid var(--line);border-radius:10px;background:rgba(8,3,6,.62);backdrop-filter:blur(16px) saturate(1.3);overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,.5)}
.term .bar{display:flex;gap:7px;align-items:center;padding:10px 14px;background:var(--bg2);border-bottom:1px solid var(--line);font-size:12px;color:var(--dim)}
.term .bar i{width:11px;height:11px;border-radius:50%;display:block}
.term .bar span{margin-left:10px}
.term .body{padding:18px;height:340px;overflow:auto;font-size:13.5px}
.term .row{display:flex;gap:8px}
.ps{color:var(--g);white-space:nowrap}
.ps em{color:var(--c);font-style:normal}
.term input{flex:1;background:none;border:0;outline:0;color:var(--fg);font:inherit;caret-color:var(--g)}
.out{color:var(--dim);white-space:pre-wrap;margin:2px 0 10px}
.out b{color:var(--fg)}.out .k{color:var(--c)}.out .y{color:var(--g)}
.chips{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}
.chips button{background:var(--bg2);border:1px solid var(--line);color:var(--dim);padding:5px 12px;border-radius:6px;font:inherit;font-size:12px;cursor:pointer;transition:.2s}
.chips button:hover{color:var(--g);border-color:var(--g)}
/* projects */
.filters{display:flex;gap:8px;margin-bottom:24px;flex-wrap:wrap}
.filters button{background:none;border:1px solid var(--line);color:var(--dim);padding:6px 14px;border-radius:99px;font:inherit;font-size:12px;cursor:pointer;transition:.2s}
.filters button.on,.filters button:hover{border-color:var(--g);color:var(--g)}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(310px,1fr));gap:18px}
.p{position:relative;border:1px solid var(--line);background:rgba(20,8,14,.5);backdrop-filter:blur(14px) saturate(1.4);border-radius:12px;padding:24px;overflow:hidden;transition:transform .25s,border-color .25s;display:flex;flex-direction:column}
.p::before{content:"";position:absolute;inset:0;background:radial-gradient(360px circle at var(--x,50%) var(--y,50%),rgba(255,45,149,.16),transparent 60%);opacity:0;transition:opacity .3s;pointer-events:none}
.p:hover{transform:translateY(-4px);border-color:rgba(255,45,149,.5)}
.p:hover::before{opacity:1}
.p>*{position:relative}
.p .top{display:flex;justify-content:space-between;font-size:12px;color:var(--dim);margin-bottom:14px}
.vis{border:1px solid var(--line);border-radius:4px;padding:0 8px}
.vis.priv{color:var(--p);border-color:rgba(255,140,198,.4)}
.vis.pub{color:var(--g);border-color:rgba(255,45,149,.4)}
.p h3{font-size:19px;margin-bottom:8px}
.p p{color:var(--dim);font-size:13.5px;flex:1}
.p ul{list-style:none;margin:12px 0 0;font-size:12.5px;color:var(--dim)}
.p li::before{content:"▹ ";color:var(--g)}
.tech{display:flex;gap:6px;flex-wrap:wrap;margin-top:16px}
.tech span{font-size:11px;color:var(--c);background:rgba(255,59,74,.07);padding:2px 9px;border-radius:4px}
.p .lnk{margin-top:16px;font-size:13px;color:var(--g)}
.p .lnk:hover{text-decoration:underline}
.hide{display:none}
/* skills */
.sk{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:18px}
.sk>div{position:relative;overflow:hidden;border:1px solid var(--line);border-radius:12px;padding:22px;background:rgba(20,8,14,.5);backdrop-filter:blur(14px) saturate(1.4)}
.sk h4{color:var(--g);font-size:13px;margin-bottom:14px}
.bar2{margin:10px 0}
.bar2 div{display:flex;justify-content:space-between;font-size:12.5px}
.bar2 i{display:block;height:4px;background:var(--line);border-radius:4px;margin-top:5px;overflow:hidden}
.bar2 i::after{content:"";display:block;height:100%;width:0;background:linear-gradient(90deg,var(--g),var(--c),var(--p),var(--g));background-size:300% 100%;animation:flow 3s linear infinite;box-shadow:0 0 10px var(--g);transition:width 1.2s cubic-bezier(.2,.8,.2,1)}
.in .bar2 i::after,.bar2.go i::after{width:var(--w)}
/* timeline */
.tl{border-left:1px solid var(--line);margin-left:6px}
.tl>div{position:relative;padding:0 0 32px 28px;transition:transform .3s}
.tl>div:hover{transform:translateX(10px)}
.tl>div:hover h4{color:var(--g)}
.tl>div::before{content:"";position:absolute;left:-5px;top:7px;width:9px;height:9px;border-radius:50%;background:var(--g);box-shadow:0 0 12px var(--g);transition:transform .3s,box-shadow .3s}
.tl>div:hover::before{transform:scale(1.9);box-shadow:0 0 18px var(--g),0 0 40px var(--c)}
.tl small{color:var(--c);font-size:12px}
.tl h4{font-size:17px;margin:2px 0 4px}
.tl p{color:var(--dim);font-size:13.5px}
/* contact */
.ct{text-align:center}
.ct h2{font-size:clamp(30px,6vw,60px);letter-spacing:-.03em;margin-bottom:14px;background:linear-gradient(90deg,var(--g),var(--c),var(--p),var(--g));background-size:300% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:flow 6s linear infinite;filter:drop-shadow(0 0 24px rgba(255,45,149,.35))}
.ct p{color:var(--dim);margin-bottom:28px}
.soc{display:flex;gap:14px;justify-content:center;margin-top:28px;flex-wrap:wrap;font-size:13px}
.soc a{display:inline-block;color:var(--dim);border-bottom:1px dashed var(--line)}
.soc a:hover{color:var(--g)}
footer{border-top:1px solid var(--line);padding:26px 0;text-align:center;color:var(--dim);font-size:12px}
.toast{position:fixed;bottom:28px;left:50%;transform:translate(-50%,80px);background:var(--g);color:#000;padding:10px 18px;border-radius:8px;font-weight:700;font-size:13px;transition:.3s;z-index:90}
.toast.on{transform:translate(-50%,0)}
/* ================= FX ================= */
#lines{position:fixed;inset:0;width:100%;height:100%;z-index:-3;display:block;pointer-events:none}
#progress{position:fixed;top:0;left:0;right:0;height:3px;z-index:60;transform-origin:0 50%;transform:scaleX(0);background:linear-gradient(90deg,var(--c),var(--g),var(--p));box-shadow:0 0 12px var(--g),0 0 30px rgba(255,45,149,.6)}
#sparks{position:fixed;inset:0;width:100%;height:100%;z-index:150;pointer-events:none}
.grain{position:fixed;inset:-50%;z-index:140;pointer-events:none;opacity:.06;mix-blend-mode:overlay;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");animation:grain 1s steps(6) infinite}
@keyframes grain{0%,100%{transform:translate(0,0)}20%{transform:translate(-5%,3%)}40%{transform:translate(4%,-6%)}60%{transform:translate(-3%,5%)}80%{transform:translate(6%,2%)}}
@keyframes flow{to{background-position:300% 0}}
/* con trỏ */
#cur-dot,#cur-ring{position:fixed;left:0;top:0;pointer-events:none;opacity:0;display:none}
html.fx-cursor #cur-dot,html.fx-cursor #cur-ring{display:flex}
html.fx-cursor,html.fx-cursor *{cursor:none!important}
html.fx-cursor input{cursor:text!important}
#cur-dot{z-index:201;width:5px;height:5px;margin:-2.5px 0 0 -2.5px;border-radius:50%;background:var(--g);transition:opacity .3s}
#cur-ring{z-index:200;width:26px;height:26px;margin:-13px 0 0 -13px;border-radius:50%;border:1px solid rgba(255,140,198,.45);transition:opacity .3s,width .25s ease,height .25s ease,margin .25s ease,background .25s,border-color .25s}
#cur-ring span{position:absolute;left:calc(100% + 8px);top:50%;transform:translateY(-50%);font-size:9px;letter-spacing:.18em;color:var(--p);white-space:nowrap;opacity:0;transition:opacity .2s}
#cur-ring.hov{width:40px;height:40px;margin:-20px 0 0 -20px;border-color:var(--g);background:rgba(255,45,149,.08)}
#cur-ring.hov span:not(:empty){opacity:.85}
#cur-ring.txt{opacity:0!important}
#cur-ring.down{width:20px;height:20px;margin:-10px 0 0 -10px}
#cur-ring.hov.down{width:34px;height:34px;margin:-17px 0 0 -17px}
/* thẻ lanyard phủ toàn vùng hero — kéo đi đâu cũng không bị cắt */
#lanyard-layer{position:absolute;top:0;left:calc(50% - 50vw);width:100vw;height:calc(100% + 30vh);z-index:6;pointer-events:none}
#lanyard-layer>div{position:relative;width:100%;height:100%;overflow:hidden}
#lanyard-layer canvas{display:block;width:100%!important;height:100%!important}
.stage::before{content:"";position:absolute;left:50%;top:50%;width:78%;aspect-ratio:1;transform:translate(-50%,-50%);border-radius:50%;background:radial-gradient(circle,rgba(255,45,149,.14),rgba(255,23,68,.05) 42%,transparent 70%);filter:blur(30px);animation:breath 4.5s ease-in-out infinite;pointer-events:none}
@keyframes breath{50%{transform:translate(-50%,-50%) scale(1.18);opacity:.65}}
/* tên ở hero */
.hero h1 .w{display:inline-block;white-space:nowrap}
.hero h1 .ch{display:inline-block;transition:transform .25s cubic-bezier(.2,.8,.2,1),color .25s,text-shadow .25s;will-change:transform}
h1.glitching{animation:glx .38s steps(3) 1}
@keyframes glx{0%{transform:translate(3px,-2px) skewX(-8deg);text-shadow:-5px 0 var(--r),5px 0 var(--p)}33%{transform:translate(-3px,2px) skewX(6deg);text-shadow:5px 0 var(--r),-5px 0 var(--p);clip-path:inset(10% 0 30% 0)}66%{transform:translate(2px,0);clip-path:inset(50% 0 5% 0)}100%{transform:none;text-shadow:none;clip-path:none}}
/* viền xoay + ánh sáng theo chuột trên thẻ */
@property --a{syntax:'<angle>';inherits:false;initial-value:0deg}
.p::after,.sk>div::after{content:"";position:absolute;inset:0;border-radius:inherit;padding:1.5px;background:conic-gradient(from var(--a),transparent 0 55%,var(--g) 70%,var(--c) 80%,transparent 92%);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:0;transition:opacity .3s;animation:spin 2.6s linear infinite;pointer-events:none}
.p:hover::after,.sk>div:hover::after{opacity:1}
@keyframes spin{to{--a:360deg}}
.sk>div::before{content:"";position:absolute;inset:0;background:radial-gradient(300px circle at var(--x,50%) var(--y,50%),rgba(255,45,149,.16),transparent 60%);opacity:0;transition:opacity .3s;pointer-events:none}
.sk>div:hover::before{opacity:1}
.sk>div>*{position:relative}
/* băng chữ chạy */
.marqs{position:relative;width:100vw;margin-left:calc(50% - 50vw);overflow:hidden;padding:56px 0 70px}
.marq{position:relative;z-index:2;width:110vw;margin-left:-5vw;padding:14px 0;transform:rotate(-3deg);background:linear-gradient(90deg,var(--g),var(--c),var(--g));box-shadow:0 0 50px rgba(255,45,149,.45)}
.marq.alt{z-index:1;transform:rotate(2.2deg);margin-top:-46px;background:rgba(10,4,7,.78);border-block:1px solid rgba(255,45,149,.35);box-shadow:none;backdrop-filter:blur(6px)}
.mq-track{display:flex;width:max-content;white-space:nowrap;font-size:clamp(26px,4.6vw,54px);font-weight:800;letter-spacing:-.02em;line-height:1.1;will-change:transform}
.mq-track span{padding:0 .35em;transition:color .2s,text-shadow .2s}
.mq-track i{font-style:normal;opacity:.7}
.marq .mq-track{color:#0a0306}
.marq .mq-track span:hover{color:#fff;text-shadow:0 0 18px #fff}
.marq.alt .mq-track{color:transparent;-webkit-text-stroke:1.2px var(--g)}
.marq.alt .mq-track span:hover{color:var(--g);text-shadow:0 0 24px var(--g)}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}.reveal{opacity:1;transform:none}}
/* đồng hồ trên thanh menu */
.clock{font-size:12px;color:var(--dim);letter-spacing:.06em;margin-left:auto;margin-right:26px;white-space:nowrap}
.clock b{color:var(--g);font-weight:600}
@media(max-width:900px){.clock{display:none}}
.out a{color:var(--g);text-decoration:underline}
