specleaf 0.0.0-stage → 1.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SpecLeaf contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,235 @@
1
- # Temporary Holding Version
1
+ # SpecLeaf
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 把 OpenAPI 契约变成可离线阅读的单页文档。
4
+
5
+ 把本地 OpenAPI **3.0 / 3.1 YAML 或 JSON 文件或模块目录**转成一个可离线阅读的 HTML 文件。各模块保留独立契约,左侧目录按模块分组展示整个项目的接口。界面采用浅紫色主题,提供左侧接口目录、正文和右侧页内目录;窄屏使用目录抽屉。
6
+
7
+ ## npm 用户用法
8
+
9
+ 需要 Node.js **22.19.0+** 及 npm。模块目录与全项目分组浏览需要 SpecLeaf **1.1.0+**:
10
+
11
+ ```bash
12
+ # 临时运行
13
+ npx specleaf ./openapi.yaml -o ./api.html
14
+
15
+ # 全局安装
16
+ npm install -g specleaf
17
+ specleaf ./openapi.yaml
18
+
19
+ # 项目内使用
20
+ npm install -D specleaf
21
+ npx specleaf ./openapi.yaml
22
+ ```
23
+
24
+ 安装包已包含编译后的 CLI 和界面资源。用户安装与运行均不需要 Vite、React、TypeScript 或前端构建步骤,支持 `--ignore-scripts` 安装。
25
+
26
+ ## 生成单个 HTML
27
+
28
+ 以下命令用于已经安装的 CLI:
29
+
30
+ ```bash
31
+ specleaf ./openapi.yaml
32
+ specleaf ./openapi.json -o ./output/api.html
33
+ specleaf ./docs/apis/management -o ./management.html
34
+ specleaf "/path/中文 目录/openapi.yaml" --output "/path/输出/API 文档.html"
35
+ specleaf --help
36
+ specleaf --version
37
+ ```
38
+
39
+ 默认输出调用目录中的 `openapi.html`。输入和输出路径均相对**调用目录**解析;引用文件相对包含 `$ref` 的文件解析。输出目录不存在时会创建。支持 `-o / --output`、`-h / --help`、`-v / --version`,`--` 后的参数按文件路径处理。
40
+
41
+ 项目内也可通过 npm scripts 调用:
42
+
43
+ ```json
44
+ {
45
+ "scripts": {
46
+ "docs": "specleaf ./openapi.yaml -o ./api.html"
47
+ }
48
+ }
49
+ ```
50
+
51
+ 在项目目录运行 `npm run docs` 即可生成。
52
+
53
+ 生成成功后,**只需复制这个 HTML 文件**。脚本、样式、SVG 图标和合并后的契约均已内嵌,不需要 Node.js、源契约、旁边的资源目录或 API 服务。
54
+
55
+ - **双击打开**:在现代浏览器中直接打开 HTML(`file://`),断网也能搜索、导航、切换示例和导出契约。
56
+ - **静态托管**:把 HTML 放到任意静态服务器。可重命名为 `index.html`,部署到根目录或 `/reference/` 等子目录;目录 URL 保留末尾 `/`。接口链接采用 Hash,无需配置路由回退。
57
+ - 页面不发送接口请求。Markdown 图片显示为可点击链接,外部示例仅显示地址;生成和阅读均不自动下载图片或远程内容。生产页面还限制了自动联网资源加载。
58
+
59
+ ## 模块目录
60
+
61
+ 目录输入会递归发现准确命名的 `openapi.yaml`、`openapi.yml`、`openapi.json`,每个入口所在目录是一个模块。跳过隐藏目录、`node_modules`、`dist`、`build`、`coverage`,不递归跟随目录符号链接;其他文件只有被 `$ref` 引用时才会解析。忽略目录中的文件仍可被入口显式引用。
62
+
63
+ 例如,下面三个入口会生成一个 HTML,模块 ID 分别是 `.`、`merchant` 和 `merchant/orders`:
64
+
65
+ ```text
66
+ management/
67
+ openapi.yaml
68
+ merchant/
69
+ openapi.yml
70
+ orders/
71
+ openapi.json
72
+ ```
73
+
74
+ 模块 ID 是相对输入目录的路径,统一使用 `/`,按 ID 排序;默认打开第一个模块。集合标题取输入目录名,左侧目录按模块显示路径、契约标题和接口数量;各模块内按 tags 分组,默认展开全部接口,无需切换模块。目录只有一个模块时仍按模块分组。同目录多个入口、整个目录没有入口或任一模块解析失败,均以中文报错并停止生成;不含入口的中间目录无需创建契约。
75
+
76
+ 每个模块独立解析,保留各自的 OpenAPI 版本、服务地址、鉴权、tags 和引用作用域,支持共享引用、同名模型及同路径接口。缺少 tags 的接口归入“未分组”。目录搜索和方法筛选覆盖**全部模块**,可按模块路径、标题或接口关键词搜索。跨模块打开接口时保留搜索、筛选和分组展开状态;正文概览的统计和导出作用于当前模块,字段树、响应、媒体类型和示例等详情状态会重置。
77
+
78
+ 模块概览链接为 `#/module/<编码后的模块ID>/overview`,接口链接为 `#/module/<编码后的模块ID>/operation/<编码后的接口ID>`;每个 ID 整体通过 `encodeURIComponent` 编码,例如 `merchant/orders` 变成 `merchant%2Forders`。链接可复制、刷新和前进后退,未知模块或接口显示无效链接状态。单文件输入继续使用原来的 `#/overview` 和 `#/operation/<编码后的接口ID>`。
79
+
80
+ 导出得到当前模块合并后的 OpenAPI JSON,文件名为 `openapi-<编码后的模块ID>.json`;根模块为 `openapi-..json`。单文件仍导出 `openapi.json`。模块集合和所需资源全部内嵌,断网后也能浏览全部模块、搜索和导出。
81
+
82
+ ## 源码开发与默认构建
83
+
84
+ ```bash
85
+ git clone https://github.com/SuperPx-CN/specleaf.git
86
+ cd specleaf
87
+ npm ci
88
+ npm run generate -- ./examples/openapi.yaml
89
+ npm run generate -- ./examples/minimal.json -o ./output/api.html
90
+ npm run generate -- ~/coin-operated/backend/docs/apis/management -o ./management.html
91
+ ```
92
+
93
+ 示例、构建脚本和测试均包含在源码中。`generate` 自动准备预编译资源,再执行源码 CLI。从其他目录调用时可用 `--prefix` 指定源码目录,输入和输出仍相对调用目录解析:
94
+
95
+ ```bash
96
+ npm --prefix /path/to/specleaf run generate -- ./openapi.yaml -o ./api.html
97
+ ```
98
+
99
+ 也可以先在源码目录执行 `npm run build:package`,再直接运行 `node /path/to/specleaf/build/cli.ts ./openapi.yaml` 或 `node /path/to/specleaf/lib/cli.js ./openapi.yaml`,路径相对当前目录。
100
+
101
+ ```bash
102
+ npm run dev
103
+ npm run build
104
+ npm run preview
105
+ ```
106
+
107
+ 默认入口为项目内的 `examples/openapi.yaml`,包含跨文件递归模型、组合类型、鉴权、参数和多媒体示例。`examples/minimal.json` 是独立的最小 JSON 示例。开发模式监听入口和跨文件引用;目录输入还监听模块入口新增、删除和重复入口修复,更新模块列表。解析失败时显示浏览器错误浮层,修复契约或补齐缺失引用后自动刷新。
108
+
109
+ `npm run build` 先检查 TypeScript、编译 CLI 和通用界面资源,再生成单文件 **`dist/index.html`**。`npm run preview` 用于本地预览。生成器不会清空输出所在目录;分发文档时只需复制本次生成的 HTML。
110
+
111
+ 开发和默认构建可通过 `OPENAPI_ENTRY` 更换入口。相对路径以本项目根目录为基准,支持绝对路径:
112
+
113
+ ```bash
114
+ OPENAPI_ENTRY=/absolute/path/to/openapi.yaml npm run dev
115
+ OPENAPI_ENTRY=/absolute/path/to/openapi.yaml npm run build
116
+ OPENAPI_ENTRY=/absolute/path/to/docs/apis/management npm run dev
117
+ OPENAPI_ENTRY=/absolute/path/to/docs/apis/management npm run build
118
+ ```
119
+
120
+ 转换命令 `generate` 使用明确传入的输入文件或目录,不依赖 `OPENAPI_ENTRY`。
121
+
122
+ ## 本地 tarball 验收
123
+
124
+ 发布前可直接从源码构建、打包和安装,以下命令不会发布到 npm:
125
+
126
+ ```bash
127
+ # 在源码目录中执行;prepack 自动检查类型并执行 build:package
128
+ npm pack
129
+
130
+ # 在独立目录安装实际压缩包,不安装开发依赖,不运行安装脚本
131
+ mkdir ../specleaf-consumer
132
+ cd ../specleaf-consumer
133
+ npm init -y
134
+ npm install --omit=dev --ignore-scripts ../specleaf/specleaf-1.1.0.tgz
135
+ npm exec -- specleaf ../specleaf/examples/minimal.json -o ./api.html
136
+ npx specleaf --version
137
+ ```
138
+
139
+ 把上面的 `../specleaf` 替换为实际源码目录。`npm run test:package` 自动在临时独立目录执行真实 `npm pack`、生产依赖安装、npm scripts、npm exec、npx 临时安装和临时全局安装,再验收文件保护、错误退出与特殊字符。验收后自动删除临时目录,不修改系统全局安装。
140
+
141
+ `build:package` 只生成 `lib/cli.js` 和 `lib/assets/`;`files` 白名单仅分发这些产物、README、LICENSE 和 npm 必需的包元信息。公开接口为 `specleaf` CLI。
142
+
143
+ ## 阅读功能
144
+
145
+ - 站点名称、标题、版本与说明来自 `info`;保留原始 tag 名称和描述。按关键词、路径、operationId、说明或请求方法筛选;支持 `⌘/Ctrl + K` 搜索、Escape 关闭移动目录及键盘焦点管理。
146
+ - 使用方法和路径生成稳定 Hash,支持复制、刷新、前进和后退。右侧页内目录随滚动高亮;提供空契约、无结果和无效链接状态。
147
+ - 展示 Path / Query / Header / Cookie 参数、鉴权、响应状态码、响应头和扩展策略。操作参数覆盖同名同位置的路径参数。
148
+ - 接口目录用彩色圆点展示接口状态,并提供中文状态说明;详情页展示对应的中文徽标。
149
+ - 字段树保留递归引用、数组、空值、布尔 Schema、`allOf` / `oneOf` / `anyOf` 分支、必填及常用约束,最多展开 32 层。常用约束以简短中文展示,长度与数量范围合并;正则与原始 Schema 约束收在默认折叠的“详细校验规则”中,导出的契约保留完整规则。
150
+ - 请求与响应可切换媒体类型和多个**原始示例**。JSON、纯文本和 YAML 按原始值展示,无示例时明确提示;不根据 Schema 编造数据。
151
+ - 可复制接口路径、分享链接、示例和 cURL,导出合并后的 OpenAPI JSON。Clipboard API 不可用或拒绝访问时会尝试备用复制;仍失败则提供自动选中的文本供手动复制。
152
+
153
+ cURL 使用服务地址、参数、第一组鉴权方案和当前原始示例生成。使用前替换相对服务地址、参数和 `{token}` 等占位符,并遵循契约中的序列化规则。页面仅供只读阅读,不执行在线调试。
154
+
155
+ ## 接口状态
156
+
157
+ 在 **Operation 层级**使用 `x-api-status`,与 `summary` 同级:
158
+
159
+ ```yaml
160
+ paths:
161
+ /items:
162
+ get:
163
+ summary: 查询资源
164
+ x-api-status: released
165
+ responses:
166
+ '200':
167
+ description: 查询成功
168
+ ```
169
+
170
+ | 值 | 中文状态 | 颜色 |
171
+ | --- | --- | --- |
172
+ | `draft` | 草稿 | 灰色 |
173
+ | `developing` | 开发中 | 紫色 |
174
+ | `testing` | 测试中 | 蓝色 |
175
+ | `released` | 已发布 | 绿色 |
176
+ | `deprecated` | 已弃用 | 琥珀色 |
177
+
178
+ 当前 Operation 的标准字段 `deprecated: true` 优先显示“已弃用”,即使 `x-api-status` 是其他值,也只显示一个状态徽标。否则只识别表中的小写字符串;缺失、未知值、大小写不符或类型错误时均不显示状态标记。状态不从文档根级、路径或 tag 继承,也不映射其他工具的状态字段。
179
+
180
+ “操作策略”以“接口状态”为标题,保留 `x-api-status` 原字段名和值。状态解析只用于展示,导出的合并契约保留原值,不自动补写 `deprecated`。`x-design-status` 仍表示设计状态,在操作策略中展示;文档根级的 `x-contract-status` 仍用于概览中的契约状态说明,两者均不作为接口状态来源。
181
+
182
+ `examples/openapi.yaml` 演示五种状态,`examples/minimal.json` 演示未指定接口状态的契约。
183
+
184
+ ## 错误与已有文件保护
185
+
186
+ 缺少输入、未知参数、多余输入、版本不支持、解析或写入失败时,命令显示中文错误上下文并以非零状态退出。引用错误附带来源文件和 JSON Pointer;远程入口和远程 `$ref` 不受支持。
187
+
188
+ 生成器在内存中生成完整 HTML 后,写入目标同目录的临时文件,最后替换目标文件;失败不会覆盖已有产物。不允许输出覆盖任何模块入口或任何被引用文件(包含符号链接和硬链接别名),也不会清空输出目录。更换输出文件或修正错误后重新执行即可。
189
+
190
+ 源契约始终只读。支持范围为 OpenAPI 3.0 / 3.1 的 HTTP 接口阅读,不包含 Swagger 2.0、远程契约、在线调试、深色主题或图片打包。解析器不会代替完整的 OpenAPI / JSON Schema 语义校验。
191
+
192
+ ## 验证
193
+
194
+ ```bash
195
+ npm test
196
+ npm run typecheck
197
+ npm run build
198
+ npm run test:package
199
+
200
+ # 首次执行浏览器验收时安装 Chromium
201
+ npx playwright install chromium
202
+ npm run test:e2e
203
+ ```
204
+
205
+ 可以设置 `PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH` 使用本机 Chromium。浏览器测试读取构建后的 HTML,检查 HTTP 根目录、子目录、移动端、开发监听和错误恢复;另将唯一 HTML 复制到临时独立目录,通过 `file://` 断网验证搜索、导航、刷新、递归模型、示例切换、复制及导出,检查外部资源请求和运行时错误。接口状态验收覆盖目录与详情一致、弃用优先、无效值隐藏、移动端长标题与圆点尺寸,以及导出后扩展值不变。桌面与移动截图保存在 `test-results/`。
206
+
207
+ 单元及命令测试覆盖 YAML / JSON、跨文件及循环引用、中文空格路径、分组顺序与去重、未声明分组及未分组接口、参数和错误退出、已有产物保护、元数据及脚本闭合字符。全部测试仅使用项目内的通用示例、fixture 和测试时生成的临时文件,可直接在独立源码副本中运行上述验证流程。
208
+
209
+ 模块测试另覆盖三级目录、三种入口格式、目录忽略规则、重复及空目录、共享引用、同名模型、同路径接口与混合版本;浏览器验收覆盖全项目分组目录和搜索、跨模块详情隔离与状态重置、编码链接与历史导航、独立导出、移动布局、无源文件的断网使用,以及开发模式的模块增删、引用变化和错误恢复。tarball 安装后同样验收目录生成和文件保护。
210
+
211
+ CI 在 Linux、macOS 和 Windows 上分别使用 Node.js 22.19.0 与 24 运行单元测试、类型检查、构建和 tarball 安装验收;Linux 上另运行完整 Chromium 浏览器验收。
212
+
213
+ ## 源码
214
+
215
+ ```text
216
+ build/contract.ts 本地契约解析、模块发现、统一加载与错误上下文
217
+ build/openapi-plugin.ts 开发模式虚拟模块和引用监听
218
+ build/serialize.ts HTML JSON 数据块的安全序列化
219
+ build/package.ts 预编译 ESM CLI、通用 IIFE、CSS 和图标
220
+ build/generate.ts 读取包内资源、HTML 内嵌与原子写入
221
+ build/cli.ts specleaf 命令、帮助和版本
222
+ build/build.ts 默认生产构建
223
+ src/lib/openapi.ts 引用、接口、Schema、示例和 cURL 处理
224
+ src/lib/documentation.ts 模块集合类型、标题与模块路由
225
+ src/components.tsx 字段树、参数表、Markdown、示例与复制
226
+ src/App.tsx 目录、概览与接口详情
227
+ examples/ 独立 YAML、JSON 和跨文件模型示例
228
+ tests/ 单元、命令及浏览器测试
229
+ ```
230
+
231
+ 使用 [JSON Schema Ref Parser 的 bundle](https://apidevtools.com/json-schema-ref-parser/docs/ref-parser.html) 合并本地引用,保留内部指针以序列化递归模型;使用 [Vite library 构建选项](https://vite.dev/config/build-options.html#build-lib) 提前生成通用 IIFE。CLI 把安全转义的契约写入 `application/json` 数据块,预编译界面通过虚拟模块读取;所有资源内嵌到同一个 HTML。
232
+
233
+ ## 许可证
234
+
235
+ [MIT](./LICENSE),Copyright (c) 2026 SpecLeaf contributors。
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect width="40" height="40" rx="12" fill="#7357e8"/><path d="m18 11-8 9 8 9m4-18 8 9-8 9" stroke="white" stroke-width="3" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>
@@ -0,0 +1,2 @@
1
+ :root{color:#282936;font-synthesis:none;--purple:#7656dd;--purple-light:#f2edff;--muted:#9293a1;--border:#edeef2;--sidebar:274px;--header:66px;background:#fff;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;font-size:14px}*{box-sizing:border-box}body{margin:0}button,input,select{font:inherit}button,a,input,select{-webkit-tap-highlight-color:transparent}button{cursor:pointer}button:disabled{cursor:default;opacity:.5}button{color:inherit}a{color:var(--purple);text-decoration:none}button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,summary:focus-visible,pre:focus-visible{outline-offset:3px;outline:2px solid #9c83eb}button{background:0 0;border:0}button,select,a{touch-action:manipulation}svg{flex-shrink:0}code,kbd,pre{font-family:SFMono-Regular,Consolas,Liberation Mono,monospace}p{line-height:1.85}h1,h2,h3,p{margin-top:0}h1{letter-spacing:-.7px;font-size:32px;font-weight:650;line-height:1.4}h2{letter-spacing:-.3px;font-size:19px;font-weight:650}h3{font-size:14px;font-weight:600}::selection{background:#e5dafa}select{color:#5e5d6e;background:#fff;border:1px solid #e4e5eb;border-radius:6px;max-width:100%;padding:6px 25px 6px 10px;font-size:14px}summary{cursor:pointer;line-height:1.7}.muted{color:var(--muted)}.rotated{transform:rotate(90deg)}.icon-button{color:#9a9aa7;border-radius:5px;justify-content:center;align-items:center;padding:4px;display:inline-flex}.icon-button:hover{color:var(--purple);background:var(--purple-light)}.skip-link{background:var(--purple);color:#fff;z-index:100;padding:12px;position:fixed;top:-60px;left:12px}.skip-link:focus{top:8px}.topbar{height:var(--header);border-bottom:1px solid var(--border);z-index:30;background:#fffffffa;align-items:center;gap:50px;padding:0 27px;display:flex;position:fixed;top:0;left:0;right:0}.brand{color:#242330;white-space:nowrap;align-items:center;gap:10px;min-width:0;max-width:40%;font-size:18px;font-weight:650;display:flex}.brand-name{text-overflow:ellipsis;overflow:hidden}.brand-symbol{background:var(--purple);color:#fff;border-radius:10px;justify-content:center;align-items:center;width:33px;height:33px;display:flex;box-shadow:0 3px 8px #7357e825}.brand-divider{color:#d3d0dc;margin:0 13px;font-size:22px;font-weight:300}.brand-docs{color:#777582;letter-spacing:.4px;font-size:13px;font-weight:400}.top-nav{align-items:center;gap:30px;height:100%;display:flex}.top-nav>a{color:#5e5c6e;align-items:center;height:100%;font-size:13px;display:flex;position:relative}.top-nav>a.active{color:var(--purple);font-weight:600}.top-nav>a.active:after{content:"";background:var(--purple);height:2px;position:absolute;bottom:0;left:0;right:0}.top-nav>button{color:#898694;align-items:center;gap:7px;padding:6px;font-size:14px;display:flex}.top-nav>button:hover{color:var(--purple)}.header-right{align-items:center;gap:22px;margin-left:auto;display:flex}.version-pill{border:1px solid var(--border);color:#777785;white-space:nowrap;border-radius:5px;align-items:center;gap:7px;padding:5px 9px;font-family:Consolas,monospace;font-size:13px;display:flex}.version-pill>span,.status-dot{background:#59b292;border-radius:50%;flex-shrink:0;width:6px;height:6px;display:inline-block}.help-link{color:#9594a2;align-items:center;display:flex}.mobile-menu,.close-drawer,.drawer-backdrop{display:none}.sidebar{top:var(--header);width:var(--sidebar);border-right:1px solid var(--border);z-index:25;background:#fcfcfe;flex-direction:column;display:flex;position:fixed;bottom:0;left:0}.sidebar-tools{flex-shrink:0;padding:24px 17px 0}.search-scope{color:#92909e;margin:0 3px 8px;font-size:12px}.workspace-label{align-items:center;gap:10px;margin-bottom:23px;padding:0 5px;display:flex}.workspace-icon{color:#8265d4;background:#f0ecfc;border:1px solid #e9e2fa;border-radius:7px;justify-content:center;align-items:center;width:32px;height:32px;display:flex}.workspace-label>div{overflow-wrap:anywhere;flex-direction:column;gap:4px;min-width:0;display:flex}.workspace-label strong{letter-spacing:.3px;font-size:13px;font-weight:600}.workspace-label>div>span{color:#a0a0ae;letter-spacing:.6px;font-size:12px}.desktop-chevron{color:#aaa7b5;margin-left:auto}.search-box{color:#aaa8b5;background:#fff;border:1px solid #e6e6ec;border-radius:6px;align-items:center;gap:8px;height:36px;padding:0 9px;display:flex;box-shadow:0 2px 3px #25213e02}.search-box:focus-within{border-color:#b2a0e5;box-shadow:0 0 0 2px #7656dd0b}.search-box input{color:#4b485d;background:0 0;border:0;flex:1;width:100%;min-width:0;padding:0;font-size:13px;outline:none!important}.search-box input::placeholder{color:#a4a2ae}.search-box kbd{color:#a5a2b1;white-space:nowrap;border:1px solid #eeedf1;border-radius:3px;align-items:center;gap:2px;padding:2px 3px;font-size:11px;display:flex}.method-filter{color:#a3a0ad;align-items:center;gap:4px;padding:11px 3px 18px;display:flex}.method-filter select{color:#92909e;background:0 0;border:0;max-width:112px;padding:0 0 0 3px;font-size:12px}.method-filter>span{color:#a5a3b0;margin-left:auto;font-size:12px}.sidebar-scroll{scrollbar-width:thin;scrollbar-color:#dedbe7 transparent;overscroll-behavior:contain;flex:1;padding:0 13px 25px;overflow:auto}.module-group+.module-group{border-top:1px solid var(--border);margin-top:14px;padding-top:14px}.module-heading{color:#6b657b;border-radius:6px;align-items:center;gap:9px;margin-bottom:3px;padding:9px;display:flex}.module-heading:hover,.module-heading.current-module{color:var(--purple);background:#f0ecfa}.module-heading>svg{flex-shrink:0}.module-heading>span:first-of-type{flex:1;min-width:0}.module-heading strong{overflow-wrap:anywhere;font-size:13px;line-height:1.5;display:block}.module-heading small{color:#92909e;text-overflow:ellipsis;white-space:nowrap;margin-top:3px;font-size:11px;display:block;overflow:hidden}.module-group .group-toggle{min-height:32px;font-size:12px}.module-empty{color:#92909e;padding:8px 12px;font-size:12px}.overview-link{color:#777282;border-radius:5px;align-items:center;gap:10px;height:39px;padding:0 13px;font-size:14px;display:flex}.overview-link.selected{color:var(--purple);background:#eee8fa;font-weight:600}.overview-link>svg:last-child{width:12px;margin-left:auto}.nav-caption{color:#b1adbc;letter-spacing:.6px;justify-content:space-between;padding:25px 12px 13px;font-size:12px;display:flex}.nav-caption>span{color:#b9b5c2;letter-spacing:0;font-size:11px}.group-toggle{color:#6b657b;text-align:left;border-radius:5px;align-items:center;gap:7px;width:100%;min-height:39px;padding:5px 9px;font-size:14px;display:flex}.group-toggle:hover{background:#f2eff7}.group-toggle>svg{color:#a5a0b2}.group-toggle>svg:first-child{color:#b4aebf;transition:transform .15s}.group-count{color:#aaa5b8;margin-left:auto;font-family:Consolas,monospace;font-size:12px}.group-operations{margin:0 0 6px;padding:1px 0 3px}.operation-link{color:#80798e;border-radius:5px;align-items:center;gap:9px;min-height:35px;margin:2px 0;padding:6px 9px 6px 20px;font-size:13px;display:flex}.operation-link-title{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.operation-link:hover{background:#f2eff8}.operation-link.selected{color:#7656cc;background:#eee8fa;font-weight:500}.method{letter-spacing:-.2px;flex-shrink:0;min-width:35px;font-family:Consolas,SFMono-Regular,monospace;font-size:12px;font-weight:700;display:inline-block}.method-get{color:#35a37e}.method-post{color:#d4a02d}.method-patch{color:#9b70d5}.method-put{color:#518dcc}.method-delete{color:#e7777e}.method-head,.method-options,.method-trace{color:#7b89ad}.api-status-draft{--api-status-color:#626776;--api-status-background:#f0f1f4}.api-status-developing{--api-status-color:#7656cc;--api-status-background:#f2edff}.api-status-testing{--api-status-color:#326db0;--api-status-background:#edf4fc}.api-status-released{--api-status-color:#247a57;--api-status-background:#eaf6ef}.api-status-deprecated{--api-status-color:#966016;--api-status-background:#fcf3e3}.api-status-dot{background:var(--api-status-color);border-radius:50%;flex-shrink:0;width:6px;height:6px;margin-left:auto}.sidebar-footer{border-top:1px solid var(--border);color:#a29dab;white-space:nowrap;align-items:center;gap:6px;height:47px;padding:0 18px;font-size:11px;display:flex}.sidebar-footer>.status-dot{background:#ad9bd7;width:5px;height:5px}.sidebar-footer>span:last-child{color:#bbb6c4;margin-left:auto;font-size:10px}.search-empty{color:#8b8394;flex-direction:column;align-items:center;gap:10px;padding:40px 10px;font-size:13px;display:flex}.search-empty svg{color:#b8accb}.search-empty strong{color:#7c718d;font-weight:500}.search-empty button{color:var(--purple);margin-top:7px;font-size:13px}.page-shell{margin-left:var(--sidebar);padding-top:var(--header);max-width:1730px;display:flex}.page-shell main{outline:none;flex:1;min-width:0;max-width:1160px;padding:30px 55px 0}.breadcrumb{color:#96919e;overflow-wrap:anywhere;flex-wrap:wrap;align-items:center;gap:9px;margin-bottom:40px;font-size:12px;display:flex}.breadcrumb>span:last-child{color:#80768e}.breadcrumb svg{color:#c2bdca}.page-outline{border-left:1px solid var(--border);flex-direction:column;flex-shrink:0;align-self:flex-start;gap:2px;width:180px;margin-top:115px;margin-right:28px;padding:0 0 0 20px;font-size:13px;display:flex;position:sticky;top:106px}.page-outline>span{color:#5d546d;margin-bottom:14px;font-size:12px;font-weight:600}.page-outline>button{text-align:left;color:#94899f;padding:4px 0;font-size:12px;line-height:2.1;position:relative}.page-outline>button:hover,.page-outline>button.current{color:var(--purple)}.page-outline>button.current:before{content:"";background:var(--purple);width:2px;height:22px;position:absolute;top:4px;left:-21px}.outline-note{color:#9c90ae;background:#fcfaff;border:1px solid #eeeaf5;border-radius:7px;margin-top:37px;padding:14px 12px}.outline-note svg{color:#ac97d3;margin-bottom:10px;display:block}.outline-note strong{color:#8f7da7;font-size:12px;font-weight:500}.outline-note p{margin:7px 0 0;font-size:12px;line-height:1.8}.eyebrow{color:#9689aa;letter-spacing:1.2px;align-items:center;gap:8px;margin-bottom:17px;font-size:12px;font-weight:500;display:flex}.eyebrow>span:first-child:not(:last-child){background:#a58bdc;border-radius:50%;width:5px;height:5px}.eyebrow .hero-badge{letter-spacing:.4px;color:#a38bbd;background:#f6f3fb;border:1px solid #eee8f6;border-radius:4px;margin-left:4px;padding:3px 6px;font-family:inherit;font-size:11px}.overview-hero h1{color:#302c3b;letter-spacing:-1px;margin-bottom:14px;font-size:34px}.heading-mark{color:#9473d8;margin-left:3px}.hero-lead{color:#726b7e;letter-spacing:.2px;margin-bottom:17px;font-size:14px}.overview-hero>.markdown{color:#85808e;max-width:760px;font-size:13px;line-height:1.95}.hero-actions{align-items:center;gap:12px;margin:25px 0 32px;display:flex}.primary-button,.secondary-button{border-radius:6px;justify-content:center;align-items:center;gap:8px;padding:10px 14px;font-size:13px;font-weight:500;line-height:1.4;display:inline-flex}.primary-button{background:var(--purple);border:1px solid var(--purple);color:#fff;box-shadow:0 3px 5px #7656dd12}.primary-button:hover{background:#6546cd}.secondary-button{color:#81748f;background:#fff;border:1px solid #e6e1ed}.secondary-button:hover{background:#faf8fe}.hero-actions>span{color:#97909f;align-items:center;gap:5px;margin-left:3px;font-size:12px;display:flex}.hero-actions>span svg{color:#a7b5a7}.stats-grid{background:linear-gradient(120deg,#fdfcff,#fff);border:1px solid #ebe7f0;border-radius:8px;grid-template-columns:repeat(3,1fr);margin-bottom:39px;padding:23px 0;display:grid}.stats-grid>div{align-items:center;gap:15px;padding:0 26px;display:flex}.stats-grid>div+div{border-left:1px solid #ebe7f0}.stat-icon{border-radius:10px;justify-content:center;align-items:center;width:39px;height:39px;display:flex}.purple{color:#9878d7;background:#f3eefc}.blue{color:#7c9ace;background:#eef3fc}.green{color:#7cae9e;background:#edf7f2}.stats-grid>div>div{flex-direction:column;gap:4px;display:flex}.stats-grid strong{color:#4d445e;font-variant-numeric:tabular-nums;font-size:25px;font-weight:600;line-height:1.1}.stats-grid strong small{color:#8e879a;margin-left:6px;font-family:inherit;font-size:12px;font-weight:400}.stats-grid>div>div>span{color:#8c8598;letter-spacing:.4px;font-size:12px}.doc-section{min-width:0;margin-bottom:35px;scroll-margin-top:90px}.section-heading{flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:18px;display:flex}.section-heading h2{color:#38323f;margin:0;font-size:17px}.section-heading>span:last-child:not(.count-badge):not(.required){color:#9b94a7;margin-left:7px;font-size:12px}.count-badge{color:#ad98c5;background:#f4f0fa;border-radius:4px;padding:2px 6px;font-family:Consolas,monospace;font-size:12px;line-height:1.3;display:inline-block}.getting-started{border:1px solid #ebe7f0;border-radius:8px;grid-template-columns:1fr 1.05fr;display:grid;overflow:hidden}.start-steps{padding:24px 23px 7px}.start-steps>div{gap:13px;margin-bottom:20px;display:flex}.start-steps>div>span{color:#b19acb;background:#fbf8ff;border:1px solid #e8e0f3;border-radius:6px;flex-shrink:0;justify-content:center;align-items:center;width:26px;height:26px;font-family:Consolas,monospace;font-size:12px;display:flex}.start-steps strong{color:#645b71;font-size:13px;font-weight:500;line-height:1.7}.start-steps p{color:#97909f;margin:4px 0 0;font-size:12px;line-height:1.8}.start-example{background:#fcfaff;border-left:1px solid #eee8f4;flex-direction:column;justify-content:center;min-width:0;padding:22px 20px;display:flex}.example-caption{color:#9890a4;align-items:center;gap:6px;margin-bottom:15px;font-size:12px;display:flex}.example-caption>.status-dot{background:#b8a2d2;width:5px;height:5px}.start-example .code-block{background:#f7f3fc;border-color:#eae2f3}.start-example .code-toolbar{background:0 0;border-color:#ede5f5;padding:10px;font-size:11px}.start-example .code-toolbar>span{font-size:11px}.start-example pre{min-height:72px;padding:16px 11px;font-size:12px}.start-example>a{color:#8a73a3;align-self:flex-end;align-items:center;gap:5px;margin-top:14px;font-size:12px;display:flex}.group-cards{grid-template-columns:repeat(2,minmax(0,1fr));gap:13px;display:grid}.group-card{text-align:left;background:#fff;border:1px solid #ede8f3;border-radius:8px;align-items:flex-start;gap:14px;padding:20px 18px;transition:border-color .15s,box-shadow .15s;display:flex}.group-card:hover{border-color:#cdb9e7;box-shadow:0 4px 15px #76608e08}.group-card-icon{border-radius:9px;flex-shrink:0;justify-content:center;align-items:center;width:38px;height:38px;display:flex}.tone-0{color:#aa90cc;background:#f5effc}.tone-1{color:#839fcf;background:#f0f4fb}.tone-2{color:#87b4a2;background:#eff7f2}.tone-3{color:#c4a580;background:#fcf6ed}.group-card-copy{flex-direction:column;flex:1;gap:8px;min-width:0;display:flex}.group-card-title{color:#595063;flex-wrap:wrap;align-items:center;gap:10px;font-size:14px;font-weight:600;display:flex}.group-card-title>code{color:#88808f;font-size:11px;font-weight:400}.group-card-copy>.markdown{color:#89828f;font-size:12px;line-height:1.5}.group-card-copy>small{color:#a29aaa;margin-top:2px;font-size:11px}.group-card>svg{color:#c3b3d0;margin-top:10px}.convention-grid{border:1px solid #ede8f3;border-radius:8px;grid-template-columns:1fr 1fr;gap:35px;padding:23px;display:grid}.convention-grid>div>svg{color:#b49bcc;margin-bottom:10px}.convention-grid h3{color:#72617e;margin-bottom:10px;font-size:13px}.convention-grid p,.convention-grid .markdown{color:#88808f;margin:8px 0 0;font-size:12px;line-height:1.85}.convention-grid code{color:#a490b7;background:#f8f4fc;border-radius:3px;padding:3px 7px;font-size:13px}.info-callout{color:#8b779a;background:#fcfaff;border:1px solid #eee8f6;border-radius:7px;gap:12px;margin-top:18px;padding:17px 19px;display:flex}.info-callout>svg{margin-top:2px}.info-callout>div{width:100%;min-width:0}.info-callout strong{font-size:13px;font-weight:500}.info-callout p{color:#9a91a4;margin:6px 0;font-size:12px}.info-callout .raw-details{margin:8px 0 0;font-size:12px}.page-footer{border-top:1px solid var(--border);color:#a29ba8;flex-wrap:wrap;justify-content:space-between;gap:15px;margin-top:45px;padding:24px 0 30px;font-size:11px;display:flex}.footer-dot{margin:0 8px}.not-found{text-align:center;color:#9e89b1;padding:70px 0}.not-found h1{margin-top:18px;font-size:27px}.not-found p{color:#b2a5bd;font-size:14px}.not-found a{align-items:center;gap:7px;font-size:14px;display:inline-flex}.operation-header{margin-bottom:30px;scroll-margin-top:90px}.operation-header .eyebrow{letter-spacing:.5px;color:#ae9dc1;margin-bottom:15px}.operation-header .eyebrow>span{font-size:12px}.title-row{justify-content:space-between;align-items:center;gap:15px;margin-bottom:14px;display:flex}.title-row h1{overflow-wrap:anywhere;color:#302b3d;min-width:0;margin:0;font-size:29px}.operation-badges{overflow-wrap:anywhere;flex-wrap:wrap;align-items:center;gap:7px;margin-bottom:22px;display:flex}.doc-badge,.tag-badge,.api-status-badge{border-radius:4px;align-items:center;gap:4px;padding:3px 6px;font-size:11px;line-height:1.5;display:inline-flex}.doc-badge{color:#a78abb;background:#f5effc;border:1px solid #ede2f6}.tag-badge{color:#ad9cbb;background:#f7f5fa}.api-status-badge{color:var(--api-status-color);background:var(--api-status-background);white-space:nowrap}.endpoint-bar{background:#faf8fe;border:1px solid #eae2f3;border-radius:7px;align-items:center;gap:13px;margin-bottom:20px;padding:14px 15px;display:flex}.endpoint-bar .method{letter-spacing:0;background:#fff;border:1px solid #e9e6ed;border-radius:4px;min-width:auto;padding:4px 8px;font-size:13px}.endpoint-bar>code{color:#897298;overflow-wrap:anywhere;min-width:0;font-size:14px;line-height:1.6}.endpoint-bar .copy-button{flex-shrink:0;margin-left:auto}.operation-header>.markdown{color:#7c7385;font-size:14px}.server-line{color:#9e93a8;flex-wrap:wrap;align-items:center;gap:8px;margin-top:14px;font-size:12px;display:flex}.server-line code{color:#a38cb6;overflow-wrap:anywhere;background:#f8f4fc;border-radius:3px;min-width:0;padding:3px 6px}.external-doc-link{align-items:center;gap:5px;margin-top:7px;font-size:13px;display:inline-flex}.auth-public{color:#8db29b;background:#f9fcfa;border:1px solid #e6eee9;border-radius:7px;flex-wrap:wrap;align-items:center;gap:9px;padding:15px 17px;font-size:13px;display:flex}.auth-public strong{font-weight:500}.auth-public>span{color:#adbdaf;margin-left:5px;font-size:12px}.helper-text{color:#9f8dab;margin:10px 0 13px;font-size:12px;line-height:1.9}.auth-option{border:1px solid #eae3f1;border-radius:7px;align-items:flex-start;gap:15px;margin-top:10px;padding:15px 17px;display:flex}.auth-option-label{color:#a58ab9;white-space:nowrap;background:#f7f1fc;border-radius:4px;padding:3px 7px;font-size:11px}.auth-scheme{min-width:0}.auth-scheme>div:first-child{color:#8e74a1;flex-wrap:wrap;align-items:center;gap:8px;font-size:13px;display:flex}.auth-scheme strong{font-weight:500}.auth-scheme>div>code{color:#baa3cd;font-size:12px}.auth-scheme>.markdown,.auth-scheme p{color:#9d8bad;margin:7px 0 0;font-size:12px}.auth-scheme p code{color:#a88ebd}.parameter-group{margin-bottom:20px}.parameter-group h3{color:#ad9bbe;align-items:center;gap:6px;font-size:12px;display:flex}.parameter-group h3>span:first-child{color:#a88abb}.parameter-group h3>.muted{font-weight:400}.empty-note{color:#9988a8;overflow-wrap:anywhere;background:#fdfbff;border:1px dashed #e7dfef;border-radius:7px;align-items:center;gap:10px;padding:20px 17px;font-size:13px;display:flex}.empty-note code{font-size:12px}.copy-button{color:#a58db8;white-space:nowrap;border-radius:4px;justify-content:center;align-items:center;gap:5px;padding:5px 7px;font-size:12px;display:inline-flex}.copy-button:hover{color:#8b6bae;background:#f1e8fa}.copy-button.icon-only{padding:4px}.copy-button [role=status]{font-size:12px}.schema-table{background:#fff;border:1px solid #ebe3f2;border-radius:7px;min-width:0;overflow:hidden}.schema-head,.schema-row{grid-template-columns:minmax(140px,1.05fr) minmax(105px,.8fr) 48px minmax(160px,1.7fr);align-items:start;display:grid}.schema-head{color:#8f7e9c;background:#faf7fd;border-bottom:1px solid #ece5f4;font-size:12px}.schema-head>span{padding:12px}.schema-row{color:#8b759a;min-height:49px;font-size:12px;line-height:1.7}.schema-row+.schema-row{border-top:1px solid #f0eaf5}.schema-row>[role=cell]{overflow-wrap:anywhere;min-width:0;padding:12px}.schema-row>[role=cell].field-name{align-items:center;gap:3px;display:flex}.field-name>code{color:#786585;overflow-wrap:anywhere;font-size:12px}.expand-field{color:#b8a1c9;flex-shrink:0;justify-content:center;align-items:center;width:17px;height:19px;padding:0;display:flex}.expand-field:hover{color:var(--purple);background:#f6effb;border-radius:3px}.expand-field svg{transition:transform .15s}.field-spacer{flex-shrink:0;width:17px}.schema-root{background:#fdfbff}.field-type{flex-direction:column;gap:4px;display:flex}.field-type>code{color:#9a80ac;font-size:11px}.field-type>span{color:#ac98ba;overflow-wrap:anywhere;font-size:10px}.required{color:#ce939f;white-space:nowrap;font-size:11px}.optional{color:#d1c3db;font-size:12px}.field-description{color:#8b7a9a}.field-description>.markdown{font-size:12px;line-height:1.8}.field-description>.markdown>p{margin:0}.field-description>strong{margin-bottom:5px;font-size:12px;font-weight:500;display:block}.constraint-summary{color:#a08cae;flex-wrap:wrap;gap:2px 12px;margin-top:4px;font-size:11px;display:flex}.constraint-summary>span{overflow-wrap:anywhere;min-width:0}.constraint-summary code{font-size:inherit;color:#9275a7;white-space:pre-wrap}.constraint-details{margin-top:5px;font-size:11px}.constraint-details>summary{cursor:pointer;color:#9275a7}.constraint-details>summary:focus-visible{outline-offset:3px;border-radius:2px;outline:2px solid #7357e8}.constraints{color:#a08cae;flex-direction:column;gap:3px;margin-top:5px;font-size:11px;display:flex}.constraints>div{min-width:0}.constraints code{color:#9275a7;overflow-wrap:anywhere;white-space:pre-wrap;font-size:11px}.reference-note{color:#a084b1;background:#f6effb;border-radius:3px;margin-top:4px;padding:3px 5px;font-size:11px;display:inline-block}.media-controls{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;margin:3px 0 15px;display:flex}.media-controls label{color:#8d7f99;align-items:center;gap:9px;min-width:0;font-size:12px;display:flex}.media-controls select{color:#84738f;background:#fefcff;border-color:#e8dff0;font-size:12px}.source-note{color:#aaa0b2;font-size:11px}.example-heading{justify-content:space-between;align-items:center;gap:12px;margin:20px 0 11px;display:flex}.example-heading>select{color:#ae94c0;border-color:#e8deef;max-width:55%;padding:5px 20px 5px 8px;font-size:11px}.small-tabs{align-items:center;gap:18px;display:flex}.small-tabs>button{color:#a18cb0;padding:3px 0 6px;font-size:12px;position:relative}.small-tabs>button.active{color:#8763a3;font-weight:500}.small-tabs>button.active:after{content:"";background:#b99dce;border-radius:2px;height:2px;position:absolute;bottom:0;left:0;right:0}.code-block{background:#faf6fd;border:1px solid #e8dff0;border-radius:7px;min-width:0;overflow:hidden}.code-toolbar{background:#f9f4fd;border-bottom:1px solid #ece3f4;justify-content:space-between;align-items:center;gap:12px;padding:8px 12px;display:flex}.code-toolbar>span{color:#a084b1;overflow-wrap:anywhere;align-items:center;gap:5px;min-width:0;font-size:11px;display:flex}.code-toolbar .copy-button{color:#9c7daf;font-size:11px}.code-block pre{tab-size:2;color:#8b779d;scrollbar-width:thin;scrollbar-color:#e4d4ee transparent;max-height:510px;margin:0;padding:18px;font-size:13px;line-height:1.9;overflow:auto}.code-key{color:#815fa3}.code-string{color:#5e8f7d}.code-value{color:#af825b}.raw-details{color:#9b7dae;border:1px solid #ece3f2;border-radius:6px;margin:13px 0;font-size:12px;overflow:hidden}.raw-details>summary{color:#9b7dae;overflow-wrap:anywhere;background:#fcf9ff;padding:11px 13px}.raw-details>.code-block,.raw-details>.media-panel{margin:12px}.parameter-serialization{color:#b49ac6;border-bottom:1px solid #f4eef8;flex-wrap:wrap;gap:10px;padding:10px 5px;font-size:11px;display:flex}.parameter-serialization>span{color:#c2afd0}.parameter-serialization code{font-size:11px}.response-panel{border:1px solid #ebe2f3;border-radius:8px;overflow:hidden}.status-tabs{background:#fcfaff;border-bottom:1px solid #ece4f3;gap:4px;padding:0 12px;display:flex;overflow:auto}.status-tabs>button{color:#a18bb1;flex-shrink:0;align-items:center;gap:5px;padding:14px 10px;font-size:12px;display:flex;position:relative}.status-tabs>button.active{color:#8e6da8;background:#f8f2fc}.status-tabs>button.active:after{content:"";background:#b89ace;height:2px;position:absolute;bottom:0;left:0;right:0}.response-dot{background:#afadce;border-radius:50%;width:5px;height:5px}.response-dot.success{background:#98baa8}.response-dot.error{background:#d1a8ad}.response-panel>[role=tabpanel]{padding:20px}.response-description{flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:17px;display:flex}.response-code{color:#be9caa;background:#fcf0f4;border-radius:4px;padding:4px 7px;font-size:12px;display:inline-block}.response-code.success{color:#89af9c;background:#eff7f0}.response-description .markdown{color:#9984a8;font-size:12px}.response-description .markdown p{margin:0}.response-headers{color:#9c7fae;margin:0 0 20px;font-size:12px}.response-headers summary{padding:10px 0;line-height:1.8}.response-headers summary>span{background:#f7f1fc;border-radius:3px;margin-left:5px;padding:1px 5px;font-size:11px}.response-headers .schema-table{margin-top:5px}.policy-grid{grid-template-columns:repeat(2,minmax(0,1fr));align-items:start;gap:14px;display:grid}.policy-card{border:1px solid #ece2f3;border-radius:7px;overflow:hidden}.policy-card>summary{color:#8b6f9c;background:#fcf9ff;align-items:center;gap:8px;padding:13px 14px;font-size:13px;list-style:none;display:flex}.policy-card>summary::-webkit-details-marker{display:none}.policy-card>summary>code{color:#ab95b9;overflow-wrap:anywhere;font-size:10px}.policy-card>summary>svg{color:#cbb4d9;margin-left:auto}.policy-card:not([open])>summary>svg{transform:rotate(-90deg)}.policy-card dl{margin:0;padding:1px 14px 8px}.policy-card dl>div{border-top:1px solid #f3ecf8;grid-template-columns:1fr 1.05fr;align-items:start;gap:12px;padding:11px 0;display:grid}.policy-card dl>div:first-child{border:0}.policy-card dt{color:#9982aa;font-size:11px;line-height:1.6}.policy-card dt>code{color:#af99bf;overflow-wrap:anywhere;margin-top:2px;font-size:10px;display:block}.policy-card dd{color:#9175a4;overflow-wrap:anywhere;white-space:pre-wrap;margin:0;font-size:11px;line-height:1.8}.policy-card>p{color:#ad90bf;margin:0;padding:13px 14px;font-size:12px}.end-note{color:#9f8ab0;background:#fdfbff;border:1px dashed #eee3f6;border-radius:7px;align-items:center;gap:7px;margin-top:40px;padding:16px;font-size:12px;display:flex}.end-note>span{color:#c8b6d4;margin-left:auto;font-size:11px}.markdown{overflow-wrap:anywhere;color:#85748f;font-size:14px;line-height:1.85}.markdown p{margin:0 0 10px}.markdown p:last-child{margin-bottom:0}.markdown ul,.markdown ol{margin:7px 0;padding-left:20px}.markdown h1,.markdown h2,.markdown h3{margin:12px 0 8px;font-size:14px;line-height:1.6}.markdown code{overflow-wrap:anywhere;background:#f7f0fc;border-radius:3px;padding:2px 4px;font-size:.9em}.markdown pre{background:#faf5fe;border:1px solid #ede1f5;border-radius:6px;padding:14px;overflow:auto}.markdown pre>code{background:0 0;padding:0}.markdown table{border-collapse:collapse;max-width:100%;font-size:13px;display:block;overflow:auto}.markdown td,.markdown th{border:1px solid #ebe0f2;padding:7px 10px}.markdown blockquote{color:#bca1ce;border-left:3px solid #d9c4e8;margin:10px 0;padding-left:13px}.markdown img{max-width:100%;height:auto}@media (width>=1600px){.page-shell main{padding-left:70px;padding-right:70px}.page-outline{width:195px;margin-right:35px}}@media (width<=1290px){.page-outline{display:none}.page-shell main{max-width:1050px;padding-left:44px;padding-right:44px}.topbar{gap:43px}.stats-grid>div{padding:0 24px}}@media (width<=1000px){:root{--sidebar:242px}.page-shell main{padding-left:28px;padding-right:28px}.topbar{gap:35px;padding:0 22px}.brand-docs,.brand-divider{display:none}.top-nav{gap:22px}.getting-started{grid-template-columns:1fr}.start-example{border-top:1px solid #eee8f4;border-left:0}.stats-grid>div{gap:9px;padding:0 16px}.stat-icon{border-radius:8px;width:31px;height:31px}.stats-grid strong{font-size:22px}.group-cards{gap:10px}.group-card{gap:10px;padding:17px 13px}.group-card-icon{width:32px;height:32px}.group-card-title>code{display:none}.schema-head,.schema-row{grid-template-columns:minmax(105px,1fr) minmax(85px,.8fr) 38px minmax(130px,1.3fr)}.schema-row>[role=cell],.schema-head>span{padding:11px 8px}.hero-actions>span{display:none}.policy-grid{grid-template-columns:1fr}.auth-option{flex-wrap:wrap}.top-nav>button{font-size:13px}}@media (width<=800px){:root{--header:58px;--sidebar:294px}.topbar{gap:12px;padding:0 17px}.mobile-menu{color:#8c749f;padding:6px 4px;display:flex}.brand{gap:8px;font-size:16px}.brand-symbol{border-radius:8px;width:29px;height:29px}.brand-symbol svg{width:19px}.brand-docs{font-size:13px;display:inline}.brand-divider{margin:0 9px;font-size:18px;display:inline}.top-nav{display:none}.header-right{gap:0}.help-link{display:none}.version-pill{border:0;padding:5px 7px;font-size:11px}.sidebar{z-index:42;transition:transform .2s;top:0;transform:translate(-100%);box-shadow:5px 0 25px #43314d14}.sidebar.drawer-open{transform:translate(0)}.sidebar-tools{padding-top:24px}.desktop-chevron{display:none}.close-drawer{margin-left:auto;display:flex}.drawer-backdrop{z-index:40;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);background:#34234550;display:block;position:fixed;inset:0}.page-shell{margin-left:0}.page-shell main{max-width:100%;padding:25px 28px 0}.breadcrumb{margin-bottom:30px}.overview-hero h1{font-size:30px}.stats-grid>div{padding:0 25px}.getting-started{grid-template-columns:1fr 1.1fr}.start-example{border-top:0;border-left:1px solid #eee8f4}.start-steps{padding:20px 17px 0}.group-cards{gap:12px}.group-card{padding:18px 16px}.schema-head,.schema-row{grid-template-columns:minmax(115px,1fr) minmax(90px,.8fr) 44px minmax(150px,1.6fr)}.policy-grid{grid-template-columns:1fr 1fr}.auth-option{flex-wrap:nowrap}}@media (width<=570px){.page-shell main{padding:22px 20px 0}.brand-docs,.brand-divider{display:none}.version-pill{font-size:11px}.breadcrumb{gap:7px;margin-bottom:27px;font-size:11px}.eyebrow{margin-bottom:14px;font-size:11px}.overview-hero h1{letter-spacing:-.7px;font-size:28px}.hero-lead{margin-bottom:15px;font-size:14px;line-height:1.8}.overview-hero>.markdown{font-size:13px}.hero-actions{gap:9px;margin-top:22px;margin-bottom:26px}.primary-button,.secondary-button{padding:10px 12px;font-size:12px}.stats-grid{margin-bottom:30px;padding:19px 0}.stats-grid>div{align-items:flex-start;gap:8px;padding:0 11px}.stat-icon{display:none}.stats-grid>div>div{gap:7px;padding-left:3px}.stats-grid strong{font-size:23px}.stats-grid strong small{margin-left:4px;font-size:10px}.stats-grid>div>div>span{font-size:11px}.section-heading{gap:6px;margin-bottom:15px}.section-heading h2{font-size:16px}.section-heading>span:last-child:not(.count-badge):not(.required){margin-left:3px;font-size:11px}.doc-section{margin-bottom:28px}.getting-started{grid-template-columns:1fr}.start-steps{padding:22px 21px 2px}.start-steps>div{margin-bottom:20px}.start-steps strong{font-size:14px}.start-steps p{font-size:12px}.start-example{border-top:1px solid #eee8f4;border-left:0;padding:19px 20px}.start-example pre{min-height:60px;font-size:12px}.group-cards{grid-template-columns:1fr;gap:10px}.group-card{gap:14px;padding:18px}.group-card-icon{width:36px;height:36px}.group-card-title{font-size:14px}.group-card-title>code{display:inline}.group-card-copy>.markdown{font-size:12px}.group-card-copy>small{font-size:11px}.convention-grid{grid-template-columns:1fr;gap:25px;padding:21px}.convention-grid h3{font-size:14px}.convention-grid p,.convention-grid .markdown{font-size:13px}.info-callout{gap:9px;padding:15px}.page-footer{flex-direction:column;gap:8px;margin-top:30px;padding-bottom:25px;font-size:11px}.title-row h1{font-size:25px}.title-row>.copy-button{padding:4px 0;font-size:11px}.title-row>.copy-button>span{font-size:11px}.endpoint-bar{gap:9px;padding:12px 10px}.endpoint-bar>code,.operation-header>.markdown{font-size:13px}.auth-public>span{margin:0;font-size:11px}.auth-public{gap:7px;padding:13px 12px}.auth-option{flex-direction:column;gap:10px;padding:14px}.schema-table{overflow-x:auto}.schema-head,.schema-row{grid-template-columns:145px 110px 40px minmax(230px,1.7fr);min-width:540px}.schema-row>[role=cell]{padding:11px 9px}.field-description>.markdown{font-size:12px}.response-panel>[role=tabpanel]{padding:14px 12px}.response-panel .schema-head,.response-panel .schema-row{grid-template-columns:135px 100px 37px minmax(225px,1.7fr);min-width:510px}.code-block pre{padding:15px 12px;font-size:12px}.code-toolbar{padding:7px 10px}.code-toolbar>span{font-size:10px}.media-controls{gap:7px}.media-controls label{gap:6px;font-size:11px}.media-controls select{font-size:11px}.source-note{display:none}.policy-grid{grid-template-columns:1fr}.policy-card>summary{padding:13px}.policy-card dl{padding:0 13px 7px}.policy-card dt{font-size:12px}.policy-card dt>code{font-size:11px}.policy-card dd{font-size:12px}.end-note{gap:5px;padding:13px 11px;font-size:11px}.end-note>span{display:none}.response-description{gap:7px}.empty-note{padding:17px 13px;font-size:12px;line-height:1.8}.small-tabs{gap:14px}}@media (prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}}.group-card-title{text-align:left;overflow-wrap:anywhere;padding:0}.group-card-copy .markdown p{margin:0}.group-card-copy .markdown strong{font-weight:600}.group-toggle>span:not(.group-count){overflow-wrap:anywhere;text-align:left;min-width:0}.overview-hero h1,.eyebrow,.page-footer,.version-pill{overflow-wrap:anywhere}.eyebrow{flex-wrap:wrap}.copy-dialog{border:1px solid var(--border);color:#42384d;border-radius:12px;width:min(560px,100vw - 32px);padding:24px;box-shadow:0 18px 80px #30203b30}.copy-dialog::backdrop{background:#34234570}.copy-dialog p{font-size:13px}.copy-dialog textarea{resize:vertical;border:1px solid #d9cee9;border-radius:6px;width:100%;min-height:140px;max-height:50vh;margin-bottom:16px;padding:12px;font:12px/1.6 SFMono-Regular,Consolas,monospace}@media (width<=800px){.brand{flex:1;max-width:none}.header-right{min-width:0;max-width:28%}.version-pill{white-space:normal}}
2
+ /*$vite$:1*/