@font-face{font-family:D2Coding;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/D2Coding-Regular.woff2) format("woff2")}@font-face{font-family:D2Coding;font-style:normal;font-weight:700;font-display:swap;src:url(/fonts/D2Coding-Bold.woff2) format("woff2")}:root{--blog-accent:#8b5cf6;--blog-accent-strong:#7c3aed;--blog-bg:#f8f8f7;--blog-surface:rgba(255,255,255,0.72);--blog-border:rgba(0,0,0,0.08);--blog-border-soft:rgba(0,0,0,0.06);--blog-text:#18181b;--blog-text-muted:#52525b;--blog-text-faint:#71717a;--blog-code-bg:rgba(0,0,0,0.04);--blog-shadow:0 2px 16px rgba(0,0,0,0.06),0 0 1px rgba(0,0,0,0.08);--blog-content-width:44rem;--blog-wide-width:72rem;--blog-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Apple SD Gothic Neo","Pretendard","Noto Sans KR",sans-serif;--blog-font-mono:"D2Coding",ui-monospace,SFMono-Regular,"SF Mono",Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;color-scheme:light}@media (prefers-color-scheme:dark){:root{--blog-bg:#000000;--blog-surface:rgba(26,26,26,0.72);--blog-border:rgba(255,255,255,0.1);--blog-border-soft:rgba(255,255,255,0.06);--blog-text:#f4f4f5;--blog-text-muted:#a1a1aa;--blog-text-faint:#8b8b94;--blog-code-bg:rgba(255,255,255,0.06);--blog-shadow:0 2px 16px rgba(0,0,0,0.3),0 0 1px rgba(0,0,0,0.4);color-scheme:dark}}*{box-sizing:border-box}html{scroll-behavior:smooth}@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}body,html{margin:0;padding:0;background:var(--blog-bg);color:var(--blog-text);font-family:var(--blog-font);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}body:before{content:"";position:fixed;inset:0;pointer-events:none;z-index:-1;background:radial-gradient(ellipse 80% 60% at 20% -10%,rgba(139,92,246,.08),transparent 60%),radial-gradient(ellipse 60% 50% at 90% 0,rgba(99,102,241,.06),transparent 60%)}@media (prefers-color-scheme:dark){body:before{background:radial-gradient(ellipse 80% 60% at 20% -10%,rgba(139,92,246,.12),transparent 60%),radial-gradient(ellipse 60% 50% at 90% 0,rgba(99,102,241,.08),transparent 60%)}}a{color:inherit}.blog-header{position:-webkit-sticky;position:sticky;top:0;z-index:10;background:var(--blog-surface);backdrop-filter:blur(12px) saturate(1.4);-webkit-backdrop-filter:blur(12px) saturate(1.4);border-bottom:1px solid var(--blog-border-soft)}.blog-header-inner{max-width:var(--blog-wide-width);margin:0 auto;padding:0 24px;height:64px;display:flex;align-items:center;justify-content:space-between;gap:16px}.blog-logo{gap:10px;white-space:nowrap;font-weight:600;letter-spacing:-.015em}.blog-logo,.blog-logo-mark{display:inline-flex;align-items:center}.blog-logo-mark{text-decoration:none}.blog-logo img{height:26px;width:auto;display:block}.blog-logo .blog-divider{width:1px;height:18px;background:var(--blog-border)}.blog-logo .blog-label{font-size:17px;color:var(--blog-text);text-decoration:none}.blog-nav{display:flex;align-items:center;gap:14px;font-size:14px;white-space:nowrap;flex-shrink:0}.blog-nav a{color:var(--blog-text-muted);text-decoration:none;transition:color .15s ease}.blog-nav a:hover{color:var(--blog-text)}.blog-nav a.blog-nav-cta{display:inline-flex;align-items:center;gap:5px;padding:6px 12px;border-radius:8px;border:1px solid var(--blog-border);color:var(--blog-text)}.blog-nav a.blog-nav-cta:hover{border-color:var(--blog-accent);color:var(--blog-accent)}.blog-main{max-width:var(--blog-content-width);margin:0 auto;padding:56px 24px 96px;min-height:calc(100vh - 64px - 120px)}.blog-footer{border-top:1px solid var(--blog-border-soft);padding:28px 24px 40px}.blog-footer-inner{max-width:var(--blog-wide-width);margin:0 auto;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;font-size:13px;color:var(--blog-text-faint)}.blog-footer-links{display:flex;gap:16px}.blog-footer a{color:var(--blog-text-faint);text-decoration:none}.blog-footer a:hover{color:var(--blog-text-muted)}.blog-main:has(.blog-index){max-width:var(--blog-wide-width)}.blog-index-head{max-width:42rem;margin:0 0 48px}.blog-index-title{font-size:52px;font-weight:700;letter-spacing:-.035em;line-height:1.08;margin:0 0 14px;text-wrap:balance}.blog-index-lede{font-size:17px;line-height:1.65;text-wrap:pretty;white-space:pre-line}.blog-index-empty,.blog-index-lede{margin:0;color:var(--blog-text-muted)}.blog-index-empty{font-size:15px;line-height:1.6}.blog-card-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));grid-gap:40px 28px;gap:40px 28px;margin-top:56px}.blog-card-link{display:block;text-decoration:none;color:inherit}.blog-card-media{aspect-ratio:16/9;border-radius:14px;border:1px solid var(--blog-border-soft);background:var(--blog-code-bg)}.blog-card-media,.blog-cover{position:relative;overflow:hidden}.blog-cover{container-type:inline-size;width:100%;height:100%;transition:transform .4s cubic-bezier(.2,.6,.2,1)}.blog-card-link:hover .blog-cover{transform:scale(1.03)}.blog-cover-grain{position:absolute;inset:0;background-repeat:repeat;opacity:.5;mix-blend-mode:soft-light;pointer-events:none}.blog-cover-inner{position:relative;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center}.blog-cover-logo{display:block;flex-shrink:0;width:auto;object-fit:contain}.blog-cover-title{font-weight:700;letter-spacing:-.02em}.blog-cover-summary,.blog-cover-title{margin:0;display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden}.blog-post-cover-figure{margin:0 0 36px;border-radius:14px;border:1px solid var(--blog-border-soft);overflow:hidden;aspect-ratio:1200/630}.blog-card-body{padding-top:18px}.blog-card-meta{display:flex;align-items:center;gap:7px;margin:0 0 10px;font-size:13px;color:var(--blog-text-faint);font-feature-settings:"tnum";font-variant-numeric:tabular-nums}.blog-card-category{color:var(--blog-accent);font-weight:600}.blog-card-meta-sep{opacity:.5}.blog-card-title{margin:0 0 8px;font-size:19px;font-weight:650;letter-spacing:-.02em;line-height:1.38;transition:color .15s ease}.blog-card-link:hover .blog-card-title{color:var(--blog-accent)}.blog-card-desc{margin:0;color:var(--blog-text-muted);font-size:14.5px;line-height:1.62;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;line-clamp:3;overflow:hidden}.blog-card-featured .blog-card-link{display:grid;grid-template-columns:1.35fr 1fr;grid-gap:36px;gap:36px;align-items:center}.blog-card-featured .blog-card-media{border-radius:18px}.blog-card-featured .blog-card-body{padding-top:0}.blog-card-featured .blog-card-title{font-size:30px;line-height:1.24;letter-spacing:-.03em;margin-bottom:12px}.blog-card-featured .blog-card-desc{font-size:16px;-webkit-line-clamp:7;line-clamp:7}@media (min-width:721px){.blog-index:not(:has(.blog-card-grid)) .blog-card-featured .blog-card-media{aspect-ratio:4/3}}@media (max-width:1080px){.blog-card-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:720px){.blog-card-featured .blog-card-link{grid-template-columns:1fr;gap:0}.blog-card-featured .blog-card-body{padding-top:18px}.blog-card-featured .blog-card-title{font-size:24px}.blog-card-featured .blog-card-desc{font-size:15px}.blog-card-grid{grid-template-columns:1fr;gap:36px;margin-top:44px}}.blog-post-header{margin-bottom:40px;padding-bottom:28px;border-bottom:1px solid var(--blog-border-soft)}.blog-post-title{margin:0 0 14px;font-size:36px;font-weight:700;letter-spacing:-.035em;line-height:1.2}.blog-post-meta{display:flex;flex-wrap:wrap;gap:10px;align-items:center;font-size:14px;color:var(--blog-text-faint)}.blog-post-meta .sep{opacity:.5}.blog-post-category{color:var(--blog-accent);font-weight:600}.blog-toc{margin:0 0 40px;padding:14px 18px 16px;border:1px solid var(--blog-border-soft);border-radius:12px;background:var(--blog-surface)}.blog-toc-title{margin:0 0 8px;font-size:12px;font-weight:640;letter-spacing:.04em;text-transform:uppercase;color:var(--blog-text-faint)}.blog-toc-list{margin:0;padding:0;list-style:none;font-size:13.5px;line-height:1.5}.blog-toc-list li{margin:0}.blog-toc-list{--toc-indent:0px}.blog-toc-list li[data-level="2"]{--toc-indent:12px}.blog-toc-flat .blog-toc-list li[data-level="2"]{--toc-indent:0px}.blog-toc-list a{display:block;padding:5px 0 5px calc(var(--toc-indent) + var(--toc-gutter, 0px));color:var(--blog-text-muted);text-decoration:none;overflow-wrap:break-word;transition:color .15s ease}.blog-toc-list a:hover{color:var(--blog-text)}.blog-toc-list a[aria-current=true]{color:var(--blog-accent);font-weight:620}@media (min-width:1280px){.blog-toc{position:fixed;top:128px;left:calc(50% + var(--blog-content-width) / 2 + 24px);width:15rem;max-height:calc(100vh - 192px);overflow-y:auto;overscroll-behavior:contain;margin:0;padding:0;border:0;border-left:1px solid var(--blog-border-soft);border-radius:0;background:none}.blog-toc-title{padding-left:16px}.blog-toc-list a{--toc-gutter:15px;margin-left:-1px;border-left:2px solid transparent}.blog-toc-list a[aria-current=true]{border-left-color:var(--blog-accent)}}.blog-human-note{display:flex;gap:12px;align-items:flex-start;margin-top:56px;padding:18px 20px;border:1px solid var(--blog-border-soft);border-radius:12px;background:var(--blog-surface);box-shadow:var(--blog-shadow)}.blog-human-note-icon{flex:none;margin-top:2px;color:var(--blog-accent)}.blog-human-note-body{display:flex;flex-direction:column;gap:4px}.blog-human-note p{margin:0;font-size:14.5px;line-height:1.68;color:var(--blog-text-muted)}.blog-human-note strong{font-weight:640;color:var(--blog-text)}.blog-back{display:inline-flex;align-items:center;gap:6px;margin-top:64px;padding-top:28px;border-top:1px solid var(--blog-border-soft);width:100%;font-size:14px;color:var(--blog-text-muted);text-decoration:none}.blog-back:hover{color:var(--blog-accent)}.blog-human-note+.blog-back{margin-top:32px}.blog-prose{font-size:16.5px;line-height:1.78;color:var(--blog-text);overflow-wrap:break-word}.blog-prose>:first-child{margin-top:0}.blog-prose h2{font-size:30px;font-weight:700;letter-spacing:-.03em;line-height:1.26;margin:64px 0 18px}.blog-prose h3{font-size:22.5px;font-weight:670;letter-spacing:-.025em;line-height:1.32;margin:48px 0 14px}.blog-prose h2,.blog-prose h3{scroll-margin-top:88px}.blog-prose h4{font-size:18.5px;font-weight:650;letter-spacing:-.02em;margin:36px 0 12px}.blog-prose h5{font-size:16.5px;font-weight:650;margin:28px 0 10px}.blog-prose p{margin:0 0 20px}.blog-prose a{color:var(--blog-accent-strong);text-decoration:underline;text-underline-offset:2.5px;text-decoration-thickness:1px;-webkit-text-decoration-color:rgba(124,58,237,.4);text-decoration-color:rgba(124,58,237,.4)}@media (prefers-color-scheme:dark){.blog-prose a{color:#a78bfa;-webkit-text-decoration-color:rgba(167,139,250,.4);text-decoration-color:rgba(167,139,250,.4)}}.blog-prose a:hover{-webkit-text-decoration-color:currentColor;text-decoration-color:currentColor}.blog-prose ol,.blog-prose ul{margin:0 0 20px;padding-left:24px}.blog-prose li,.blog-prose li>ol,.blog-prose li>ul{margin:6px 0}.blog-prose blockquote{margin:24px 0;padding:2px 0 2px 18px;border-left:3px solid var(--blog-accent);color:var(--blog-text-muted)}.blog-prose blockquote p:last-child{margin-bottom:0}.blog-prose hr{border:0;border-top:1px solid var(--blog-border-soft);margin:44px 0}.blog-prose img,.blog-prose video{max-width:100%;height:auto;border-radius:10px;border:1px solid var(--blog-border-soft);display:block;margin:28px 0}.blog-prose strong{font-weight:650}.blog-prose code{font-family:var(--blog-font-mono);font-size:.88em;font-feature-settings:none;font-variant-ligatures:none;background:var(--blog-code-bg);padding:.15em .4em;border-radius:5px}.blog-prose pre{font-family:var(--blog-font-mono);font-size:13.5px;line-height:1.65;background:var(--blog-code-bg);border:1px solid var(--blog-border-soft);border-radius:10px;padding:16px 18px;margin:24px 0;overflow-x:auto}.blog-prose pre code{background:none;padding:0;border-radius:0;font-size:inherit}.blog-prose pre:not(.blog-hl) code span{color:var(--shiki-light)}@media (prefers-color-scheme:dark){.blog-prose pre:not(.blog-hl) code span{color:var(--shiki-dark)}}.blog-prose pre.blog-hl{--hl-keyword:#7c3aed;--hl-string:#0a7d5a;--hl-comment:#71717a;--hl-name:var(--blog-text);--hl-func:#1d4ed8;--hl-number:#b45309;--hl-punct:var(--blog-text-muted)}@media (prefers-color-scheme:dark){.blog-prose pre.blog-hl{--hl-keyword:#c4b5fd;--hl-string:#6ee7b7;--hl-comment:#8b8b94;--hl-func:#93c5fd;--hl-number:#fcd34d}}.blog-prose pre.blog-hl .k,.blog-prose pre.blog-hl .kc,.blog-prose pre.blog-hl .kd,.blog-prose pre.blog-hl .kn,.blog-prose pre.blog-hl .kr,.blog-prose pre.blog-hl .ow{color:var(--hl-keyword)}.blog-prose pre.blog-hl .s,.blog-prose pre.blog-hl .s1,.blog-prose pre.blog-hl .s2,.blog-prose pre.blog-hl .sb,.blog-prose pre.blog-hl .sd,.blog-prose pre.blog-hl .se,.blog-prose pre.blog-hl .si,.blog-prose pre.blog-hl .sr{color:var(--hl-string)}.blog-prose pre.blog-hl .c,.blog-prose pre.blog-hl .c1,.blog-prose pre.blog-hl .cm,.blog-prose pre.blog-hl .cp,.blog-prose pre.blog-hl .cs{color:var(--hl-comment);font-style:italic}.blog-prose pre.blog-hl .fm,.blog-prose pre.blog-hl .nd,.blog-prose pre.blog-hl .nf{color:var(--hl-func)}.blog-prose pre.blog-hl .nb,.blog-prose pre.blog-hl .nc,.blog-prose pre.blog-hl .nn,.blog-prose pre.blog-hl .nt{color:var(--hl-keyword)}.blog-prose pre.blog-hl .il,.blog-prose pre.blog-hl .m,.blog-prose pre.blog-hl .mf,.blog-prose pre.blog-hl .mh,.blog-prose pre.blog-hl .mi{color:var(--hl-number)}.blog-prose pre.blog-hl .o,.blog-prose pre.blog-hl .p{color:var(--hl-punct)}.blog-preview-banner{max-width:var(--blog-content-width);margin:0 auto 32px;padding:11px 16px;border:1px solid var(--blog-border);border-radius:10px;background:var(--blog-surface);color:var(--blog-text-muted);font-size:14px;text-align:center}.blog-preview-banner-error{color:#b91c1c}@media (prefers-color-scheme:dark){.blog-preview-banner-error{color:#fca5a5}}.blog-prose .blog-table-scroll,.blog-prose figure{overflow-x:auto;margin:24px 0}.blog-prose table{border-collapse:collapse;width:100%;font-size:15px}.blog-prose td,.blog-prose th{border:1px solid var(--blog-border-soft);padding:9px 13px;text-align:left;vertical-align:top}.blog-prose th{background:var(--blog-code-bg);font-weight:640}@media (max-width:640px){.blog-post-title{font-size:28px}.blog-index-title{font-size:34px}.blog-main{padding:40px 20px 72px}.blog-header-inner{padding:0 20px}}@media (max-width:520px){.blog-header-inner{gap:12px}.blog-logo .blog-divider,.blog-logo .blog-label{display:none}.blog-nav{gap:12px}}