@font-face{font-family:excalifont;src:url(/fonts/excalifont/excalifont-0.woff2)format("woff2");font-display:swap;unicode-range:U+20-7E,U+A0-A3,U+A5-A6,U+A8-AB,U+AD-B1,U+B4,U+B6-B8,U+BA-FF,U+131,U+152-153,U+2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+2013-2014,U+2018-201A,U+201C-201E,U+2020,U+2022,U+2024-2026,U+2030,U+2039-203A,U+20AC,U+2122,U+2212}@font-face{font-family:excalifont;src:url(/fonts/excalifont/excalifont-1.woff2)format("woff2");font-display:swap;unicode-range:U+100-130,U+132-137,U+139-149,U+14C-151,U+154-17E,U+192,U+1FC-1FF,U+218-21B,U+237,U+1E80-1E85,U+1EF2-1EF3,U+2113}@font-face{font-family:excalifont;src:url(/fonts/excalifont/excalifont-2.woff2)format("woff2");font-display:swap;unicode-range:U+400-45F,U+490-491,U+2116}@font-face{font-family:excalifont;src:url(/fonts/excalifont/excalifont-3.woff2)format("woff2");font-display:swap;unicode-range:U+37E,U+384-38A,U+38C,U+38E-393,U+395-3A1,U+3A3-3A8,U+3AA-3CF,U+3D7}@font-face{font-family:excalifont;src:url(/fonts/excalifont/excalifont-4.woff2)format("woff2");font-display:swap;unicode-range:U+2C7,U+2D8-2D9,U+2DB,U+2DD,U+302,U+306-307,U+30A-30C,U+326-328,U+212E,U+2211,U+FB01-FB02}@font-face{font-family:excalifont;src:url(/fonts/excalifont/excalifont-5.woff2)format("woff2");font-display:swap;unicode-range:U+462-463,U+472-475,U+4D8-4D9,U+4E2-4E3,U+4E6-4E9,U+4EE-4EF}@font-face{font-family:excalifont;src:url(/fonts/excalifont/excalifont-6.woff2)format("woff2");font-display:swap;unicode-range:U+300-301,U+303}@font-face{font-family:shantell sans;src:url(/fonts/shantell/shantell-sans-normal.woff2)format("woff2");font-weight:300 800;font-style:normal;font-display:swap}@font-face{font-family:shantell sans;src:url(/fonts/shantell/shantell-sans-italic.woff2)format("woff2");font-weight:300 800;font-style:italic;font-display:swap}:root{--bg:#ffffff;--fg:#000000;--muted:#555555;--rule:#000000;--code-bg:#f2f2f2;--font:"Shantell Sans", "Comic Sans MS", "Segoe Print", sans-serif;--display:"Excalifont", "Comic Sans MS", "Segoe Print", cursive, sans-serif;--cursor:url("/cursors/pencil.svg") 3 3, auto;--cursor-link:url("/cursors/pencil-link.svg") 8 8, pointer;--mono:ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;--accent:#0000ee;--visited:#551a8b;--active:#ee0000;--mark:#ffff66}*{box-sizing:border-box}html{-webkit-text-size-adjust:100%}body{margin:0;background:var(--bg);color:var(--fg);font:18px/1.65 var(--font);cursor:var(--cursor);overflow-wrap:break-word}.wrap{width:min(720px,calc(100% - 2.5rem));margin:0 auto}@media(max-width:32rem){body{font-size:17px}}a,button,summary{cursor:var(--cursor-link)}a{color:var(--accent);text-decoration-thickness:1px;text-underline-offset:.2em}a:where(:visited){color:var(--visited)}a:where(:active){color:var(--active)}a:hover{background:var(--mark)}:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.skip-link{position:absolute;left:-9999px}.skip-link:focus{left:1rem;top:1rem;padding:.5rem;background:var(--fg);color:var(--bg)}.site-header{display:flex;flex-wrap:wrap;gap:.25rem 1rem;justify-content:space-between;align-items:flex-end;padding:.75rem 0;margin-bottom:2.5rem;border-bottom:1px solid var(--rule)}.site-header .site-name{color:var(--fg);text-decoration:none;font-size:1.15rem}.site-header nav{margin-left:auto}.duku{position:relative;margin-bottom:calc(-.75rem - 3px);line-height:0}.dog{width:6.25rem;height:auto}.dog-tail{transform-origin:80px 95px}.duku:hover .dog-tail,.duku:focus .dog-tail{animation:wag .28s ease-in-out infinite alternate}@keyframes wag{from{transform:rotate(-10deg)}to{transform:rotate(16deg)}}@media(max-width:32rem){.site-header{position:relative;justify-content:flex-end;min-height:5.25rem;padding-left:5rem}.duku{position:absolute;left:0;bottom:-3px;margin:0}.dog{width:4.75rem}}.duku::after{content:attr(data-says);position:absolute;left:calc(100% - .5rem);top:.4rem;z-index:1;display:none}.duku::after,.bubble{padding:.3rem .7rem;border:2px solid #1e1e1e;background:var(--bg);box-shadow:4px 4px #1e1e1e;font-size:1rem;line-height:1.4;white-space:nowrap}.duku:hover::after,.duku:focus::after{display:block}@media(max-width:32rem){.duku::after{left:.5rem;top:calc(100% + .6rem)}}.duku:focus{outline:none}.duku:focus-visible .dog{outline:2px solid var(--accent);outline-offset:2px}.site-header nav a{margin-left:.75rem}.site-header nav a:first-child{margin-left:0}.site-header nav a::before{content:"["}.site-header nav a::after{content:"]"}.site-footer{margin:8.5rem 0 0}.site-footer .wrap{position:relative;padding:.75rem 0 3rem;border-top:1px solid var(--rule)}.duku-rest{position:absolute;left:0;bottom:calc(100% - 4px);display:flex;align-items:flex-start;gap:.4rem;margin:0;line-height:0}@media(max-width:32rem){.site-footer{margin-top:10.5rem}.duku-rest{flex-direction:column-reverse}.dog-rest{width:8rem}.duku-rest .bubble{margin-left:2.5rem;font-size:.9rem}}.dog-rest{width:11rem;height:auto}.duku-rest:hover .rest-zzz{animation:snore 1.6s ease-in-out infinite}@media(prefers-reduced-motion:no-preference){.rest-zzz{animation:snore 2.4s ease-in-out infinite}}@keyframes snore{from{opacity:0;transform:translate(-3px,5px)}40%{opacity:1}to{opacity:0;transform:translate(4px,-6px)}}@media print{.duku,.duku-rest{display:none}}.social-links{display:flex;flex-wrap:wrap;gap:.25rem 1.25rem}.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}.actions{display:flex;flex-wrap:wrap;gap:.25rem 1.25rem;margin:0 0 2.25rem}.section{margin:0 0 3rem}.section:last-child{margin-bottom:0}.section-h{margin:0 0 1rem;padding-bottom:.2rem;border-bottom:1px solid var(--rule);font-size:1.5rem}.home-about p{margin:0 0 .9rem}.section .actions{margin:1.25rem 0 0}.home-note{margin:1rem 0 0;color:var(--muted);font-size:.75rem;font-style:italic}.projects li{margin-bottom:1rem}.project-desc{display:block;color:var(--fg);line-height:1.5}h1,h2,h3,h4,.site-header,.toc-title{font-family:var(--display)}h1,h2,h3,h4{font-weight:400;line-height:1.25;margin:2.5rem 0 .6rem}h1{font-size:clamp(2rem,6vw,2.6rem);line-height:1.15;margin-top:0}h2{font-size:1.6rem}h3{font-size:1.3rem}h4{font-size:1.1rem}p,ul,ol,pre,table,blockquote,figure{margin:0 0 1rem}ul,ol{padding-left:1.25rem}li{margin-bottom:.25rem}hr{border:0;border-top:1px solid var(--rule);margin:2rem 0}.muted,.date{color:var(--muted);font-size:.9rem}.projects strong,.areas strong{font-family:var(--display);font-size:1.2rem;font-weight:400}.posts{list-style:square;margin:0;padding-left:1.4rem}.posts li{margin-bottom:.55rem}.posts .date{margin-left:.35rem;white-space:nowrap}.posts .date::before{content:"["}.posts .date::after{content:"]"}.post>*{width:min(720px,calc(100% - 2.5rem));margin-left:auto;margin-right:auto}.post-head .hero{margin:1.6rem 0 2rem}.post-head .hero img{display:block;width:100%;height:auto}@media(min-width:1200px){.post{display:grid;grid-template-columns:1fr min(720px,calc(100% - 2.5rem))1fr;max-width:1320px;margin:0 auto}.post>*{width:auto;margin:0}.post>.post-head{grid-column:2;grid-row:1}.post>.content{grid-column:2;grid-row:2}.post>.post-end{grid-column:2;grid-row:3}.post>.toc{grid-column:1;grid-row:2;justify-self:end;align-self:start;position:sticky;top:2rem;width:min(240px,100%);margin:0;padding:0 1.5rem 0 0;border:0;max-height:calc(100vh - 4rem);overflow-y:auto}}.toc{margin-top:1.75rem;margin-bottom:2.5rem;padding:.9rem 0;border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);font-size:.9375rem}.toc-title{margin:0 0 .55rem;font-size:1.15rem}.toc ul{list-style:none;margin:0;padding:0}.toc ul ul{display:none}@media(min-width:1200px){.toc ul ul{display:block;padding-left:.75rem;margin-top:.3rem;font-size:.875rem}.toc ul ul li{margin-bottom:.25rem}}.toc li{margin-bottom:.35rem}.toc li:last-child{margin-bottom:0}.toc a{color:var(--fg);text-decoration:none}.toc a:hover{text-decoration:underline}.content h2,.content h3{scroll-margin-top:1.5rem}.content img,.content video{max-width:100%;height:auto;display:block}.content blockquote{margin-left:0;padding-left:1rem;border-left:3px solid var(--rule)}code{font-family:var(--mono);font-size:.85em;background:var(--code-bg);padding:.1em .3em}pre{border:1px solid var(--rule);background:var(--bg);padding:.85rem 1rem;overflow-x:auto}pre code{background:0 0;padding:0}.diagram{margin:1.5rem 0;text-align:center}.diagram-scroll{overflow-x:auto}.diagram svg{max-width:100%;height:auto;cursor:zoom-in}.diagram-expand,.viewer-bar button{padding:0;border:0;background:0 0;color:var(--accent);font:inherit;text-decoration:underline}.diagram-expand:hover,.viewer-bar button:hover{background:var(--mark)}.diagram-expand{font-size:.875rem}.viewer{width:100vw;max-width:none;height:100vh;height:100dvh;max-height:none;margin:0;padding:0;border:0;background:var(--bg)}.viewer[open]{display:flex;flex-direction:column}.viewer-bar{display:flex;flex-wrap:wrap;gap:.25rem 1rem;justify-content:flex-end;align-items:baseline;padding:.6rem 1rem;border-bottom:1px solid var(--rule)}.viewer-hint{margin-right:auto;color:var(--muted);font-size:.875rem}.viewer-stage{flex:1;overflow:hidden;cursor:grab;touch-action:none;user-select:none}.viewer-stage:active{cursor:grabbing}.viewer-stage svg{display:block;transform-origin:0 0;pointer-events:none}.banner{margin:1.6rem 0 2rem}.banner svg{display:block;width:100%;height:auto}table{border-collapse:collapse;width:100%;display:block;overflow-x:auto;font-size:.9375rem}th,td{border:1px solid var(--rule);padding:.4rem .6rem;text-align:left}.chroma .k,.chroma .kc,.chroma .kd,.chroma .kn,.chroma .kr,.chroma .kt{color:#cf222e}.chroma .na,.chroma .nc,.chroma .nx,.chroma .p{color:#1f2328}.chroma .nd,.chroma .nt,.chroma .m,.chroma .mi,.chroma .o,.chroma .ow{color:#0550ae}.chroma .nn{color:#24292e}.chroma .nb,.chroma .nf,.chroma .fm{color:#6639ba}.chroma .bp{color:#6a737d}.chroma .nv{color:#953800}.chroma .s,.chroma .sb,.chroma .sd,.chroma .se,.chroma .si{color:#0a3069}.chroma .c,.chroma .cp{color:#57606a;font-style:italic}.chroma .err{color:inherit;background:0 0}.profile-head{margin-bottom:2.75rem}.profile-head .actions{margin:1.25rem 0 0}.timeline{display:flex;margin:0 0 2rem;padding:.5rem 0 .75rem;overflow-x:auto;list-style:none;font-family:var(--display)}.timeline li{position:relative;flex:1 0 6.5rem;margin:0;text-align:center}.timeline li::before{content:"";position:absolute;top:calc(2.2rem + 1px);left:0;right:0;border-top:2px solid var(--rule)}.timeline li:first-child::before{left:50%}.timeline li:last-child::before{right:50%}.stop{position:relative;display:block;padding:0 .25rem;color:var(--fg);text-decoration:none}.stop:hover{background:0 0}.stop-when{display:block;height:1.5rem;color:var(--muted);font-size:.85rem;line-height:1.5rem}.stop-dot{display:block;width:1.4rem;height:1.4rem;margin:0 auto;border:2px solid #1e1e1e;border-radius:48% 52% 50% 46%/52% 47% 53% 48%;background:var(--c)}.stop-what{display:block;margin-top:.45rem;line-height:1.25}.stop:hover .stop-dot,.stop[aria-current=true] .stop-dot{box-shadow:3px 3px #1e1e1e;transform:scale(1.3)}.stop[aria-current=true] .stop-what{text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:.25em}.job{margin-bottom:2.5rem}.job:last-child{margin-bottom:0}.job h3{margin:0;font-size:1.3rem}.job h3 .date{margin-left:.35rem;font-weight:400;white-space:nowrap}.job h3 .date::before{content:"["}.job h3 .date::after{content:"]"}.job p{margin:0 0 .75rem}.areas{list-style:square;margin:1rem 0 0;padding-left:1.4rem}.areas li{margin-bottom:.9rem}.areas li:last-child{margin-bottom:0}.skills{display:grid;grid-template-columns:11rem 1fr;gap:.6rem 1.25rem;margin:0;line-height:1.5}.skills dt{color:var(--muted)}.skills dd{margin:0}@media(max-width:32rem){.skills{grid-template-columns:1fr;gap:0}.skills dd{margin-bottom:.75rem}}.page-nav{margin-top:3rem;font-size:.9375rem}.page-nav a{margin-right:1rem}@media print{:root{--bg:#ffffff;--fg:#000000;--muted:#444444;--rule:#000000;--code-bg:#f4f4f4}.site-header nav,.site-footer,.page-nav,.skip-link{display:none}body{font-size:11pt}.wrap{width:100%}h1,h2,h3{break-after:avoid}pre,blockquote,li,img{break-inside:avoid}.job h3,.areas li{break-inside:avoid}.timeline{display:none}.job[hidden]{display:block}a{text-decoration:none}.content a[href^=http]::after,.profile a[href^=http]::after{content:" (" attr(href)")";font-size:9pt;color:var(--muted)}}