:root{
  --bg:#0d0d0d;--text:#ededeb;--text2:#a8a7a3;--mute:#72716d;--line:rgba(255,255,255,.08);--acc:#ffb454;
  --sans:'Huninn',system-ui,sans-serif;--mono:var(--sans);
  --ease:cubic-bezier(.22,.9,.28,1);--spring:cubic-bezier(.34,1.35,.5,1);
  /* the content column is at most 1360 px wide, with at least 20 px on each side */
  --pad:max(20px,calc(50vw - 680px));
  color-scheme:dark;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;overflow-x:clip;scroll-padding-top:24px}
body{margin:0;background:var(--bg);color:var(--text);font-family:var(--sans);font-size:16px;line-height:1.5;-webkit-font-smoothing:antialiased;font-synthesis:none}
::selection{background:var(--acc);color:var(--bg)}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:pointer}
img{max-width:100%}
:focus-visible{outline:1.5px solid var(--acc);outline-offset:3px;border-radius:4px}
.skip{position:absolute;left:12px;top:-60px;z-index:100;padding:8px 14px;border-radius:10px;background:var(--text);color:var(--bg);font-weight:600}
.skip:focus{top:12px}



/* ---------- the cut-outs: plain images; .in is what tips over when the ball hits it ---------- */
.fig{position:relative;display:inline-block;line-height:0}
.fig .in{position:relative;display:inline-block;transform-origin:50% 100%;isolation:isolate}
/* the dotted echo behind a figure on the first screen; its feet fade out like the photo does */
.fig .fx-bg{position:absolute;z-index:-1;pointer-events:none;-webkit-mask-image:linear-gradient(180deg,#000 66%,transparent 86%);mask-image:linear-gradient(180deg,#000 66%,transparent 86%)}
.fig img{display:block;width:auto;height:auto;-webkit-mask-image:linear-gradient(180deg,#000 80%,transparent);mask-image:linear-gradient(180deg,#000 80%,transparent);user-select:none;-webkit-user-drag:none}

/* ---------- the ball and what it breaks ---------- */
.ball{position:fixed;left:0;top:0;z-index:9;border:0;padding:0;aspect-ratio:1;border-radius:50%;cursor:grab;will-change:transform;touch-action:none;user-select:none;-webkit-user-select:none}
.ball-face{position:absolute;left:50%;top:50%;translate:-50% -50%;width:var(--ball-dot-size);height:var(--ball-dot-size);border-radius:50%;background:#fff;pointer-events:none;transition:width .3s var(--ease),height .3s var(--ease),box-shadow .55s ease}
.ball::after{content:"";position:absolute;inset:-22px;border-radius:50%}
.ball{dynamic-range-limit:standard;transition:dynamic-range-limit .55s ease,box-shadow .55s ease}
.ball .hdr-ball{position:absolute;inset:0;width:100%;height:100%;border-radius:50%;pointer-events:none;opacity:0;dynamic-range-limit:standard;transition:dynamic-range-limit .55s ease,opacity .55s ease}
html.ball-out .ball{position:absolute}
html.ball-out .ball,html.ball-out .ball .hdr-ball{dynamic-range-limit:no-limit}
html.ball-out .ball .hdr-ball{opacity:1}
html.ball-out .ball-face{width:100%;height:100%;box-shadow:0 2px 4px #0006,0 0 12px 8px #0009}
.motion-jolt{position:relative;left:var(--motion-x,0px);top:var(--motion-y,0px)}
.ball:active,html.grabbing,html.grabbing *{cursor:grabbing!important}
.ball .seam{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;opacity:0;transition:opacity .55s ease}
html.ball-out .ball .seam{opacity:1}
.ball .seam path{fill:none;stroke:rgba(0,0,0,.2);stroke-width:1.1;stroke-linecap:round}
.ball.docking{transition:transform .3s var(--ease),width .3s var(--ease),dynamic-range-limit .55s ease,box-shadow .55s ease}
.ph canvas.crack{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
.lt-free{transition:none!important;position:fixed!important;left:0;top:0;z-index:6;pointer-events:none;text-align:center;white-space:pre;will-change:transform}
.lt-free.tg,.lt-free.ph{pointer-events:auto}

/* ---------- logo: its full stop is the ball ---------- */
.logo{position:fixed;right:var(--pad);top:18px;z-index:8;font-size:clamp(28px,3vw,42px);letter-spacing:-.03em;line-height:1;color:var(--text);user-select:none}
.logo-dot{display:inline-block;width:.14em;height:.14em;margin:0 .02em 0 .04em;border-radius:50%;transition:box-shadow .3s}
html.ball-out .logo-dot{box-shadow:inset 0 0 0 1.5px rgba(237,237,235,.3)}

/* ---------- first screen ---------- */
/* the first screen is one block: the phrase as the hook, the name right under it, then the transcription, the
   facts and the ways to reach me, so the eye goes from the big line straight to who and where */
.hero{position:relative;min-height:100vh;min-height:100svh;display:flex;flex-direction:column;justify-content:center;padding:110px var(--pad) 10vh}
.who{display:flex;flex-direction:column;gap:6px;margin:30px 0 0}
.who b{font-size:clamp(28px,3vw,44px);line-height:1.1;font-weight:400;color:var(--text);letter-spacing:-.01em}
.ipa{font-size:16px;color:var(--mute)}
.me{display:flex;flex-wrap:wrap;align-items:center;gap:10px 22px;margin-top:34px}
.me a{color:var(--text2);display:flex;align-items:center;gap:8px;font-size:16px;transition:color .2s,transform .3s var(--spring)}
.me a:hover{color:var(--text);transform:translateY(-2px)}
.me svg{width:18px;height:18px}
/* Telegram is the way to reach me, so it is the one button */
.me .tg-link{padding:9px 16px 9px 13px;border-radius:12px;background:#2aabee;color:#fff;box-shadow:inset 0 1px 0 #ffffff40,inset 0 -2px 0 #00000026,0 1px 2px #0004,0 6px 16px -8px #1a8fd84d;transition:box-shadow .15s,transform .15s}
.me .tg-link:active{transform:translateY(1px);box-shadow:inset 0 1px 0 #ffffff40,inset 0 -1px 0 #00000026,0 1px 1px #0004,0 3px 10px -6px #1a8fd84d}
.me .tg-link:hover{background:#3db6f2;color:#fff}
.hero-in{max-width:1180px}
.phrase{margin:0;font-size:clamp(40px,6vw,96px);letter-spacing:-.015em;line-height:1}
.facts{list-style:none;margin:26px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:10px 30px;color:var(--text2);font-size:18px}
.facts li{display:flex;align-items:center;gap:9px}
.facts img{width:15px;height:15px}

/* ---------- chapters ---------- */
.ch{padding:14vh var(--pad) 10vh;overflow-x:clip}
.ch-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,30%);gap:56px;align-items:start}
.ch-fig{display:flex;justify-content:center;padding-top:2vh;container-type:inline-size}
/* every chapter figure is the same height; the wide one with the plush toy may only be as tall as its column allows */
.ch-fig img{height:min(56vh,480px);width:auto;max-width:none}
.ch[data-k="school"] .ch-fig img{height:min(56vh,500px,118cqw)}
.ch-h{margin:0 0 4vh}
.ch-h h2{font-size:clamp(44px,5.4vw,80px);letter-spacing:-.02em;line-height:.95;font-weight:750;margin:0 0 12px}
.ch-h p{margin:0;color:var(--text2);font-size:19px;max-width:30em}
.cols{display:grid;grid-auto-columns:minmax(0,1fr);grid-auto-flow:column;gap:40px}
.col h3{margin:0 0 10px;font-family:var(--mono);font-size:13px;font-weight:400;color:var(--mute);letter-spacing:.02em}
.col ul{list-style:none;margin:0;padding:0}
.col li{position:relative;display:grid;grid-template-columns:50px minmax(0,1fr);gap:0 12px;padding:6px 0;line-height:1.35}
.col li .y{font-family:var(--mono);font-size:12.5px;color:var(--mute);padding-top:3px;transition:color .25s}
.col li .t{font-size:16px;font-weight:560;letter-spacing:-.005em}
.col li .t em{font-style:normal;font-weight:520;color:var(--acc);white-space:nowrap}
.col li .d{margin:3px 0 0;font-size:14.5px;color:var(--text2);line-height:1.45}
.col li[data-ph]{cursor:zoom-in}
.col li[data-ph]::before{content:"";position:absolute;left:-14px;top:14px;width:5px;height:5px;border-radius:50%;background:var(--acc);opacity:0;transform:scale(.4);transition:opacity .25s,transform .35s var(--spring)}
.col li.on::before{opacity:1;transform:none}
.col li.on .y{color:var(--acc)}
.col.noy li{grid-template-columns:minmax(0,1fr)}
/* work dates sit in their own column, on two lines, like the years in Education */
.col.exp li{grid-template-columns:88px minmax(0,1fr);gap:0 18px}
.col.exp li .y{line-height:1.5;padding-top:4px}
/* a single column reads as a short list, set larger */
.cols > .col:only-child{max-width:38em}
.cols > .col:only-child li{padding:10px 0}
.cols > .col:only-child li .t{font-size:19px}
.cols > .col:only-child li .d{font-size:16px;margin-top:5px}
.arr{display:inline-block;width:.72em;height:.72em;margin-left:5px;vertical-align:-.02em;color:var(--mute);transition:transform .25s var(--spring),color .2s}
.arr path{fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
a:hover > .arr{color:var(--acc);transform:translate(2px,-2px)}

/* photos: rows that keep every photo's proportions and end flush with the column (sized from JS; without JS
   the flex rows still come out close) */
.gal{display:flex;flex-wrap:wrap;gap:12px;margin-top:7vh}
.gal::after{content:"";flex:10 1 0}
.ph{position:relative;flex:var(--ar) 1 auto;height:200px;aspect-ratio:var(--ar);border-radius:10px;overflow:hidden;background:#1a1a1a;box-shadow:0 0 0 1px var(--line);cursor:zoom-in;transition:transform .45s var(--spring),box-shadow .3s}
.gal.sized .ph{flex:none;aspect-ratio:auto}
.ph img{width:100%;height:100%;object-fit:cover;display:block;transition:filter .35s var(--ease)}
.ph:hover,.ph.lit{transform:translateY(-3px);box-shadow:0 0 0 1px rgba(255,180,84,.55)}

/* ---------- stack and projects ---------- */
.sec{padding:12vh var(--pad) 8vh;overflow-x:clip}
.sec-h{margin-bottom:40px}
.sec-h h2{font-size:clamp(44px,5.4vw,80px);letter-spacing:-.02em;line-height:.95;font-weight:750;margin:0 0 14px}
.sec-h p{margin:0;max-width:34em;color:var(--text2);font-size:17px}
.st{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:32px 48px}
.st-g:first-child{grid-column:span 2}
.st-g:last-child{grid-column:1 / -1}
.st-g h3{margin:0 0 14px;font-family:var(--mono);font-size:13px;font-weight:400;color:var(--mute)}
.chips{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.chips li{display:inline-flex;align-items:center;gap:8px;padding:7px 14px 7px 10px;border-radius:999px;border:1px solid var(--line);background:rgba(255,255,255,.03);font-size:15px;font-weight:520}
.chips img{width:16px;height:16px}
.chips.dim li{color:var(--text2);background:none}
.chips.dim img{opacity:.6}

.pj-list{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,400px),1fr));gap:22px 36px}
.pj{display:grid;grid-template-columns:128px minmax(0,1fr);gap:16px;align-items:start}
.pj-img{display:block;width:100%;padding:0;border:0;aspect-ratio:16/10;border-radius:10px;overflow:hidden;background:#161616;box-shadow:0 0 0 1px var(--line)}
.pj-img img{width:100%;height:100%;object-fit:cover;object-position:top;display:block}
button.pj-img{cursor:zoom-in;transition:box-shadow .25s,transform .35s var(--spring)}
button.pj-img:hover{transform:translateY(-2px);box-shadow:0 0 0 1px rgba(255,180,84,.55)}
/* projects without a screenshot get their main tool on the site's dot grid */
.pj-img.is-tile{display:grid;place-items:center;background:radial-gradient(circle,rgba(255,255,255,.13) 1px,transparent 1.4px) 0 0/8px 8px,#141414}
.tile{font-size:34px;font-weight:760;letter-spacing:-.04em;line-height:1;color:var(--text);text-shadow:0 0 14px #141414,0 0 4px #141414}
.pj-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.pj h3{margin:0;font-size:18px;font-weight:620;letter-spacing:-.015em}
.ext{display:inline-flex;color:var(--mute);transition:color .2s}
.ext:hover{color:var(--acc)}
.ext svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.ext.gh svg{width:14px;height:14px;fill:currentColor;stroke:none}
.pj-stk{display:inline-flex;gap:6px;margin-left:2px}
.pj-stk img{width:14px;height:14px;display:block}
.pj p{margin:4px 0 0;color:var(--text2);font-size:15px;line-height:1.45}

/* ---------- Nomad: a dotted map ---------- */
.map{position:relative;margin:0;max-width:860px}
.map canvas{display:block;width:100%;height:auto;-webkit-mask-image:radial-gradient(ellipse 72% 68% at 50% 48%,#000 58%,transparent 100%);mask-image:radial-gradient(ellipse 72% 68% at 50% 48%,#000 58%,transparent 100%)}
.pins{list-style:none;margin:0;padding:0}
.pin{position:absolute;transform:translate(-50%,-50%);display:grid;place-items:center;width:26px;height:26px;border-radius:50%}
.pin i{width:8px;height:8px;border-radius:50%;background:var(--text);box-shadow:0 0 0 3px rgba(13,13,13,.9);transition:transform .3s var(--spring),background .2s}
.pin.home i{background:var(--text)}
/* the trips are background; home and now are what the map is about */
.pin:not(.home):not(.now) i{width:6px;height:6px;background:var(--mute);opacity:.7}
.pin.now i{width:11px;height:11px;background:var(--acc);box-shadow:0 0 0 3px rgba(13,13,13,.9),0 0 0 7px rgba(255,180,84,.18)}
.pin span{position:absolute;left:100%;top:50%;transform:translate(-4px,-50%);white-space:nowrap;padding:3px 8px;border-radius:8px;background:rgba(13,13,13,.86);font-size:13px;font-weight:560;color:var(--text);opacity:0;pointer-events:none;transition:opacity .2s,transform .25s var(--ease)}
.pin span em{font-style:normal;font-weight:400;color:var(--mute);margin-left:4px}
.pin.home span,.pin.now span{opacity:1;transform:translate(0,-50%)}
.pin.now span em{color:var(--acc)}
/* Da Nang sits near the right edge, so its name goes on the left */
.pin.now span{left:auto;right:100%;transform:translate(4px,-50%)}
.pin.now span,.pin.now:hover span{transform:translate(0,-50%)}
.pin:hover i,.pin:focus-visible i,.pin.on i{transform:scale(1.5)}
.pin:hover span,.pin:focus-visible span,.pin.on span{opacity:1;transform:translate(0,-50%);z-index:2}
.pin:hover,.pin.on{z-index:3}

/* ---------- ending ---------- */
.end{padding:18vh 16px 0;text-align:center}
.end-h{margin:0;font-size:clamp(30px,4.6vw,64px);letter-spacing:-.015em;line-height:1}
.end-h .now-t{color:var(--acc);font-variant-numeric:tabular-nums}
.tg{position:relative;z-index:6;margin-top:40px;display:inline-flex;align-items:center;gap:10px;padding:12px 20px 12px 16px;border-radius:14px;background:#2aabee;color:#fff;font-size:18px;font-weight:600;white-space:nowrap;box-shadow:inset 0 1px 0 #ffffff40,inset 0 -2px 0 #00000026,0 1px 2px #0004,0 8px 20px -8px #1a8fd84d;transition:background .2s,transform .35s var(--spring)}
.tg:hover{background:#3db6f2;transform:translateY(-2px)}
.tg:active{transform:translateY(0);box-shadow:inset 0 1px 0 #ffffff40,inset 0 -1px 0 #00000026,0 1px 1px #0004,0 3px 10px -6px #1a8fd84d}
.tg svg{width:22px;height:22px}

/* ---------- footer: the site's name in dots ---------- */
.foot{padding:20vh 0 8vh}
#fcv{display:block;width:calc(100% - 2 * var(--pad));margin:0 auto;touch-action:pan-y}

/* ---------- lightbox ---------- */
.lb{position:fixed;inset:0;z-index:80;display:grid;place-items:center;background:rgba(8,8,8,.92);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);padding:56px 16px}
.lb[hidden]{display:none}
.lb-frame{position:relative;margin:0;aspect-ratio:var(--lb-ratio);width:min(var(--lb-width),1100px,calc(100vw - 32px),calc((100vh - 120px)*var(--lb-ratio)));width:min(var(--lb-width),1100px,calc(100vw - 32px),calc((100svh - 120px)*var(--lb-ratio)))}
.lb-frame img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:14px;display:block}
.lb-nav{position:absolute;top:50%;transform:translateY(-50%);width:44px;height:44px;border-radius:50%;display:grid;place-items:center;color:var(--text);background:rgba(255,255,255,.08);transition:background .2s,opacity .2s}
.lb-nav:hover{background:rgba(255,255,255,.16)}
.lb-nav:disabled{opacity:.25;cursor:default}
.lb-nav svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.lb-prev{left:20px}.lb-next{right:20px}
.lb.single .lb-nav{display:none}
.lb-x{position:absolute;top:14px;right:16px;font-size:14px;color:var(--text2);padding:6px 12px;border-radius:10px;background:rgba(255,255,255,.07)}

/* ---------- big screens (1440p and up, 4K): a wider column and larger type, not just more empty space ---------- */
@media (min-width:2000px){
  :root{--pad:max(20px,calc(50vw - 960px))}
  .phrase{font-size:clamp(96px,5.4vw,150px)}.facts{font-size:23px}.facts img{width:19px;height:19px}
  body{font-size:19px}
  .who b{font-size:clamp(44px,2.6vw,60px)}.ipa{font-size:20px}.me a{font-size:19px}.me svg{width:22px;height:22px}
  .ch-fig img{height:min(56vh,720px)}.ch[data-k="school"] .ch-fig img{height:min(56vh,720px,118cqw)}
  .logo{font-size:52px;top:28px}
  .ch-h h2,.sec-h h2{font-size:clamp(80px,5vw,130px)}
  .ch-h p{font-size:24px}.sec-h p{font-size:21px}
  .col h3,.st-g h3{font-size:16px}
  .col li{grid-template-columns:62px minmax(0,1fr)}
  .col li .y{font-size:15px}.col li .t{font-size:19.5px}.col li .d{font-size:17px}
  .cols > .col:only-child li .t{font-size:23px}.cols > .col:only-child li .d{font-size:19px}
  .chips li{font-size:18px;padding:9px 18px 9px 13px;gap:10px}.chips img{width:20px;height:20px}
  .pj-list{grid-template-columns:repeat(auto-fill,minmax(520px,1fr));gap:30px 44px}
  .pj{grid-template-columns:170px minmax(0,1fr);gap:20px}
  .pj h3{font-size:22px}.pj p{font-size:18px}.pj-stk img{width:17px;height:17px}.tile{font-size:44px}
  .map{max-width:1180px}.pin span{font-size:16px}
  .end-h{font-size:clamp(64px,4.2vw,110px)}
  .tg{font-size:22px;padding:15px 26px 15px 20px}.tg svg{width:27px;height:27px}
}

/* ---------- tablets ---------- */
@media (max-width:1100px){
  .ch-grid{grid-template-columns:minmax(0,1fr) minmax(0,34%);gap:32px}
  .cols{display:block}
  .col + .col{margin-top:28px}
  .st{grid-template-columns:1fr 1fr}
  .st-g:first-child{grid-column:1 / -1}
}
/* ---------- phones ---------- */
@media (max-width:760px){
  body{font-size:15.5px}
  .logo{top:10px;right:10px;font-size:26px;padding:6px 10px 7px;border-radius:12px;background:rgba(13,13,13,.72);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
  .who{margin-top:22px}.who b{font-size:30px}.ipa{font-size:14.5px}
  .hero{min-height:88svh;padding:96px var(--pad) 8vh}
  .phrase{font-size:clamp(34px,10vw,50px)}
  .facts{flex-direction:column;gap:8px;margin-top:26px;font-size:15.5px}
  .col.exp li{grid-template-columns:76px minmax(0,1fr);gap:0 12px}
  .me{gap:12px 18px;margin-top:28px}.me a{font-size:15px}
  .ch{padding:10vh var(--pad) 8vh}
  /* the figure stands next to the heading instead of in its own column */
  .ch-grid{display:block;position:relative}
  .ch-fig{position:absolute;right:-12px;top:-4vh;width:46%;padding:0;pointer-events:none}
  .ch-fig img{height:min(29svh,236px)}
  .ch[data-k="school"] .ch-fig img{height:min(29svh,236px,118cqw)}
  .ch-h{min-height:26svh;padding-right:44%}
  /* the cut-out with the plush toy is wide, so it gets more room to stay tall */
  .ch[data-k="school"] .ch-fig{width:60%;right:-28px}
  .ch-h h2{font-size:44px}
  .ch-h p{font-size:16.5px}
  .gal{gap:8px;margin-top:5vh}
  .ph{height:120px}
  .st{grid-template-columns:1fr}
  .chips li{font-size:14px;padding:6px 12px 6px 9px}
  .pj{grid-template-columns:96px minmax(0,1fr);gap:12px}
  .pj h3{font-size:17px}
  .pj p{font-size:14.5px}
  .map{margin:0 -8px}
  .pin span{font-size:12px}
  .tg{font-size:16px}
}
/* ---------- large phones and small tablets: wide enough for a row, not for the full-size one ---------- */
@media (min-width:521px) and (max-width:760px){
}
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important}}
@media print{.ball,.logo,.lb,.foot,.ch-fig{display:none!important}body{background:#fff;color:#111}}
