:root{--paper:#f3f2ef;--ink:#0b0c0e;--line:rgba(11,12,14,.28);--ease:cubic-bezier(.22,1,.36,1)}
*{box-sizing:border-box}html,body{margin:0;min-height:100%;background:var(--paper);color:var(--ink)}body{font-family:Inter,"Noto Sans SC",sans-serif;overflow:hidden}button,a{font:inherit;color:inherit}button{border:0;background:none;cursor:pointer}.noise{position:fixed;inset:0;pointer-events:none;z-index:100;opacity:.055;mix-blend-mode:multiply;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.52'/%3E%3C/svg%3E")}.cursor-dot{position:fixed;width:8px;height:8px;border:1px solid currentColor;z-index:120;pointer-events:none;transform:translate(-50%,-50%);transition:.25s}.cursor-dot.is-hover{width:28px;height:28px;background:rgba(255,255,255,.16);backdrop-filter:blur(2px)}
.site-header{position:fixed;z-index:80;top:0;left:0;right:0;height:74px;display:flex;align-items:center;justify-content:space-between;padding:0 28px;border-bottom:1px solid rgba(10,12,15,.08)}.brand{display:flex;align-items:center;gap:10px;font:600 11px/1 "IBM Plex Mono",monospace;letter-spacing:.08em}.brand-mark{font-size:18px;transition:transform .8s var(--ease)}.brand:hover .brand-mark{transform:rotate(180deg)}.top-nav{display:flex;align-items:center;gap:28px;font:500 11px/1 "IBM Plex Mono",monospace}.nav-link{position:relative;padding:10px 0}.nav-link:after{content:"";position:absolute;left:0;right:100%;bottom:3px;height:1px;background:currentColor;transition:right .3s}.nav-link:hover:after,.nav-link.is-active:after{right:0}.lang-toggle{display:flex;gap:5px;opacity:.55}.lang-toggle span{opacity:.45}.lang-toggle span.is-active{opacity:1;font-weight:600}.lang-toggle i{font-style:normal;opacity:.35}.contact-wrap{position:relative}
.id-card{position:absolute;right:-70px;top:35px;width:292px;padding:16px;background:rgba(235,237,239,.94);border:1px solid #141519;box-shadow:0 28px 70px rgba(0,0,0,.22);transform:translateY(-145%) rotate(-3deg);transform-origin:80% -30px;opacity:0;pointer-events:none;transition:transform .75s var(--ease),opacity .25s;backdrop-filter:blur(14px)}.contact-wrap:hover .id-card,.contact-wrap.is-open .id-card{transform:translateY(12px) rotate(1deg);opacity:1;pointer-events:auto}.lanyard{position:absolute;width:1px;height:56px;background:#111;top:-55px;right:75px}.lanyard:after{content:"";position:absolute;width:20px;height:7px;border:1px solid #111;bottom:-4px;left:-10px;background:#d7dadd}.id-card-top{display:flex;justify-content:space-between;border-bottom:1px solid #111;padding-bottom:8px;font-size:9px}.id-card-main{display:grid;grid-template-columns:82px 1fr;gap:13px;padding:16px 0}.id-card-main img{width:82px;height:98px;object-fit:cover;filter:grayscale(1) contrast(1.08);border:1px solid #111}.id-card-main strong{font-size:15px;line-height:1.35}.id-label{font-size:8px;opacity:.55;margin:0 0 3px}.id-card-main span{font-size:10px}.id-card-meta{border-top:1px solid #111;padding-top:9px;display:grid;gap:4px;font-size:9px}.id-card-meta a{text-decoration:none}.barcode{margin-top:12px;height:22px;background:repeating-linear-gradient(90deg,#111 0 1px,transparent 1px 3px,#111 3px 5px,transparent 5px 8px)}
#app{height:100vh;position:relative}.scene{position:absolute;inset:0;visibility:hidden;opacity:0;pointer-events:none;transition:opacity .55s var(--ease),visibility .55s;overflow:hidden}.scene.is-visible{visibility:visible;opacity:1;pointer-events:auto}.scene-home{background:var(--paper)}.star-stage{position:absolute;left:50%;top:49%;width:min(46vw,630px);height:min(46vw,630px);transform:translate(-50%,-50%);z-index:2;transition:transform 1.15s var(--ease),left 1.15s var(--ease),width 1.15s var(--ease),height 1.15s var(--ease)}.star-stage canvas{width:100%!important;height:100%!important;display:block}.star-glow{position:absolute;left:50%;top:51%;width:27vw;height:12vw;transform:translate(-50%,-50%);background:radial-gradient(ellipse,rgba(61,70,82,.2),transparent 72%);filter:blur(25px);z-index:1;transition:1.15s var(--ease)}
.hero-copy{position:absolute;left:4.2vw;top:13vh;z-index:4;max-width:420px;transition:opacity .55s,transform .8s var(--ease)}.eyebrow{font:500 10px/1.4 "IBM Plex Mono",monospace;letter-spacing:.09em}.hero-copy h1{margin:18px 0 14px;font-size:clamp(38px,4.2vw,72px);line-height:.95;letter-spacing:-.065em;font-weight:500}.hero-sub{max-width:320px;font:400 11px/1.6 "IBM Plex Mono",monospace;text-transform:uppercase}
.chapter-network{position:absolute;inset:0;z-index:5}.chapter{position:absolute;min-width:180px;text-align:left;font-family:"IBM Plex Mono",monospace;transition:transform .35s var(--ease),opacity .5s}.chapter:before{content:"";position:absolute;height:1px;background:var(--line);transform-origin:left center;z-index:-1}.chapter .node{position:absolute;width:10px;height:10px;background:var(--paper);border:1px solid var(--ink);box-shadow:inset 0 0 0 2px var(--paper);transition:.3s}.chapter:hover{transform:translateY(-4px)}.chapter:hover .node{background:var(--ink);transform:scale(1.25)}.chapter-index{display:block;font-size:9px;opacity:.55;margin-bottom:6px}.chapter strong{display:block;font-size:12px}.chapter small{display:block;margin-top:5px;font-size:9px;opacity:.55}.chapter-data{left:15.8vw;top:47vh}.chapter-data:before{width:24vw;left:94%;top:9px;transform:rotate(-13deg)}.chapter-data .node{left:calc(94% + 23.2vw);top:calc(9px - 5.3vw)}.chapter-poster{right:7vw;top:28vh}.chapter-poster:before{width:21vw;right:103%;top:11px;transform-origin:right;transform:rotate(15deg)}.chapter-poster .node{right:calc(103% + 20.4vw);top:calc(11px - 5.1vw)}.chapter-video{right:5vw;bottom:22vh}.chapter-video:before{width:23vw;right:103%;top:11px;transform-origin:right;transform:rotate(-14deg)}.chapter-video .node{right:calc(103% + 22.3vw);top:calc(11px + 5.5vw)}.chapter-about{left:17vw;bottom:13vh}.chapter-about:before{width:23vw;left:94%;top:9px;transform:rotate(18deg)}.chapter-about .node{left:calc(94% + 22vw);top:calc(9px + 7vw)}
.project-branches{position:absolute;right:4vw;top:27vh;z-index:7;width:min(32vw,410px);display:grid;opacity:0;transform:translateX(45px);pointer-events:none;transition:opacity .45s .45s,transform .75s .32s var(--ease)}.branch-label{font:500 9px "IBM Plex Mono",monospace;border-bottom:1px solid var(--line);padding-bottom:10px}.project-branches button{display:grid;grid-template-columns:34px 1fr;gap:12px;align-items:center;text-align:left;padding:16px 0;border-bottom:1px solid var(--line);font:500 11px "IBM Plex Mono",monospace}.project-branches button span{opacity:.45}.project-branches button b{font-weight:500;transition:transform .25s}.project-branches button:hover b{transform:translateX(8px)}.branch-back{margin-top:13px}.scene-home.data-mode .star-stage{left:29%;width:min(62vw,810px);height:min(62vw,810px);transform:translate(-50%,-50%) scale(1.08)}.scene-home.data-mode .star-glow{left:29%;transform:translate(-50%,-50%) scale(1.45)}.scene-home.data-mode .hero-copy{opacity:0;transform:translateX(-55px);pointer-events:none}.scene-home.data-mode .chapter{opacity:0;pointer-events:none}.scene-home.data-mode .project-branches{opacity:1;transform:none;pointer-events:auto}
.corner-meta{position:absolute;bottom:25px;z-index:6;display:flex;gap:10px;align-items:center;font:500 8px "IBM Plex Mono",monospace}.left-meta{left:28px}.right-meta{right:28px;gap:24px}.pulse{width:7px;height:7px;border-radius:50%;background:#23a65f;animation:pulse 2s infinite}@keyframes pulse{70%{box-shadow:0 0 0 8px rgba(35,166,95,0)}}.scroll-hint{position:absolute;left:50%;bottom:22px;transform:translateX(-50%);z-index:6;margin:0;display:flex;align-items:center;gap:10px;font:500 8px "IBM Plex Mono",monospace}.scroll-hint span{width:22px;height:1px;background:currentColor;animation:hint 1.8s infinite}.scroll-hint em{font-style:normal}@keyframes hint{50%{transform:scaleX(.45);opacity:.35}}
.gallery-scene{padding:112px 0 55px}.poster-scene{background:#f5f3ef;color:#101114}.video-scene{background:#06070a;color:#e8e9eb}.gallery-head{position:relative;z-index:3;display:flex;align-items:end;justify-content:space-between;padding:0 4.2vw}.gallery-head h2{margin:8px 0 0;font-size:clamp(42px,6vw,88px);line-height:.9;letter-spacing:-.06em;font-weight:500}.gallery-head>p{max-width:360px;font:400 10px/1.55 "IBM Plex Mono",monospace;text-transform:uppercase}.gallery-viewport{position:absolute;left:0;right:0;top:30vh;height:55vh;perspective:1500px;overflow:hidden;touch-action:pan-y}.gallery-track{position:absolute;left:50%;top:48%;transform-style:preserve-3d;transform:translate(-50%,-50%);width:1px;height:1px}.gallery-card{position:absolute;left:0;top:0;width:min(29vw,390px);aspect-ratio:4/5;transform-style:preserve-3d;transform:translate(-50%,-50%) translateX(calc(var(--offset)*min(31vw,420px))) rotateY(calc(var(--offset)*-17deg)) translateZ(calc(var(--abs-offset)*-65px));opacity:var(--opacity);transition:.75s var(--ease);cursor:pointer}.gallery-card:hover{filter:brightness(1.07)}.gallery-art{position:absolute;inset:0;overflow:hidden;border:1px solid currentColor;background:var(--card-bg)}.gallery-art:before{content:"";position:absolute;inset:0;background:var(--card-pattern)}.gallery-art:after{content:attr(data-code);position:absolute;top:12px;left:12px;padding:5px 7px;border:1px solid currentColor;font:500 8px "IBM Plex Mono",monospace;background:rgba(255,255,255,.35)}.video-scene .gallery-art:after{background:rgba(0,0,0,.38)}.card-copy{position:absolute;left:14px;right:14px;bottom:13px;display:flex;justify-content:space-between;align-items:end;gap:10px;z-index:2;font:500 9px "IBM Plex Mono",monospace}.card-copy b{max-width:75%;font-size:11px}.gallery-controls{position:absolute;left:50%;bottom:35px;transform:translateX(-50%);z-index:5;display:flex;align-items:center;gap:20px;font:500 9px "IBM Plex Mono",monospace}.gallery-controls button{border:1px solid currentColor;width:34px;height:28px}.gallery-controls em{font-style:normal;opacity:.45}.scene-back{position:absolute;left:28px;bottom:28px;z-index:5;font:500 9px "IBM Plex Mono",monospace}.video-ambient{position:absolute;inset:0;opacity:.7;background:radial-gradient(circle at 50% 58%,rgba(38,53,77,.42),transparent 38%),linear-gradient(115deg,transparent 20%,rgba(67,37,67,.18),transparent 70%);animation:ambient 8s ease-in-out infinite alternate}@keyframes ambient{to{transform:scale(1.1) translateY(-2%);filter:hue-rotate(18deg)}}.video-scene .gallery-card{aspect-ratio:16/10;width:min(42vw,600px);transform:translate(-50%,-50%) translateX(calc(var(--offset)*min(39vw,560px))) rotateY(calc(var(--offset)*-15deg)) translateZ(calc(var(--abs-offset)*-80px))}.video-scene .gallery-viewport{top:36vh;height:48vh}
.about-scene{background:#d9dcdf;padding:18vh 6vw 10vh}.about-grid{display:grid;grid-template-columns:1.1fr .9fr;gap:10vw}.about-title h2{font-size:clamp(48px,7vw,100px);line-height:.94;letter-spacing:-.07em;font-weight:500;margin:20px 0}.about-copy{padding-top:11vh;max-width:560px}.about-copy>p{font-size:clamp(17px,1.7vw,25px);line-height:1.45;letter-spacing:-.02em}.skill-grid{display:grid;grid-template-columns:repeat(2,1fr);margin-top:55px;border-top:1px solid}.skill-grid span{padding:13px 0;border-bottom:1px solid;font:500 10px "IBM Plex Mono",monospace}
.project-dialog{width:min(1040px,92vw);height:min(680px,86vh);padding:0;border:1px solid #111;background:#efefec;color:#111;box-shadow:0 45px 120px rgba(0,0,0,.36)}.project-dialog::backdrop{background:rgba(5,7,10,.68);backdrop-filter:blur(9px)}.project-dialog[open]{display:grid;grid-template-columns:1.18fr .82fr}.dialog-close{position:absolute;right:12px;top:10px;z-index:4;width:34px;height:34px;border:1px solid;font-size:22px}.dialog-visual{min-height:100%;background:var(--dialog-bg);position:relative;overflow:hidden}.dialog-visual:before{content:"";position:absolute;inset:0;background:var(--dialog-pattern)}.dialog-content{padding:62px 42px 35px;overflow:auto}.dialog-kicker{font:500 9px "IBM Plex Mono",monospace;opacity:.6}.dialog-content h3{font-size:clamp(34px,4vw,58px);line-height:.95;letter-spacing:-.055em;margin:20px 0 28px}.dialog-description{font-size:14px;line-height:1.7}.dialog-content dl{margin-top:38px}.dialog-content dl div{display:grid;grid-template-columns:75px 1fr;padding:11px 0;border-top:1px solid rgba(0,0,0,.25)}.dialog-content dt{font:500 8px "IBM Plex Mono",monospace;opacity:.55}.dialog-content dd{margin:0;font:500 10px/1.45 "IBM Plex Mono",monospace}.dialog-tags{display:flex;flex-wrap:wrap;gap:7px;margin-top:30px}.dialog-tags span{border:1px solid;padding:6px 8px;font:500 8px "IBM Plex Mono",monospace}
@media(max-width:900px){body{overflow:auto}#app{height:100svh}.site-header{padding:0 16px;height:62px}.brand-name{display:none}.top-nav{gap:16px}.star-stage{width:90vw;height:90vw;top:48%}.hero-copy{left:20px;top:12vh;max-width:77vw}.hero-copy h1{font-size:43px}.chapter{min-width:140px}.chapter small,.chapter:before,.chapter .node,.corner-meta,.scroll-hint{display:none}.chapter-data{left:17px;top:48vh}.chapter-poster{right:-12px;top:27vh}.chapter-video{right:-12px;bottom:18vh}.chapter-about{left:20px;bottom:13vh}.scene-home.data-mode .star-stage{left:38%;width:108vw;height:108vw;opacity:.52}.project-branches{width:48vw;right:14px;top:25vh}.gallery-head>p{display:none}.gallery-card{width:55vw;transform:translate(-50%,-50%) translateX(calc(var(--offset)*59vw)) rotateY(calc(var(--offset)*-11deg))}.video-scene .gallery-card{width:74vw;transform:translate(-50%,-50%) translateX(calc(var(--offset)*78vw)) rotateY(calc(var(--offset)*-10deg))}.about-grid{grid-template-columns:1fr}.about-copy{padding-top:2vh}.about-title h2{font-size:49px}.project-dialog[open]{grid-template-columns:1fr;height:90vh;overflow:auto}.dialog-visual{min-height:42vh}.id-card{right:-56px}.cursor-dot{display:none}}
@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.001ms!important;transition-duration:.001ms!important}}
.resume-link{display:inline-flex;align-items:center;margin:18px 0 22px;padding:10px 14px;border:1px solid var(--line);font-family:"IBM Plex Mono","Noto Sans SC",ui-monospace,monospace;font-size:10px;letter-spacing:.08em;text-decoration:none;color:inherit;transition:background .2s ease,color .2s ease,transform .2s ease}.resume-link:hover{background:var(--ink);color:var(--paper);transform:translateY(-1px)}
