@font-face{font-family:"TT Display";src:url(../fonts/tiktok-sans-display.woff2) format("woff2");font-weight:820;font-display:swap}
@font-face{font-family:"TT Text";src:url(../fonts/tiktok-sans-text.woff2) format("woff2");font-weight:400;font-display:swap}

:root{
  --bg:#0b0d10;--card:#11151a;--line:#1f272e;--ink:#eef1f4;--ink2:#9aa4ad;--ink3:#66717b;
  --green:#3ee08f;--amber:#ffb43d;--cyan:#39c6ff;--orange:#ff7a33;
  --disp:"TT Display","Arial Narrow",sans-serif;--sans:"TT Text",system-ui,sans-serif;
  color-scheme:dark;
}
*,*::before,*::after{box-sizing:border-box}
html{background:var(--bg);color:var(--ink);scroll-behavior:smooth}
body{margin:0;font:400 16px/1.5 var(--sans);-webkit-font-smoothing:antialiased}
h1,h2,p{margin:0}
a{color:inherit}
:focus-visible{outline:2px solid var(--cyan);outline-offset:3px;border-radius:6px}

/* ---------- hero: pointer wipes the cover off a 3D scene ---------- */
.rv{position:relative;height:100svh;min-height:540px;overflow:hidden;background:#05070a;isolation:isolate}
.rv-3d,.rv-cover{position:absolute;inset:0;width:100%;height:100%;display:block}
.rv-cover{z-index:1;touch-action:pan-y}
.no-js .rv-3d,.no-js .rv-cover{display:none}
.rv-flat{background:radial-gradient(60% 70% at 70% 60%,#123447,#05070a 70%)}
.rv-text{position:absolute;z-index:2;left:clamp(1.25rem,6vw,7rem);bottom:clamp(5rem,15vh,10rem);pointer-events:none}
.rv-name{font:820 clamp(3.4rem,11vw,11.5rem)/.86 var(--disp);letter-spacing:-.035em}
.rv-role{margin-top:1.2rem;font-size:clamp(1rem,.95rem + .5vw,1.4rem);color:#c3cad1}
.rv-down{position:absolute;z-index:2;right:clamp(1.25rem,6vw,7rem);bottom:clamp(1.5rem,4vh,2.5rem);color:var(--ink2);text-decoration:none;font-size:.95rem}
.rv-down:hover{color:var(--ink)}

/* ---------- project cards ---------- */
.work{padding:clamp(3rem,7vw,6rem) clamp(1rem,4vw,4rem)}
.grid{max-width:1320px;margin:0 auto;display:grid;gap:clamp(.9rem,1.6vw,1.4rem);grid-template-columns:repeat(auto-fill,minmax(min(100%,290px),1fr))}
.card{position:relative;display:flex;flex-direction:column;background:var(--card);border:1px solid var(--line);border-radius:16px;overflow:hidden;text-decoration:none;color:var(--ink);transition:border-color .25s,transform .25s}
a.card:hover,.card:hover{border-color:var(--k);transform:translateY(-3px)}
.big{grid-column:span 2}
@media (max-width:660px){.big{grid-column:auto}}
.c-green{--k:var(--green)}.c-amber{--k:var(--amber)}.c-cyan{--k:var(--cyan)}.c-orange{--k:var(--orange)}
.art{display:block;width:100%;height:auto;aspect-ratio:16/9;background:radial-gradient(120% 100% at 50% 0%,color-mix(in srgb,var(--k) 9%,transparent),transparent 65%)}
.big .art{aspect-ratio:16/8}
.meta{padding:1rem 1.1rem 1.15rem;border-top:1px solid var(--line)}
.meta h2{font:820 1.35rem/1.1 var(--disp);letter-spacing:-.01em}
.meta p{margin-top:.3rem;font-size:.9rem;color:var(--ink2)}
a.card .meta h2::after{content:" ↗";font:400 .9em var(--sans);color:var(--ink3)}
.tag{position:absolute;top:.8rem;right:.8rem;font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;color:var(--ink3);border:1px solid var(--line);border-radius:99px;padding:.15rem .55rem}

/* ---------- svg vocabulary: one drawing system for every card ---------- */
.defs{position:absolute;width:0;height:0;overflow:hidden}
.art .plate{fill:url(#dots)}
.art .reg{fill:none;stroke:#2a3540;stroke-width:1}
.art .idx{font:600 9px ui-monospace,"Cascadia Mono",Menlo,monospace;fill:var(--ink3);letter-spacing:.1em}
.art .t{font:500 8px ui-monospace,"Cascadia Mono",Menlo,monospace;fill:var(--ink3);letter-spacing:.03em}
.art .t.c{text-anchor:middle}.art .t.tiny{font-size:6.5px}
.art .tk{fill:var(--k)}.art .ti{fill:var(--ink2)}.art .dark{fill:#0b0d10;font-weight:700}
.art .sh *{fill:#05070a!important;stroke:#05070a!important;animation:none!important}
.art .b{fill:#0e1418;stroke:#34424d;stroke-width:1.5}
.art .b2{fill:#141c22;stroke:#34424d;stroke-width:1.5}
.art .bk{fill:#0e1418;stroke:var(--k);stroke-width:1.5}
.art .l,.art .lk,.art .os{fill:none;stroke:#34424d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.art .lk{stroke:var(--k)}.art .os{stroke:var(--orange)}.art .os.soft{fill:color-mix(in srgb,var(--orange) 18%,transparent)}
.art .thin{stroke-width:1}.art .thick{stroke-width:2.5}.art .dash{stroke-dasharray:3 4}
.art .f{fill:#1d272f}.art .f2{fill:#2b3741}.art .fk{fill:var(--k)}.art .o{fill:var(--orange)}
.art .sk{fill:color-mix(in srgb,var(--k) 20%,#0e1418)}
.art .scr{fill:#090e12}
.art .die{fill:color-mix(in srgb,var(--k) 10%,#10171c);stroke:color-mix(in srgb,var(--k) 35%,#10171c);stroke-width:1}
.art .ok{fill:color-mix(in srgb,var(--green) 18%,#0e1418);stroke:var(--green);stroke-width:1.5}
.art .ok-m{fill:none;stroke:var(--green);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}.art .ok-m.thin{stroke-width:1.6}
.art .pulse{fill:none;stroke:var(--k);stroke-width:2;stroke-linecap:round;stroke-dasharray:10 400;stroke-dashoffset:410;animation:flow 2.8s linear infinite}
.art .pulse.s{stroke-dasharray:6 40;stroke-dashoffset:46;animation-name:flows;animation-duration:1.6s}
.art .d2{animation-delay:.9s}.art .d3{animation-delay:1.8s}
.art .ar,.art .he-t{font:12px "Segoe UI",Tahoma,"Noto Sans Hebrew","Noto Sans Arabic",sans-serif;fill:var(--ink2)}.art .he-t{fill:var(--ink)}
.art .sweep,.art .type,.art .cursor,.art .ripple,.art .paper,.art .eye,.art .pages,.art .fan,.art .bar,.art .chunk{transform-box:fill-box}
/* 01 DH2 */
.cells rect{rx:1}
.f-a{fill:var(--green)}.f-b{fill:#7d8b96}.f-c{fill:#3a4650}.f-d{fill:var(--orange)}
.art .sweep{fill:#fff;opacity:.07;animation:sweep 5s ease-in-out infinite}
/* 02 NeOS */
.art .pcb{fill:#0f1c16;stroke:#2b4a39;stroke-width:1.5}
.art .hole{fill:#0b0d10;stroke:#3d5b49;stroke-width:1.5}
.art .tr{fill:none;stroke:color-mix(in srgb,var(--amber) 38%,#0f1c16);stroke-width:1.5;stroke-linejoin:round}
.art .pin{fill:#8a7444}.art .pin1{fill:var(--amber)}
.art .chip{fill:#0c1013;stroke:#3a4650;stroke-width:1.5}
.art .port{fill:#1a2229;stroke:#53616c;stroke-width:1.2}
.art .term{fill:#06090b;stroke:color-mix(in srgb,var(--amber) 55%,#06090b);stroke-width:1.5}
.art .led{fill:#3b2a10}.art .led.act{fill:var(--amber);animation:blink 1.3s steps(1) infinite}.art .led.pwr{fill:var(--orange)}
.art .caret{animation:blink 1.1s steps(1) infinite}
/* 03 agents */
.art .type{transform-origin:left center;animation:type 3s steps(8) infinite}
.art .btn{opacity:.9}
.art .cursor{fill:var(--ink);stroke:#0b0f12;stroke-width:1;transform-origin:0 0;animation:click 3s ease-in-out infinite}
.art .ripple{fill:none;stroke:var(--k);stroke-width:1.5;opacity:0;transform-origin:center;animation:ripple 3s ease-out infinite}
/* 04 G-BRIDGE */
.art .seat .body{fill:#0e1418;stroke:var(--ink3);stroke-width:1.5;animation:speak 4.2s steps(1) infinite}
.art .seat .ring{fill:none;stroke:var(--k);stroke-width:1.5;opacity:0;animation:ring 4.2s steps(1) infinite}
.art .s1 *{animation-delay:.7s}.art .s2 *{animation-delay:1.4s}.art .s3 *{animation-delay:2.1s}.art .s4 *{animation-delay:2.8s}.art .s5 *{animation-delay:3.5s}
.art .paper{fill:var(--ink2);animation:drop 2.1s ease-in infinite}
.art .eye{transform-origin:center;animation:look 4.2s ease-in-out infinite}
/* 05 office helper */
.art .sand{fill:color-mix(in srgb,var(--k) 4%,transparent);stroke:#46545f;stroke-width:1.2;stroke-dasharray:4 3}
/* 06 pdfree */
.art .pages{animation:fan 4s ease-in-out infinite}
.art .tile .b2{animation:tile 6s steps(1) infinite}
.art .t1 .b2{animation-delay:1s}.art .t2 .b2{animation-delay:2s}.art .t3 .b2{animation-delay:3s}.art .t4 .b2{animation-delay:4s}.art .t5 .b2{animation-delay:5s}
/* 07 lumen */
.art .fan{transform-origin:center;animation:spin 1.8s linear infinite}
.art .glow{animation:glow 2.4s ease-in-out infinite}
.art .hl{stroke:var(--k);stroke-width:1}
/* 08 elior */
.art .row .box{fill:#0e1418;stroke:#46545f;stroke-width:1.3}
.art .row .mark{fill:none;stroke:#0b0d10;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;opacity:0}
.art .row.done .box{fill:var(--k);stroke:var(--k)}.art .row.done .mark{opacity:1}
.art .row.now .box{animation:check 3s steps(1) infinite}.art .row.now .mark{animation:checkm 3s steps(1) infinite}
.art .bar{fill:#1d272f;transform-origin:bottom;animation:grow 3.6s cubic-bezier(.2,.8,.2,1) infinite}
.art .bar.on{fill:color-mix(in srgb,var(--k) 75%,#0e1418)}
.art .b1{animation-delay:.1s}.art .b2.bar{animation-delay:.2s}.art .b3{animation-delay:.3s}.art .b4{animation-delay:.4s}.art .b5{animation-delay:.5s}.art .b6{animation-delay:.6s}
/* 09 pocket files */
.art .chunk{fill:#0e1418;stroke:var(--k);stroke-width:1.3;stroke-dasharray:4 3;animation:pop 3.2s ease-in-out infinite}
.art .chunk:nth-child(2){animation-delay:.25s}.art .chunk:nth-child(3){animation-delay:.5s}.art .chunk:nth-child(4){animation-delay:.75s}
.art .hb{fill:#1d272f;animation:hash 3.2s steps(1) infinite}
/* 10 data analyzer */
.art .hist{fill:color-mix(in srgb,var(--k) 55%,#0e1418)}
.art .scan{fill:var(--k);opacity:.14;animation:scan 4s ease-in-out infinite}
.art .lens .glass{fill:color-mix(in srgb,var(--k) 12%,transparent);stroke:var(--k);stroke-width:2.5}.art .lens path{stroke:var(--k);stroke-width:4;stroke-linecap:round}

@keyframes flow{to{stroke-dashoffset:0}}
@keyframes flows{to{stroke-dashoffset:0}}
@keyframes blink{50%{opacity:0}}
@keyframes sweep{0%,100%{transform:translateX(0)}50%{transform:translateX(266px)}}
@keyframes type{0%{transform:scaleX(0)}70%,100%{transform:scaleX(1)}}
@keyframes click{0%,55%,100%{transform:translate(0,0)}65%{transform:translate(-2px,-2px) scale(.9)}}
@keyframes ripple{0%,60%{opacity:0;transform:scale(.4)}66%{opacity:.9}100%{opacity:0;transform:scale(1.6)}}
@keyframes speak{0%{stroke:var(--k);fill:color-mix(in srgb,var(--k) 25%,#0e1418)}16.6%,100%{stroke:var(--ink3);fill:#0e1418}}
@keyframes ring{0%{opacity:.8}16.6%,100%{opacity:0}}
@keyframes drop{0%{transform:translateY(-6px);opacity:0}30%{opacity:1}80%{transform:translateY(10px);opacity:1}100%{transform:translateY(12px);opacity:0}}
@keyframes look{0%,40%,100%{transform:translateX(0)}50%,90%{transform:translateX(-4px)}}
@keyframes fan{50%{transform:translateX(-4px) rotate(-1deg)}}
@keyframes tile{0%{stroke:var(--k);fill:color-mix(in srgb,var(--k) 16%,#141c22)}16.6%,100%{stroke:#34424d;fill:#141c22}}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes glow{50%{opacity:.4}}
@keyframes check{0%{fill:#0e1418;stroke:#46545f}50%,100%{fill:var(--k);stroke:var(--k)}}
@keyframes checkm{0%{opacity:0}50%,100%{opacity:1}}
@keyframes grow{0%{transform:scaleY(.15)}35%,100%{transform:scaleY(1)}}
@keyframes pop{0%,100%{transform:translateX(0)}50%{transform:translateX(5px)}}
@keyframes hash{0%,45%{fill:#1d272f}50%,100%{fill:var(--k)}}
@keyframes scan{0%,100%{transform:translateY(0)}50%{transform:translateY(96px)}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ---------- footer ---------- */
.foot{border-top:1px solid var(--line);padding:2.5rem clamp(1rem,4vw,4rem) 3rem;display:grid;gap:1.2rem;max-width:1320px;margin:0 auto}
.fav{display:flex;flex-wrap:wrap;gap:.6rem 2rem;color:var(--ink3);font-size:.9rem}
.fav img{vertical-align:-3px}
.links{display:flex;flex-wrap:wrap;gap:.6rem 1.6rem;font:820 clamp(1.1rem,1rem + 1vw,1.7rem) var(--disp)}
.links a{text-decoration:none;color:var(--ink)}.links a:hover{color:var(--cyan)}
.tag{top:auto;bottom:1.15rem}

/* ---------- round 7: code wall in 3D, cards in 3D ---------- */
.rv{--tx:0;--ty:0;perspective:1100px}
.rv-3d{inset:-18% -12% -8% -12%;width:124%;height:126%;
  transform-origin:50% 70%;
  transform:rotateX(calc(26deg + var(--ty) * -8deg)) rotateY(calc(var(--tx) * 10deg)) translateZ(-40px);
  -webkit-mask:linear-gradient(to bottom,transparent 0,#000 35%,#000 100%);mask:linear-gradient(to bottom,transparent 0,#000 35%,#000 100%)}

.grid{perspective:1400px}
.card{--rx:0deg;--ry:0deg;--gx:50%;--gy:50%;transform:rotateX(var(--rx)) rotateY(var(--ry));transition:transform .5s cubic-bezier(.2,.8,.2,1),border-color .25s,opacity .7s}
.card.tilt{transition:transform .08s linear,border-color .25s}
a.card:hover,.card:hover{transform:rotateX(var(--rx)) rotateY(var(--ry)) translateZ(14px)}
.card::after{content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;opacity:0;transition:opacity .3s;
  background:radial-gradient(420px circle at var(--gx) var(--gy),rgba(255,255,255,.09),transparent 60%)}
.card:hover::after{opacity:1}
.js .card.pre{opacity:0;transform:rotateX(-22deg) translateY(40px) scale(.96)}
@media (prefers-reduced-motion:reduce){.rv-3d{transform:rotateX(26deg)}.js .card.pre{opacity:1;transform:none}}
.rv-name,.rv-role{text-shadow:0 0 18px #0b0d10,0 0 6px #0b0d10,0 2px 2px #0b0d10}
.rv-role{background:rgba(11,13,16,.75);display:inline-block;padding:.2em .5em;margin-left:-.5em;border-radius:6px}
.art .h0{animation-delay:0.0s}.art .h1{animation-delay:0.1s}.art .h2{animation-delay:0.2s}.art .h3{animation-delay:0.3s}.art .h4{animation-delay:0.4s}.art .h5{animation-delay:0.5s}.art .h6{animation-delay:0.6s}.art .h7{animation-delay:0.7s}.art .h8{animation-delay:0.8s}.art .h9{animation-delay:0.9s}.art .h10{animation-delay:1.0s}.art .h11{animation-delay:1.1s}.art .h12{animation-delay:1.2s}.art .h13{animation-delay:1.3s}.art .h14{animation-delay:1.4s}.art .h15{animation-delay:1.5s}
.card:has(.tag) .meta{padding-right:5.5rem}

/* ---------- round 9: the code wall is the whole page's background ---------- */
main{position:relative;z-index:1}
.rv{background:transparent;perspective:none}
.rv-3d,.rv-cover{position:fixed;z-index:0;pointer-events:none}
.rv-3d{inset:-12% -10% auto -10%;width:120%;height:124%;--tx:0;--ty:0;transform-origin:50% 60%;
  transform:perspective(1200px) rotateX(calc(12deg + var(--ty) * -6deg)) rotateY(calc(var(--tx) * 8deg));-webkit-mask:none;mask:none}
.rv-cover{inset:0;width:100%;height:100%;opacity:.9}
.work,.foot{position:relative}
@media (prefers-reduced-motion:reduce){.rv-3d{transform:perspective(1200px) rotateX(12deg)}}

/* ---------- round 10: name in the middle, drawn as a mosaic of chip cells ---------- */
.rv-text{inset:0;left:0;bottom:0;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:0 1.25rem}
.rv-name{font-size:clamp(3.2rem,10.5vw,12rem);line-height:.9}
.rv-name span{display:inline-block}
@media (max-width:700px){.rv-name span{display:block}.rv-name{font-size:16.5vw}}
.rv-role{margin:1.6rem 0 0}
.name-fx{position:absolute;inset:0;width:100%;height:100%;z-index:3;pointer-events:none;display:block}
.no-js .name-fx{display:none}
.fx-on .rv-name{color:transparent;text-shadow:none}
.rv::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;background:radial-gradient(60% 40% at 50% 47%,rgba(5,7,10,.75),rgba(5,7,10,.35) 60%,transparent 85%)}
