learn-anything-cli 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -95,6 +95,7 @@ program
95
95
  .command('serve [path]')
96
96
  .description(m.cli.serveCommandDescription)
97
97
  .option('--port <number>', m.cli.portOption, parseInt)
98
+ .option('--strict-port', m.cli.strictPortOption)
98
99
  .option('--no-open', m.cli.noOpenOption)
99
100
  .option('--lang <locale>', m.cli.langOption)
100
101
  .action(async (targetPath = '.', options) => {
@@ -105,6 +106,7 @@ program
105
106
  await executeServe({
106
107
  targetPath,
107
108
  port: options?.port,
109
+ strictPort: options?.strictPort,
108
110
  open: options?.open,
109
111
  locale: cliLocale,
110
112
  });
@@ -2,6 +2,7 @@ import type { SupportedLocale } from '../i18n/types.js';
2
2
  export interface ServeOptions {
3
3
  targetPath?: string;
4
4
  port?: number;
5
+ strictPort?: boolean;
5
6
  open?: boolean;
6
7
  locale?: SupportedLocale;
7
8
  }
@@ -5,6 +5,7 @@ import * as fs from 'fs';
5
5
  import { createRequire } from 'module';
6
6
  import { LEARN_DIR } from '../core/config.js';
7
7
  import { getMessages } from '../i18n/index.js';
8
+ import { DEFAULT_PORT, findFreePort, isPortFree } from '../utils/port.js';
8
9
  export async function executeServe(options) {
9
10
  const locale = options.locale ?? 'en';
10
11
  const msg = getMessages(locale);
@@ -27,7 +28,29 @@ export async function executeServe(options) {
27
28
  console.log(chalk.cyan(m.startingServer));
28
29
  const require = createRequire(import.meta.url);
29
30
  const siteDistDir = path.join(path.dirname(require.resolve('../../package.json')), 'site-dist');
30
- const port = options.port ?? 24278;
31
+ const requestedPort = options.port ?? DEFAULT_PORT;
32
+ let port;
33
+ if (options.strictPort) {
34
+ // Honour the exact port; surface a clear error if it is taken.
35
+ if (!(await isPortFree(requestedPort))) {
36
+ console.error(chalk.red(m.portInUse(requestedPort)));
37
+ process.exit(1);
38
+ }
39
+ port = requestedPort;
40
+ }
41
+ else {
42
+ try {
43
+ port = await findFreePort(requestedPort);
44
+ }
45
+ catch {
46
+ const endPort = requestedPort + 50 - 1;
47
+ console.error(chalk.red(m.portRangeExhausted(requestedPort, endPort)));
48
+ process.exit(1);
49
+ }
50
+ if (port !== requestedPort) {
51
+ console.log(chalk.yellow(m.portSwitched(requestedPort, port)));
52
+ }
53
+ }
31
54
  if (!fs.existsSync(path.join(siteDistDir, 'serve.mjs'))) {
32
55
  console.error(chalk.red(m.siteNotBuilt));
33
56
  process.exit(1);
@@ -12,6 +12,7 @@ export const en = {
12
12
  forceOption: 'Skip confirmation prompt',
13
13
  langOption: 'Display language: zh-CN or en (default: system locale)',
14
14
  portOption: 'Port for the dev server (default: 24278)',
15
+ strictPortOption: 'Use the exact port from --port; do not auto-pick a free one when busy',
15
16
  noOpenOption: 'Do not open browser automatically',
16
17
  serveCommandDescription: 'Start a local site to visualize learning progress',
17
18
  serveHint: 'Run npx learn-anything serve to view your learning progress in browser',
@@ -36,6 +37,8 @@ export const en = {
36
37
  startingServer: 'Starting server...',
37
38
  siteReady: (url) => `Site ready at ${url}`,
38
39
  portInUse: (port) => `Port ${port} is already in use. Try a different port with --port option.`,
40
+ portSwitched: (from, to) => `Port ${from} is already in use — switching to port ${to}.`,
41
+ portRangeExhausted: (start, end) => `No free port found in range ${start}-${end}. Specify one manually with --port.`,
39
42
  emptyTopics: 'No learning topics found in .learn/topics/. Start learning with /learn:topic.',
40
43
  serverStopped: 'Server stopped.',
41
44
  siteNotBuilt: 'Site files not found. Please reinstall the package or run the build step.',
@@ -12,6 +12,7 @@ export const zhCN = {
12
12
  forceOption: '跳过确认提示',
13
13
  langOption: '界面语言:zh-CN 或 en(默认读取系统语言设置)',
14
14
  portOption: '开发服务器端口(默认:24278)',
15
+ strictPortOption: '严格使用 --port 指定的端口,被占用时不自动寻找空闲端口',
15
16
  noOpenOption: '不自动打开浏览器',
16
17
  serveCommandDescription: '启动本地站点以可视化学习进度',
17
18
  serveHint: '运行 npx learn-anything serve 在浏览器中查看学习进度',
@@ -36,6 +37,8 @@ export const zhCN = {
36
37
  startingServer: '正在启动服务器...',
37
38
  siteReady: (url) => `站点已就绪: ${url}`,
38
39
  portInUse: (port) => `端口 ${port} 已被占用。请使用 --port 选项指定其他端口。`,
40
+ portSwitched: (from, to) => `端口 ${from} 已被占用 —— 自动切换到端口 ${to}。`,
41
+ portRangeExhausted: (start, end) => `在 ${start}-${end} 范围内未找到可用端口。请使用 --port 手动指定。`,
39
42
  emptyTopics: '.learn/topics/ 中未找到学习主题。使用 /learn:topic 开始学习。',
40
43
  serverStopped: '服务器已停止。',
41
44
  siteNotBuilt: '未找到站点文件。请重新安装包或运行构建步骤。',
@@ -3,6 +3,8 @@ export interface ServeMessages {
3
3
  startingServer: string;
4
4
  siteReady: (url: string) => string;
5
5
  portInUse: (port: number) => string;
6
+ portSwitched: (from: number, to: number) => string;
7
+ portRangeExhausted: (start: number, end: number) => string;
6
8
  emptyTopics: string;
7
9
  serverStopped: string;
8
10
  siteNotBuilt: string;
@@ -20,6 +22,7 @@ export interface CLIMessages {
20
22
  forceOption: string;
21
23
  langOption: string;
22
24
  portOption: string;
25
+ strictPortOption: string;
23
26
  noOpenOption: string;
24
27
  serveCommandDescription: string;
25
28
  serveHint: string;
@@ -0,0 +1,17 @@
1
+ export declare const DEFAULT_PORT = 24278;
2
+ export declare const DEFAULT_MAX_ATTEMPTS = 50;
3
+ /**
4
+ * Test whether a TCP port is free to bind.
5
+ *
6
+ * Probes without binding a specific host so the check matches the behaviour of
7
+ * `server.listen(port)` used by the dev server (which listens on the wildcard
8
+ * address). The probe socket is unreffed so it never keeps the process alive.
9
+ */
10
+ export declare function isPortFree(port: number): Promise<boolean>;
11
+ /**
12
+ * Find the first free port starting from `startPort`, incrementing one at a
13
+ * time up to `maxAttempts` (inclusive of the start port). Throws when the
14
+ * whole range is occupied.
15
+ */
16
+ export declare function findFreePort(startPort: number, maxAttempts?: number): Promise<number>;
17
+ //# sourceMappingURL=port.d.ts.map
@@ -0,0 +1,49 @@
1
+ import { createServer } from 'node:net';
2
+ export const DEFAULT_PORT = 24278;
3
+ export const DEFAULT_MAX_ATTEMPTS = 50;
4
+ /**
5
+ * Test whether a TCP port is free to bind.
6
+ *
7
+ * Probes without binding a specific host so the check matches the behaviour of
8
+ * `server.listen(port)` used by the dev server (which listens on the wildcard
9
+ * address). The probe socket is unreffed so it never keeps the process alive.
10
+ */
11
+ export function isPortFree(port) {
12
+ return new Promise((resolve) => {
13
+ let settled = false;
14
+ const probe = createServer();
15
+ probe.unref();
16
+ const done = (result) => {
17
+ if (settled)
18
+ return;
19
+ settled = true;
20
+ probe.removeAllListeners();
21
+ resolve(result);
22
+ };
23
+ probe.once('error', () => {
24
+ // EADDRINUSE / EACCES / permission issues → port unavailable.
25
+ done(false);
26
+ });
27
+ probe.once('listening', () => {
28
+ // Successfully bound — close and hand the port back.
29
+ probe.close(() => done(true));
30
+ });
31
+ probe.listen(port);
32
+ });
33
+ }
34
+ /**
35
+ * Find the first free port starting from `startPort`, incrementing one at a
36
+ * time up to `maxAttempts` (inclusive of the start port). Throws when the
37
+ * whole range is occupied.
38
+ */
39
+ export async function findFreePort(startPort, maxAttempts = DEFAULT_MAX_ATTEMPTS) {
40
+ for (let offset = 0; offset < maxAttempts; offset++) {
41
+ const port = startPort + offset;
42
+ if (await isPortFree(port)) {
43
+ return port;
44
+ }
45
+ }
46
+ const endPort = startPort + maxAttempts - 1;
47
+ throw new Error(`No free port found in range ${startPort}-${endPort}`);
48
+ }
49
+ //# sourceMappingURL=port.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "learn-anything-cli",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "AI-powered recursive learning system with Socratic method and TDD practice",
5
5
  "keywords": [
6
6
  "learn-anything-cli",
@@ -1 +1 @@
1
- import{d as u,u as m,c as n,a as s,t,b as a,e as x,F as _,r as h,f as p,o as l,n as f,g,l as b}from"./index-VhcS_S3t.js";const v={class:"w-full"},y={class:"mb-4"},k={key:0,class:"text-sm text-text-3 mb-10"},C={key:1,class:"flex flex-col items-center justify-center py-24 text-center"},w={class:"text-sm font-medium text-text-2 mb-2"},T={class:"text-xs text-text-3 max-w-md"},B={key:2,class:"grid grid-cols-[repeat(auto-fill,minmax(320px,1fr))] gap-4"},$=["onClick"],D={class:"text-base font-semibold text-text-1 leading-snug mb-3"},F={class:"text-[13px] text-text-2 leading-relaxed"},L={class:"mt-4 flex items-center gap-3"},N={class:"flex-1 h-1 bg-(--color-divider) rounded-full overflow-hidden"},S={class:"text-xs font-semibold tabular-nums text-text-2"},E=u({__name:"Dashboard",setup(V){const c=g(),{t:o}=m(),r=p(()=>b());function i(d){c.push(`/topics/${d}`)}return(d,j)=>(l(),n("div",v,[s("h1",y,t(a(o)("dashboard.title")),1),r.value.length>0?(l(),n("p",k,t(r.value.length)+" "+t(r.value.length===1?"topic":"topics"),1)):x("",!0),r.value.length===0?(l(),n("div",C,[s("p",w,t(a(o)("dashboard.noTopics")),1),s("p",T,t(a(o)("dashboard.startLearning")),1)])):(l(),n("div",B,[(l(!0),n(_,null,h(r.value,e=>(l(),n("button",{key:e.slug,class:"text-left bg-(--color-bg-soft) rounded-xl border border-(--color-divider) p-6 hover:border-brand-2 transition-colors duration-150 cursor-pointer",onClick:z=>i(e.slug)},[s("h3",D,t(e.name),1),s("p",F,t(e.domainCount)+" "+t(a(o)("topic.domains"))+" · "+t(e.totalConcepts)+" "+t(a(o)("topic.concepts"))+" · "+t(e.masteredCount)+"/"+t(e.totalConcepts)+" "+t(a(o)("topic.mastered")),1),s("div",L,[s("div",N,[s("div",{class:"h-full rounded-full bg-brand-2 transition-all duration-500",style:f({width:`${e.percentage}%`})},null,4)]),s("span",S,t(e.percentage)+"% ",1)])],8,$))),128))]))]))}});export{E as default};
1
+ import{d as u,u as m,c as n,a as s,t,b as a,e as x,F as _,r as h,f as p,o as l,n as f,g,l as b}from"./index-C_Tvzi-T.js";const v={class:"w-full"},y={class:"mb-4"},k={key:0,class:"text-sm text-text-3 mb-10"},C={key:1,class:"flex flex-col items-center justify-center py-24 text-center"},w={class:"text-sm font-medium text-text-2 mb-2"},T={class:"text-xs text-text-3 max-w-md"},B={key:2,class:"grid grid-cols-[repeat(auto-fill,minmax(320px,1fr))] gap-4"},$=["onClick"],D={class:"text-base font-semibold text-text-1 leading-snug mb-3"},F={class:"text-[13px] text-text-2 leading-relaxed"},L={class:"mt-4 flex items-center gap-3"},N={class:"flex-1 h-1 bg-(--color-divider) rounded-full overflow-hidden"},S={class:"text-xs font-semibold tabular-nums text-text-2"},E=u({__name:"Dashboard",setup(V){const c=g(),{t:o}=m(),r=p(()=>b());function i(d){c.push(`/topics/${d}`)}return(d,j)=>(l(),n("div",v,[s("h1",y,t(a(o)("dashboard.title")),1),r.value.length>0?(l(),n("p",k,t(r.value.length)+" "+t(r.value.length===1?"topic":"topics"),1)):x("",!0),r.value.length===0?(l(),n("div",C,[s("p",w,t(a(o)("dashboard.noTopics")),1),s("p",T,t(a(o)("dashboard.startLearning")),1)])):(l(),n("div",B,[(l(!0),n(_,null,h(r.value,e=>(l(),n("button",{key:e.slug,class:"text-left bg-(--color-bg-soft) rounded-xl border border-(--color-divider) p-6 hover:border-brand-2 transition-colors duration-150 cursor-pointer",onClick:z=>i(e.slug)},[s("h3",D,t(e.name),1),s("p",F,t(e.domainCount)+" "+t(a(o)("topic.domains"))+" · "+t(e.totalConcepts)+" "+t(a(o)("topic.concepts"))+" · "+t(e.masteredCount)+"/"+t(e.totalConcepts)+" "+t(a(o)("topic.mastered")),1),s("div",L,[s("div",N,[s("div",{class:"h-full rounded-full bg-brand-2 transition-all duration-500",style:f({width:`${e.percentage}%`})},null,4)]),s("span",S,t(e.percentage)+"% ",1)])],8,$))),128))]))]))}});export{E as default};
@@ -0,0 +1 @@
1
+ import{d as _,u as k,c as f,a as n,t as g,b as h,F as M,r as I,e as L,o as c,w as N,n as S,h as B,i as E,j as x,k as j,m as F,p as H,q as b,f as v,s as T,v as V,x as R,y as z,z as w,A,B as D}from"./index-C_Tvzi-T.js";const q={key:0,class:"toc-nav","aria-label":"Table of contents"},K={class:"mb-3 text-sm font-semibold text-text-1"},O={class:"border-l border-divider"},P=["href","onClick"],U=_({__name:"TableOfContents",props:{headings:{},activeId:{}},emits:["navigate"],setup(i,{emit:e}){const a=e,{t:d}=k();return(s,t)=>i.headings.length?(c(),f("nav",q,[n("p",K,g(h(d)("toc.title")),1),n("ul",O,[(c(!0),f(M,null,I(i.headings,o=>(c(),f("li",{key:o.id},[n("a",{href:`#${o.id}`,class:B(["block border-l-2 -ml-px py-1 pr-2 text-[13px] leading-6 transition-colors truncate",o.id===i.activeId?"border-brand-2 text-brand-2 font-medium":"border-transparent text-text-3 hover:text-text-1"]),style:S({paddingLeft:`${(o.level-2)*12+12}px`}),onClick:N(l=>a("navigate",o.id),["prevent"])},g(o.text),15,P)]))),128))])])):L("",!0)}});function G(i){const e=x([]),a=x(""),d=x(!1);let s=null,t=null;function o(){const r=i.value;if(!r){e.value=[];return}const m=Array.from(r.querySelectorAll("h2[id], h3[id]"));e.value=m.map(u=>{var p;return{id:u.id,text:((p=u.textContent)==null?void 0:p.replace(/^#\s*/,"").trim())??"",level:Number(u.tagName.substring(1))}}),s==null||s.disconnect(),m.length!==0&&(s=new IntersectionObserver(u=>{if(d.value)return;const p=u.filter(y=>y.isIntersecting);p.length!==0&&(p.sort((y,C)=>y.boundingClientRect.top-C.boundingClientRect.top),a.value=p[0].target.id)},{rootMargin:"-80px 0px -70% 0px"}),m.forEach(u=>s.observe(u)))}function l(r){const m=document.getElementById(r);if(!m)return;m.scrollIntoView({behavior:"smooth",block:"start"}),a.value=r,d.value=!0,t&&clearTimeout(t);const u=()=>{t&&clearTimeout(t),t=setTimeout(()=>{d.value=!1,window.removeEventListener("scroll",u),t=null},150)};window.addEventListener("scroll",u,{passive:!0}),typeof history<"u"&&history.replaceState(null,"",`#${r}`)}return E(()=>{s==null||s.disconnect(),t&&clearTimeout(t)}),{headings:e,activeId:a,refresh:o,scrollTo:l}}const J={class:"xl:flex xl:justify-center xl:gap-8"},Q=["innerHTML"],W={class:"hidden shrink-0 xl:block w-48 2xl:w-64"},X={class:"sticky top-20 max-h-[calc(100vh-6rem)] overflow-y-auto"},$=_({__name:"TocLayout",props:{html:{}},setup(i){const e=i,a=x(),{headings:d,activeId:s,refresh:t,scrollTo:o}=G(a);return j(()=>e.html,()=>H(()=>t()),{immediate:!0}),(l,r)=>(c(),f("div",J,[n("article",{ref_key:"contentRef",ref:a,class:"prose-content xl:mx-0! xl:min-w-0 xl:flex-1",innerHTML:i.html},null,8,Q),n("aside",W,[n("div",X,[F(U,{headings:h(d),"active-id":h(s),onNavigate:h(o)},null,8,["headings","active-id","onNavigate"])])])]))}}),Y={class:"h-full"},Z={key:0,class:"flex items-center justify-center h-full min-h-75 text-sm text-text-3"},ee={key:1,class:"prose-content space-y-3","aria-hidden":"true"},te={key:3,class:"prose-content rounded-lg overflow-hidden bg-(--color-bg-alt)"},ne={class:"flex items-center justify-between px-5 py-2 bg-transparent"},se={class:"text-xs text-text-3 font-mono"},oe={class:"m-0! p-0! bg-transparent! text-left overflow-x-auto"},le=["innerHTML"],ie=_({__name:"ContentViewer",props:{file:{}},setup(i){const e=i,a=v(()=>e.file&&e.file.path.split("/").pop()||""),d=v(()=>R(a.value)),s=v(()=>{var l;return((l=e.file)==null?void 0:l.content)!==void 0}),t=v(()=>{var l;return((l=e.file)==null?void 0:l.content)===void 0?"":e.file.type==="markdown"?T(e.file.content):V(e.file.content,d.value)}),o=v(()=>{var l;return((l=e.file)==null?void 0:l.type)==="markdown"});return(l,r)=>(c(),f("div",Y,[i.file?s.value?o.value?(c(),b($,{key:2,html:t.value},null,8,["html"])):(c(),f("div",te,[n("div",ne,[n("span",se,g(a.value),1)]),n("pre",oe,[n("code",{class:"block px-6! py-5! leading-[1.7] font-mono text-[0.875em] text-text-2",innerHTML:t.value},null,8,le)])])):(c(),f("div",ee,[...r[0]||(r[0]=[n("div",{class:"h-5 w-2/3 rounded bg-(--color-divider)"},null,-1),n("div",{class:"h-3 w-full rounded bg-(--color-divider)"},null,-1),n("div",{class:"h-3 w-full rounded bg-(--color-divider)"},null,-1),n("div",{class:"h-3 w-4/5 rounded bg-(--color-divider)"},null,-1)])])):(c(),f("div",Z," Select a file from the sidebar to view its content "))]))}}),re={key:0,class:"flex flex-col items-center justify-center py-24 text-center"},ae={class:"text-base text-(--color-pencil)"},ce={key:1},ue=_({__name:"TopicPage",props:{slug:{}},setup(i){const e=i,{t:a}=k(),d=v(()=>(w(),A(e.slug))),s=v(()=>(w(),D(e.slug))),t=v(()=>{const r=s.value;return r?T(r):""}),o=z("topicSelectedFile",x(null)),l=v(()=>!o.value);return(r,m)=>d.value?(c(),f("div",ce,[l.value?(c(),b($,{key:0,html:t.value},null,8,["html"])):(c(),b(ie,{key:1,file:h(o)},null,8,["file"]))])):(c(),f("div",re,[m[0]||(m[0]=n("div",{class:"text-4xl mb-4 opacity-60 select-none"},"🔍",-1)),n("p",ae,g(h(a)("topic.notFound"))+": "+g(i.slug),1)]))}});export{ue as default};
@@ -0,0 +1 @@
1
+ .hljs{color:var(--color-ink);background:var(--color-code-bg)}.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-section,.hljs-link{color:#9b3eb0}.hljs-string,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-addition{color:#3d8b5e}.hljs-number,.hljs-meta .hljs-string,.hljs-regexp{color:#d94e34}.hljs-built_in,.hljs-title.function_,.hljs-type{color:#3b6fb6}.hljs-comment,.hljs-quote{color:var(--color-pencil);font-style:italic}.hljs-tag,.hljs-selector-class,.hljs-selector-id{color:#d94e34}.hljs-attr,.hljs-attribute{color:#d9a34a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-deletion{color:#d94e34;background:#d94e341a}.hljs-addition{color:#3d8b5e;background:#3d8b5e1a}.loading-overlay[data-v-58e3a895]{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;background-color:color-mix(in srgb,var(--color-bg) 72%,transparent);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}.loading-overlay__inner[data-v-58e3a895]{display:flex;flex-direction:column;align-items:center;gap:14px}.loading-overlay__label[data-v-58e3a895]{font-size:var(--text-sm);color:var(--color-pencil);letter-spacing:.01em}.loading-overlay__pen[data-v-58e3a895]{width:132px;height:auto;overflow:visible}.loading-overlay__pen line[data-v-58e3a895]{stroke:var(--color-divider);stroke-width:1;shape-rendering:crispEdges}.pen-stroke[data-v-58e3a895]{fill:none;stroke:var(--color-brand-2);stroke-width:8;stroke-linecap:round;stroke-dasharray:136;stroke-dashoffset:136;animation:la-pen-draw-58e3a895 1.2s cubic-bezier(.65,0,.35,1) infinite}@keyframes la-pen-draw-58e3a895{0%{stroke-dashoffset:136;opacity:0}10%{opacity:1}85%{stroke-dashoffset:0;opacity:1}to{stroke-dashoffset:0;opacity:0}}@keyframes la-nib-move-58e3a895{0%{offset-distance:0%;opacity:0}10%{opacity:1}85%{offset-distance:100%;opacity:1}to{offset-distance:100%;opacity:0}}.ld-fade-enter-active[data-v-58e3a895],.ld-fade-leave-active[data-v-58e3a895]{transition:opacity .18s ease}.ld-fade-enter-from[data-v-58e3a895],.ld-fade-leave-to[data-v-58e3a895]{opacity:0}@media(prefers-reduced-motion:reduce){.pen-stroke[data-v-58e3a895]{animation:none;stroke-dashoffset:0;opacity:1}}.truncate-start[data-v-2a1c829b]{direction:rtl;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}/*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:"Inter", ui-sans-serif, system-ui, -apple-system, "PingFang SC", "Noto Sans SC", "Microsoft YaHei", sans-serif;--font-mono:ui-monospace, "Cascadia Code", "Fira Code", "JetBrains Mono", "SF Mono", "Menlo", "Monaco", "Consolas", monospace;--color-black:#000;--spacing:.25rem;--container-md:28rem;--container-xl:36rem;--text-xs:.75rem;--text-xs--line-height:1rem;--text-sm:.875rem;--text-sm--line-height:1.25rem;--text-base:1rem;--text-base--line-height:1.75;--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-wide:.025em;--leading-snug:1.375;--leading-relaxed:1.625;--radius-sm:4px;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-text-1:#3c3c43;--color-text-2:#67676c;--color-text-3:#929295;--color-bg:#fff;--color-bg-alt:#f6f6f7;--color-bg-soft:#f6f6f7;--color-bg-elv:#fff;--color-border:#c2c2c4;--color-divider:#e2e2e3;--color-brand-1:#cc4428;--color-brand-2:#d94e34;--color-brand-soft:#d94e3424;--color-code-bg:var(--color-bg-alt)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.top-0{top:0}.top-4{top:calc(var(--spacing) * 4)}.top-20{top:calc(var(--spacing) * 20)}.bottom-0{bottom:0}.left-0{left:0}.left-4{left:calc(var(--spacing) * 4)}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-100{z-index:100}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.m-0\!{margin:0!important}.mx-6{margin-inline:calc(var(--spacing) * 6)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:var(--spacing)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-10{margin-bottom:calc(var(--spacing) * 10)}.-ml-3{margin-left:calc(var(--spacing) * -3)}.-ml-px{margin-left:-1px}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.h-1{height:var(--spacing)}.h-1\/2{height:50%}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-16{height:calc(var(--spacing) * 16)}.h-\[5px\]{height:5px}.h-full{height:100%}.max-h-\[50vh\]{max-height:50vh}.max-h-\[calc\(100vh-6rem\)\]{max-height:calc(100vh - 6rem)}.min-h-75{min-height:calc(var(--spacing) * 75)}.min-h-screen{min-height:100vh}.w-0\.5{width:calc(var(--spacing) * .5)}.w-1\/2{width:50%}.w-2\/3{width:66.6667%}.w-3{width:calc(var(--spacing) * 3)}.w-4{width:calc(var(--spacing) * 4)}.w-4\/5{width:80%}.w-5{width:calc(var(--spacing) * 5)}.w-48{width:calc(var(--spacing) * 48)}.w-68{width:calc(var(--spacing) * 68)}.w-\[5px\]{width:5px}.w-full{width:100%}.max-w-md{max-width:var(--container-md)}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0{--tw-translate-x:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.cursor-pointer{cursor:pointer}.grid-cols-\[repeat\(auto-fill\,minmax\(320px\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(320px,1fr))}.flex-col{flex-direction:column}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-px>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(1px * var(--tw-space-y-reverse));margin-block-end:calc(1px * calc(1 - var(--tw-space-y-reverse)))}.self-stretch{align-self:stretch}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-\(--color-divider\){border-color:var(--color-divider)}.border-brand-2{border-color:var(--color-brand-2)}.border-divider{border-color:var(--color-divider)}.border-transparent{border-color:#0000}.bg-\(--color-bg\){background-color:var(--color-bg)}.bg-\(--color-bg-alt\){background-color:var(--color-bg-alt)}.bg-\(--color-bg-elv\){background-color:var(--color-bg-elv)}.bg-\(--color-bg-soft\){background-color:var(--color-bg-soft)}.bg-\(--color-divider\){background-color:var(--color-divider)}.bg-\(--color-page\){background-color:var(--color-page)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black) 50%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black) 60%,transparent)}}.bg-brand-2{background-color:var(--color-brand-2)}.bg-brand-soft{background-color:var(--color-brand-soft)}.bg-text-3{background-color:var(--color-text-3)}.bg-transparent{background-color:#0000}.bg-transparent\!{background-color:#0000!important}.p-0\!{padding:0!important}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-6{padding:calc(var(--spacing) * 6)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-6\!{padding-inline:calc(var(--spacing) * 6)!important}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5\!{padding-block:calc(var(--spacing) * 5)!important}.py-6{padding-block:calc(var(--spacing) * 6)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-24{padding-block:calc(var(--spacing) * 24)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pt-\[12vh\]{padding-top:12vh}.pr-2{padding-right:calc(var(--spacing) * 2)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pl-4{padding-left:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.875em\]{font-size:.875em}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.leading-6{--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.leading-\[1\.7\]{--tw-leading:1.7;line-height:1.7}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.text-\(--color-ink\){color:var(--color-ink)}.text-\(--color-pencil\){color:var(--color-pencil)}.text-brand-2{color:var(--color-brand-2)}.text-text-1{color:var(--color-text-1)}.text-text-2{color:var(--color-text-2)}.text-text-3{color:var(--color-text-3)}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.placeholder-text-3::placeholder{color:var(--color-text-3)}.opacity-60{opacity:.6}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.hover\:border-border:hover{border-color:var(--color-border)}.hover\:border-brand-2:hover{border-color:var(--color-brand-2)}.hover\:bg-\(--color-bg-soft\):hover{background-color:var(--color-bg-soft)}.hover\:text-brand-1:hover{color:var(--color-brand-1)}.hover\:text-brand-2:hover{color:var(--color-brand-2)}.hover\:text-text-1:hover{color:var(--color-text-1)}.hover\:text-text-2:hover{color:var(--color-text-2)}}@media(min-width:64rem){.lg\:hidden{display:none}.lg\:translate-x-0{--tw-translate-x:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.lg\:px-10{padding-inline:calc(var(--spacing) * 10)}.lg\:pl-68{padding-left:calc(var(--spacing) * 68)}}@media(min-width:80rem){.xl\:mx-0\!{margin-inline:0!important}.xl\:block{display:block}.xl\:flex{display:flex}.xl\:min-w-0{min-width:0}.xl\:flex-1{flex:1}.xl\:justify-center{justify-content:center}.xl\:gap-8{gap:calc(var(--spacing) * 8)}}@media(min-width:96rem){.\32xl\:w-64{width:calc(var(--spacing) * 64)}}}.dark{--color-text-1:#dfdfd6;--color-text-2:#98989f;--color-text-3:#6a6a71;--color-text-1-rgb:223 223 214;--color-bg:#1b1b1f;--color-bg-alt:#161618;--color-bg-soft:#202127;--color-bg-elv:#202127;--color-border:#3c3f44;--color-divider:#2e2e32;--color-gutter:#000;--color-brand-1:#f0705a;--color-brand-2:#e85d44;--color-brand-3:#d94e34;--color-brand-soft:#e85d4429;--color-mastered:#3dd68c;--color-progress:#f9b44e}:root{--color-page:var(--color-bg);--color-ink:var(--color-text-1);--color-pencil:var(--color-text-2);--color-rule:var(--color-divider);--color-surface:var(--color-bg-soft);--color-surface-hover:var(--color-bg-alt);--color-accent:var(--color-brand-2);--color-accent-soft:var(--color-brand-soft)}body{font-family:var(--font-sans);font-weight:var(--font-weight-normal);font-size:var(--text-base);line-height:var(--text-base--line-height);color:var(--color-text-1);background-color:var(--color-bg);font-optical-sizing:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*{scrollbar-color:var(--color-border) transparent;scrollbar-width:thin}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:3px}::-webkit-scrollbar-thumb:hover{background-color:var(--color-text-3)}h1,h2,h3,h4,h5,h6{font-family:var(--font-sans);font-weight:var(--font-weight-semibold);color:var(--color-text-1);outline:none}h1{letter-spacing:-.02em;font-size:28px;line-height:40px}h2{letter-spacing:-.02em;font-size:24px;line-height:32px}h3{letter-spacing:-.01em;font-size:20px;line-height:28px}code{font-family:var(--font-mono);font-size:.875em}pre{font-family:var(--font-mono)}pre code{font-size:.875rem}a:not([class]){color:var(--color-accent);text-decoration:none}a:not([class]):hover{text-decoration:underline}:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px}::selection{background-color:var(--color-accent-soft)}.prose-content{max-width:56rem;color:var(--color-ink);margin:0 auto;line-height:28px}.prose-content h1,.prose-content h2,.prose-content h3,.prose-content h4,.prose-content h5,.prose-content h6{outline:none;font-weight:600;position:relative}.prose-content h1{letter-spacing:-.02em;font-size:28px;line-height:40px}.prose-content h2{border-top:1px solid var(--color-rule);letter-spacing:-.02em;margin:48px 0 16px;padding-top:24px;font-size:24px;line-height:32px}.prose-content h3{letter-spacing:-.01em;margin:32px 0 0;font-size:20px;line-height:28px}.prose-content h4{letter-spacing:-.01em;margin:24px 0 0;font-size:18px;line-height:24px}@media(min-width:768px){.prose-content h1{font-size:32px}}.prose-content :is(h1,h2,h3,h4,h5,h6){scroll-margin-top:2rem}.prose-content .header-anchor{opacity:0;margin-left:-.87em;font-weight:500;text-decoration:none;transition:opacity .25s;position:absolute;left:0}.prose-content :is(h1,h2,h3,h4,h5,h6):hover .header-anchor{opacity:1}.prose-content p,.prose-content img,.prose-content summary{margin:16px 0}.prose-content p{line-height:28px}.prose-content strong{font-weight:600}.prose-content a{color:var(--color-accent);text-underline-offset:2px;font-weight:500;text-decoration:underline;transition:color .25s}.prose-content a:hover{color:var(--color-ink)}.prose-content blockquote{border-left:2px solid var(--color-rule);color:var(--color-pencil);margin:16px 0;padding-left:16px;transition:border-color .5s}.prose-content blockquote>p{margin:0;font-size:16px}.prose-content ul,.prose-content ol{margin:16px 0;padding-left:1.25rem}.prose-content ul{list-style:outside}.prose-content ol{list-style:decimal}.prose-content li+li{margin-top:8px}.prose-content li>ol,.prose-content li>ul{margin:8px 0 0}.prose-content hr{border:none;border-top:1px solid var(--color-rule);margin:16px 0}.prose-content table{border-collapse:collapse;margin:20px 0;font-size:14px;display:block;overflow-x:auto}.prose-content tr{background-color:var(--color-page);border-top:1px solid var(--color-rule)}.prose-content tr:nth-child(2n){background-color:var(--color-surface)}.prose-content th,.prose-content td{border:1px solid var(--color-rule);padding:8px 16px}.prose-content th{text-align:left;color:var(--color-pencil);background-color:var(--color-surface);font-size:14px;font-weight:600}.prose-content td{font-size:14px}.prose-content :not(pre,h1,h2,h3,h4,h5,h6)>code{color:var(--color-accent);font-size:.875em}.prose-content :not(pre)>code{background-color:var(--color-code-bg);font-family:var(--font-mono);border-radius:4px;padding:3px 6px;transition:color .25s,background-color .5s}.prose-content a>code{color:var(--color-accent)}.prose-content a:hover>code{color:var(--color-ink)}.prose-content h1>code,.prose-content h2>code,.prose-content h3>code,.prose-content h4>code{font-size:.9em}.prose-content div[class*=language-],.prose-content pre:has(code){background-color:var(--color-code-bg);margin:16px -24px;transition:background-color .5s;position:relative;overflow-x:auto}@media(min-width:640px){.prose-content div[class*=language-],.prose-content pre:has(code){border-radius:8px;margin:16px 0}}.prose-content [class*=language-] pre,.prose-content [class*=language-] code,.prose-content pre:has(code){-moz-tab-size:4;tab-size:4}.prose-content [class*=language-] pre,.prose-content pre:has(code){z-index:1;text-align:left;background:0 0;margin:0;padding:20px 0;position:relative;overflow-x:auto}.prose-content [class*=language-] code,.prose-content pre:has(code)>code{width:fit-content;min-width:100%;color:var(--color-ink);font-size:.875em;line-height:1.7;font-family:var(--font-mono);background:0 0;padding:0 24px;transition:color .5s;display:block}.prose-content>:first-child{margin-top:0}.prose-content>:last-child{margin-bottom:0}@media(prefers-reduced-motion:reduce){*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}