@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/_astro/geist-cyrillic-ext-wght-normal.DjL33-gN.woff2)format("woff2-variations");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/_astro/geist-cyrillic-wght-normal.BEAKL7Jp.woff2)format("woff2-variations");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/_astro/geist-vietnamese-wght-normal.6IgcOCM7.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/_astro/geist-latin-ext-wght-normal.DC-KSUi6.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/_astro/geist-latin-wght-normal.BgDaEnEv.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Geist Mono Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/_astro/geist-mono-cyrillic-ext-wght-normal.X_5orZeX.woff2)format("woff2-variations");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Geist Mono Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/_astro/geist-mono-cyrillic-wght-normal.DiZS0aHC.woff2)format("woff2-variations");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:Geist Mono Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/_astro/geist-mono-symbols2-wght-normal.CO5SzqOn.woff2)format("woff2-variations");unicode-range:U+2000-2001,U+2004-2008,U+200A,U+23B8-23BD,U+2500-259F}@font-face{font-family:Geist Mono Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/_astro/geist-mono-vietnamese-wght-normal.DadHysG0.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Geist Mono Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/_astro/geist-mono-latin-ext-wght-normal.Bwz-egvJ.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Geist Mono Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/_astro/geist-mono-latin-wght-normal.XN7g48iV.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--bg:#fcfcfb;--ink:#18181a;--ink-2:#4f4f56;--ink-3:#6e6e76;--line:#e8e8e4;--soft:#f3f3f0;--accent:#2f45c8;--accent-soft:#eceefa;--ok:#1f7a4d;--warn:#b4471b;--font-sans:"Geist Variable", -apple-system, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "Noto Sans SC", system-ui, sans-serif;--font-mono:"Geist Mono Variable", ui-monospace, "SF Mono", Menlo, monospace;--measure:680px;--gutter:24px;--astro-code-foreground:var(--ink);--astro-code-background:#f6f6f3;--astro-code-token-keyword:#9a3fb8;--astro-code-token-function:#2f45c8;--astro-code-token-string:#1f7a4d;--astro-code-token-string-expression:#1f7a4d;--astro-code-token-constant:#b4471b;--astro-code-token-parameter:#4f4f56;--astro-code-token-comment:#8a8a92;--astro-code-token-punctuation:#6e6e76;--astro-code-token-link:#2f45c8;color-scheme:light}:root[data-theme=dark]{--bg:#111113;--ink:#ececee;--ink-2:#b4b4bc;--ink-3:#8e8e97;--line:#26262b;--soft:#19191c;--accent:#8e9dff;--accent-soft:#1d2140;--ok:#5bc894;--warn:#f08a5d;--astro-code-background:#17171a;--astro-code-token-keyword:#d49bea;--astro-code-token-function:#8e9dff;--astro-code-token-string:#5bc894;--astro-code-token-string-expression:#5bc894;--astro-code-token-constant:#f08a5d;--astro-code-token-parameter:#b4b4bc;--astro-code-token-comment:#7a7a83;--astro-code-token-punctuation:#8e8e97;--astro-code-token-link:#8e9dff;color-scheme:dark}*,:before,:after{box-sizing:border-box}html{-webkit-text-size-adjust:100%;text-size-adjust:100%}body{background:var(--bg);color:var(--ink);font-family:var(--font-sans);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;margin:0;font-size:16px;line-height:1.6}a{color:inherit;text-decoration:none}a:hover{color:var(--accent)}img,svg,video{max-width:100%}button{font:inherit;color:inherit}:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}::selection{background:var(--accent-soft)}.mono{font-family:var(--font-mono)}.sr-only{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.container{max-width:calc(var(--measure) + var(--gutter) * 2);padding:0 var(--gutter);margin:0 auto}.site-header{justify-content:space-between;align-items:center;gap:12px;height:96px;display:flex}.wordmark{font-family:var(--font-mono);letter-spacing:-.01em;color:var(--ink);align-items:center;gap:10px;font-size:14px;font-weight:500;display:flex}.wordmark i{background:var(--accent);border-radius:2px;width:8px;height:8px}.site-nav{color:var(--ink-2);align-items:center;gap:4px;font-size:14px;display:flex}.site-nav a{padding:12px 10px}.site-nav a[aria-current=page]{color:var(--ink)}.theme-toggle{width:44px;height:44px;color:var(--ink-2);cursor:pointer;background:0 0;border:0;place-items:center;display:grid}.theme-toggle:hover{color:var(--ink)}.theme-toggle .moon,:root[data-theme=dark] .theme-toggle .sun{display:none}:root[data-theme=dark] .theme-toggle .moon{display:block}.site-footer{color:var(--ink-3);flex-wrap:wrap;justify-content:space-between;gap:12px;padding:64px 0 56px;font-size:13px;display:flex}.site-footer nav{gap:20px;display:flex}.section-head{border-bottom:1px solid var(--line);color:var(--ink-3);justify-content:space-between;align-items:baseline;padding-bottom:16px;font-size:14px;display:flex}.section-head h1,.section-head h2{font-size:inherit;margin:0;font-weight:500}.year-group{border-bottom:1px solid var(--line);grid-template-columns:72px minmax(0,1fr);padding:22px 0;display:grid}.year-group>.year{font-family:var(--font-mono);color:var(--ink-3);padding-top:13px;font-size:13px}.post-row{align-items:baseline;gap:16px;padding:10px 0;display:flex}.post-row .t{color:var(--ink);flex:auto;font-size:16px;line-height:1.6;transition:color .15s}.post-row:hover .t{color:var(--accent)}.post-row .d{font-family:var(--font-mono);color:var(--ink-3);flex:none;font-size:13px}.badge{color:var(--accent);background:var(--accent-soft);border-radius:999px;flex:none;padding:0 8px;font-size:12px;line-height:20px}.badge.muted{color:var(--ink-3);background:var(--soft)}@media (width<=520px){.year-group{grid-template-columns:1fr;padding:18px 0}.year-group>.year{padding:0 0 4px}}.progress{background:var(--accent);transform-origin:0;width:100%;height:2px;transform:scaleX(var(--p,0));z-index:10;position:fixed;inset:0 auto auto 0}.post-shell{grid-template-columns:minmax(0, 1fr) minmax(0, calc(var(--measure) + var(--gutter) * 2)) minmax(0, 1fr);display:grid}.post-shell>.container{grid-column:2;width:100%}.post-header .back{color:var(--ink-3);padding:10px 0;font-size:14px;display:inline-block}.post-header h1{letter-spacing:-.02em;margin:20px 0 0;font-size:40px;font-weight:600;line-height:1.3}.post-meta{font-family:var(--font-mono);color:var(--ink-3);flex-wrap:wrap;gap:10px;margin-top:20px;font-size:13px;display:flex}.post-meta a:hover{color:var(--accent)}@media (width<=640px){.post-header h1{font-size:30px;line-height:1.35}}.toc{grid-column:3;padding:220px 0 0 40px;font-size:13px;line-height:1.5}.toc nav{max-width:220px;position:sticky;top:48px}.toc .label{color:var(--ink-3);margin-bottom:10px;font-size:12px}.toc a{color:var(--ink-3);align-items:center;gap:8px;padding:5px 0;display:flex}.toc a:hover{color:var(--ink)}.toc a:before{content:"";background:0 0;border-radius:2px;flex:none;width:4px;height:4px;transition:background .15s}.toc a.active{color:var(--ink)}.toc a.active:before{background:var(--accent)}.toc a.d3{padding-left:12px}@media (width<=1180px){.toc{display:none}}.post-pager{border-top:1px solid var(--line);grid-template-columns:1fr 1fr;gap:16px;margin-top:72px;padding-top:28px;display:grid}.post-pager a{padding:8px 0}.post-pager .next{text-align:right}.post-pager small{color:var(--ink-3);font-size:12px;display:block}.post-pager span{margin-top:6px;font-size:15px;display:block}.prose{overflow-wrap:break-word;margin-top:56px;font-size:17px;line-height:1.85}.prose>:first-child{margin-top:0}.prose p,.prose ul,.prose ol,.prose blockquote,.prose table{margin:0 0 1.25em}.prose ul,.prose ol{padding-left:1.3em}.prose li{margin:.3em 0}.prose li>ul,.prose li>ol{margin:0}.prose h2{letter-spacing:-.01em;margin:64px 0 20px;font-size:22px;font-weight:600;line-height:1.4}.prose h3{margin:40px 0 12px;font-size:17px;font-weight:600;line-height:1.5}.prose h4{margin:32px 0 8px;font-size:16px;font-weight:600}.prose h2,.prose h3,.prose h4{scroll-margin-top:32px}.prose strong{font-weight:600}.prose a{color:var(--accent);text-underline-offset:3px;text-decoration:underline 1px}.prose hr{border:0;border-top:1px solid var(--line);margin:48px 0}.prose blockquote{color:var(--ink-2);box-shadow:inset 2px 0 0 var(--line);padding:2px 0 2px 20px}.prose img{border-radius:10px;height:auto;margin:32px auto;display:block}.prose :not(pre)>code{font-family:var(--font-mono);background:var(--soft);border-radius:5px;padding:.12em .4em;font-size:.86em}.prose table{border-collapse:collapse;font-size:15px;display:block;overflow-x:auto}.prose th,.prose td{border-bottom:1px solid var(--line);text-align:left;padding:8px 14px 8px 0}.prose th{color:var(--ink-3);font-weight:500}@media (width<=640px){.prose{margin-top:36px;font-size:16px}.prose h2{margin-top:48px;font-size:20px}}.prose .code-block{margin:28px 0;position:relative}.prose pre.astro-code{border:1px solid var(--line);font-family:var(--font-mono);tab-size:2;border-radius:14px;margin:0;padding:18px 20px;font-size:13.5px;line-height:1.75;overflow-x:auto}.prose pre.astro-code code{font-family:inherit}.code-tools{color:var(--ink-3);opacity:0;align-items:center;gap:6px;font-size:12px;transition:opacity .15s;display:flex;position:absolute;top:8px;right:8px}.code-block:hover .code-tools,.code-tools:focus-within{opacity:1}.code-tools button{border:1px solid var(--line);background:var(--bg);height:28px;color:var(--ink-2);cursor:pointer;border-radius:7px;padding:0 10px;font-size:12px}@media (hover:none){.code-tools{opacity:1}.code-tools .lang{display:none}}.figure{margin:40px 0}.figure>img,.figure>.figure-body{margin:0 auto}.figure figcaption{text-align:center;color:var(--ink-3);margin-top:14px;font-size:13px;line-height:1.6}.figure.panel .figure-body{background:var(--soft);border-radius:16px;padding:32px}.note{background:var(--accent-soft);color:var(--ink-2);border-radius:12px;gap:14px;margin:32px 0;padding:18px 20px;font-size:15px;line-height:1.75;display:flex}.note>.label{color:var(--accent);flex:none;padding-top:3px;font-size:12px;font-weight:600}.note>.body>:last-child{margin-bottom:0}.note.warn{background:color-mix(in srgb, var(--warn) 10%, var(--bg))}.note.warn>.label{color:var(--warn)}.demo{margin:40px calc(var(--gutter) * -1);border:1px solid var(--line);border-radius:18px;padding:24px;font-size:14px;line-height:1.6}.demo-head{justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:20px;display:flex}.demo-title{font-size:15px;font-weight:600}.demo-sub{color:var(--ink-3);font-size:13px}.demo.plain{background:var(--soft);border:0;border-radius:16px;margin-inline:0}.demo .demo-fallback{color:var(--ink-3);font-size:13px}@media (width<=640px){.demo{margin-inline:-8px;padding:18px 16px}}.video{aspect-ratio:16/9;background:var(--soft);border-radius:12px;margin:32px 0;position:relative;overflow:hidden}.video iframe{border:0;width:100%;height:100%;position:absolute;inset:0}.ui-btn{border:1px solid var(--line);background:var(--bg);height:44px;color:var(--ink);cursor:pointer;border-radius:10px;padding:0 18px;font-size:14px;transition:border-color .15s,opacity .15s}.ui-btn:hover{border-color:var(--ink-3)}.ui-btn.primary{background:var(--ink);border-color:var(--ink);color:var(--bg)}.ui-btn.primary:hover{opacity:.88}.ui-btn:disabled{opacity:.4;cursor:not-allowed}.ui-row{flex-wrap:wrap;gap:8px;display:flex}.ui-seg{background:var(--soft);border-radius:10px;padding:3px;display:inline-flex}.ui-seg button{height:36px;color:var(--ink-2);cursor:pointer;background:0 0;border:0;border-radius:8px;padding:0 14px;font-size:13px}.ui-seg button[aria-pressed=true]{background:var(--bg);color:var(--ink);box-shadow:0 1px 2px #00000014, 0 0 0 1px var(--line)}.ui-slider{display:block}.ui-slider .head{color:var(--ink-2);justify-content:space-between;align-items:baseline;display:flex}.ui-slider .value{font-family:var(--font-mono);color:var(--ink);font-size:20px;font-weight:500}.ui-slider input{width:100%;height:28px;accent-color:var(--accent);margin:6px 0 0}.ui-meter .head{color:var(--ink-2);justify-content:space-between;font-size:13px;display:flex}.ui-meter .head span:last-child{font-family:var(--font-mono)}.ui-meter .track{background:var(--line);border-radius:3px;height:6px;margin-top:8px;overflow:hidden}.ui-meter .fill{background:var(--accent);border-radius:3px;height:100%;transition:width .2s}.ui-log{border-top:1px solid var(--line)}.ui-log .r{border-bottom:1px solid var(--line);align-items:baseline;gap:12px;padding:10px 0;display:grid}.ui-log .r.h{color:var(--ink-3);font-size:12px}.ui-hatch{background-image:repeating-linear-gradient(135deg, var(--soft) 0 6px, transparent 6px 12px)}.ui-blur{filter:blur(4px);user-select:none}.ok{color:var(--ok)}.warn{color:var(--warn)}@media (prefers-reduced-motion:reduce){*,:before,:after{transition:none!important;animation:none!important}}
