@keyframes astroFadeInOut{0%{opacity:1}to{opacity:0}}@keyframes astroFadeIn{0%{opacity:0;mix-blend-mode:plus-lighter}to{opacity:1;mix-blend-mode:plus-lighter}}@keyframes astroFadeOut{0%{opacity:1;mix-blend-mode:plus-lighter}to{opacity:0;mix-blend-mode:plus-lighter}}@keyframes astroSlideFromRight{0%{transform:translate(100%)}}@keyframes astroSlideFromLeft{0%{transform:translate(-100%)}}@keyframes astroSlideToRight{to{transform:translate(100%)}}@keyframes astroSlideToLeft{to{transform:translate(-100%)}}@media(prefers-reduced-motion){::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}[data-astro-transition-scope]{animation:none!important}}footer[data-astro-cid-35ed7um5]{font-size:var(--font-size-label);font-weight:var(--font-weight-label);line-height:var(--leading-label);letter-spacing:var(--tracking-label);color:var(--text-secondary);margin-top:clamp(4rem,9vw,7rem);padding:1.5rem 0}.footer-content[data-astro-cid-35ed7um5]{display:flex;justify-content:space-between;align-items:center;flex-direction:row;flex-wrap:nowrap;width:100%}.copyright[data-astro-cid-35ed7um5],.social-links[data-astro-cid-35ed7um5]{white-space:nowrap}.separator[data-astro-cid-35ed7um5]{color:var(--text-tertiary);margin:0 .25rem}.copyright[data-astro-cid-35ed7um5] .date[data-astro-cid-35ed7um5]{opacity:1}footer[data-astro-cid-35ed7um5] a[data-astro-cid-35ed7um5]{color:var(--text-secondary);text-decoration:none;display:inline-flex;align-items:center;min-height:var(--spacing-target)}@media(hover:hover)and (pointer:fine){footer[data-astro-cid-35ed7um5] a[data-astro-cid-35ed7um5]:hover{color:var(--text-primary)}}@media(max-width:479px){.footer-content[data-astro-cid-35ed7um5]{align-items:flex-start;flex-direction:column;gap:.25rem}}:root{--bg: #f7f7f7;--surface: #ededed;--surface-hover: color-mix(in srgb, #ededed 88%, #202020);--overlay-disc: color-mix(in srgb, #f7f7f7 85%, #00000000);--text-primary: #202020;--text-secondary: #626262;--text-tertiary: #6b6b6b;--accent: #202020;--border: #dcdcdc;--selection: #d9d9d9;--code-bg: #eeeeee;--mark: #e3e3e3;--focus: #202020;--sans: Geist, -apple-system, BlinkMacSystemFont, sans-serif;--mono: "SF Mono", SFMono-Regular, monospace;--font-weight-bold: 550;--font-weight-heavy: 650;--font-size-display: clamp(4.5rem, 8vw, 6rem);--font-weight-display: 650;--leading-display: 1.08;--tracking-display: -.04em;--font-size-display-tablet: clamp(2.4rem, 7vw, 4rem);--font-weight-display-tablet: 650;--leading-display-tablet: 1.08;--tracking-display-tablet: -.04em;--font-size-display-mobile: clamp(4rem, 18vw, 5rem);--font-weight-display-mobile: 650;--leading-display-mobile: 1.08;--tracking-display-mobile: -.04em;--font-size-greeting: .53em;--font-weight-greeting: 400;--leading-greeting: 1.08;--tracking-greeting: -.03em;--font-size-greeting-mobile: .45em;--font-weight-greeting-mobile: 400;--leading-greeting-mobile: 1.08;--tracking-greeting-mobile: -.03em;--font-size-greeting-tablet: 1em;--font-weight-greeting-tablet: 400;--leading-greeting-tablet: 1.08;--tracking-greeting-tablet: -.03em;--font-size-headline: clamp(2rem, 4vw, 2.5rem);--font-weight-headline: 550;--leading-headline: 1.25;--tracking-headline: -.035em;--font-size-subheadline: 1.75rem;--font-weight-subheadline: 550;--leading-subheadline: 1.25;--tracking-subheadline: -.035em;--font-size-entry-title: 1.375rem;--font-weight-entry-title: 550;--leading-entry-title: 1.3;--tracking-entry-title: -.035em;--font-size-entry-title-mobile: 1.25rem;--font-weight-entry-title-mobile: 550;--leading-entry-title-mobile: 1.3;--tracking-entry-title-mobile: -.035em;--font-size-prose-heading: 1.5rem;--font-weight-prose-heading: 550;--leading-prose-heading: 1.3;--tracking-prose-heading: -.035em;--font-size-project-title: clamp(1.5rem, 2.5vw, 1.875rem);--font-weight-project-title: 550;--leading-project-title: 1.15;--tracking-project-title: -.03em;--font-size-project-title-mobile: 1.5rem;--font-weight-project-title-mobile: 550;--leading-project-title-mobile: 1.15;--tracking-project-title-mobile: -.03em;--font-size-section-title: 1.125rem;--font-weight-section-title: 550;--leading-section-title: 1.15;--tracking-section-title: -.025em;--font-size-index-title: 1.125rem;--font-weight-index-title: 550;--leading-index-title: 1.5;--tracking-index-title: -.015em;--font-size-body: 1rem;--font-weight-body: 400;--leading-body: 1.65;--tracking-body: 0;--font-size-site-title: 1rem;--font-weight-site-title: 550;--leading-site-title: 1.65;--tracking-site-title: 0;--font-size-prose: 1rem;--font-weight-prose: 400;--leading-prose: 1.75;--tracking-prose: 0;--font-size-brand-link: 1em;--font-weight-brand-link: 400;--leading-brand-link: 1.25;--tracking-brand-link: 0;--font-size-bio: 1rem;--font-weight-bio: 400;--leading-bio: 1.8;--tracking-bio: 0;--font-size-small: .9375rem;--font-weight-small: 400;--leading-small: 1.65;--tracking-small: 0;--font-size-summary: .9375rem;--font-weight-summary: 400;--leading-summary: 1.75;--tracking-summary: 0;--font-size-meta: .8125rem;--font-weight-meta: 400;--leading-meta: 1.65;--tracking-meta: 0;--font-size-tooltip-title: .8125rem;--font-weight-tooltip-title: 550;--leading-tooltip-title: 1.65;--tracking-tooltip-title: 0;--font-size-label: .875rem;--font-weight-label: 400;--leading-label: 1.65;--tracking-label: 0;--font-size-caption: .6875rem;--font-weight-caption: 400;--leading-caption: 1.65;--tracking-caption: 0;--font-size-map-city: 9px;--font-weight-map-city: 400;--leading-map-city: 1;--tracking-map-city: .08em;--font-size-map-water: 8px;--font-weight-map-water: 400;--leading-map-water: 1;--tracking-map-water: .12em;--font-size-code: .875rem;--font-weight-code: 400;--leading-code: 1.5;--tracking-code: 0;--radius-action: .25em;--radius-brand-link: .25em;--radius-preview: 10px;--radius-panel: 8px;--radius-code: 5px;--radius-checkbox: 4px;--radius-marker: 4px;--radius-full: 9999px;--spacing-1: .25rem;--spacing-2: .5rem;--spacing-3: .75rem;--spacing-4: 1rem;--spacing-5: 1.25rem;--spacing-6: 1.5rem;--spacing-8: 2rem;--spacing-10: 2.5rem;--spacing-12: 3rem;--spacing-13: 3.25rem;--spacing-16: 4rem;--spacing-18: 4.5rem;--gutter: 1.35rem;--spacing-section: 2.5rem;--spacing-page-top: 4rem;--spacing-page-top-mobile: 2.5rem;--spacing-header-gap: 3rem;--spacing-header-gap-mobile: 2.5rem;--spacing-home-spread: 3.25rem;--spacing-home-section: 4.5rem;--spacing-target: 44px;--spacing-project-gap: .5rem;--container-prose: 42rem;--container-shell: 56rem;--ease-out: cubic-bezier(.23, 1, .32, 1);--ease-in-out: cubic-bezier(.77, 0, .175, 1);--ease-color: cubic-bezier(.25, .1, .25, 1);--duration-press: .1s;--duration-fast: .16s;--duration-base: .24s;--duration-reveal: .42s;--duration-hero: .6s;--stagger-letter: 18ms;--scale-press: .97;--scale-enter: .96;--nudge-internal: translateX(2px);--nudge-external: translate(1px, -1px);--opacity-pressed: .65;--opacity-disabled: .3;--shadow-tooltip: 0px 2px 12px 0px #00000011;--shadow-chooser: 0px 6px 22px 0px #00000033;--focus-ring-width: 2px;--focus-ring-offset: 5px;--focus-ring-radius: 2px;--border-hairline: 1px;--z-base: 1;--z-raised: 2;--z-popover: 3;--z-tooltip: 4;--z-skip-link: 1000;--z-viewer: 9999}html.dark{--bg: #181818;--surface: #262626;--surface-hover: color-mix(in srgb, #262626 88%, #eeeeee);--overlay-disc: color-mix(in srgb, #181818 85%, #00000000);--text-primary: #eeeeee;--text-secondary: #b3b3b3;--text-tertiary: #999999;--accent: #eeeeee;--border: #343434;--selection: #414141;--code-bg: #242424;--mark: #414141;--focus: #eeeeee}@font-face{font-family:Geist;font-style:normal;font-weight:100 900;font-display:swap;src:url(/fonts/Geist.woff2) format("woff2")}.prose *{margin:0;padding:0}.prose{font-size:var(--font-size-prose);font-weight:var(--font-weight-prose);line-height:var(--leading-prose);letter-spacing:var(--tracking-prose);margin-bottom:0}.prose .content>:first-child,.prose.content>:first-child{margin-top:0}.prose h2{font-size:var(--font-size-prose-heading);font-weight:var(--font-weight-prose-heading);line-height:var(--leading-prose-heading);letter-spacing:var(--tracking-prose-heading);margin-block:3rem 1.25rem}.prose h3,.prose h4,.prose h5{font-size:var(--font-size-index-title);font-weight:var(--font-weight-index-title);line-height:var(--leading-index-title);letter-spacing:var(--tracking-index-title);margin-block:2.5rem 1rem}.prose strong,.prose b{font-weight:var(--font-weight-bold)}.prose em{font-family:var(--sans);font-style:italic}.prose a{color:var(--text-primary);text-decoration:underline;text-decoration-color:var(--text-tertiary);transition:text-decoration-color var(--duration-fast) var(--ease-color)}@media(hover:hover)and (pointer:fine){.prose a:hover{color:var(--accent);text-decoration-color:var(--accent)}}.prose p{margin:1.75em 0}.prose table{table-layout:fixed;width:100%;border-collapse:separate;border-spacing:0;margin:1.75em 0;border:var(--border-hairline) solid var(--border);border-radius:var(--radius-panel);overflow:hidden}.prose th,.prose td{border:none;border-right:var(--border-hairline) solid var(--border);border-bottom:var(--border-hairline) solid var(--border);padding:.5em 1em;text-align:left}.prose th:last-child,.prose td:last-child{border-right:none}.prose tr:last-child td{border-bottom:none}.prose th{background:var(--astro-code-background);font-weight:var(--font-weight-bold)}.prose img{max-width:100%;height:auto;display:block;margin:2em 0}.prose figure{margin-bottom:2em;text-align:center}.prose figure img{margin-bottom:1em}.prose figure figcaption{color:var(--text-secondary);font-size:var(--font-size-label);font-weight:var(--font-weight-label);line-height:var(--leading-label);letter-spacing:var(--tracking-label);text-align:center}.prose p>img{position:relative;margin-bottom:2em}.prose p>img:after{content:attr(alt);display:block;position:absolute;left:0;width:100%;text-align:center;color:var(--text-secondary);font-size:var(--font-size-label);font-weight:var(--font-weight-label);line-height:var(--leading-label);letter-spacing:var(--tracking-label);margin-top:.75em}.prose code{padding:2.5px 3.5px;border-radius:var(--radius-code);background-color:var(--code-bg);border:.5px solid var(--border);font-family:var(--mono);font-size:.9em;font-feature-settings:"liga" 0,"calt" 0;-webkit-font-feature-settings:"liga" 0,"calt" 0}.prose blockquote{border-left:2px solid var(--border);margin:0 0 1.75em .125em;padding:0 0 0 1.375em;text-align:left}.prose blockquote p{margin:0}.prose blockquote cite{display:inline-block;margin-top:.5em}.prose ul{list-style-type:none;padding-left:0;margin-left:1rem;margin-bottom:1.75em}.prose ul ul{margin-left:.625rem;margin-top:.5em;margin-bottom:.5em}.prose ul li{position:relative;padding-left:.125rem;margin-bottom:.5em}.prose ul li:last-child{margin-bottom:0}.prose ul li>ul{margin-top:.5em;margin-bottom:.5em}.prose ul li:before{--size: .3125rem;content:"";position:absolute;left:-.785rem;top:calc((1.75em - var(--size)) / 2);width:var(--size);height:var(--size);border-radius:var(--radius-full);background-color:var(--text-tertiary)}.prose ol{list-style-position:outside;padding-left:0;margin-left:1.25rem;margin-bottom:1.75em;counter-reset:item}.prose ol li{display:block;position:relative;padding-left:.125rem;margin-bottom:.5em}.prose ol li:last-child{margin-bottom:0}.prose ol li:before{content:counter(item) ".";counter-increment:item;position:absolute;left:-1.15rem;width:1.5rem;text-align:left;color:var(--text-secondary);opacity:.75;font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1,"zero" 0,"cv01" 1,"cv02" 1,"calt" 1,"ss03" 1,"liga" 1,"ordn" 1}.prose ul.contains-task-list{list-style:none;margin-left:0;white-space:nowrap}.prose ul.contains-task-list li:before{content:none}.prose ul.contains-task-list li.task-list-item{padding-left:.125em;margin-bottom:.5em}.prose ul.contains-task-list li.task-list-item:last-child{margin-bottom:0}.prose ul.contains-task-list li.task-list-item input[type=checkbox]{margin-right:.625em;position:relative;top:.15em;width:1em;height:1em;border:1.35px solid var(--text-tertiary);border-radius:var(--radius-checkbox);background:transparent;appearance:none;-webkit-appearance:none}.prose ul.contains-task-list li.task-list-item input[type=checkbox]:checked{position:relative;background:var(--code-bg);font-family:var(--sans);border:1.35px solid var(--text-tertiary);opacity:.75}.prose ul.contains-task-list li.task-list-item input[type=checkbox]:checked:after{content:"✓";position:absolute;top:50%;left:50%;transform:translate(-45%,-55%);font-family:var(--sans);font-size:.625em;font-weight:var(--font-weight-heavy);color:var(--text-primary);opacity:.55}.prose ul.contains-task-list li.task-list-item input[type=checkbox]+*{display:inline;margin-left:0;white-space:nowrap}.prose sup,.prose sub,.prose sup a{margin:0 .125em;font-size:.875em;line-height:1}.prose hr{margin:3.75em 0;height:auto;border:none;background:none;text-align:center;position:relative}.prose hr:before{content:"***";font-family:var(--mono);color:var(--text-tertiary);font-size:.875em;letter-spacing:.25em}.prose kbd{font-family:var(--mono);font-size:.9em;line-height:1.5;border:var(--border-hairline) solid var(--text-tertiary);padding:1px 4px;border-radius:var(--radius-code);min-width:1.75em;display:inline-block;text-align:center}.prose mark{background-color:var(--mark);color:var(--text-primary);padding:3px 1px}.prose .footnotes{margin-top:4rem;padding-top:1.75rem;position:relative}.prose .footnotes:before{content:"";position:absolute;top:0;left:0;width:4rem;height:var(--border-hairline);background-color:var(--border)}.prose cite{font-style:normal}.prose [data-footnote-backref]{position:relative;font-family:var(--mono);font-size:1.125em;top:-.05em}.prose [data-footnote-ref]{font-size:1em;font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1,"zero" 0,"cv01" 1,"cv02" 1,"calt" 1,"ss03" 1,"liga" 1,"ordn" 1}.prose [data-footnote-ref],.prose [data-footnote-backref]{color:var(--text-secondary);opacity:.875;text-decoration:none;transition:color var(--duration-fast) var(--ease-color);padding-right:.125em}@media(hover:hover)and (pointer:fine){.prose [data-footnote-ref]:hover,.prose [data-footnote-backref]:hover{color:var(--text-primary)}}.prose pre{background-color:var(--astro-code-background);border-radius:var(--radius-panel);padding:1.25em 1.5em;margin:2em 0;overflow-x:auto}@media(max-width:767px){.prose pre{padding:1em 1.25em}}.prose pre>code{font-family:var(--mono);font-feature-settings:"liga" 0,"calt" 0;display:block;white-space:pre;word-break:normal;overflow-wrap:normal;padding:0;margin:0;background:none;border:none;font-size:var(--font-size-code);font-weight:var(--font-weight-code);line-height:var(--leading-code);letter-spacing:var(--tracking-code);border-radius:0}.prose iframe{width:100%;aspect-ratio:16/9;border:none;border-radius:var(--radius-panel);margin:.25em 0 0}:root{color-scheme:light;--astro-code-foreground: var(--text-primary);--astro-code-background: var(--surface);--astro-code-token-constant: var(--text-primary);--astro-code-token-string: var(--text-primary);--astro-code-token-comment: var(--text-secondary);--astro-code-token-keyword: var(--text-secondary);--astro-code-token-parameter: var(--text-primary);--astro-code-token-function: var(--text-primary);--astro-code-token-string-expression: var(--text-secondary);--astro-code-token-punctuation: var(--text-secondary);--astro-code-token-link: var(--text-secondary)}html.dark{color-scheme:dark}*{box-sizing:border-box}html{background:var(--bg);scrollbar-gutter:stable;scrollbar-color:var(--border) var(--bg);-webkit-tap-highlight-color:transparent}body{margin:0;min-width:0;min-height:100dvh;color:var(--text-primary);font-family:var(--sans);font-size:var(--font-size-body);font-weight:var(--font-weight-body);line-height:var(--leading-body);letter-spacing:var(--tracking-body);text-rendering:optimizeLegibility;overflow-wrap:break-word;-webkit-font-smoothing:antialiased}.layout-wrapper{width:min(var(--container-shell),calc(100% - var(--gutter) * 2));min-height:100dvh;margin-inline:auto;padding-block:var(--spacing-page-top) var(--spacing-6);display:flex;flex-direction:column}.page-content,.project-container,.stack-container{flex:1;display:flex;flex-direction:column;min-width:0}main{flex:1;min-width:0}.page-content main{padding-top:var(--spacing-header-gap)}.project-container,.stack-container{width:100%}.page-content:not(.page-content--wide) main,.stack-container main{width:100%;max-width:var(--container-prose)}.project-container main{width:100%}h1,h2,h3,h4,h5,p{margin:0}p{text-wrap:pretty}h1,h2,h3,h4,h5{text-wrap:balance}.page-heading{font-size:var(--font-size-headline);font-weight:var(--font-weight-headline);line-height:var(--leading-headline);letter-spacing:var(--tracking-headline);margin-bottom:.75rem}.page-intro{color:var(--text-secondary)}.page-header{margin-bottom:2rem}button,input,textarea,select{font:inherit}button,a{touch-action:manipulation}a{color:inherit;text-underline-offset:.2em}button{color:inherit}img{max-width:100%}::selection{background:var(--selection);color:var(--text-primary)}:focus-visible{outline:var(--focus-ring-width) solid var(--focus);outline-offset:var(--focus-ring-offset);border-radius:var(--focus-ring-radius)}:focus:not(:focus-visible){outline:none}:target{scroll-margin-top:2rem}input,textarea{caret-color:var(--text-primary)}.date{color:var(--text-secondary);font-variant-numeric:tabular-nums}.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.skip-link{position:fixed;top:1rem;left:1rem;z-index:var(--z-skip-link);padding:.5rem 1rem;background:var(--text-primary);color:var(--bg);transform:translateY(calc(-100% - 2rem))}.skip-link:focus{transform:translateY(0)}@media(max-width:767px){.layout-wrapper{padding-top:var(--spacing-page-top-mobile)}.page-content main{padding-top:var(--spacing-header-gap-mobile)}}.press-dim{transition:opacity var(--duration-fast) var(--ease-out)}.press-dim:active{opacity:var(--opacity-pressed);transition-duration:var(--duration-press)}@media(prefers-reduced-motion:no-preference){.press-scale:not(:focus-visible){transition:transform var(--duration-fast) var(--ease-out),opacity var(--duration-fast) var(--ease-out)!important}.press-scale:active:not(:focus-visible,:disabled){transform:scale(var(--scale-press));transition-duration:var(--duration-press)!important}}:where(html[data-theme-switching]) :not(.theme-icon),:where(html[data-theme-switching]) :before,:where(html[data-theme-switching]) :after{transition:none!important}@media(prefers-reduced-motion:reduce){.press-scale:active:not(:disabled){opacity:var(--opacity-pressed)}::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}}.astro-route-announcer{position:absolute;left:0;top:0;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden;white-space:nowrap;width:1px;height:1px}a.brand-link,.prose a.brand-link{display:inline-block;max-width:100%;padding:.15em .35em .05em;border-radius:var(--radius-brand-link);background:var(--surface);color:var(--text-primary);font-size:var(--font-size-brand-link);font-weight:var(--font-weight-brand-link);line-height:var(--leading-brand-link);letter-spacing:var(--tracking-brand-link);vertical-align:baseline;white-space:normal;overflow-wrap:normal;text-decoration:none}@media(hover:hover)and (pointer:fine){a.brand-link:hover{color:var(--accent);background:var(--surface-hover)}}.link-external-arrow{display:inline-block;flex:none;width:.75em;height:.75em;vertical-align:-.02em;margin-left:.2em}@media(hover:hover)and (pointer:fine)and (prefers-reduced-motion:no-preference){.link-external-arrow{transition:transform var(--duration-fast) var(--ease-out)}a:hover>.link-external-arrow{transform:var(--nudge-external)}}.link-brand-icon,.prose .link-brand-icon{display:inline-block;width:.95em;height:.95em;margin:0 .3em 0 0;padding:0;font-size:inherit;line-height:1;vertical-align:-.125em}a.brand-link>.link-brand-icon,.prose a.brand-link>.link-brand-icon{margin:0 .3em 0 0}.link-brand-icon img.link-favicon,.prose .link-brand-icon img.link-favicon{display:block;width:100%;height:100%;min-width:0;max-width:none;margin:0;padding:0;object-fit:contain;background:none;border:0;border-radius:0;box-shadow:none;cursor:inherit}.link-brand-icon img.link-favicon-dark,.prose .link-brand-icon img.link-favicon-dark,html.dark .link-brand-icon img.link-favicon-light{display:none}html.dark .link-brand-icon img.link-favicon-dark{display:block}.link-favicon-monochrome{display:block;width:100%;height:100%;background-color:currentColor;mask-size:contain;mask-repeat:no-repeat;mask-position:center}#transition-wrapper{display:flex;flex:1;flex-direction:column;min-width:0}@media(prefers-reduced-motion:no-preference){html:not([data-client-navigation]) #transition-wrapper{animation:content-reveal var(--duration-reveal) var(--ease-out) backwards}}@keyframes content-reveal{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}
